Add readline 8.2 to third_party

This commit is contained in:
Justine Tunney 2023-12-11 05:59:20 -08:00
parent cbe72c4339
commit e1f65d5f2b
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
67 changed files with 37504 additions and 0 deletions

View file

@ -224,6 +224,7 @@ include dsp/BUILD.mk # │
include third_party/stb/BUILD.mk # │
include third_party/mbedtls/BUILD.mk # │
include third_party/ncurses/BUILD.mk # │
include third_party/readline/BUILD.mk # │
include third_party/libcxx/BUILD.mk # │
include third_party/pcre/BUILD.mk # │
include third_party/less/BUILD.mk # │

View file

@ -29,6 +29,7 @@ o/$(MODE)/third_party: \
o/$(MODE)/third_party/puff \
o/$(MODE)/third_party/python \
o/$(MODE)/third_party/quickjs \
o/$(MODE)/third_party/readline \
o/$(MODE)/third_party/regex \
o/$(MODE)/third_party/sed \
o/$(MODE)/third_party/smallz4 \

71
third_party/readline/BUILD.mk vendored Normal file
View file

@ -0,0 +1,71 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += THIRD_PARTY_READLINE
THIRD_PARTY_READLINE_ARTIFACTS += THIRD_PARTY_READLINE_A
THIRD_PARTY_READLINE = $(THIRD_PARTY_READLINE_A_DEPS) $(THIRD_PARTY_READLINE_A)
THIRD_PARTY_READLINE_A = o/$(MODE)/third_party/readline/readline.a
THIRD_PARTY_READLINE_A_FILES := $(wildcard third_party/readline/*)
THIRD_PARTY_READLINE_A_HDRS = $(filter %.h,$(THIRD_PARTY_READLINE_A_FILES))
THIRD_PARTY_READLINE_A_INCS = $(filter %.inc,$(THIRD_PARTY_READLINE_A_FILES))
THIRD_PARTY_READLINE_A_SRCS = $(filter %.c,$(THIRD_PARTY_READLINE_A_FILES))
THIRD_PARTY_READLINE_A_OBJS = $(THIRD_PARTY_READLINE_A_SRCS:%.c=o/$(MODE)/%.o)
THIRD_PARTY_READLINE_A_CHECKS = $(THIRD_PARTY_READLINE_A).pkg
THIRD_PARTY_READLINE_A_DIRECTDEPS = \
LIBC_CALLS \
LIBC_FMT \
LIBC_INTRIN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_PROC \
LIBC_RUNTIME \
LIBC_STDIO \
LIBC_STR \
LIBC_SYSV \
THIRD_PARTY_MUSL \
THIRD_PARTY_NCURSES
THIRD_PARTY_READLINE_A_DEPS := \
$(call uniq,$(foreach x,$(THIRD_PARTY_READLINE_A_DIRECTDEPS),$($(x))))
$(THIRD_PARTY_READLINE_A): \
third_party/readline/ \
$(THIRD_PARTY_READLINE_A).pkg \
$(THIRD_PARTY_READLINE_A_OBJS)
$(THIRD_PARTY_READLINE_A).pkg: \
$(THIRD_PARTY_READLINE_A_OBJS) \
$(foreach x,$(THIRD_PARTY_READLINE_A_DIRECTDEPS),$($(x)_A).pkg)
$(THIRD_PARTY_READLINE_A_OBJS): private \
CPPFLAGS += \
-DHAVE_CONFIG_H \
-DRL_LIBRARY_VERSION=\"8.2\" \
-DBRACKETED_PASTE_DEFAULT=1
$(THIRD_PARTY_READLINE_A_OBJS): private \
CFLAGS += \
-Wno-unused-but-set-variable \
-Wno-stringop-truncation \
-Wno-maybe-uninitialized \
-Wno-unused-variable \
-Wno-unused-label \
-Wno-parentheses \
-fportcosmo
THIRD_PARTY_READLINE_BINS = $(THIRD_PARTY_READLINE_COMS) $(THIRD_PARTY_READLINE_COMS:%=%.dbg)
THIRD_PARTY_READLINE_LIBS = $(foreach x,$(THIRD_PARTY_READLINE_ARTIFACTS),$($(x)))
THIRD_PARTY_READLINE_SRCS = $(foreach x,$(THIRD_PARTY_READLINE_ARTIFACTS),$($(x)_SRCS))
THIRD_PARTY_READLINE_HDRS = $(foreach x,$(THIRD_PARTY_READLINE_ARTIFACTS),$($(x)_HDRS))
THIRD_PARTY_READLINE_INCS = $(foreach x,$(THIRD_PARTY_READLINE_ARTIFACTS),$($(x)_INCS))
THIRD_PARTY_READLINE_CHECKS = $(foreach x,$(THIRD_PARTY_READLINE_ARTIFACTS),$($(x)_CHECKS))
THIRD_PARTY_READLINE_OBJS = $(foreach x,$(THIRD_PARTY_READLINE_ARTIFACTS),$($(x)_OBJS))
$(THIRD_PARTY_READLINE_A_OBJS): $(BUILD_FILES) third_party/readline/BUILD.mk
.PHONY: o/$(MODE)/third_party/readline
o/$(MODE)/third_party/readline: \
$(THIRD_PARTY_READLINE_A) \
$(THIRD_PARTY_READLINE_BINS) \
$(THIRD_PARTY_READLINE_CHECKS)

674
third_party/readline/LICENSE vendored Normal file
View file

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

15
third_party/readline/README.cosmo vendored Normal file
View file

@ -0,0 +1,15 @@
DESCRIPTION
readline is a teletypewriter line editing library
LICENSE
GPL v3
ORIGIN
https://ftp.gnu.org/gnu/readline/readline-8.2.tar.gz
LOCAL CHANGES
- Favor FIONREAD in _rl_input_available()

54
third_party/readline/ansi_stdlib.h vendored Normal file
View file

@ -0,0 +1,54 @@
/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */
/* A minimal stdlib.h containing extern declarations for those functions
that bash uses. */
/* Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_STDLIB_H_)
#define _STDLIB_H_ 1
/* String conversion functions. */
extern int atoi ();
extern double atof ();
extern double strtod ();
/* Memory allocation functions. */
/* Generic pointer type. */
#ifndef PTR_T
#if defined (__STDC__)
# define PTR_T void *
#else
# define PTR_T char *
#endif
#endif /* PTR_T */
extern PTR_T malloc ();
extern PTR_T realloc ();
extern void free ();
/* Other miscellaneous functions. */
extern void abort ();
extern void exit ();
extern char *getenv ();
extern void qsort ();
#endif /* _STDLIB_H */

3082
third_party/readline/bind.c vendored Normal file

File diff suppressed because it is too large Load diff

378
third_party/readline/callback.c vendored Normal file
View file

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

165
third_party/readline/chardefs.h vendored Normal file
View file

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

320
third_party/readline/colors.c vendored Normal file
View file

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

126
third_party/readline/colors.h vendored Normal file
View file

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

106
third_party/readline/compat.c vendored Normal file
View file

@ -0,0 +1,106 @@
/* compat.c -- backwards compatibility functions. */
/* Copyright (C) 2000-2021 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Readline is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include <stdio.h>
#include "rlstdc.h"
#include "rltypedefs.h"
extern void rl_free_undo_list (void);
extern int rl_maybe_save_line (void);
extern int rl_maybe_unsave_line (void);
extern int rl_maybe_replace_line (void);
extern int rl_crlf (void);
extern int rl_ding (void);
extern int rl_alphabetic (int);
extern char **rl_completion_matches (const char *, rl_compentry_func_t *);
extern char *rl_username_completion_function (const char *, int);
extern char *rl_filename_completion_function (const char *, int);
/* Provide backwards-compatible entry points for old function names. */
void
free_undo_list (void)
{
rl_free_undo_list ();
}
int
maybe_replace_line (void)
{
return rl_maybe_replace_line ();
}
int
maybe_save_line (void)
{
return rl_maybe_save_line ();
}
int
maybe_unsave_line (void)
{
return rl_maybe_unsave_line ();
}
int
ding (void)
{
return rl_ding ();
}
int
crlf (void)
{
return rl_crlf ();
}
int
alphabetic (int c)
{
return rl_alphabetic (c);
}
char **
completion_matches (const char *s, rl_compentry_func_t *f)
{
return rl_completion_matches (s, f);
}
char *
username_completion_function (const char *s, int i)
{
return rl_username_completion_function (s, i);
}
char *
filename_completion_function (const char *s, int i)
{
return rl_filename_completion_function (s, i);
}

2992
third_party/readline/complete.c vendored Normal file

File diff suppressed because it is too large Load diff

312
third_party/readline/config.h vendored Normal file
View file

@ -0,0 +1,312 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Maintained by hand. */
/* Template definitions for autoconf */
/* These are set by AC_USE_SYSTEM_EXTENSIONS */
#define __EXTENSIONS__ 1
#define _ALL_SOURCE 1
#define _GNU_SOURCE 1
/* #undef _POSIX_SOURCE */
/* #undef _POSIX_1_SOURCE */
#define _POSIX_PTHREAD_SEMANTICS 1
#define _TANDEM_SOURCE 1
/* #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 */
#define PROTOTYPES 1
#define __PROTOTYPES 1
/* #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. */
#define HAVE_CHOWN 1
/* Define if you have the fcntl function. */
#define HAVE_FCNTL 1
/* Define if you have the fnmatch function. */
#define HAVE_FNMATCH 1
/* Define if you have the getpwent function. */
#define HAVE_GETPWENT 1
/* Define if you have the getpwnam function. */
#define HAVE_GETPWNAM 1
/* Define if you have the getpwuid function. */
#define HAVE_GETPWUID 1
/* Define if you have the gettimeofday function. */
#define HAVE_GETTIMEOFDAY 1
/* Define if you have the isascii function. */
#define HAVE_ISASCII 1
/* Define if you have the iswctype function. */
#define HAVE_ISWCTYPE 1
/* Define if you have the iswlower function. */
#define HAVE_ISWLOWER 1
/* Define if you have the iswupper function. */
#define HAVE_ISWUPPER 1
/* Define if you have the isxdigit function. */
#define HAVE_ISXDIGIT 1
/* Define if you have the kill function. */
#define HAVE_KILL 1
/* Define if you have the lstat function. */
#define HAVE_LSTAT 1
/* Define if you have the mbrlen function. */
#define HAVE_MBRLEN 1
/* Define if you have the mbrtowc function. */
#define HAVE_MBRTOWC 1
/* Define if you have the mbsrtowcs function. */
#define HAVE_MBSRTOWCS 1
/* Define if you have the memmove function. */
#define HAVE_MEMMOVE 1
/* Define if you have the pselect function. */
#define HAVE_PSELECT 1
/* Define if you have the putenv function. */
#define HAVE_PUTENV 1
/* Define if you have the readlink function. */
#define HAVE_READLINK 1
/* Define if you have the select function. */
#define HAVE_SELECT 1
/* Define if you have the setenv function. */
#define HAVE_SETENV 1
/* Define if you have the setitimer function. */
#define HAVE_SETITIMER 1
/* Define if you have the setlocale function. */
#define HAVE_SETLOCALE 1
/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP 1
/* Define if you have the strcoll function. */
#define HAVE_STRCOLL 1
/* #undef STRCOLL_BROKEN */
/* Define if you have the strpbrk function. */
#define HAVE_STRPBRK 1
/* Define if you have the sysconf function. */
#define HAVE_SYSCONF 1
/* Define if you have the tcgetattr function. */
#define HAVE_TCGETATTR 1
/* Define if you have the towlower function. */
#define HAVE_TOWLOWER 1
/* Define if you have the towupper function. */
#define HAVE_TOWUPPER 1
/* Define if you have the vsnprintf function. */
#define HAVE_VSNPRINTF 1
/* Define if you have the wcrtomb function. */
#define HAVE_WCRTOMB 1
/* Define if you have the wcscoll function. */
#define HAVE_WCSCOLL 1
/* Define if you have the wctype function. */
#define HAVE_WCTYPE 1
/* Define if you have the wcwidth function. */
#define HAVE_WCWIDTH 1
/* and whether it works */
/* #undef WCWIDTH_BROKEN */
/* Define if you have the <dirent.h> header file. */
#define HAVE_DIRENT_H 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <langinfo.h> header file. */
#define HAVE_LANGINFO_H 1
/* Define if you have the <libaudit.h> header file. */
/* #undef HAVE_LIBAUDIT_H */
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if you have the <ndir.h> header file. */
/* #undef HAVE_NDIR_H */
/* Define if you have the "third_party/ncurses/termcap.h" header file. */
#define HAVE_NCURSES_TERMCAP_H 1
/* Define if you have the <pwd.h> header file. */
#define HAVE_PWD_H 1
/* Define if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define if you have the <stdbool.h> header file. */
#define HAVE_STDBOOL_H 1
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* 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. */
#define HAVE_SYS_FILE_H 1
/* Define if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* 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. */
#define HAVE_SYS_SELECT_H 1
/* 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. */
#define HAVE_SYS_TIME_H 1
/* 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. */
#define HAVE_TERMIOS_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define if you have the <varargs.h> header file. */
/* #undef HAVE_VARARGS_H */
/* Define if you have the <wchar.h> header file. */
#define HAVE_WCHAR_H 1
/* Define if you have the <wctype.h> header file. */
#define HAVE_WCTYPE_H 1
#define HAVE_MBSTATE_T 1
/* Define if you have wchar_t in <wctype.h>. */
#define HAVE_WCHAR_T 1
/* Define if you have wctype_t in <wctype.h>. */
#define HAVE_WCTYPE_T 1
/* Define if you have wint_t in <wctype.h>. */
#define HAVE_WINT_T 1
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#define HAVE_LANGINFO_CODESET 1
/* Define if you have <linux/audit.h> and it defines AUDIT_USER_TTY */
#define HAVE_DECL_AUDIT_USER_TTY 0
/* Definitions pulled in from aclocal.m4. */
/* #undef GWINSZ_IN_SYS_IOCTL */
#define STRUCT_WINSIZE_IN_SYS_IOCTL 1
/* #undef STRUCT_WINSIZE_IN_TERMIOS */
/* #undef TIOCSTAT_IN_SYS_IOCTL */
#define FIONREAD_IN_SYS_IOCTL 1
#define SPEED_T_IN_SYS_TYPES 1
#define HAVE_GETPW_DECLS 1
#define HAVE_STRUCT_DIRENT_D_INO 1
/* #undef HAVE_STRUCT_DIRENT_D_FILENO */
/* #undef HAVE_STRUCT_DIRENT_D_NAMLEN */
#define HAVE_TIMEVAL 1
/* #undef HAVE_BSD_SIGNALS */
#define HAVE_POSIX_SIGNALS 1
/* #undef HAVE_USG_SIGHOLD */
/* #undef MUST_REINSTALL_SIGHANDLERS */
#define HAVE_POSIX_SIGSETJMP 1
/* #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 */

3583
third_party/readline/display.c vendored Normal file

File diff suppressed because it is too large Load diff

872
third_party/readline/emacs_keymap.inc vendored Normal file
View file

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

273
third_party/readline/funmap.c vendored Normal file
View file

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

1718
third_party/readline/histexpand.c vendored Normal file

File diff suppressed because it is too large Load diff

833
third_party/readline/histfile.c vendored Normal file
View file

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

92
third_party/readline/histlib.h vendored Normal file
View file

@ -0,0 +1,92 @@
/* histlib.h -- internal definitions for the history library. */
/* Copyright (C) 1989-2009,2021-2022 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
History is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
History is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with History. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_HISTLIB_H_)
#define _HISTLIB_H_
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if !defined (STREQ)
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
#define STREQN(a, b, n) (((n) == 0) ? (1) \
: ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
#endif
#ifndef savestring
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
#ifndef _rl_digit_p
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
#endif
#ifndef _rl_digit_value
#define _rl_digit_value(c) ((c) - '0')
#endif
#ifndef member
# if !defined (strchr) && !defined (__STDC__)
extern char *strchr ();
# endif /* !strchr && !__STDC__ */
#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
#endif
#ifndef FREE
# define FREE(x) if (x) free (x)
#endif
/* Possible history errors passed to hist_error. */
#define EVENT_NOT_FOUND 0
#define BAD_WORD_SPEC 1
#define SUBST_FAILED 2
#define BAD_MODIFIER 3
#define NO_PREV_SUBST 4
/* Possible definitions for history starting point specification. */
#define NON_ANCHORED_SEARCH 0
#define ANCHORED_SEARCH 0x01
#define PATTERN_SEARCH 0x02
/* Possible definitions for what style of writing the history file we want. */
#define HISTORY_APPEND 0
#define HISTORY_OVERWRITE 1
/* internal extern function declarations used by other parts of the library */
/* histsearch.c */
extern int _hs_history_patsearch (const char *, int, int);
/* history.c */
extern void _hs_replace_history_data (int, histdata_t *, histdata_t *);
extern int _hs_at_end_of_history (void);
/* histfile.c */
extern void _hs_append_history_line (int, const char *);
#endif /* !_HISTLIB_H_ */

613
third_party/readline/history.c vendored Normal file
View file

@ -0,0 +1,613 @@
/* 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))
{
/* 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;
(void)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
third_party/readline/history.h vendored Normal file
View file

@ -0,0 +1,291 @@
/* history.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989-2022 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
History is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
History is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with History. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _HISTORY_H_
#define _HISTORY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <time.h> /* XXX - for history timestamp code */
#if defined READLINE_LIBRARY
# include "rlstdc.h"
# include "rltypedefs.h"
#else
# include "third_party/readline/rlstdc.h"
# include "third_party/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_ */

287
third_party/readline/histsearch.c vendored Normal file
View file

@ -0,0 +1,287 @@
/* histsearch.c -- searching the history list. */
/* Copyright (C) 1989, 1992-2009,2017,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/>.
*/
#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
#if defined (HAVE_FNMATCH)
# include <fnmatch.h>
#endif
#include "history.h"
#include "histlib.h"
#include "xmalloc.h"
/* The list of alternate characters that can delimit a history search
string. */
char *history_search_delimiter_chars = (char *)NULL;
static int history_search_internal (const char *, int, int);
/* Search the history for STRING, starting at history_offset.
If DIRECTION < 0, then the search is through previous entries, else
through subsequent. If ANCHORED is non-zero, the string must
appear at the beginning of a history line, otherwise, the string
may appear anywhere in the line. 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. */
static int
history_search_internal (const char *string, int direction, int flags)
{
register int i, reverse;
register char *line;
register int line_index;
int string_len, anchored, patsearch;
HIST_ENTRY **the_history; /* local */
i = history_offset;
reverse = (direction < 0);
anchored = (flags & ANCHORED_SEARCH);
#if defined (HAVE_FNMATCH)
patsearch = (flags & PATTERN_SEARCH);
#else
patsearch = 0;
#endif
/* Take care of trivial cases first. */
if (string == 0 || *string == '\0')
return (-1);
if (!history_length || ((i >= history_length) && !reverse))
return (-1);
if (reverse && (i >= history_length))
i = history_length - 1;
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
the_history = history_list ();
string_len = strlen (string);
while (1)
{
/* Search each line in the history list for STRING. */
/* At limit for direction? */
if ((reverse && i < 0) || (!reverse && i == history_length))
return (-1);
line = the_history[i]->line;
line_index = strlen (line);
/* If STRING is longer than line, no match. */
if (patsearch == 0 && (string_len > line_index))
{
NEXT_LINE ();
continue;
}
/* Handle anchored searches first. */
if (anchored == ANCHORED_SEARCH)
{
#if defined (HAVE_FNMATCH)
if (patsearch)
{
if (fnmatch (string, line, 0) == 0)
{
history_offset = i;
return (0);
}
}
else
#endif
if (STREQN (string, line, string_len))
{
history_offset = i;
return (0);
}
NEXT_LINE ();
continue;
}
/* Do substring search. */
if (reverse)
{
line_index -= (patsearch == 0) ? string_len : 1;
while (line_index >= 0)
{
#if defined (HAVE_FNMATCH)
if (patsearch)
{
if (fnmatch (string, line + line_index, 0) == 0)
{
history_offset = i;
return (line_index);
}
}
else
#endif
if (STREQN (string, line + line_index, string_len))
{
history_offset = i;
return (line_index);
}
line_index--;
}
}
else
{
register int limit;
limit = line_index - string_len + 1;
line_index = 0;
while (line_index < limit)
{
#if defined (HAVE_FNMATCH)
if (patsearch)
{
if (fnmatch (string, line + line_index, 0) == 0)
{
history_offset = i;
return (line_index);
}
}
else
#endif
if (STREQN (string, line + line_index, string_len))
{
history_offset = i;
return (line_index);
}
line_index++;
}
}
NEXT_LINE ();
}
}
int
_hs_history_patsearch (const char *string, int direction, int flags)
{
char *pat;
size_t len, start;
int ret, unescaped_backslash;
#if defined (HAVE_FNMATCH)
/* Assume that the string passed does not have a leading `^' and any
anchored search request is captured in FLAGS */
len = strlen (string);
ret = len - 1;
/* fnmatch is required to reject a pattern that ends with an unescaped
backslash */
if ((unescaped_backslash = (string[ret] == '\\')))
{
while (ret > 0 && string[--ret] == '\\')
unescaped_backslash = 1 - unescaped_backslash;
}
if (unescaped_backslash)
return -1;
pat = (char *)xmalloc (len + 3);
/* If the search string is not anchored, we'll be calling fnmatch (assuming
we have it). Prefix a `*' to the front of the search string so we search
anywhere in the line. */
if ((flags & ANCHORED_SEARCH) == 0 && string[0] != '*')
{
pat[0] = '*';
start = 1;
len++;
}
else
{
start = 0;
}
/* Attempt to reduce the number of searches by tacking a `*' onto the end
of a pattern that doesn't have one. Assume a pattern that ends in a
backslash contains an even number of trailing backslashes; we check
above */
strcpy (pat + start, string);
if (pat[len - 1] != '*')
{
pat[len] = '*'; /* XXX */
pat[len+1] = '\0';
}
#else
pat = string;
#endif
ret = history_search_internal (pat, direction, flags|PATTERN_SEARCH);
if (pat != string)
xfree (pat);
return ret;
}
/* Do a non-anchored search for STRING through the history in DIRECTION. */
int
history_search (const char *string, int direction)
{
return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
}
/* Do an anchored search for string through the history in DIRECTION. */
int
history_search_prefix (const char *string, int direction)
{
return (history_search_internal (string, direction, ANCHORED_SEARCH));
}
/* Search for STRING in the history list. DIR is < 0 for searching
backwards. POS is an absolute index into the history list at
which point to begin searching. */
int
history_search_pos (const char *string, int dir, int pos)
{
int ret, old;
old = where_history ();
history_set_pos (pos);
if (history_search (string, dir) == -1)
{
history_set_pos (old);
return (-1);
}
ret = where_history ();
history_set_pos (old);
return ret;
}

1002
third_party/readline/input.c vendored Normal file

File diff suppressed because it is too large Load diff

893
third_party/readline/isearch.c vendored Normal file
View file

@ -0,0 +1,893 @@
/* isearch.c - incremental searching */
/* **************************************************************** */
/* */
/* I-Search and Searching */
/* */
/* **************************************************************** */
/* 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
#include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Variables exported to other files in the readline library. */
char *_rl_isearch_terminators = (char *)NULL;
_rl_search_cxt *_rl_iscxt = 0;
static int rl_search_history (int, int);
static _rl_search_cxt *_rl_isearch_init (int);
static void _rl_isearch_fini (_rl_search_cxt *);
/* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. Now part of isearch context. */
/* static char *prev_line_found; */
/* Last search string and its length. */
static char *last_isearch_string;
static int last_isearch_string_len;
static char * const default_isearch_terminators = "\033\012";
_rl_search_cxt *
_rl_scxt_alloc (int type, int flags)
{
_rl_search_cxt *cxt;
cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt));
cxt->type = type;
cxt->sflags = flags;
cxt->search_string = 0;
cxt->search_string_size = cxt->search_string_index = 0;
cxt->lines = 0;
cxt->allocated_line = 0;
cxt->hlen = cxt->hindex = 0;
cxt->save_point = rl_point;
cxt->save_mark = rl_mark;
cxt->save_line = where_history ();
cxt->last_found_line = cxt->save_line;
cxt->prev_line_found = 0;
cxt->save_undo_list = 0;
cxt->keymap = _rl_keymap;
cxt->okeymap = _rl_keymap;
cxt->history_pos = 0;
cxt->direction = 0;
cxt->prevc = cxt->lastc = 0;
cxt->sline = 0;
cxt->sline_len = cxt->sline_index = 0;
cxt->search_terminators = 0;
return cxt;
}
void
_rl_scxt_dispose (_rl_search_cxt *cxt, int flags)
{
FREE (cxt->search_string);
FREE (cxt->allocated_line);
FREE (cxt->lines);
xfree (cxt);
}
/* Search backwards through the history looking for a string which is typed
interactively. Start with the current line. */
int
rl_reverse_search_history (int sign, int key)
{
return (rl_search_history (-sign, key));
}
/* Search forwards through the history looking for a string which is typed
interactively. Start with the current line. */
int
rl_forward_search_history (int sign, int key)
{
return (rl_search_history (sign, key));
}
/* Display the current state of the search in the echo-area.
SEARCH_STRING contains the string that is being searched for,
DIRECTION is zero for forward, or non-zero for reverse,
WHERE is the history list number of the current line. If it is
-1, then this line is the starting one. */
static void
rl_display_search (char *search_string, int flags, int where)
{
char *message;
int msglen, searchlen;
searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
message = (char *)xmalloc (searchlen + 64);
msglen = 0;
#if defined (NOTDEF)
if (where != -1)
{
sprintf (message, "[%d]", where + history_base);
msglen = strlen (message);
}
#endif /* NOTDEF */
message[msglen++] = '(';
if (flags & SF_FAILED)
{
strcpy (message + msglen, "failed ");
msglen += 7;
}
if (flags & SF_REVERSE)
{
strcpy (message + msglen, "reverse-");
msglen += 8;
}
strcpy (message + msglen, "i-search)`");
msglen += 10;
if (search_string && *search_string)
{
strcpy (message + msglen, search_string);
msglen += searchlen;
}
else
_rl_optimize_redisplay ();
strcpy (message + msglen, "': ");
rl_message ("%s", message);
xfree (message);
#if 0
/* rl_message calls this */
(*rl_redisplay_function) ();
#endif
}
static _rl_search_cxt *
_rl_isearch_init (int direction)
{
_rl_search_cxt *cxt;
register int i;
HIST_ENTRY **hlist;
cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0);
if (direction < 0)
cxt->sflags |= SF_REVERSE;
cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
: default_isearch_terminators;
/* Create an array of pointers to the lines that we want to search. */
hlist = history_list ();
rl_maybe_replace_line ();
i = 0;
if (hlist)
for (i = 0; hlist[i]; i++);
/* Allocate space for this many lines, +1 for the current input line,
and remember those lines. */
cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
for (i = 0; i < cxt->hlen; i++)
cxt->lines[i] = hlist[i]->line;
if (_rl_saved_line_for_history)
cxt->lines[i] = _rl_saved_line_for_history->line;
else
{
/* Keep track of this so we can free it. */
cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
strcpy (cxt->allocated_line, &rl_line_buffer[0]);
cxt->lines[i] = cxt->allocated_line;
}
cxt->hlen++;
/* The line where we start the search. */
cxt->history_pos = cxt->save_line;
rl_save_prompt ();
/* Initialize search parameters. */
cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128);
cxt->search_string[cxt->search_string_index = 0] = '\0';
/* Normalize DIRECTION into 1 or -1. */
cxt->direction = (direction >= 0) ? 1 : -1;
cxt->sline = rl_line_buffer;
cxt->sline_len = strlen (cxt->sline);
cxt->sline_index = rl_point;
_rl_iscxt = cxt; /* save globally */
/* experimental right now */
_rl_init_executing_keyseq ();
return cxt;
}
static void
_rl_isearch_fini (_rl_search_cxt *cxt)
{
/* First put back the original state. */
rl_replace_line (cxt->lines[cxt->save_line], 0);
rl_restore_prompt ();
/* Save the search string for possible later use. */
FREE (last_isearch_string);
last_isearch_string = cxt->search_string;
last_isearch_string_len = cxt->search_string_index;
cxt->search_string = 0;
cxt->search_string_size = 0;
cxt->search_string_index = 0;
if (cxt->last_found_line < cxt->save_line)
rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0);
else
rl_get_next_history (cxt->last_found_line - cxt->save_line, 0);
/* If the string was not found, put point at the end of the last matching
line. If last_found_line == orig_line, we didn't find any matching
history lines at all, so put point back in its original position. */
if (cxt->sline_index < 0)
{
if (cxt->last_found_line == cxt->save_line)
cxt->sline_index = cxt->save_point;
else
cxt->sline_index = strlen (rl_line_buffer);
rl_mark = cxt->save_mark;
rl_deactivate_mark ();
}
rl_point = cxt->sline_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it.
If we want to highlight the search string, this is where to set the
point and mark to do it. */
_rl_fix_point (0);
rl_deactivate_mark ();
/* _rl_optimize_redisplay (); */
rl_clear_message ();
}
/* XXX - we could use _rl_bracketed_read_mbstring () here. */
int
_rl_search_getchar (_rl_search_cxt *cxt)
{
int c;
/* Read a key and decide how to proceed. */
RL_SETSTATE(RL_STATE_MOREINPUT);
c = cxt->lastc = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
/* This ends up with C (and LASTC) being set to the last byte of the
multibyte character. In most cases c == lastc == mb[0] */
if (c >= 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
#endif
RL_CHECK_SIGNALS ();
return c;
}
#define ENDSRCH_CHAR(c) \
((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
/* Process just-read character C according to isearch context CXT. Return
-1 if the caller should just free the context and return, 0 if we should
break out of the loop, and 1 if we should continue to read characters. */
int
_rl_isearch_dispatch (_rl_search_cxt *cxt, int c)
{
int n, wstart, wlen, limit, cval, incr;
char *paste;
size_t pastelen;
int j;
rl_command_func_t *f;
f = (rl_command_func_t *)NULL;
if (c < 0)
{
cxt->sflags |= SF_FAILED;
cxt->history_pos = cxt->last_found_line;
return -1;
}
_rl_add_executing_keyseq (c);
/* XXX - experimental code to allow users to bracketed-paste into the search
string even when ESC is one of the isearch-terminators. Not perfect yet. */
if (_rl_enable_bracketed_paste && c == ESC && strchr (cxt->search_terminators, c) && (n = _rl_nchars_available ()) > (BRACK_PASTE_SLEN-1))
{
j = _rl_read_bracketed_paste_prefix (c);
if (j == 1)
{
cxt->lastc = -7; /* bracketed paste, see below */
goto opcode_dispatch;
}
else if (_rl_pushed_input_available ()) /* eat extra char we pushed back */
c = cxt->lastc = rl_read_key ();
else
c = cxt->lastc; /* last ditch */
}
/* If we are moving into a new keymap, modify cxt->keymap and go on.
This can be a problem if c == ESC and we want to terminate the
incremental search, so we check */
if (c >= 0 && cxt->keymap[c].type == ISKMAP && strchr (cxt->search_terminators, cxt->lastc) == 0)
{
/* _rl_keyseq_timeout specified in milliseconds; _rl_input_queued
takes microseconds, so multiply by 1000. If we don't get any
additional input and this keymap shadows another function, process
that key as if it was all we read. */
if (_rl_keyseq_timeout > 0 &&
RL_ISSTATE (RL_STATE_CALLBACK) == 0 &&
RL_ISSTATE (RL_STATE_INPUTPENDING) == 0 &&
_rl_pushed_input_available () == 0 &&
((Keymap)(cxt->keymap[c].function))[ANYOTHERKEY].function &&
_rl_input_queued (_rl_keyseq_timeout*1000) == 0)
goto add_character;
cxt->okeymap = cxt->keymap;
cxt->keymap = FUNCTION_TO_KEYMAP (cxt->keymap, c);
cxt->sflags |= SF_CHGKMAP;
/* XXX - we should probably save this sequence, so we can do
something useful if this doesn't end up mapping to a command we
interpret here. Right now we just save the most recent character
that caused the index into a new keymap. */
cxt->prevc = c;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (cxt->mb[1] == 0)
{
cxt->pmb[0] = c; /* XXX should be == cxt->mb[0] */
cxt->pmb[1] = '\0';
}
else
memcpy (cxt->pmb, cxt->mb, sizeof (cxt->pmb));
}
#endif
return 1;
}
add_character:
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && cxt->keymap[c].type == ISFUNC)
{
/* If we have a multibyte character, see if it's bound to something that
affects the search. */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && cxt->mb[1])
f = rl_function_of_keyseq (cxt->mb, cxt->keymap, (int *)NULL);
else
#endif
{
f = cxt->keymap[c].function;
if (f == rl_do_lowercase_version)
f = cxt->keymap[_rl_to_lower (c)].function;
}
if (f == rl_reverse_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
else if (f == rl_forward_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
else if (f == rl_rubout)
cxt->lastc = -3;
else if (c == CTRL ('G') || f == rl_abort)
cxt->lastc = -4;
else if (c == CTRL ('W') || f == rl_unix_word_rubout) /* XXX */
cxt->lastc = -5;
else if (c == CTRL ('Y') || f == rl_yank) /* XXX */
cxt->lastc = -6;
else if (f == rl_bracketed_paste_begin)
cxt->lastc = -7;
}
/* If we changed the keymap earlier while translating a key sequence into
a command, restore it now that we've succeeded. */
if (cxt->sflags & SF_CHGKMAP)
{
cxt->keymap = cxt->okeymap;
cxt->sflags &= ~SF_CHGKMAP;
/* If we indexed into a new keymap, but didn't map to a command that
affects the search (lastc > 0), and the character that mapped to a
new keymap would have ended the search (ENDSRCH_CHAR(cxt->prevc)),
handle that now as if the previous char would have ended the search
and we would have read the current character. */
/* XXX - should we check cxt->mb? */
if (cxt->lastc > 0 && ENDSRCH_CHAR (cxt->prevc))
{
rl_stuff_char (cxt->lastc);
rl_execute_next (cxt->prevc);
/* XXX - do we insert everything in cxt->pmb? */
return (0);
}
/* Otherwise, if the current character is mapped to self-insert or
nothing (i.e., not an editing command), and the previous character
was a keymap index, then we need to insert both the previous
character and the current character into the search string. */
else if (cxt->lastc > 0 && cxt->prevc > 0 &&
cxt->keymap[cxt->prevc].type == ISKMAP &&
(f == 0 || f == rl_insert))
{
/* Make lastc be the next character read */
/* XXX - do we insert everything in cxt->mb? */
rl_execute_next (cxt->lastc);
/* Dispatch on the previous character (insert into search string) */
cxt->lastc = cxt->prevc;
#if defined (HANDLE_MULTIBYTE)
/* Have to overwrite cxt->mb here because dispatch uses it below */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (cxt->pmb[1] == 0)
{
cxt->mb[0] = cxt->lastc; /* == cxt->prevc */
cxt->mb[1] = '\0';
}
else
memcpy (cxt->mb, cxt->pmb, sizeof (cxt->mb));
}
#endif
cxt->prevc = 0;
}
else if (cxt->lastc > 0 && cxt->prevc > 0 && f && f != rl_insert)
{
_rl_term_executing_keyseq (); /* should this go in the caller? */
_rl_pending_command.map = cxt->keymap;
_rl_pending_command.count = 1; /* XXX */
_rl_pending_command.key = cxt->lastc;
_rl_pending_command.func = f;
_rl_command_to_execute = &_rl_pending_command;
return (0);
}
}
/* The characters in isearch_terminators (set from the user-settable
variable isearch-terminators) are used to terminate the search but
not subsequently execute the character as a command. The default
value is "\033\012" (ESC and C-J). */
if (cxt->lastc > 0 && strchr (cxt->search_terminators, cxt->lastc))
{
/* ESC still terminates the search, but if there is pending
input or if input arrives within 0.1 seconds (on systems
with select(2)) it is used as a prefix character
with rl_execute_next. WATCH OUT FOR THIS! This is intended
to allow the arrow keys to be used like ^F and ^B are used
to terminate the search and execute the movement command.
XXX - since _rl_input_available depends on the application-
settable keyboard timeout value, this could alternatively
use _rl_input_queued(100000) */
if (cxt->lastc == ESC && (_rl_pushed_input_available () || _rl_input_available ()))
rl_execute_next (ESC);
return (0);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to LASTC; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (cxt->lastc);
return (0);
}
}
else
#endif
if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to LASTC; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (cxt->lastc);
return (0);
}
_rl_init_executing_keyseq ();
opcode_dispatch:
/* Now dispatch on the character. `Opcodes' affect the search string or
state. Other characters are added to the string. */
switch (cxt->lastc)
{
/* search again */
case -1:
if (cxt->search_string_index == 0)
{
if (last_isearch_string)
{
cxt->search_string_size = 64 + last_isearch_string_len;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
strcpy (cxt->search_string, last_isearch_string);
cxt->search_string_index = last_isearch_string_len;
rl_display_search (cxt->search_string, cxt->sflags, -1);
break;
}
/* XXX - restore keymap here? */
return (1);
}
else if ((cxt->sflags & SF_REVERSE) && cxt->sline_index >= 0)
cxt->sline_index--;
else if (cxt->sline_index != cxt->sline_len)
cxt->sline_index++;
else
rl_ding ();
break;
/* switch directions */
case -2:
cxt->direction = -cxt->direction;
if (cxt->direction < 0)
cxt->sflags |= SF_REVERSE;
else
cxt->sflags &= ~SF_REVERSE;
break;
/* delete character from search string. */
case -3: /* C-H, DEL */
/* This is tricky. To do this right, we need to keep a
stack of search positions for the current search, with
sentinels marking the beginning and end. But this will
do until we have a real isearch-undo. */
if (cxt->search_string_index == 0)
rl_ding ();
else if (MB_CUR_MAX == 1 || rl_byte_oriented)
cxt->search_string[--cxt->search_string_index] = '\0';
else
{
wstart = _rl_find_prev_mbchar (cxt->search_string, cxt->search_string_index, MB_FIND_NONZERO);
if (wstart >= 0)
cxt->search_string[cxt->search_string_index = wstart] = '\0';
else
cxt->search_string[cxt->search_string_index = 0] = '\0';
}
if (cxt->search_string_index == 0)
rl_ding ();
break;
case -4: /* C-G, abort */
rl_replace_line (cxt->lines[cxt->save_line], 0);
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_deactivate_mark ();
rl_restore_prompt();
rl_clear_message ();
_rl_fix_point (1); /* in case save_line and save_point are out of sync */
return -1;
case -5: /* C-W */
/* skip over portion of line we already matched and yank word */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
/* if not in a word, move to one. */
cval = _rl_char_value (rl_line_buffer, wstart);
if (_rl_walphabetic (cval) == 0)
{
rl_ding ();
break;
}
n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);;
while (n < rl_end)
{
cval = _rl_char_value (rl_line_buffer, n);
if (_rl_walphabetic (cval) == 0)
break;
n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);;
}
wlen = n - wstart + 1;
if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
{
cxt->search_string_size += wlen + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (; wstart < n; wstart++)
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart];
cxt->search_string[cxt->search_string_index] = '\0';
break;
case -6: /* C-Y */
/* skip over portion of line we already matched and yank rest */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
n = rl_end - wstart + 1;
if (cxt->search_string_index + n + 1 >= cxt->search_string_size)
{
cxt->search_string_size += n + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (n = wstart; n < rl_end; n++)
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n];
cxt->search_string[cxt->search_string_index] = '\0';
break;
case -7: /* bracketed paste */
paste = _rl_bracketed_text (&pastelen);
if (paste == 0 || *paste == 0)
{
xfree (paste);
break;
}
if (_rl_enable_active_region)
rl_activate_mark ();
if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size)
{
cxt->search_string_size += pastelen + 2;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
memcpy (cxt->search_string + cxt->search_string_index, paste, pastelen);
cxt->search_string_index += pastelen;
cxt->search_string[cxt->search_string_index] = '\0';
xfree (paste);
break;
/* Add character to search string and continue search. */
default:
#if defined (HANDLE_MULTIBYTE)
wlen = (cxt->mb[0] == 0 || cxt->mb[1] == 0) ? 1 : RL_STRLEN (cxt->mb);
#else
wlen = 1;
#endif
if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
{
cxt->search_string_size += 128; /* 128 much greater than MB_CUR_MAX */
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j;
if (cxt->mb[0] == 0 || cxt->mb[1] == 0)
cxt->search_string[cxt->search_string_index++] = cxt->mb[0];
else
for (j = 0; j < wlen; )
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
}
else
#endif
cxt->search_string[cxt->search_string_index++] = cxt->lastc; /* XXX - was c instead of lastc */
cxt->search_string[cxt->search_string_index] = '\0';
break;
}
for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
{
if (cxt->search_string_index == 0)
{
cxt->sflags |= SF_FAILED;
break;
}
limit = cxt->sline_len - cxt->search_string_index + 1;
/* Search the current line. */
while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit))
{
if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index))
{
cxt->sflags |= SF_FOUND;
break;
}
else
cxt->sline_index += cxt->direction;
if (cxt->sline_index < 0)
{
cxt->sline_index = 0;
break;
}
}
if (cxt->sflags & SF_FOUND)
break;
/* Move to the next line, but skip new copies of the line
we just found and lines shorter than the string we're
searching for. */
do
{
/* Move to the next line. */
cxt->history_pos += cxt->direction;
/* At limit for direction? */
if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen))
{
cxt->sflags |= SF_FAILED;
break;
}
/* We will need these later. */
cxt->sline = cxt->lines[cxt->history_pos];
cxt->sline_len = strlen (cxt->sline);
}
while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) ||
(cxt->search_string_index > cxt->sline_len));
if (cxt->sflags & SF_FAILED)
{
/* XXX - reset sline_index if < 0 */
if (cxt->sline_index < 0)
cxt->sline_index = 0;
break;
}
/* Now set up the line for searching... */
cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
}
/* reset the keymaps for the next time through the loop */
cxt->keymap = cxt->okeymap = _rl_keymap;
if (cxt->sflags & SF_FAILED)
{
/* We cannot find the search string. Ding the bell. */
rl_ding ();
cxt->history_pos = cxt->last_found_line;
rl_deactivate_mark ();
rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
return 1;
}
/* We have found the search string. Just display it. But don't
actually move there in the history list until the user accepts
the location. */
if (cxt->sflags & SF_FOUND)
{
cxt->prev_line_found = cxt->lines[cxt->history_pos];
rl_replace_line (cxt->lines[cxt->history_pos], 0);
if (_rl_enable_active_region)
rl_activate_mark ();
rl_point = cxt->sline_index;
if (rl_mark_active_p () && cxt->search_string_index > 0)
rl_mark = rl_point + cxt->search_string_index;
cxt->last_found_line = cxt->history_pos;
rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
}
return 1;
}
int
_rl_isearch_cleanup (_rl_search_cxt *cxt, int r)
{
if (r >= 0)
_rl_isearch_fini (cxt);
_rl_scxt_dispose (cxt, 0);
_rl_iscxt = 0;
RL_UNSETSTATE(RL_STATE_ISEARCH);
return (r != 0);
}
/* Search through the history looking for an interactively typed string.
This is analogous to i-search. We start the search in the current line.
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static int
rl_search_history (int direction, int invoking_key)
{
_rl_search_cxt *cxt; /* local for now, but saved globally */
int c, r;
RL_SETSTATE(RL_STATE_ISEARCH);
cxt = _rl_isearch_init (direction);
rl_display_search (cxt->search_string, cxt->sflags, -1);
/* If we are using the callback interface, all we do is set up here and
return. The key is that we leave RL_STATE_ISEARCH set. */
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
r = -1;
for (;;)
{
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here (c == 0) */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
if (r <= 0)
break;
}
/* The searching is over. The user may have found the string that she
was looking for, or else she may have exited a failing search. If
LINE_INDEX is -1, then that shows that the string searched for was
not found. We use this to determine where to place rl_point. */
return (_rl_isearch_cleanup (cxt, r));
}
#if defined (READLINE_CALLBACKS)
/* Called from the callback functions when we are ready to read a key. The
callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH).
If _rl_isearch_dispatch finishes searching, this function is responsible
for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */
int
_rl_isearch_callback (_rl_search_cxt *cxt)
{
int c, r;
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0;
}
#endif

174
third_party/readline/keymaps.c vendored Normal file
View file

@ -0,0 +1,174 @@
/* keymaps.c -- Functions and keymaps for the GNU Readline library. */
/* Copyright (C) 1988,1989-2009,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/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h> /* for FILE * definition for readline.h */
#include "readline.h"
#include "rlconf.h"
#include "emacs_keymap.inc"
#if defined (VI_MODE)
#include "vi_keymap.inc"
#endif
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Functions for manipulating Keymaps. */
/* */
/* **************************************************************** */
/* Return a new, empty keymap.
Free it with free() when you are done. */
Keymap
rl_make_bare_keymap (void)
{
register int i;
Keymap keymap;
keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY));
for (i = 0; i < KEYMAP_SIZE; i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = (rl_command_func_t *)NULL;
}
#if 0
for (i = 'A'; i < ('Z' + 1); i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = rl_do_lowercase_version;
}
#endif
return (keymap);
}
/* A convenience function that returns 1 if there are no keys bound to
functions in KEYMAP */
int
rl_empty_keymap (Keymap keymap)
{
int i;
for (i = 0; i < ANYOTHERKEY; i++)
{
if (keymap[i].type != ISFUNC || keymap[i].function)
return 0;
}
return 1;
}
/* Return a new keymap which is a copy of MAP. Just copies pointers, does
not copy text of macros or descend into child keymaps. */
Keymap
rl_copy_keymap (Keymap map)
{
register int i;
Keymap temp;
temp = rl_make_bare_keymap ();
for (i = 0; i < KEYMAP_SIZE; i++)
{
temp[i].type = map[i].type;
temp[i].function = map[i].function;
}
return (temp);
}
/* Return a new keymap with the printing characters bound to rl_insert,
the uppercase Meta characters bound to run their lowercase equivalents,
and the Meta digits bound to produce numeric arguments. */
Keymap
rl_make_keymap (void)
{
register int i;
Keymap newmap;
newmap = rl_make_bare_keymap ();
/* All ASCII printing characters are self-inserting. */
for (i = ' '; i < 127; i++)
newmap[i].function = rl_insert;
newmap[TAB].function = rl_insert;
newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */
newmap[CTRL('H')].function = rl_rubout;
#if KEYMAP_SIZE > 128
/* Printing characters in ISO Latin-1 and some 8-bit character sets. */
for (i = 128; i < 256; i++)
newmap[i].function = rl_insert;
#endif /* KEYMAP_SIZE > 128 */
return (newmap);
}
/* Free the storage associated with MAP. */
void
rl_discard_keymap (Keymap map)
{
int i;
if (map == 0)
return;
for (i = 0; i < KEYMAP_SIZE; i++)
{
switch (map[i].type)
{
case ISFUNC:
break;
case ISKMAP:
rl_discard_keymap ((Keymap)map[i].function);
xfree ((char *)map[i].function);
break;
case ISMACR:
xfree ((char *)map[i].function);
break;
}
}
}
/* Convenience function that discards, then frees, MAP. */
void
rl_free_keymap (Keymap map)
{
rl_discard_keymap (map);
xfree ((char *)map);
}

100
third_party/readline/keymaps.h vendored Normal file
View file

@ -0,0 +1,100 @@
/* keymaps.h -- Manipulation of readline keymaps. */
/* Copyright (C) 1987, 1989, 1992-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 _KEYMAPS_H_
#define _KEYMAPS_H_
#ifdef __cplusplus
extern "C" {
#endif
#if defined (READLINE_LIBRARY)
# include "rlstdc.h"
# include "chardefs.h"
# include "rltypedefs.h"
#else
# include "third_party/readline/rlstdc.h"
# include "third_party/readline/chardefs.h"
# include "third_party/readline/rltypedefs.h"
#endif
/* A keymap contains one entry for each key in the ASCII set.
Each entry consists of a type and a pointer.
FUNCTION is the address of a function to run, or the
address of a keymap to indirect through.
TYPE says which kind of thing FUNCTION is. */
typedef struct _keymap_entry {
char type;
rl_command_func_t *function;
} KEYMAP_ENTRY;
/* This must be large enough to hold bindings for all of the characters
in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x,
and so on) plus one for subsequence matching. */
#define KEYMAP_SIZE 257
#define ANYOTHERKEY KEYMAP_SIZE-1
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
typedef KEYMAP_ENTRY *Keymap;
/* The values that TYPE can have in a keymap entry. */
#define ISFUNC 0
#define ISKMAP 1
#define ISMACR 2
extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap;
extern KEYMAP_ENTRY_ARRAY vi_insertion_keymap, vi_movement_keymap;
/* Return a new, empty keymap.
Free it with free() when you are done. */
extern Keymap rl_make_bare_keymap (void);
/* Return a new keymap which is a copy of MAP. */
extern Keymap rl_copy_keymap (Keymap);
/* Return a new keymap with the printing characters bound to rl_insert,
the lowercase Meta characters bound to run their equivalents, and
the Meta digits bound to produce numeric arguments. */
extern Keymap rl_make_keymap (void);
/* Free the storage associated with a keymap. */
extern void rl_discard_keymap (Keymap);
/* These functions actually appear in bind.c */
/* Return the keymap corresponding to a given name. Names look like
`emacs' or `emacs-meta' or `vi-insert'. */
extern Keymap rl_get_keymap_by_name (const char *);
/* Return the current keymap. */
extern Keymap rl_get_keymap (void);
/* Set the current keymap to MAP. */
extern void rl_set_keymap (Keymap);
/* Set the name of MAP to NAME */
extern int rl_set_keymap_name (const char *, Keymap);
#ifdef __cplusplus
}
#endif
#endif /* _KEYMAPS_H_ */

900
third_party/readline/kill.c vendored Normal file
View file

@ -0,0 +1,900 @@
/* kill.c -- kill ring management. */
/* 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/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Killing Mechanism */
/* */
/* **************************************************************** */
/* What we assume for a max number of kills. */
#define DEFAULT_MAX_KILLS 10
/* The real variable to look at to find out when to flush kills. */
static int rl_max_kills = DEFAULT_MAX_KILLS;
/* Where to store killed text. */
static char **rl_kill_ring = (char **)NULL;
/* Where we are in the kill ring. */
static int rl_kill_index;
/* How many slots we have in the kill ring. */
static int rl_kill_ring_length;
static int _rl_copy_to_kill_ring (char *, int);
static int region_kill_internal (int);
static int _rl_copy_word_as_kill (int, int);
static int rl_yank_nth_arg_internal (int, int, int);
/* How to say that you only want to save a certain amount
of kill material. */
int
rl_set_retained_kills (int num)
{
return 0;
}
/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
This uses TEXT directly, so the caller must not free it. If APPEND is
non-zero, and the last command was a kill, the text is appended to the
current kill ring slot, otherwise prepended. */
static int
_rl_copy_to_kill_ring (char *text, int append)
{
char *old, *new;
int slot;
/* First, find the slot to work with. */
if (_rl_last_command_was_kill == 0 || rl_kill_ring == 0)
{
/* Get a new slot. */
if (rl_kill_ring == 0)
{
/* If we don't have any defined, then make one. */
rl_kill_ring = (char **)
xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
rl_kill_ring[slot = 0] = (char *)NULL;
}
else
{
/* We have to add a new slot on the end, unless we have
exceeded the max limit for remembering kills. */
slot = rl_kill_ring_length;
if (slot == rl_max_kills)
{
register int i;
xfree (rl_kill_ring[0]);
for (i = 0; i < slot; i++)
rl_kill_ring[i] = rl_kill_ring[i + 1];
}
else
{
slot = rl_kill_ring_length += 1;
rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *));
}
rl_kill_ring[--slot] = (char *)NULL;
}
}
else
slot = rl_kill_ring_length - 1;
/* If the last command was a kill, prepend or append. */
if (_rl_last_command_was_kill && rl_kill_ring[slot] && rl_editing_mode != vi_mode)
{
old = rl_kill_ring[slot];
new = (char *)xmalloc (1 + strlen (old) + strlen (text));
if (append)
{
strcpy (new, old);
strcat (new, text);
}
else
{
strcpy (new, text);
strcat (new, old);
}
xfree (old);
xfree (text);
rl_kill_ring[slot] = new;
}
else
rl_kill_ring[slot] = text;
rl_kill_index = slot;
return 0;
}
/* The way to kill something. This appends or prepends to the last
kill, if the last command was a kill command. if FROM is less
than TO, then the text is appended, otherwise prepended. If the
last command was not a kill command, then a new slot is made for
this kill. */
int
rl_kill_text (int from, int to)
{
char *text;
/* Is there anything to kill? */
if (from == to)
{
_rl_last_command_was_kill++;
return 0;
}
text = rl_copy_text (from, to);
/* Delete the copied text from the line. */
rl_delete_text (from, to);
_rl_copy_to_kill_ring (text, from < to);
_rl_last_command_was_kill++;
return 0;
}
/* Now REMEMBER! In order to do prepending or appending correctly, kill
commands always make rl_point's original position be the FROM argument,
and rl_point's extent be the TO argument. */
/* **************************************************************** */
/* */
/* Killing Commands */
/* */
/* **************************************************************** */
/* Delete the word at point, saving the text in the kill ring. */
int
rl_kill_word (int count, int key)
{
int orig_point;
if (count < 0)
return (rl_backward_kill_word (-count, key));
else
{
orig_point = rl_point;
rl_forward_word (count, key);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Rubout the word before point, placing it on the kill ring. */
int
rl_backward_kill_word (int count, int key)
{
int orig_point;
if (count < 0)
return (rl_kill_word (-count, key));
else
{
orig_point = rl_point;
rl_backward_word (count, key);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Kill from here to the end of the line. If DIRECTION is negative, kill
back to the line start instead. */
int
rl_kill_line (int direction, int key)
{
int orig_point;
if (direction < 0)
return (rl_backward_kill_line (1, key));
else
{
orig_point = rl_point;
rl_end_of_line (1, key);
if (orig_point != rl_point)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Kill backwards to the start of the line. If DIRECTION is negative, kill
forwards to the line end instead. */
int
rl_backward_kill_line (int direction, int key)
{
int orig_point;
if (direction < 0)
return (rl_kill_line (1, key));
else
{
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
rl_beg_of_line (1, key);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
}
return 0;
}
/* Kill the whole line, no matter where point is. */
int
rl_kill_full_line (int count, int key)
{
rl_begin_undo_group ();
rl_point = 0;
rl_kill_text (rl_point, rl_end);
rl_mark = 0;
rl_end_undo_group ();
return 0;
}
/* The next two functions mimic unix line editing behaviour, except they
save the deleted text on the kill ring. This is safer than not saving
it, and since we have a ring, nobody should get screwed. */
/* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */
int
rl_unix_word_rubout (int count, int key)
{
int orig_point;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
rl_point--;
while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
rl_point--; /* XXX - multibyte? */
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* This deletes one filename component in a Unix pathname. That is, it
deletes backward to directory separator (`/') or whitespace. */
int
rl_unix_filename_rubout (int count, int key)
{
int orig_point, c;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
c = rl_line_buffer[rl_point - 1];
/* First move backwards through whitespace */
while (rl_point && whitespace (c))
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
/* Consume one or more slashes. */
if (c == '/')
{
int i;
i = rl_point - 1;
while (i > 0 && c == '/')
c = rl_line_buffer[--i];
if (i == 0 || whitespace (c))
{
rl_point = i + whitespace (c);
continue; /* slashes only */
}
c = '/';
}
while (rl_point && (whitespace (c) || c == '/'))
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
while (rl_point && (whitespace (c) == 0) && c != '/')
{
rl_point--; /* XXX - multibyte? */
c = rl_line_buffer[rl_point - 1];
}
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Here is C-u doing what Unix does. You don't *have* to use these
key-bindings. We have a choice of killing the entire line, or
killing from where we are to the start of the line. We choose the
latter, because if you are a Unix weenie, then you haven't backspaced
into the line at all, and if you aren't, then you know what you are
doing. */
int
rl_unix_line_discard (int count, int key)
{
if (rl_point == 0)
rl_ding ();
else
{
rl_kill_text (rl_point, 0);
rl_point = 0;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Copy the text in the `region' to the kill ring. If DELETE is non-zero,
delete the text from the line as well. */
static int
region_kill_internal (int delete)
{
char *text;
if (rl_mark != rl_point)
{
text = rl_copy_text (rl_point, rl_mark);
if (delete)
rl_delete_text (rl_point, rl_mark);
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
}
_rl_fix_point (1);
_rl_last_command_was_kill++;
return 0;
}
/* Copy the text in the region to the kill ring. */
int
rl_copy_region_to_kill (int count, int key)
{
return (region_kill_internal (0));
}
/* Kill the text between the point and mark. */
int
rl_kill_region (int count, int key)
{
int r, npoint;
npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
r = region_kill_internal (1);
rl_point = npoint;
_rl_fix_point (1);
return r;
}
/* Copy COUNT words to the kill ring. DIR says which direction we look
to find the words. */
static int
_rl_copy_word_as_kill (int count, int dir)
{
int om, op, r;
om = rl_mark;
op = rl_point;
if (dir > 0)
rl_forward_word (count, 0);
else
rl_backward_word (count, 0);
rl_mark = rl_point;
if (dir > 0)
rl_backward_word (count, 0);
else
rl_forward_word (count, 0);
r = region_kill_internal (0);
rl_mark = om;
rl_point = op;
return r;
}
int
rl_copy_forward_word (int count, int key)
{
if (count < 0)
return (rl_copy_backward_word (-count, key));
return (_rl_copy_word_as_kill (count, 1));
}
int
rl_copy_backward_word (int count, int key)
{
if (count < 0)
return (rl_copy_forward_word (-count, key));
return (_rl_copy_word_as_kill (count, -1));
}
/* Yank back the last killed text. This ignores arguments. */
int
rl_yank (int count, int key)
{
if (rl_kill_ring == 0)
{
_rl_abort_internal ();
return 1;
}
_rl_set_mark_at_pos (rl_point);
rl_insert_text (rl_kill_ring[rl_kill_index]);
return 0;
}
/* If the last command was yank, or yank_pop, and the text just
before point is identical to the current kill item, then
delete that text from the line, rotate the index down, and
yank back some other text. */
int
rl_yank_pop (int count, int key)
{
int l, n;
if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
!rl_kill_ring)
{
_rl_abort_internal ();
return 1;
}
l = strlen (rl_kill_ring[rl_kill_index]);
n = rl_point - l;
if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
{
rl_delete_text (n, rl_point);
rl_point = n;
rl_kill_index--;
if (rl_kill_index < 0)
rl_kill_index = rl_kill_ring_length - 1;
rl_yank (1, 0);
return 0;
}
else
{
_rl_abort_internal ();
return 1;
}
}
#if defined (VI_MODE)
int
rl_vi_yank_pop (int count, int key)
{
int l, n, origpoint;
if (((rl_last_func != rl_vi_yank_pop) && (rl_last_func != rl_vi_put)) ||
!rl_kill_ring)
{
_rl_abort_internal ();
return 1;
}
l = strlen (rl_kill_ring[rl_kill_index]);
#if 0 /* TAG:readline-8.3 8/29/2022 matteopaolini1995@gmail.com */
origpoint = rl_point;
n = rl_point - l + 1;
#else
n = rl_point - l;
#endif
if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
{
#if 0 /* TAG:readline-8.3 */
rl_delete_text (n, n + l); /* remember vi cursor positioning */
rl_point = origpoint - l;
#else
rl_delete_text (n, rl_point);
rl_point = n;
#endif
rl_kill_index--;
if (rl_kill_index < 0)
rl_kill_index = rl_kill_ring_length - 1;
rl_vi_put (1, 'p');
return 0;
}
else
{
_rl_abort_internal ();
return 1;
}
}
#endif /* VI_MODE */
/* Yank the COUNTh argument from the previous history line, skipping
HISTORY_SKIP lines before looking for the `previous line'. */
static int
rl_yank_nth_arg_internal (int count, int key, int history_skip)
{
register HIST_ENTRY *entry;
char *arg;
int i, pos;
pos = where_history ();
if (history_skip)
{
for (i = 0; i < history_skip; i++)
entry = previous_history ();
}
entry = previous_history ();
history_set_pos (pos);
if (entry == 0)
{
rl_ding ();
return 1;
}
arg = history_arg_extract (count, count, entry->line);
if (!arg || !*arg)
{
rl_ding ();
FREE (arg);
return 1;
}
rl_begin_undo_group ();
_rl_set_mark_at_pos (rl_point);
#if defined (VI_MODE)
/* Vi mode always inserts a space before yanking the argument, and it
inserts it right *after* rl_point. */
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
{
rl_vi_append_mode (1, key);
rl_insert_text (" ");
}
#endif /* VI_MODE */
rl_insert_text (arg);
xfree (arg);
rl_end_undo_group ();
return 0;
}
/* Yank the COUNTth argument from the previous history line. */
int
rl_yank_nth_arg (int count, int key)
{
return (rl_yank_nth_arg_internal (count, key, 0));
}
/* Yank the last argument from the previous history line. This `knows'
how rl_yank_nth_arg treats a count of `$'. With an argument, this
behaves the same as rl_yank_nth_arg. */
int
rl_yank_last_arg (int count, int key)
{
static int history_skip = 0;
static int explicit_arg_p = 0;
static int count_passed = 1;
static int direction = 1;
static int undo_needed = 0;
int retval;
if (rl_last_func != rl_yank_last_arg)
{
history_skip = 0;
explicit_arg_p = rl_explicit_arg;
count_passed = count;
direction = 1;
}
else
{
if (undo_needed)
rl_do_undo ();
if (count < 0) /* XXX - was < 1 */
direction = -direction;
history_skip += direction;
if (history_skip < 0)
history_skip = 0;
}
if (explicit_arg_p)
retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
else
retval = rl_yank_nth_arg_internal ('$', key, history_skip);
undo_needed = retval == 0;
return retval;
}
/* Having read the special escape sequence denoting the beginning of a
`bracketed paste' sequence, read the rest of the pasted input until the
closing sequence and return the pasted text. */
char *
_rl_bracketed_text (size_t *lenp)
{
int c;
size_t len, cap;
char *buf;
len = 0;
buf = xmalloc (cap = 64);
buf[0] = '\0';
RL_SETSTATE (RL_STATE_MOREINPUT);
while ((c = rl_read_key ()) >= 0)
{
if (RL_ISSTATE (RL_STATE_MACRODEF))
_rl_add_macro_char (c);
if (c == '\r') /* XXX */
c = '\n';
if (len == cap)
buf = xrealloc (buf, cap *= 2);
buf[len++] = c;
if (len >= BRACK_PASTE_SLEN && c == BRACK_PASTE_LAST &&
STREQN (buf + len - BRACK_PASTE_SLEN, BRACK_PASTE_SUFF, BRACK_PASTE_SLEN))
{
len -= BRACK_PASTE_SLEN;
break;
}
}
RL_UNSETSTATE (RL_STATE_MOREINPUT);
if (c >= 0)
{
if (len == cap)
buf = xrealloc (buf, cap + 1);
buf[len] = '\0';
}
if (lenp)
*lenp = len;
return (buf);
}
/* Having read the special escape sequence denoting the beginning of a
`bracketed paste' sequence, read the rest of the pasted input until the
closing sequence and insert the pasted text as a single unit without
interpretation. Temporarily highlight the inserted text. */
int
rl_bracketed_paste_begin (int count, int key)
{
int retval, c;
size_t len, cap;
char *buf;
buf = _rl_bracketed_text (&len);
rl_mark = rl_point;
retval = rl_insert_text (buf) == len ? 0 : 1;
if (_rl_enable_active_region)
rl_activate_mark ();
xfree (buf);
return (retval);
}
int
_rl_read_bracketed_paste_prefix (int c)
{
char pbuf[BRACK_PASTE_SLEN+1], *pbpref;
int key, ind, j;
pbpref = BRACK_PASTE_PREF; /* XXX - debugging */
if (c != pbpref[0])
return (0);
pbuf[ind = 0] = c;
while (ind < BRACK_PASTE_SLEN-1 &&
(RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
_rl_pushed_input_available () == 0 &&
_rl_input_queued (0))
{
key = rl_read_key (); /* XXX - for now */
if (key < 0)
break;
pbuf[++ind] = key;
if (pbuf[ind] != pbpref[ind])
break;
}
if (ind < BRACK_PASTE_SLEN-1) /* read incomplete sequence */
{
while (ind >= 0)
_rl_unget_char (pbuf[ind--]);
return (key < 0 ? key : 0);
}
return (key < 0 ? key : 1);
}
/* Get a character from wherever we read input, handling input in bracketed
paste mode. If we don't have or use bracketed paste mode, this can be
used in place of rl_read_key(). */
int
_rl_bracketed_read_key ()
{
int c, r;
char *pbuf;
size_t pblen;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
return -1;
/* read pasted data with bracketed-paste mode enabled. */
if (_rl_enable_bracketed_paste && c == ESC && (r = _rl_read_bracketed_paste_prefix (c)) == 1)
{
pbuf = _rl_bracketed_text (&pblen);
if (pblen == 0)
{
xfree (pbuf);
return 0; /* XXX */
}
c = (unsigned char)pbuf[0];
if (pblen > 1)
{
while (--pblen > 0)
_rl_unget_char ((unsigned char)pbuf[pblen]);
}
xfree (pbuf);
}
return c;
}
/* Get a character from wherever we read input, handling input in bracketed
paste mode. If we don't have or use bracketed paste mode, this can be
used in place of rl_read_key(). */
int
_rl_bracketed_read_mbstring (char *mb, int mlen)
{
int c, r;
c = _rl_bracketed_read_key ();
if (c < 0)
return -1;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, mlen);
else
#endif
mb[0] = c;
mb[mlen] = '\0'; /* just in case */
return c;
}
/* A special paste command for Windows users. */
#if defined (_WIN32)
#include <windows.h>
int
rl_paste_from_clipboard (int count, int key)
{
char *data, *ptr;
int len;
if (OpenClipboard (NULL) == 0)
return (0);
data = (char *)GetClipboardData (CF_TEXT);
if (data)
{
ptr = strchr (data, '\r');
if (ptr)
{
len = ptr - data;
ptr = (char *)xmalloc (len + 1);
ptr[len] = '\0';
strncpy (ptr, data, len);
}
else
ptr = data;
_rl_set_mark_at_pos (rl_point);
rl_insert_text (ptr);
if (ptr != data)
xfree (ptr);
CloseClipboard ();
}
return (0);
}
#endif /* _WIN32 */

334
third_party/readline/macro.c vendored Normal file
View file

@ -0,0 +1,334 @@
/* macro.c -- keyboard macros for readline. */
/* Copyright (C) 1994-2009,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/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
#define MAX_MACRO_LEVEL 16
/* **************************************************************** */
/* */
/* Hacking Keyboard Macros */
/* */
/* **************************************************************** */
/* The currently executing macro string. If this is non-zero,
then it is a malloc ()'ed string where input is coming from. */
char *rl_executing_macro = (char *)NULL;
/* The offset in the above string to the next character to be read. */
static int executing_macro_index;
/* The current macro string being built. Characters get stuffed
in here by add_macro_char (). */
static char *current_macro = (char *)NULL;
/* The size of the buffer allocated to current_macro. */
static int current_macro_size;
/* The index at which characters are being added to current_macro. */
static int current_macro_index;
/* A structure used to save nested macro strings.
It is a linked list of string/index for each saved macro. */
struct saved_macro {
struct saved_macro *next;
char *string;
int sindex;
};
/* The list of saved macros. */
static struct saved_macro *macro_list = (struct saved_macro *)NULL;
static int macro_level = 0;
/* Set up to read subsequent input from STRING.
STRING is free ()'ed when we are done with it. */
void
_rl_with_macro_input (char *string)
{
if (macro_level > MAX_MACRO_LEVEL)
{
_rl_errmsg ("maximum macro execution nesting level exceeded");
_rl_abort_internal ();
return;
}
#if 0
if (rl_executing_macro) /* XXX - later */
#endif
_rl_push_executing_macro ();
rl_executing_macro = string;
executing_macro_index = 0;
RL_SETSTATE(RL_STATE_MACROINPUT);
}
/* Return the next character available from a macro, or 0 if
there are no macro characters. */
int
_rl_next_macro_key (void)
{
int c;
if (rl_executing_macro == 0)
return (0);
if (rl_executing_macro[executing_macro_index] == 0)
{
_rl_pop_executing_macro ();
return (_rl_next_macro_key ());
}
#if defined (READLINE_CALLBACKS)
c = rl_executing_macro[executing_macro_index++];
if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD|RL_STATE_MOREINPUT) && rl_executing_macro[executing_macro_index] == 0)
_rl_pop_executing_macro ();
return c;
#else
/* XXX - consider doing the same as the callback code, just not testing
whether we're running in callback mode */
return (rl_executing_macro[executing_macro_index++]);
#endif
}
int
_rl_peek_macro_key (void)
{
if (rl_executing_macro == 0)
return (0);
if (rl_executing_macro[executing_macro_index] == 0 && (macro_list == 0 || macro_list->string == 0))
return (0);
if (rl_executing_macro[executing_macro_index] == 0 && macro_list && macro_list->string)
return (macro_list->string[0]);
return (rl_executing_macro[executing_macro_index]);
}
int
_rl_prev_macro_key (void)
{
if (rl_executing_macro == 0)
return (0);
if (executing_macro_index == 0)
return (0);
executing_macro_index--;
return (rl_executing_macro[executing_macro_index]);
}
/* Save the currently executing macro on a stack of saved macros. */
void
_rl_push_executing_macro (void)
{
struct saved_macro *saver;
saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
saver->next = macro_list;
saver->sindex = executing_macro_index;
saver->string = rl_executing_macro;
macro_list = saver;
macro_level++;
}
/* Discard the current macro, replacing it with the one
on the top of the stack of saved macros. */
void
_rl_pop_executing_macro (void)
{
struct saved_macro *macro;
FREE (rl_executing_macro);
rl_executing_macro = (char *)NULL;
executing_macro_index = 0;
if (macro_list)
{
macro = macro_list;
rl_executing_macro = macro_list->string;
executing_macro_index = macro_list->sindex;
macro_list = macro_list->next;
xfree (macro);
}
macro_level--;
if (rl_executing_macro == 0)
RL_UNSETSTATE(RL_STATE_MACROINPUT);
}
/* Add a character to the macro being built. */
void
_rl_add_macro_char (int c)
{
if (current_macro_index + 1 >= current_macro_size)
{
if (current_macro == 0)
current_macro = (char *)xmalloc (current_macro_size = 25);
else
current_macro = (char *)xrealloc (current_macro, current_macro_size += 25);
}
current_macro[current_macro_index++] = c;
current_macro[current_macro_index] = '\0';
}
void
_rl_kill_kbd_macro (void)
{
if (current_macro)
{
xfree (current_macro);
current_macro = (char *) NULL;
}
current_macro_size = current_macro_index = 0;
FREE (rl_executing_macro);
rl_executing_macro = (char *) NULL;
executing_macro_index = 0;
RL_UNSETSTATE(RL_STATE_MACRODEF);
}
/* Begin defining a keyboard macro.
Keystrokes are recorded as they are executed.
End the definition with rl_end_kbd_macro ().
If a numeric argument was explicitly typed, then append this
definition to the end of the existing macro, and start by
re-executing the existing macro. */
int
rl_start_kbd_macro (int ignore1, int ignore2)
{
if (RL_ISSTATE (RL_STATE_MACRODEF))
{
_rl_abort_internal ();
return 1;
}
if (rl_explicit_arg)
{
if (current_macro)
_rl_with_macro_input (savestring (current_macro));
}
else
current_macro_index = 0;
RL_SETSTATE(RL_STATE_MACRODEF);
return 0;
}
/* Stop defining a keyboard macro.
A numeric argument says to execute the macro right now,
that many times, counting the definition as the first time. */
int
rl_end_kbd_macro (int count, int ignore)
{
if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
{
_rl_abort_internal ();
return 1;
}
current_macro_index -= rl_key_sequence_length;
if (current_macro_index < 0)
current_macro_index = 0;
current_macro[current_macro_index] = '\0';
RL_UNSETSTATE(RL_STATE_MACRODEF);
return (rl_call_last_kbd_macro (--count, 0));
}
/* Execute the most recently defined keyboard macro.
COUNT says how many times to execute it. */
int
rl_call_last_kbd_macro (int count, int ignore)
{
if (current_macro == 0)
_rl_abort_internal ();
if (RL_ISSTATE (RL_STATE_MACRODEF))
{
rl_ding (); /* no recursive macros */
current_macro[--current_macro_index] = '\0'; /* erase this char */
return 0;
}
while (count--)
_rl_with_macro_input (savestring (current_macro));
return 0;
}
int
rl_print_last_kbd_macro (int count, int ignore)
{
char *m;
if (current_macro == 0)
{
rl_ding ();
return 0;
}
m = _rl_untranslate_macro_value (current_macro, 1);
rl_crlf ();
printf ("%s", m);
fflush (stdout);
rl_crlf ();
FREE (m);
rl_forced_update_display ();
rl_display_fixed = 1;
return 0;
}
void
rl_push_macro_input (char *macro)
{
_rl_with_macro_input (macro);
}

524
third_party/readline/mbutil.c vendored Normal file
View file

@ -0,0 +1,524 @@
/* mbutil.c -- readline multibyte character utility functions */
/* Copyright (C) 2001-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 <sys/types.h>
#include <fcntl.h>
#include "posixjmp.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
#include <ctype.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
#if defined (TIOCSTAT_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* TIOCSTAT_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Declared here so it can be shared between the readline and history
libraries. */
#if defined (HANDLE_MULTIBYTE)
int rl_byte_oriented = 0;
#else
int rl_byte_oriented = 1;
#endif
/* Ditto */
int _rl_utf8locale = 0;
/* **************************************************************** */
/* */
/* Multibyte Character Utility Functions */
/* */
/* **************************************************************** */
#if defined(HANDLE_MULTIBYTE)
/* **************************************************************** */
/* */
/* UTF-8 specific Character Utility Functions */
/* */
/* **************************************************************** */
/* Return the length in bytes of the possibly-multibyte character beginning
at S. Encoding is UTF-8. */
static int
_rl_utf8_mblen (const char *s, size_t n)
{
unsigned char c, c1, c2, c3;
if (s == 0)
return (0); /* no shift states */
if (n <= 0)
return (-1);
c = (unsigned char)*s;
if (c < 0x80)
return (c != 0);
if (c >= 0xc2)
{
c1 = (unsigned char)s[1];
if (c < 0xe0)
{
if (n == 1)
return -2;
if (n >= 2 && (c1 ^ 0x80) < 0x40)
return 2;
}
else if (c < 0xf0)
{
if (n == 1)
return -2;
if ((c1 ^ 0x80) < 0x40
&& (c >= 0xe1 || c1 >= 0xa0)
&& (c != 0xed || c1 < 0xa0))
{
if (n == 2)
return -2;
c2 = (unsigned char)s[2];
if ((c2 ^ 0x80) < 0x40)
return 3;
}
}
else if (c < 0xf4)
{
if (n == 1)
return -2;
if (((c1 ^ 0x80) < 0x40)
&& (c >= 0xf1 || c1 >= 0x90)
&& (c < 0xf4 || (c == 0xf4 && c1 < 0x90)))
{
if (n == 2)
return -2;
c2 = (unsigned char)s[2];
if ((c2 ^ 0x80) < 0x40)
{
if (n == 3)
return -2;
c3 = (unsigned char)s[3];
if ((c3 ^ 0x80) < 0x40)
return 4;
}
}
}
}
/* invalid or incomplete multibyte character */
return -1;
}
static int
_rl_find_next_mbchar_internal (char *string, int seed, int count, int find_non_zero)
{
size_t tmp, len;
mbstate_t ps;
int point;
WCHAR_T wc;
tmp = 0;
memset(&ps, 0, sizeof (mbstate_t));
if (seed < 0)
seed = 0;
if (count <= 0)
return seed;
point = seed + _rl_adjust_point (string, seed, &ps);
/* if _rl_adjust_point returns -1, the character or string is invalid.
treat as a byte. */
if (point == seed - 1) /* invalid */
return seed + 1;
/* if this is true, means that seed was not pointing to a byte indicating
the beginning of a multibyte character. Correct the point and consume
one char. */
if (seed < point)
count--;
while (count > 0)
{
len = strlen (string + point);
if (len == 0)
break;
if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point]))
{
tmp = 1;
wc = (WCHAR_T) string[point];
memset(&ps, 0, sizeof(mbstate_t));
}
else
tmp = MBRTOWC (&wc, string+point, len, &ps);
if (MB_INVALIDCH ((size_t)tmp))
{
/* invalid bytes. assume a byte represents a character */
point++;
count--;
/* reset states. */
memset(&ps, 0, sizeof(mbstate_t));
}
else if (MB_NULLWCH (tmp))
break; /* found wide '\0' */
else
{
/* valid bytes */
point += tmp;
if (find_non_zero)
{
if (WCWIDTH (wc) == 0)
continue;
else
count--;
}
else
count--;
}
}
if (find_non_zero)
{
tmp = MBRTOWC (&wc, string + point, strlen (string + point), &ps);
while (MB_NULLWCH (tmp) == 0 && MB_INVALIDCH (tmp) == 0 && WCWIDTH (wc) == 0)
{
point += tmp;
tmp = MBRTOWC (&wc, string + point, strlen (string + point), &ps);
}
}
return point;
}
static inline int
_rl_test_nonzero (char *string, int ind, int len)
{
size_t tmp;
WCHAR_T wc;
mbstate_t ps;
memset (&ps, 0, sizeof (mbstate_t));
tmp = MBRTOWC (&wc, string + ind, len - ind, &ps);
/* treat invalid multibyte sequences as non-zero-width */
return (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp) || WCWIDTH (wc) > 0);
}
/* experimental -- needs to handle zero-width characters better */
static int
_rl_find_prev_utf8char (char *string, int seed, int find_non_zero)
{
char *s;
unsigned char b;
int save, prev;
size_t len;
if (find_non_zero)
len = RL_STRLEN (string);
prev = seed - 1;
while (prev >= 0)
{
b = (unsigned char)string[prev];
if (UTF8_SINGLEBYTE (b))
return (prev);
save = prev;
/* Move back until we're not in the middle of a multibyte char */
if (UTF8_MBCHAR (b))
{
while (prev > 0 && (b = (unsigned char)string[--prev]) && UTF8_MBCHAR (b))
;
}
if (UTF8_MBFIRSTCHAR (b))
{
if (find_non_zero)
{
if (_rl_test_nonzero (string, prev, len))
return (prev);
else /* valid but WCWIDTH (wc) == 0 */
prev = prev - 1;
}
else
return (prev);
}
else
return (save); /* invalid utf-8 multibyte sequence */
}
return ((prev < 0) ? 0 : prev);
}
/*static*/ int
_rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero)
{
mbstate_t ps;
int prev, non_zero_prev, point, length;
size_t tmp;
WCHAR_T wc;
if (_rl_utf8locale)
return (_rl_find_prev_utf8char (string, seed, find_non_zero));
memset(&ps, 0, sizeof(mbstate_t));
length = strlen(string);
if (seed < 0)
return 0;
else if (length < seed)
return length;
prev = non_zero_prev = point = 0;
while (point < seed)
{
if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point]))
{
tmp = 1;
wc = (WCHAR_T) string[point];
memset(&ps, 0, sizeof(mbstate_t));
}
else
tmp = MBRTOWC (&wc, string + point, length - point, &ps);
if (MB_INVALIDCH ((size_t)tmp))
{
/* in this case, bytes are invalid or too short to compose
multibyte char, so assume that the first byte represents
a single character anyway. */
tmp = 1;
/* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */
memset(&ps, 0, sizeof (mbstate_t));
/* Since we're assuming that this byte represents a single
non-zero-width character, don't forget about it. */
prev = point;
}
else if (MB_NULLWCH (tmp))
break; /* Found '\0' char. Can this happen? */
else
{
if (find_non_zero)
{
if (WCWIDTH (wc) != 0)
prev = point;
}
else
prev = point;
}
point += tmp;
}
return prev;
}
/* return the number of bytes parsed from the multibyte sequence starting
at src, if a non-L'\0' wide character was recognized. It returns 0,
if a L'\0' wide character was recognized. It returns (size_t)(-1),
if an invalid multibyte sequence was encountered. It returns (size_t)(-2)
if it couldn't parse a complete multibyte character. */
int
_rl_get_char_len (char *src, mbstate_t *ps)
{
size_t tmp, l;
int mb_cur_max;
/* Look at no more than MB_CUR_MAX characters */
l = (size_t)strlen (src);
if (_rl_utf8locale && l > 0 && UTF8_SINGLEBYTE(*src))
tmp = (*src != 0) ? 1 : 0;
else
{
mb_cur_max = MB_CUR_MAX;
tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps);
}
if (tmp == (size_t)(-2))
{
/* too short to compose multibyte char */
if (ps)
memset (ps, 0, sizeof(mbstate_t));
return -2;
}
else if (tmp == (size_t)(-1))
{
/* invalid to compose multibyte char */
/* initialize the conversion state */
if (ps)
memset (ps, 0, sizeof(mbstate_t));
return -1;
}
else if (tmp == (size_t)0)
return 0;
else
return (int)tmp;
}
/* compare the specified two characters. If the characters matched,
return 1. Otherwise return 0. */
int
_rl_compare_chars (char *buf1, int pos1, mbstate_t *ps1, char *buf2, int pos2, mbstate_t *ps2)
{
int i, w1, w2;
if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 ||
(w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 ||
(w1 != w2) ||
(buf1[pos1] != buf2[pos2]))
return 0;
for (i = 1; i < w1; i++)
if (buf1[pos1+i] != buf2[pos2+i])
return 0;
return 1;
}
/* adjust pointed byte and find mbstate of the point of string.
adjusted point will be point <= adjusted_point, and returns
differences of the byte(adjusted_point - point).
if point is invalid (point < 0 || more than string length),
it returns -1 */
int
_rl_adjust_point (char *string, int point, mbstate_t *ps)
{
size_t tmp;
int length, pos;
tmp = 0;
pos = 0;
length = strlen(string);
if (point < 0)
return -1;
if (length < point)
return -1;
while (pos < point)
{
if (_rl_utf8locale && UTF8_SINGLEBYTE(string[pos]))
tmp = 1;
else
tmp = mbrlen (string + pos, length - pos, ps);
if (MB_INVALIDCH ((size_t)tmp))
{
/* in this case, bytes are invalid or too short to compose
multibyte char, so assume that the first byte represents
a single character anyway. */
pos++;
/* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */
if (ps)
memset (ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (tmp))
pos++;
else
pos += tmp;
}
return (pos - point);
}
int
_rl_is_mbchar_matched (char *string, int seed, int end, char *mbchar, int length)
{
int i;
if ((end - seed) < length)
return 0;
for (i = 0; i < length; i++)
if (string[seed + i] != mbchar[i])
return 0;
return 1;
}
WCHAR_T
_rl_char_value (char *buf, int ind)
{
size_t tmp;
WCHAR_T wc;
mbstate_t ps;
int l;
if (MB_LEN_MAX == 1 || rl_byte_oriented)
return ((WCHAR_T) buf[ind]);
if (_rl_utf8locale && UTF8_SINGLEBYTE(buf[ind]))
return ((WCHAR_T) buf[ind]);
l = strlen (buf);
if (ind >= l - 1)
return ((WCHAR_T) buf[ind]);
if (l < ind) /* Sanity check */
l = strlen (buf+ind);
memset (&ps, 0, sizeof (mbstate_t));
tmp = MBRTOWC (&wc, buf + ind, l - ind, &ps);
if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))
return ((WCHAR_T) buf[ind]);
return wc;
}
#endif /* HANDLE_MULTIBYTE */
/* Find next `count' characters started byte point of the specified seed.
If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte
characters. */
#undef _rl_find_next_mbchar
int
_rl_find_next_mbchar (char *string, int seed, int count, int flags)
{
#if defined (HANDLE_MULTIBYTE)
return _rl_find_next_mbchar_internal (string, seed, count, flags);
#else
return (seed + count);
#endif
}
/* Find previous character started byte point of the specified seed.
Returned point will be point <= seed. If flags is MB_FIND_NONZERO,
we look for non-zero-width multibyte characters. */
#undef _rl_find_prev_mbchar
int
_rl_find_prev_mbchar (char *string, int seed, int flags)
{
#if defined (HANDLE_MULTIBYTE)
return _rl_find_prev_mbchar_internal (string, seed, flags);
#else
return ((seed == 0) ? seed : seed - 1);
#endif
}

781
third_party/readline/misc.c vendored Normal file
View file

@ -0,0 +1,781 @@
/* misc.c -- miscellaneous bindable readline functions. */
/* 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
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_LOCALE_H)
# include <locale.h>
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "histlib.h"
#include "rlshell.h"
#include "xmalloc.h"
static int rl_digit_loop (void);
static void _rl_history_set_point (void);
/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
to preserve the value of rl_point from line to line. */
int _rl_history_preserve_point = 0;
_rl_arg_cxt _rl_argcxt;
/* Saved target point for when _rl_history_preserve_point is set. Special
value of -1 means that point is at the end of the line. */
int _rl_history_saved_point = -1;
/* **************************************************************** */
/* */
/* Numeric Arguments */
/* */
/* **************************************************************** */
int
_rl_arg_overflow (void)
{
if (rl_numeric_arg > 1000000)
{
_rl_argcxt = 0;
rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
return 0;
}
void
_rl_arg_init (void)
{
rl_save_prompt ();
_rl_argcxt = 0;
RL_SETSTATE(RL_STATE_NUMERICARG);
}
int
_rl_arg_getchar (void)
{
int c;
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
return c;
}
/* Process C as part of the current numeric argument. Return -1 if the
argument should be aborted, 0 if we should not read any more chars, and
1 if we should continue to read chars. */
int
_rl_arg_dispatch (_rl_arg_cxt cxt, int c)
{
int key, r;
key = c;
/* If we see a key bound to `universal-argument' after seeing digits,
it ends the argument but is otherwise ignored. */
if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
if ((cxt & NUM_SAWDIGITS) == 0)
{
rl_numeric_arg *= 4;
return 1;
}
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_argcxt |= NUM_READONE;
return 0; /* XXX */
}
else
{
key = _rl_bracketed_read_key ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
if (key < 0)
return -1;
return (_rl_dispatch (key, _rl_keymap));
}
}
c = UNMETA (c);
if (_rl_digit_p (c))
{
r = _rl_digit_value (c);
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
rl_explicit_arg = 1;
_rl_argcxt |= NUM_SAWDIGITS;
}
else if (c == '-' && rl_explicit_arg == 0)
{
rl_numeric_arg = 1;
_rl_argcxt |= NUM_SAWMINUS;
rl_arg_sign = -1;
}
else
{
/* Make M-- command equivalent to M--1 command. */
if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
rl_explicit_arg = 1;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
r = _rl_dispatch (key, _rl_keymap);
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* At worst, this will cause an extra redisplay. Otherwise,
we have to wait until the next character comes in. */
if (rl_done == 0)
(*rl_redisplay_function) ();
r = 0;
}
return r;
}
return 1;
}
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop (void)
{
int c, r;
while (1)
{
if (_rl_arg_overflow ())
return 1;
c = _rl_arg_getchar ();
if (c < 0)
{
_rl_abort_internal ();
return -1;
}
r = _rl_arg_dispatch (_rl_argcxt, c);
if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
break;
}
return r;
}
/* Create a default argument. */
void
_rl_reset_argument (void)
{
rl_numeric_arg = rl_arg_sign = 1;
rl_explicit_arg = 0;
_rl_argcxt = 0;
}
/* Start a numeric argument with initial value KEY */
int
rl_digit_argument (int ignore, int key)
{
_rl_arg_init ();
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_arg_dispatch (_rl_argcxt, key);
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
return 0;
}
else
{
rl_execute_next (key);
return (rl_digit_loop ());
}
}
/* C-u, universal argument. Multiply the current argument by 4.
Read a key. If the key has nothing to do with arguments, then
dispatch on it. If the key is the abort character then abort. */
int
rl_universal_argument (int count, int key)
{
_rl_arg_init ();
rl_numeric_arg *= 4;
return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
}
int
_rl_arg_callback (_rl_arg_cxt cxt)
{
int c, r;
c = _rl_arg_getchar ();
if (c < 0)
return (1); /* EOF */
if (_rl_argcxt & NUM_READONE)
{
_rl_argcxt &= ~NUM_READONE;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
rl_execute_next (c);
return 0;
}
r = _rl_arg_dispatch (cxt, c);
if (r > 0)
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
return (r != 1);
}
/* What to do when you abort reading an argument. */
int
rl_discard_argument (void)
{
rl_ding ();
rl_clear_message ();
_rl_reset_argument ();
return 0;
}
/* **************************************************************** */
/* */
/* History Utilities */
/* */
/* **************************************************************** */
/* We already have a history library, and that is what we use to control
the history features of readline. This is our local interface to
the history mechanism. */
/* While we are editing the history, this is the saved
version of the original line. */
HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
/* Set the history pointer back to the last entry in the history. */
void
_rl_start_using_history (void)
{
using_history ();
if (_rl_saved_line_for_history)
_rl_free_saved_history_line ();
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
_rl_history_search_pos = -99; /* some random invalid history position */
}
/* Free the contents (and containing structure) of a HIST_ENTRY. */
void
_rl_free_history_entry (HIST_ENTRY *entry)
{
if (entry == 0)
return;
FREE (entry->line);
FREE (entry->timestamp);
xfree (entry);
}
/* Perhaps put back the current line if it has changed. */
int
rl_maybe_replace_line (void)
{
HIST_ENTRY *temp;
temp = current_history ();
/* If the current line has changed, save the changes. */
if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
{
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
xfree (temp->line);
FREE (temp->timestamp);
xfree (temp);
}
return 0;
}
/* Restore the _rl_saved_line_for_history if there is one. */
int
rl_maybe_unsave_line (void)
{
if (_rl_saved_line_for_history)
{
/* Can't call with `1' because rl_undo_list might point to an undo
list from a history entry, as in rl_replace_from_history() below. */
rl_replace_line (_rl_saved_line_for_history->line, 0);
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
/* Doesn't free `data'. */
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
rl_point = rl_end; /* rl_replace_line sets rl_end */
}
else
rl_ding ();
return 0;
}
/* Save the current line in _rl_saved_line_for_history. */
int
rl_maybe_save_line (void)
{
if (_rl_saved_line_for_history == 0)
{
_rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->timestamp = (char *)NULL;
_rl_saved_line_for_history->data = (char *)rl_undo_list;
}
return 0;
}
int
_rl_free_saved_history_line (void)
{
UNDO_LIST *orig;
if (_rl_saved_line_for_history)
{
if (rl_undo_list && rl_undo_list == (UNDO_LIST *)_rl_saved_line_for_history->data)
rl_undo_list = 0;
/* Have to free this separately because _rl_free_history entry can't:
it doesn't know whether or not this has application data. Only the
callers that know this is _rl_saved_line_for_history can know that
it's an undo list. */
if (_rl_saved_line_for_history->data)
_rl_free_undo_list ((UNDO_LIST *)_rl_saved_line_for_history->data);
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
return 0;
}
static void
_rl_history_set_point (void)
{
rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
? _rl_history_saved_point
: rl_end;
if (rl_point > rl_end)
rl_point = rl_end;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
rl_point = 0;
#endif /* VI_MODE */
if (rl_editing_mode == emacs_mode)
rl_mark = (rl_point == rl_end ? 0 : rl_end);
}
void
rl_replace_from_history (HIST_ENTRY *entry, int flags)
{
/* Can't call with `1' because rl_undo_list might point to an undo list
from a history entry, just like we're setting up here. */
rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data;
rl_point = rl_end;
rl_mark = 0;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
{
rl_point = 0;
rl_mark = rl_end;
}
#endif
}
/* Process and free undo lists attached to each history entry prior to the
current entry, inclusive, reverting each line to its saved state. This
is destructive, and state about the current line is lost. This is not
intended to be called while actively editing, and the current line is
not assumed to have been added to the history list. */
void
_rl_revert_previous_lines (void)
{
int hpos;
HIST_ENTRY *entry;
UNDO_LIST *ul, *saved_undo_list;
char *lbuf;
lbuf = savestring (rl_line_buffer);
saved_undo_list = rl_undo_list;
hpos = where_history ();
entry = (hpos == history_length) ? previous_history () : current_history ();
while (entry)
{
if (ul = (UNDO_LIST *)entry->data)
{
if (ul == saved_undo_list)
saved_undo_list = 0;
/* Set up rl_line_buffer and other variables from history entry */
rl_replace_from_history (entry, 0); /* entry->line is now current */
entry->data = 0; /* entry->data is now current undo list */
/* Undo all changes to this history entry */
while (rl_undo_list)
rl_do_undo ();
/* And copy the reverted line back to the history entry, preserving
the timestamp. */
FREE (entry->line);
entry->line = savestring (rl_line_buffer);
}
entry = previous_history ();
}
/* Restore history state */
rl_undo_list = saved_undo_list; /* may have been set to null */
history_set_pos (hpos);
/* reset the line buffer */
rl_replace_line (lbuf, 0);
_rl_set_the_line ();
/* and clean up */
xfree (lbuf);
}
/* Revert all lines in the history by making sure we are at the end of the
history before calling _rl_revert_previous_lines() */
void
_rl_revert_all_lines (void)
{
int pos;
pos = where_history ();
using_history ();
_rl_revert_previous_lines ();
history_set_pos (pos);
}
/* Free the history list, including private readline data and take care
of pointer aliases to history data. Resets rl_undo_list if it points
to an UNDO_LIST * saved as some history entry's data member. This
should not be called while editing is active. */
void
rl_clear_history (void)
{
HIST_ENTRY **hlist, *hent;
register int i;
UNDO_LIST *ul, *saved_undo_list;
saved_undo_list = rl_undo_list;
hlist = history_list (); /* direct pointer, not copy */
for (i = 0; i < history_length; i++)
{
hent = hlist[i];
if (ul = (UNDO_LIST *)hent->data)
{
if (ul == saved_undo_list)
saved_undo_list = 0;
_rl_free_undo_list (ul);
hent->data = 0;
}
_rl_free_history_entry (hent);
}
history_offset = history_length = 0;
rl_undo_list = saved_undo_list; /* should be NULL */
}
/* **************************************************************** */
/* */
/* History Commands */
/* */
/* **************************************************************** */
/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (int count, int key)
{
return (rl_get_previous_history (1 + where_history (), key));
}
/* Meta-> goes to the end of the history. (The current line). */
int
rl_end_of_history (int count, int key)
{
rl_maybe_replace_line ();
using_history ();
rl_maybe_unsave_line ();
return 0;
}
/* Move down to the next history line. */
int
rl_get_next_history (int count, int key)
{
HIST_ENTRY *temp;
if (count < 0)
return (rl_get_previous_history (-count, key));
if (count == 0)
return 0;
rl_maybe_replace_line ();
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
temp = (HIST_ENTRY *)NULL;
while (count)
{
temp = next_history ();
if (!temp)
break;
--count;
}
if (temp == 0)
rl_maybe_unsave_line ();
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
/* Get the previous item out of our interactive history, making it the current
line. If there is no previous history, just ding. */
int
rl_get_previous_history (int count, int key)
{
HIST_ENTRY *old_temp, *temp;
int had_saved_line;
if (count < 0)
return (rl_get_next_history (-count, key));
if (count == 0 || history_list () == 0)
return 0;
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
/* If we don't have a line saved, then save this one. */
had_saved_line = _rl_saved_line_for_history != 0;
rl_maybe_save_line ();
/* If the current line has changed, save the changes. */
rl_maybe_replace_line ();
temp = old_temp = (HIST_ENTRY *)NULL;
while (count)
{
temp = previous_history ();
if (temp == 0)
break;
old_temp = temp;
--count;
}
/* If there was a large argument, and we moved back to the start of the
history, that is not an error. So use the last value found. */
if (!temp && old_temp)
temp = old_temp;
if (temp == 0)
{
if (had_saved_line == 0)
_rl_free_saved_history_line ();
rl_ding ();
}
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
/* With an argument, move back that many history lines, else move to the
beginning of history. */
int
rl_fetch_history (int count, int c)
{
int wanted, nhist;
/* Giving an argument of n means we want the nth command in the history
file. The command number is interpreted the same way that the bash
`history' command does it -- that is, giving an argument count of 450
to this command would get the command listed as number 450 in the
output of `history'. */
if (rl_explicit_arg)
{
nhist = history_base + where_history ();
/* Negative arguments count back from the end of the history list. */
wanted = (count >= 0) ? nhist - count : -count;
if (wanted <= 0 || wanted >= nhist)
{
/* In vi mode, we don't change the line with an out-of-range
argument, as for the `G' command. */
if (rl_editing_mode == vi_mode)
rl_ding ();
else
rl_beginning_of_history (0, 0);
}
else
rl_get_previous_history (wanted, c);
}
else
rl_beginning_of_history (count, 0);
return (0);
}
/* The equivalent of the Korn shell C-o operate-and-get-next-history-line
editing command. */
/* This could stand to be global to the readline library */
static rl_hook_func_t *_rl_saved_internal_startup_hook = 0;
static int saved_history_logical_offset = -1;
#define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries)
static int
set_saved_history ()
{
int absolute_offset, count;
if (saved_history_logical_offset >= 0)
{
absolute_offset = saved_history_logical_offset - history_base;
count = where_history () - absolute_offset;
rl_get_previous_history (count, 0);
}
saved_history_logical_offset = -1;
_rl_internal_startup_hook = _rl_saved_internal_startup_hook;
return (0);
}
int
rl_operate_and_get_next (int count, int c)
{
/* Accept the current line. */
rl_newline (1, c);
saved_history_logical_offset = rl_explicit_arg ? count : where_history () + history_base + 1;
_rl_saved_internal_startup_hook = _rl_internal_startup_hook;
_rl_internal_startup_hook = set_saved_history;
return 0;
}
/* **************************************************************** */
/* */
/* Editing Modes */
/* */
/* **************************************************************** */
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (int count, int key)
{
#if defined (VI_MODE)
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
rl_editing_mode = vi_mode;
rl_vi_insert_mode (1, key);
#endif /* VI_MODE */
return 0;
}
int
rl_emacs_editing_mode (int count, int key)
{
rl_editing_mode = emacs_mode;
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
_rl_keymap = emacs_standard_keymap;
if (_rl_show_mode_in_prompt)
_rl_reset_prompt ();
return 0;
}
/* Function for the rest of the library to use to set insert/overwrite mode. */
void
_rl_set_insert_mode (int im, int force)
{
#ifdef CURSOR_MODE
_rl_set_cursor (im, force);
#endif
rl_insert_mode = im;
}
/* Toggle overwrite mode. A positive explicit argument selects overwrite
mode. A negative or zero explicit argument selects insert mode. */
int
rl_overwrite_mode (int count, int key)
{
if (rl_explicit_arg == 0)
_rl_set_insert_mode (rl_insert_mode ^ 1, 0);
else if (count > 0)
_rl_set_insert_mode (RL_IM_OVERWRITE, 0);
else
_rl_set_insert_mode (RL_IM_INSERT, 0);
return 0;
}

345
third_party/readline/nls.c vendored Normal file
View file

@ -0,0 +1,345 @@
/* nls.c -- skeletal internationalization code. */
/* Copyright (C) 1996-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 <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_LOCALE_H)
# include <locale.h>
#endif
#if defined (HAVE_LANGINFO_CODESET)
# include <langinfo.h>
#endif
#include <ctype.h>
#include "rldefs.h"
#include "readline.h"
#include "rlshell.h"
#include "rlprivate.h"
#include "xmalloc.h"
static int utf8locale (char *);
#define RL_DEFAULT_LOCALE "C"
static char *_rl_current_locale = 0;
#if !defined (HAVE_SETLOCALE)
/* A list of legal values for the LANG or LC_CTYPE environment variables.
If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
or LANG environment variable (using the first of those with a value),
readline eight-bit mode is enabled. */
static char *legal_lang_values[] =
{
"iso88591",
"iso88592",
"iso88593",
"iso88594",
"iso88595",
"iso88596",
"iso88597",
"iso88598",
"iso88599",
"iso885910",
"koi8r",
"utf8",
0
};
static char *normalize_codeset (char *);
#endif /* !HAVE_SETLOCALE */
static char *find_codeset (char *, size_t *);
static char *_rl_get_locale_var (const char *);
static char *
_rl_get_locale_var (const char *v)
{
char *lspec;
lspec = sh_get_env_value ("LC_ALL");
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value (v);
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value ("LANG");
return lspec;
}
static int
utf8locale (char *lspec)
{
char *cp;
size_t len;
#if HAVE_LANGINFO_CODESET
(void)len;
cp = nl_langinfo (CODESET);
return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8"));
#else
cp = find_codeset (lspec, &len);
if (cp == 0 || len < 4 || len > 5)
return 0;
return ((len == 5) ? strncmp (cp, "UTF-8", len) == 0 : strncmp (cp, "utf8", 4) == 0);
#endif
}
/* Query the right environment variables and call setlocale() to initialize
the C library locale settings. */
char *
_rl_init_locale (void)
{
char *ret, *lspec;
/* Set the LC_CTYPE locale category from environment variables. */
lspec = _rl_get_locale_var ("LC_CTYPE");
/* Since _rl_get_locale_var queries the right environment variables,
we query the current locale settings with setlocale(), and, if
that doesn't return anything, we set lspec to the empty string to
force the subsequent call to setlocale() to define the `native'
environment. */
#if defined (HAVE_SETLOCALE)
if (lspec == 0 || *lspec == 0)
lspec = setlocale (LC_CTYPE, (char *)NULL);
if (lspec == 0)
lspec = "";
ret = setlocale (LC_CTYPE, lspec); /* ok, since it does not change locale */
#else
ret = (lspec == 0 || *lspec == 0) ? RL_DEFAULT_LOCALE : lspec;
#endif
_rl_utf8locale = (ret && *ret) ? utf8locale (ret) : 0;
_rl_current_locale = savestring (ret);
return ret;
}
/* If we have setlocale(3), just check the current LC_CTYPE category
value (passed as LOCALESTR), and go into eight-bit mode if it's not "C"
or "POSIX". If FORCE is non-zero, we reset the locale variables to values
appropriate for the C locale if the locale is "C" or "POSIX". FORCE is 0
when this is called from _rl_init_eightbit, since we're modifying the
default initial values and don't need to change anything else. If we
don't have setlocale(3), we check the codeset portion of LOCALESTR against
a set of known values and go into eight-bit mode if it matches one of those.
Returns 1 if we set eight-bit (multibyte) mode. */
static int
_rl_set_localevars (char *localestr, int force)
{
#if defined (HAVE_SETLOCALE)
if (localestr && *localestr && (localestr[0] != 'C' || localestr[1]) && (STREQ (localestr, "POSIX") == 0))
{
_rl_meta_flag = 1;
_rl_convert_meta_chars_to_ascii = 0;
_rl_output_meta_chars = 1;
return (1);
}
else if (force)
{
/* Default "C" locale settings. */
_rl_meta_flag = 0;
_rl_convert_meta_chars_to_ascii = 1;
_rl_output_meta_chars = 0;
return (0);
}
else
return (0);
#else /* !HAVE_SETLOCALE */
char *t;
int i;
/* We don't have setlocale. Finesse it. Check the environment for the
appropriate variables and set eight-bit mode if they have the right
values. */
if (localestr == 0 || (t = normalize_codeset (localestr)) == 0)
return (0);
for (i = 0; t && legal_lang_values[i]; i++)
if (STREQ (t, legal_lang_values[i]))
{
_rl_meta_flag = 1;
_rl_convert_meta_chars_to_ascii = 0;
_rl_output_meta_chars = 1;
break;
}
if (force && legal_lang_values[i] == 0) /* didn't find it */
{
/* Default "C" locale settings. */
_rl_meta_flag = 0;
_rl_convert_meta_chars_to_ascii = 1;
_rl_output_meta_chars = 0;
}
_rl_utf8locale = *t ? STREQ (t, "utf8") : 0;
xfree (t);
return (legal_lang_values[i] ? 1 : 0);
#endif /* !HAVE_SETLOCALE */
}
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
to decide the defaults for 8-bit character input and output. Returns
1 if we set eight-bit mode. */
int
_rl_init_eightbit (void)
{
char *t, *ol;
ol = _rl_current_locale;
t = _rl_init_locale (); /* resets _rl_current_locale, returns static pointer */
xfree (ol);
return (_rl_set_localevars (t, 0));
}
#if !defined (HAVE_SETLOCALE)
static char *
normalize_codeset (char *codeset)
{
size_t namelen, i;
int len, all_digits;
char *wp, *retval;
codeset = find_codeset (codeset, &namelen);
if (codeset == 0)
return (codeset);
all_digits = 1;
for (len = 0, i = 0; i < namelen; i++)
{
if (ISALNUM ((unsigned char)codeset[i]))
{
len++;
all_digits &= _rl_digit_p (codeset[i]);
}
}
retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
if (retval == 0)
return ((char *)0);
wp = retval;
/* Add `iso' to beginning of an all-digit codeset */
if (all_digits)
{
*wp++ = 'i';
*wp++ = 's';
*wp++ = 'o';
}
for (i = 0; i < namelen; i++)
if (ISALPHA ((unsigned char)codeset[i]))
*wp++ = _rl_to_lower (codeset[i]);
else if (_rl_digit_p (codeset[i]))
*wp++ = codeset[i];
*wp = '\0';
return retval;
}
#endif /* !HAVE_SETLOCALE */
/* Isolate codeset portion of locale specification. */
static char *
find_codeset (char *name, size_t *lenp)
{
char *cp, *language, *result;
cp = language = name;
result = (char *)0;
while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
cp++;
/* This does not make sense: language has to be specified. As
an exception we allow the variable to contain only the codeset
name. Perhaps there are funny codeset names. */
if (language == cp)
{
*lenp = strlen (language);
result = language;
}
else
{
/* Next is the territory. */
if (*cp == '_')
do
++cp;
while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
/* Now, finally, is the codeset. */
result = cp;
if (*cp == '.')
do
++cp;
while (*cp && *cp != '@');
if (cp - result > 2)
{
result++;
*lenp = cp - result;
}
else
{
*lenp = strlen (language);
result = language;
}
}
return result;
}
void
_rl_reset_locale (void)
{
char *ol, *nl;
/* This should not be NULL; _rl_init_eightbit sets it on the first call to
readline() or rl_initialize(). */
ol = _rl_current_locale;
nl = _rl_init_locale (); /* resets _rl_current_locale */
if ((ol == 0 && nl) || (ol && nl && (STREQ (ol, nl) == 0)))
(void)_rl_set_localevars (nl, 1);
xfree (ol);
}

185
third_party/readline/parens.c vendored Normal file
View file

@ -0,0 +1,185 @@
/* parens.c -- implementation of matching parentheses feature. */
/* Copyright (C) 1987, 1989, 1992-2015, 2017, 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 (__TANDEM)
# include <floss.h>
#endif
#include "rlconf.h"
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include <stdio.h>
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "posixselect.h"
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if !defined (strchr) && !defined (__STDC__)
extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */
#include "readline.h"
#include "rlprivate.h"
static int find_matching_open (char *, int, int);
/* Non-zero means try to blink the matching open parenthesis when the
close parenthesis is inserted. */
int rl_blink_matching_paren = 0;
static int _paren_blink_usec = 500000;
/* Change emacs_standard_keymap to have bindings for paren matching when
ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */
void
_rl_enable_paren_matching (int on_or_off)
{
if (on_or_off)
{
/* ([{ */
rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
#if defined (VI_MODE)
/* ([{ */
rl_bind_key_in_map (')', rl_insert_close, vi_insertion_keymap);
rl_bind_key_in_map (']', rl_insert_close, vi_insertion_keymap);
rl_bind_key_in_map ('}', rl_insert_close, vi_insertion_keymap);
#endif
}
else
{
/* ([{ */
rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
#if defined (VI_MODE)
/* ([{ */
rl_bind_key_in_map (')', rl_insert, vi_insertion_keymap);
rl_bind_key_in_map (']', rl_insert, vi_insertion_keymap);
rl_bind_key_in_map ('}', rl_insert, vi_insertion_keymap);
#endif
}
}
int
rl_set_paren_blink_timeout (int u)
{
int o;
o = _paren_blink_usec;
if (u > 0)
_paren_blink_usec = u;
return (o);
}
int
rl_insert_close (int count, int invoking_key)
{
if (rl_explicit_arg || !rl_blink_matching_paren)
_rl_insert_char (count, invoking_key);
else
{
#if defined (HAVE_SELECT)
int orig_point, match_point, ready;
struct timeval timer;
fd_set readfds;
(void)ready;
_rl_insert_char (1, invoking_key);
(*rl_redisplay_function) ();
match_point =
find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
/* Emacs might message or ring the bell here, but I don't. */
if (match_point < 0)
return 1;
FD_ZERO (&readfds);
FD_SET (fileno (rl_instream), &readfds);
USEC_TO_TIMEVAL (_paren_blink_usec, timer);
orig_point = rl_point;
rl_point = match_point;
(*rl_redisplay_function) ();
# if defined (RL_TIMEOUT_USE_SELECT)
ready = _rl_timeout_select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer, NULL);
# else
ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
# endif
rl_point = orig_point;
#else /* !HAVE_SELECT */
_rl_insert_char (count, invoking_key);
#endif /* !HAVE_SELECT */
}
return 0;
}
static int
find_matching_open (char *string, int from, int closer)
{
register int i;
int opener, level, delimiter;
switch (closer)
{
case ']': opener = '['; break;
case '}': opener = '{'; break;
case ')': opener = '('; break;
default:
return (-1);
}
level = 1; /* The closer passed in counts as 1. */
delimiter = 0; /* Delimited state unknown. */
for (i = from; i > -1; i--)
{
if (delimiter && (string[i] == delimiter))
delimiter = 0;
else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
delimiter = string[i];
else if (!delimiter && (string[i] == closer))
level++;
else if (!delimiter && (string[i] == opener))
level--;
if (!level)
break;
}
return (i);
}

440
third_party/readline/parse-colors.c vendored Normal file
View file

@ -0,0 +1,440 @@
/* `dir', `vdir' and `ls' directory listing programs for GNU.
Modified by Chet Ramey for Readline.
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2017
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 <stdio.h>
// strdup() / strcpy()
#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 "rldefs.h" // STREQ, savestring
#include "readline.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
#include "colors.h"
#include "parse-colors.h"
#if defined (COLOR_SUPPORT)
static bool get_funky_string (char **dest, const char **src, bool equals_end, size_t *output_count);
struct bin_str _rl_color_indicator[] =
{
{ LEN_STR_PAIR ("\033[") }, // lc: Left of color sequence
{ LEN_STR_PAIR ("m") }, // rc: Right of color sequence
{ 0, NULL }, // ec: End color (replaces lc+no+rc)
{ LEN_STR_PAIR ("0") }, // rs: Reset to ordinary colors
{ 0, NULL }, // no: Normal
{ 0, NULL }, // fi: File: default
{ LEN_STR_PAIR ("01;34") }, // di: Directory: bright blue
{ LEN_STR_PAIR ("01;36") }, // ln: Symlink: bright cyan
{ LEN_STR_PAIR ("33") }, // pi: Pipe: yellow/brown
{ LEN_STR_PAIR ("01;35") }, // so: Socket: bright magenta
{ LEN_STR_PAIR ("01;33") }, // bd: Block device: bright yellow
{ LEN_STR_PAIR ("01;33") }, // cd: Char device: bright yellow
{ 0, NULL }, // mi: Missing file: undefined
{ 0, NULL }, // or: Orphaned symlink: undefined
{ LEN_STR_PAIR ("01;32") }, // ex: Executable: bright green
{ LEN_STR_PAIR ("01;35") }, // do: Door: bright magenta
{ LEN_STR_PAIR ("37;41") }, // su: setuid: white on red
{ LEN_STR_PAIR ("30;43") }, // sg: setgid: black on yellow
{ LEN_STR_PAIR ("37;44") }, // st: sticky: black on blue
{ LEN_STR_PAIR ("34;42") }, // ow: other-writable: blue on green
{ LEN_STR_PAIR ("30;42") }, // tw: ow w/ sticky: black on green
{ LEN_STR_PAIR ("30;41") }, // ca: black on red
{ 0, NULL }, // mh: disabled by default
{ LEN_STR_PAIR ("\033[K") }, // cl: clear to end of line
};
/* Parse a string as part of the LS_COLORS variable; this may involve
decoding all kinds of escape characters. If equals_end is set an
unescaped equal sign ends the string, otherwise only a : or \0
does. Set *OUTPUT_COUNT to the number of bytes output. Return
true if successful.
The resulting string is *not* null-terminated, but may contain
embedded nulls.
Note that both dest and src are char **; on return they point to
the first free byte after the array and the character that ended
the input string, respectively. */
static bool
get_funky_string (char **dest, const char **src, bool equals_end, size_t *output_count) {
char num; /* For numerical codes */
size_t count; /* Something to count with */
enum {
ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR
} state;
const char *p;
char *q;
p = *src; /* We don't want to double-indirect */
q = *dest; /* the whole darn time. */
count = 0; /* No characters counted in yet. */
num = 0;
state = ST_GND; /* Start in ground state. */
while (state < ST_END)
{
switch (state)
{
case ST_GND: /* Ground state (no escapes) */
switch (*p)
{
case ':':
case '\0':
state = ST_END; /* End of string */
break;
case '\\':
state = ST_BACKSLASH; /* Backslash scape sequence */
++p;
break;
case '^':
state = ST_CARET; /* Caret escape */
++p;
break;
case '=':
if (equals_end)
{
state = ST_END; /* End */
break;
}
/* else fall through */
default:
*(q++) = *(p++);
++count;
break;
}
break;
case ST_BACKSLASH: /* Backslash escaped character */
switch (*p)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
state = ST_OCTAL; /* Octal sequence */
num = *p - '0';
break;
case 'x':
case 'X':
state = ST_HEX; /* Hex sequence */
num = 0;
break;
case 'a': /* Bell */
num = '\a';
break;
case 'b': /* Backspace */
num = '\b';
break;
case 'e': /* Escape */
num = 27;
break;
case 'f': /* Form feed */
num = '\f';
break;
case 'n': /* Newline */
num = '\n';
break;
case 'r': /* Carriage return */
num = '\r';
break;
case 't': /* Tab */
num = '\t';
break;
case 'v': /* Vtab */
num = '\v';
break;
case '?': /* Delete */
num = 127;
break;
case '_': /* Space */
num = ' ';
break;
case '\0': /* End of string */
state = ST_ERROR; /* Error! */
break;
default: /* Escaped character like \ ^ : = */
num = *p;
break;
}
if (state == ST_BACKSLASH)
{
*(q++) = num;
++count;
state = ST_GND;
}
++p;
break;
case ST_OCTAL: /* Octal sequence */
if (*p < '0' || *p > '7')
{
*(q++) = num;
++count;
state = ST_GND;
}
else
num = (num << 3) + (*(p++) - '0');
break;
case ST_HEX: /* Hex sequence */
switch (*p)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
num = (num << 4) + (*(p++) - '0');
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
num = (num << 4) + (*(p++) - 'a') + 10;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
num = (num << 4) + (*(p++) - 'A') + 10;
break;
default:
*(q++) = num;
++count;
state = ST_GND;
break;
}
break;
case ST_CARET: /* Caret escape */
state = ST_GND; /* Should be the next state... */
if (*p >= '@' && *p <= '~')
{
*(q++) = *(p++) & 037;
++count;
}
else if (*p == '?')
{
*(q++) = 127;
++count;
}
else
state = ST_ERROR;
break;
default:
/* should we ? */
/* abort (); no, we should not */
state = ST_ERROR;
break;
}
}
*dest = q;
*src = p;
*output_count = count;
return state != ST_ERROR;
}
#endif /* COLOR_SUPPORT */
void _rl_parse_colors(void)
{
#if defined (COLOR_SUPPORT)
const char *p; /* Pointer to character being parsed */
char *buf; /* color_buf buffer pointer */
int state; /* State of parser */
int ind_no; /* Indicator number */
char label[3]; /* Indicator label */
COLOR_EXT_TYPE *ext; /* Extension we are working on */
p = sh_get_env_value ("LS_COLORS");
if (p == 0 || *p == '\0')
{
_rl_color_ext_list = NULL;
return;
}
ext = NULL;
strcpy (label, "??");
/* This is an overly conservative estimate, but any possible
LS_COLORS string will *not* generate a color_buf longer than
itself, so it is a safe way of allocating a buffer in
advance. */
buf = color_buf = savestring (p);
state = 1;
while (state > 0)
{
switch (state)
{
case 1: /* First label character */
switch (*p)
{
case ':':
++p;
break;
case '*':
/* Allocate new extension block and add to head of
linked list (this way a later definition will
override an earlier one, which can be useful for
having terminal-specific defs override global). */
ext = (COLOR_EXT_TYPE *)xmalloc (sizeof *ext);
ext->next = _rl_color_ext_list;
_rl_color_ext_list = ext;
++p;
ext->ext.string = buf;
state = (get_funky_string (&buf, &p, true, &ext->ext.len)
? 4 : -1);
break;
case '\0':
state = 0; /* Done! */
break;
default: /* Assume it is file type label */
label[0] = *(p++);
state = 2;
break;
}
break;
case 2: /* Second label character */
if (*p)
{
label[1] = *(p++);
state = 3;
}
else
state = -1; /* Error */
break;
case 3: /* Equal sign after indicator label */
state = -1; /* Assume failure... */
if (*(p++) == '=')/* It *should* be... */
{
for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no)
{
if (STREQ (label, indicator_name[ind_no]))
{
_rl_color_indicator[ind_no].string = buf;
state = (get_funky_string (&buf, &p, false,
&_rl_color_indicator[ind_no].len)
? 1 : -1);
break;
}
}
if (state == -1)
{
_rl_errmsg ("LS_COLORS: unrecognized prefix: %s", label);
/* recover from an unrecognized prefix */
while (p && *p && *p != ':')
p++;
if (p && *p == ':')
state = 1;
else if (p && *p == 0)
state = 0;
}
}
break;
case 4: /* Equal sign after *.ext */
if (*(p++) == '=')
{
ext->seq.string = buf;
state = (get_funky_string (&buf, &p, false, &ext->seq.len)
? 1 : -1);
}
else
state = -1;
/* XXX - recover here as with an unrecognized prefix? */
if (state == -1 && ext->ext.string)
_rl_errmsg ("LS_COLORS: syntax error: %s", ext->ext.string);
break;
}
}
if (state < 0)
{
COLOR_EXT_TYPE *e;
COLOR_EXT_TYPE *e2;
_rl_errmsg ("unparsable value for LS_COLORS environment variable");
free (color_buf);
for (e = _rl_color_ext_list; e != NULL; /* empty */)
{
e2 = e;
e = e->next;
free (e2);
}
_rl_color_ext_list = NULL;
_rl_colored_stats = 0; /* can't have colored stats without colors */
}
#else /* !COLOR_SUPPORT */
;
#endif /* !COLOR_SUPPORT */
}

46
third_party/readline/parse-colors.h vendored Normal file
View file

@ -0,0 +1,46 @@
/* `dir', `vdir' and `ls' directory listing programs for GNU.
Modified by Chet Ramey for Readline.
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 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 _PARSE_COLORS_H_
#define _PARSE_COLORS_H_
#include "readline.h"
#define LEN_STR_PAIR(s) sizeof (s) - 1, s
void _rl_parse_colors (void);
static const char *const indicator_name[]=
{
"lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so",
"bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st",
"ow", "tw", "ca", "mh", "cl", NULL
};
/* Buffer for color sequences */
static char *color_buf;
#endif /* !_PARSE_COLORS_H_ */

71
third_party/readline/posixdir.h vendored Normal file
View file

@ -0,0 +1,71 @@
/* posixdir.h -- Posix directory reading includes and defines. */
/* Copyright (C) 1987,1991,2012,2019,2021 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/>.
*/
/* This file should be included instead of <dirent.h> or <sys/dir.h>. */
#if !defined (_POSIXDIR_H_)
#define _POSIXDIR_H_
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN)
# define D_NAMLEN(d) ((d)->d_namlen)
# else
# define D_NAMLEN(d) (strlen ((d)->d_name))
# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */
#else
# if defined (HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# endif
# if defined (HAVE_SYS_DIR_H)
# include <sys/dir.h>
# endif
# if defined (HAVE_NDIR_H)
# include <ndir.h>
# endif
# if !defined (dirent)
# define dirent direct
# endif /* !dirent */
# define D_NAMLEN(d) ((d)->d_namlen)
#endif /* !HAVE_DIRENT_H */
/* The bash code fairly consistently uses d_fileno; make sure it's available */
#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO)
# define d_fileno d_ino
#endif
/* Posix does not require that the d_ino field be present, and some
systems do not provide it. */
#if !defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO)
# define REAL_DIR_ENTRY(dp) 1
#else
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#endif /* _POSIX_SOURCE */
#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (BROKEN_DIRENT_D_INO)
# define D_INO_AVAILABLE
#endif
/* Signal the rest of the code that it can safely use dirent.d_fileno */
#if defined (D_INO_AVAILABLE) || defined (HAVE_STRUCT_DIRENT_D_FILENO)
# define D_FILENO_AVAILABLE 1
#endif
#endif /* !_POSIXDIR_H_ */

46
third_party/readline/posixjmp.h vendored Normal file
View file

@ -0,0 +1,46 @@
/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */
/* Copyright (C) 1987,1991-2015 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/>.
*/
#ifndef _POSIXJMP_H_
#define _POSIXJMP_H_
#include <setjmp.h>
/* This *must* be included *after* config.h */
#if defined (HAVE_POSIX_SIGSETJMP)
# define procenv_t sigjmp_buf
# define setjmp_nosigs(x) sigsetjmp((x), 0)
# define setjmp_sigs(x) sigsetjmp((x), 1)
# define _rl_longjmp(x, n) siglongjmp((x), (n))
# define sh_longjmp(x, n) siglongjmp((x), (n))
#else
# define procenv_t jmp_buf
# define setjmp_nosigs setjmp
# define setjmp_sigs setjmp
# define _rl_longjmp(x, n) longjmp((x), (n))
# define sh_longjmp(x, n) longjmp((x), (n))
#endif
#endif /* _POSIXJMP_H_ */

47
third_party/readline/posixselect.h vendored Normal file
View file

@ -0,0 +1,47 @@
/* posixselect.h -- wrapper for select(2) includes and definitions */
/* Copyright (C) 2009 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/>.
*/
#ifndef _POSIXSELECT_H_
#define _POSIXSELECT_H_
#if defined (FD_SET) && !defined (HAVE_SELECT)
# define HAVE_SELECT 1
#endif
#if defined (HAVE_SELECT)
# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
# include <sys/time.h>
# endif
#endif /* HAVE_SELECT */
#if defined (HAVE_SYS_SELECT_H)
# include <sys/select.h>
#endif
#ifndef USEC_PER_SEC
# define USEC_PER_SEC 1000000
#endif
#define USEC_TO_TIMEVAL(us, tv) \
do { \
(tv).tv_sec = (us) / USEC_PER_SEC; \
(tv).tv_usec = (us) % USEC_PER_SEC; \
} while (0)
#endif /* _POSIXSELECT_H_ */

162
third_party/readline/posixstat.h vendored Normal file
View file

@ -0,0 +1,162 @@
/* posixstat.h -- Posix stat(2) definitions for systems that
don't have them. */
/* Copyright (C) 1987-2019 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/>.
*/
/* This file should be included instead of <sys/stat.h>.
It relies on the local sys/stat.h to work though. */
#if !defined (_POSIXSTAT_H_)
#define _POSIXSTAT_H_
#include <sys/stat.h>
#if defined (STAT_MACROS_BROKEN)
# undef S_ISBLK
# undef S_ISCHR
# undef S_ISDIR
# undef S_ISFIFO
# undef S_ISREG
# undef S_ISLNK
#endif /* STAT_MACROS_BROKEN */
/* These are guaranteed to work only on isc386 */
#if !defined (S_IFDIR) && !defined (S_ISDIR)
# define S_IFDIR 0040000
#endif /* !S_IFDIR && !S_ISDIR */
#if !defined (S_IFMT)
# define S_IFMT 0170000
#endif /* !S_IFMT */
/* Posix 1003.1 5.6.1.1 <sys/stat.h> file types */
/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but
do not provide the S_IS* macros that Posix requires. */
#if defined (_S_IFMT) && !defined (S_IFMT)
#define S_IFMT _S_IFMT
#endif
#if defined (_S_IFIFO) && !defined (S_IFIFO)
#define S_IFIFO _S_IFIFO
#endif
#if defined (_S_IFCHR) && !defined (S_IFCHR)
#define S_IFCHR _S_IFCHR
#endif
#if defined (_S_IFDIR) && !defined (S_IFDIR)
#define S_IFDIR _S_IFDIR
#endif
#if defined (_S_IFBLK) && !defined (S_IFBLK)
#define S_IFBLK _S_IFBLK
#endif
#if defined (_S_IFREG) && !defined (S_IFREG)
#define S_IFREG _S_IFREG
#endif
#if defined (_S_IFLNK) && !defined (S_IFLNK)
#define S_IFLNK _S_IFLNK
#endif
#if defined (_S_IFSOCK) && !defined (S_IFSOCK)
#define S_IFSOCK _S_IFSOCK
#endif
/* Test for each symbol individually and define the ones necessary (some
systems claiming Posix compatibility define some but not all). */
#if defined (S_IFBLK) && !defined (S_ISBLK)
#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */
#endif
#if defined (S_IFCHR) && !defined (S_ISCHR)
#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */
#endif
#if defined (S_IFDIR) && !defined (S_ISDIR)
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */
#endif
#if defined (S_IFREG) && !defined (S_ISREG)
#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */
#endif
#if defined (S_IFIFO) && !defined (S_ISFIFO)
#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */
#endif
#if defined (S_IFLNK) && !defined (S_ISLNK)
#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */
#endif
#if defined (S_IFSOCK) && !defined (S_ISSOCK)
#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */
#endif
/*
* POSIX 1003.1 5.6.1.2 <sys/stat.h> File Modes
*/
#if !defined (S_IRWXU)
# if !defined (S_IREAD)
# define S_IREAD 00400
# define S_IWRITE 00200
# define S_IEXEC 00100
# endif /* S_IREAD */
# if !defined (S_IRUSR)
# define S_IRUSR S_IREAD /* read, owner */
# define S_IWUSR S_IWRITE /* write, owner */
# define S_IXUSR S_IEXEC /* execute, owner */
# define S_IRGRP (S_IREAD >> 3) /* read, group */
# define S_IWGRP (S_IWRITE >> 3) /* write, group */
# define S_IXGRP (S_IEXEC >> 3) /* execute, group */
# define S_IROTH (S_IREAD >> 6) /* read, other */
# define S_IWOTH (S_IWRITE >> 6) /* write, other */
# define S_IXOTH (S_IEXEC >> 6) /* execute, other */
# endif /* !S_IRUSR */
# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
#else /* !S_IRWXU */
/* S_IRWXU is defined, but "group" and "other" bits might not be
(happens in certain versions of MinGW). */
# if !defined (S_IRGRP)
# define S_IRGRP (S_IREAD >> 3) /* read, group */
# define S_IWGRP (S_IWRITE >> 3) /* write, group */
# define S_IXGRP (S_IEXEC >> 3) /* execute, group */
# endif /* !S_IRGRP */
# if !defined (S_IROTH)
# define S_IROTH (S_IREAD >> 6) /* read, other */
# define S_IWOTH (S_IWRITE >> 6) /* write, other */
# define S_IXOTH (S_IEXEC >> 6) /* execute, other */
# endif /* !S_IROTH */
# if !defined (S_IRWXG)
# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
# endif
# if !defined (S_IRWXO)
# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
# endif
#endif /* !S_IRWXU */
/* These are non-standard, but are used in builtins.c$symbolic_umask() */
#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH)
#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
#endif /* _POSIXSTAT_H_ */

84
third_party/readline/posixtime.h vendored Normal file
View file

@ -0,0 +1,84 @@
/* posixtime.h -- wrapper for time.h, sys/times.h mess. */
/* Copyright (C) 1999-2021 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/>.
*/
#ifndef _POSIXTIME_H_
#define _POSIXTIME_H_
/* include this after config.h */
/* Some systems require this, mostly for the definition of `struct timezone'.
For example, Dynix/ptx has that definition in <time.h> rather than
sys/time.h */
#if defined (HAVE_SYS_TIME_H)
# include <sys/time.h>
#endif
#include <time.h>
#if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK)
# if !defined (CLK_TCK)
# if defined (HZ)
# define CLK_TCK HZ
# else
# define CLK_TCK 60 /* 60HZ */
# endif
# endif /* !CLK_TCK */
#endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */
#if !HAVE_TIMEVAL
struct timeval
{
time_t tv_sec;
long int tv_usec;
};
#endif
#if !HAVE_GETTIMEOFDAY
extern int gettimeofday PARAMS((struct timeval *, void *));
#endif
/* These exist on BSD systems, at least. */
#if !defined (timerclear)
# define timerclear(tvp) do { (tvp)->tv_sec = 0; (tvp)->tv_usec = 0; } while (0)
#endif
#if !defined (timerisset)
# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#endif
#if !defined (timercmp)
# define timercmp(a, b, CMP) \
(((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_usec CMP (b)->tv_usec) \
: ((a)->tv_sec CMP (b)->tv_sec))
#endif
/* These are non-standard. */
#if !defined (timerisunset)
# define timerisunset(tvp) ((tvp)->tv_sec == 0 && (tvp)->tv_usec == 0)
#endif
#if !defined (timerset)
# define timerset(tvp, s, u) do { tvp->tv_sec = s; tvp->tv_usec = u; } while (0)
#endif
#ifndef TIMEVAL_TO_TIMESPEC
# define TIMEVAL_TO_TIMESPEC(tv, ts) \
do { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
} while (0)
#endif
#endif /* _POSIXTIME_H_ */

1575
third_party/readline/readline.c vendored Normal file

File diff suppressed because it is too large Load diff

986
third_party/readline/readline.h vendored Normal file
View file

@ -0,0 +1,986 @@
/* Readline.h -- the names of functions callable from within readline. */
/* 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/>.
*/
#if !defined (_READLINE_H_)
#define _READLINE_H_
#ifdef __cplusplus
extern "C" {
#endif
#if defined (READLINE_LIBRARY)
# include "rlstdc.h"
# include "rltypedefs.h"
# include "keymaps.h"
# include "tilde.h"
#else
# include "third_party/readline/rlstdc.h"
# include "third_party/readline/rltypedefs.h"
# include "third_party/readline/keymaps.h"
# include "third_party/readline/tilde.h"
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0802 /* Readline 8.2 */
#define RL_VERSION_MAJOR 8
#define RL_VERSION_MINOR 2
/* Readline data structures. */
/* Maintaining the state of undo. We remember individual deletes and inserts
on a chain of things to do. */
/* The actions that undo knows how to undo. Notice that UNDO_DELETE means
to insert some text, and UNDO_INSERT means to delete some text. I.e.,
the code tells undo what to undo, not how to undo it. */
enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END };
/* What an element of THE_UNDO_LIST looks like. */
typedef struct undo_list {
struct undo_list *next;
int start, end; /* Where the change took place. */
char *text; /* The text to insert, if undoing a delete. */
enum undo_code what; /* Delete, Insert, Begin, End. */
} UNDO_LIST;
/* The current undo list for RL_LINE_BUFFER. */
extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */
typedef struct _funmap {
const char *name;
rl_command_func_t *function;
} FUNMAP;
extern FUNMAP **funmap;
/* **************************************************************** */
/* */
/* Functions available to bind to key sequences */
/* */
/* **************************************************************** */
/* Bindable commands for numeric arguments. */
extern int rl_digit_argument (int, int);
extern int rl_universal_argument (int, int);
/* Bindable commands for moving the cursor. */
extern int rl_forward_byte (int, int);
extern int rl_forward_char (int, int);
extern int rl_forward (int, int);
extern int rl_backward_byte (int, int);
extern int rl_backward_char (int, int);
extern int rl_backward (int, int);
extern int rl_beg_of_line (int, int);
extern int rl_end_of_line (int, int);
extern int rl_forward_word (int, int);
extern int rl_backward_word (int, int);
extern int rl_refresh_line (int, int);
extern int rl_clear_screen (int, int);
extern int rl_clear_display (int, int);
extern int rl_skip_csi_sequence (int, int);
extern int rl_arrow_keys (int, int);
extern int rl_previous_screen_line (int, int);
extern int rl_next_screen_line (int, int);
/* Bindable commands for inserting and deleting text. */
extern int rl_insert (int, int);
extern int rl_quoted_insert (int, int);
extern int rl_tab_insert (int, int);
extern int rl_newline (int, int);
extern int rl_do_lowercase_version (int, int);
extern int rl_rubout (int, int);
extern int rl_delete (int, int);
extern int rl_rubout_or_delete (int, int);
extern int rl_delete_horizontal_space (int, int);
extern int rl_delete_or_show_completions (int, int);
extern int rl_insert_comment (int, int);
/* Bindable commands for changing case. */
extern int rl_upcase_word (int, int);
extern int rl_downcase_word (int, int);
extern int rl_capitalize_word (int, int);
/* Bindable commands for transposing characters and words. */
extern int rl_transpose_words (int, int);
extern int rl_transpose_chars (int, int);
/* Bindable commands for searching within a line. */
extern int rl_char_search (int, int);
extern int rl_backward_char_search (int, int);
/* Bindable commands for readline's interface to the command history. */
extern int rl_beginning_of_history (int, int);
extern int rl_end_of_history (int, int);
extern int rl_get_next_history (int, int);
extern int rl_get_previous_history (int, int);
extern int rl_operate_and_get_next (int, int);
extern int rl_fetch_history (int, int);
/* Bindable commands for managing the mark and region. */
extern int rl_set_mark (int, int);
extern int rl_exchange_point_and_mark (int, int);
/* Bindable commands to set the editing mode (emacs or vi). */
extern int rl_vi_editing_mode (int, int);
extern int rl_emacs_editing_mode (int, int);
/* Bindable commands to change the insert mode (insert or overwrite) */
extern int rl_overwrite_mode (int, int);
/* Bindable commands for managing key bindings. */
extern int rl_re_read_init_file (int, int);
extern int rl_dump_functions (int, int);
extern int rl_dump_macros (int, int);
extern int rl_dump_variables (int, int);
/* Bindable commands for word completion. */
extern int rl_complete (int, int);
extern int rl_possible_completions (int, int);
extern int rl_insert_completions (int, int);
extern int rl_old_menu_complete (int, int);
extern int rl_menu_complete (int, int);
extern int rl_backward_menu_complete (int, int);
/* Bindable commands for killing and yanking text, and managing the kill ring. */
extern int rl_kill_word (int, int);
extern int rl_backward_kill_word (int, int);
extern int rl_kill_line (int, int);
extern int rl_backward_kill_line (int, int);
extern int rl_kill_full_line (int, int);
extern int rl_unix_word_rubout (int, int);
extern int rl_unix_filename_rubout (int, int);
extern int rl_unix_line_discard (int, int);
extern int rl_copy_region_to_kill (int, int);
extern int rl_kill_region (int, int);
extern int rl_copy_forward_word (int, int);
extern int rl_copy_backward_word (int, int);
extern int rl_yank (int, int);
extern int rl_yank_pop (int, int);
extern int rl_yank_nth_arg (int, int);
extern int rl_yank_last_arg (int, int);
extern int rl_bracketed_paste_begin (int, int);
/* Not available unless _WIN32 is defined. */
#if defined (_WIN32)
extern int rl_paste_from_clipboard (int, int);
#endif
/* Bindable commands for incremental searching. */
extern int rl_reverse_search_history (int, int);
extern int rl_forward_search_history (int, int);
/* Bindable keyboard macro commands. */
extern int rl_start_kbd_macro (int, int);
extern int rl_end_kbd_macro (int, int);
extern int rl_call_last_kbd_macro (int, int);
extern int rl_print_last_kbd_macro (int, int);
/* Bindable undo commands. */
extern int rl_revert_line (int, int);
extern int rl_undo_command (int, int);
/* Bindable tilde expansion commands. */
extern int rl_tilde_expand (int, int);
/* Bindable terminal control commands. */
extern int rl_restart_output (int, int);
extern int rl_stop_output (int, int);
/* Miscellaneous bindable commands. */
extern int rl_abort (int, int);
extern int rl_tty_status (int, int);
/* Bindable commands for incremental and non-incremental history searching. */
extern int rl_history_search_forward (int, int);
extern int rl_history_search_backward (int, int);
extern int rl_history_substr_search_forward (int, int);
extern int rl_history_substr_search_backward (int, int);
extern int rl_noninc_forward_search (int, int);
extern int rl_noninc_reverse_search (int, int);
extern int rl_noninc_forward_search_again (int, int);
extern int rl_noninc_reverse_search_again (int, int);
/* Bindable command used when inserting a matching close character. */
extern int rl_insert_close (int, int);
/* Not available unless READLINE_CALLBACKS is defined. */
extern void rl_callback_handler_install (const char *, rl_vcpfunc_t *);
extern void rl_callback_read_char (void);
extern void rl_callback_handler_remove (void);
extern void rl_callback_sigcleanup (void);
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
/* VI-mode bindable commands. */
extern int rl_vi_redo (int, int);
extern int rl_vi_undo (int, int);
extern int rl_vi_yank_arg (int, int);
extern int rl_vi_fetch_history (int, int);
extern int rl_vi_search_again (int, int);
extern int rl_vi_search (int, int);
extern int rl_vi_complete (int, int);
extern int rl_vi_tilde_expand (int, int);
extern int rl_vi_prev_word (int, int);
extern int rl_vi_next_word (int, int);
extern int rl_vi_end_word (int, int);
extern int rl_vi_insert_beg (int, int);
extern int rl_vi_append_mode (int, int);
extern int rl_vi_append_eol (int, int);
extern int rl_vi_eof_maybe (int, int);
extern int rl_vi_insertion_mode (int, int);
extern int rl_vi_insert_mode (int, int);
extern int rl_vi_movement_mode (int, int);
extern int rl_vi_arg_digit (int, int);
extern int rl_vi_change_case (int, int);
extern int rl_vi_put (int, int);
extern int rl_vi_column (int, int);
extern int rl_vi_delete_to (int, int);
extern int rl_vi_change_to (int, int);
extern int rl_vi_yank_to (int, int);
extern int rl_vi_yank_pop (int, int);
extern int rl_vi_rubout (int, int);
extern int rl_vi_delete (int, int);
extern int rl_vi_back_to_indent (int, int);
extern int rl_vi_unix_word_rubout (int, int);
extern int rl_vi_first_print (int, int);
extern int rl_vi_char_search (int, int);
extern int rl_vi_match (int, int);
extern int rl_vi_change_char (int, int);
extern int rl_vi_subst (int, int);
extern int rl_vi_overstrike (int, int);
extern int rl_vi_overstrike_delete (int, int);
extern int rl_vi_replace (int, int);
extern int rl_vi_set_mark (int, int);
extern int rl_vi_goto_mark (int, int);
/* VI-mode utility functions. */
extern int rl_vi_check (void);
extern int rl_vi_domove (int, int *);
extern int rl_vi_bracktype (int);
extern void rl_vi_start_inserting (int, int, int);
/* VI-mode pseudo-bindable commands, used as utility functions. */
extern int rl_vi_fWord (int, int);
extern int rl_vi_bWord (int, int);
extern int rl_vi_eWord (int, int);
extern int rl_vi_fword (int, int);
extern int rl_vi_bword (int, int);
extern int rl_vi_eword (int, int);
/* **************************************************************** */
/* */
/* Well Published Functions */
/* */
/* **************************************************************** */
/* Readline functions. */
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
extern char *readline (const char *);
extern int rl_set_prompt (const char *);
extern int rl_expand_prompt (char *);
extern int rl_initialize (void);
/* Undocumented; unused by readline */
extern int rl_discard_argument (void);
/* Utility functions to bind keys to readline commands. */
extern int rl_add_defun (const char *, rl_command_func_t *, int);
extern int rl_bind_key (int, rl_command_func_t *);
extern int rl_bind_key_in_map (int, rl_command_func_t *, Keymap);
extern int rl_unbind_key (int);
extern int rl_unbind_key_in_map (int, Keymap);
extern int rl_bind_key_if_unbound (int, rl_command_func_t *);
extern int rl_bind_key_if_unbound_in_map (int, rl_command_func_t *, Keymap);
extern int rl_unbind_function_in_map (rl_command_func_t *, Keymap);
extern int rl_unbind_command_in_map (const char *, Keymap);
extern int rl_bind_keyseq (const char *, rl_command_func_t *);
extern int rl_bind_keyseq_in_map (const char *, rl_command_func_t *, Keymap);
extern int rl_bind_keyseq_if_unbound (const char *, rl_command_func_t *);
extern int rl_bind_keyseq_if_unbound_in_map (const char *, rl_command_func_t *, Keymap);
extern int rl_generic_bind (int, const char *, char *, Keymap);
extern char *rl_variable_value (const char *);
extern int rl_variable_bind (const char *, const char *);
/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */
extern int rl_set_key (const char *, rl_command_func_t *, Keymap);
/* Backwards compatibility, use rl_generic_bind instead. */
extern int rl_macro_bind (const char *, const char *, Keymap);
/* Undocumented in the texinfo manual; not really useful to programs. */
extern int rl_translate_keyseq (const char *, char *, int *);
extern char *rl_untranslate_keyseq (int);
extern rl_command_func_t *rl_named_function (const char *);
extern rl_command_func_t *rl_function_of_keyseq (const char *, Keymap, int *);
extern rl_command_func_t *rl_function_of_keyseq_len (const char *, size_t, Keymap, int *);
extern int rl_trim_arg_from_keyseq (const char *, size_t, Keymap);
extern void rl_list_funmap_names (void);
extern char **rl_invoking_keyseqs_in_map (rl_command_func_t *, Keymap);
extern char **rl_invoking_keyseqs (rl_command_func_t *);
extern void rl_function_dumper (int);
extern void rl_macro_dumper (int);
extern void rl_variable_dumper (int);
extern int rl_read_init_file (const char *);
extern int rl_parse_and_bind (char *);
/* Functions for manipulating keymaps. */
extern Keymap rl_make_bare_keymap (void);
extern int rl_empty_keymap (Keymap);
extern Keymap rl_copy_keymap (Keymap);
extern Keymap rl_make_keymap (void);
extern void rl_discard_keymap (Keymap);
extern void rl_free_keymap (Keymap);
extern Keymap rl_get_keymap_by_name (const char *);
extern char *rl_get_keymap_name (Keymap);
extern void rl_set_keymap (Keymap);
extern Keymap rl_get_keymap (void);
extern int rl_set_keymap_name (const char *, Keymap);
/* Undocumented; used internally only. */
extern void rl_set_keymap_from_edit_mode (void);
extern char *rl_get_keymap_name_from_edit_mode (void);
/* Functions for manipulating the funmap, which maps command names to functions. */
extern int rl_add_funmap_entry (const char *, rl_command_func_t *);
extern const char **rl_funmap_names (void);
/* Undocumented, only used internally -- there is only one funmap, and this
function may be called only once. */
extern void rl_initialize_funmap (void);
/* Utility functions for managing keyboard macros. */
extern void rl_push_macro_input (char *);
/* Functions for undoing, from undo.c */
extern void rl_add_undo (enum undo_code, int, int, char *);
extern void rl_free_undo_list (void);
extern int rl_do_undo (void);
extern int rl_begin_undo_group (void);
extern int rl_end_undo_group (void);
extern int rl_modifying (int, int);
/* Functions for redisplay. */
extern void rl_redisplay (void);
extern int rl_on_new_line (void);
extern int rl_on_new_line_with_prompt (void);
extern int rl_forced_update_display (void);
extern int rl_clear_visible_line (void);
extern int rl_clear_message (void);
extern int rl_reset_line_state (void);
extern int rl_crlf (void);
/* Functions to manage the mark and region, especially the notion of an
active mark and an active region. */
extern void rl_keep_mark_active (void);
extern void rl_activate_mark (void);
extern void rl_deactivate_mark (void);
extern int rl_mark_active_p (void);
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
extern int rl_message ();
#endif
extern int rl_show_char (int);
/* Undocumented in texinfo manual. */
extern int rl_character_len (int, int);
extern void rl_redraw_prompt_last_line (void);
/* Save and restore internal prompt redisplay information. */
extern void rl_save_prompt (void);
extern void rl_restore_prompt (void);
/* Modifying text. */
extern void rl_replace_line (const char *, int);
extern int rl_insert_text (const char *);
extern int rl_delete_text (int, int);
extern int rl_kill_text (int, int);
extern char *rl_copy_text (int, int);
/* Terminal and tty mode management. */
extern void rl_prep_terminal (int);
extern void rl_deprep_terminal (void);
extern void rl_tty_set_default_bindings (Keymap);
extern void rl_tty_unset_default_bindings (Keymap);
extern int rl_tty_set_echoing (int);
extern int rl_reset_terminal (const char *);
extern void rl_resize_terminal (void);
extern void rl_set_screen_size (int, int);
extern void rl_get_screen_size (int *, int *);
extern void rl_reset_screen_size (void);
extern char *rl_get_termcap (const char *);
/* Functions for character input. */
extern int rl_stuff_char (int);
extern int rl_execute_next (int);
extern int rl_clear_pending_input (void);
extern int rl_read_key (void);
extern int rl_getc (FILE *);
extern int rl_set_keyboard_input_timeout (int);
/* Functions to set and reset timeouts. */
extern int rl_set_timeout (unsigned int, unsigned int);
extern int rl_timeout_remaining (unsigned int *, unsigned int *);
#undef rl_clear_timeout
#define rl_clear_timeout() rl_set_timeout (0, 0)
/* `Public' utility functions . */
extern void rl_extend_line_buffer (int);
extern int rl_ding (void);
extern int rl_alphabetic (int);
extern void rl_free (void *);
/* Readline signal handling, from signals.c */
extern int rl_set_signals (void);
extern int rl_clear_signals (void);
extern void rl_cleanup_after_signal (void);
extern void rl_reset_after_signal (void);
extern void rl_free_line_state (void);
extern int rl_pending_signal (void);
extern void rl_check_signals (void);
extern void rl_echo_signal_char (int);
extern int rl_set_paren_blink_timeout (int);
/* History management functions. */
extern void rl_clear_history (void);
/* Undocumented. */
extern int rl_maybe_save_line (void);
extern int rl_maybe_unsave_line (void);
extern int rl_maybe_replace_line (void);
/* Completion functions. */
extern int rl_complete_internal (int);
extern void rl_display_match_list (char **, int, 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);
extern int rl_completion_mode (rl_command_func_t *);
#if 0
/* Backwards compatibility (compat.c). These will go away sometime. */
extern void free_undo_list (void);
extern int maybe_save_line (void);
extern int maybe_unsave_line (void);
extern int maybe_replace_line (void);
extern int ding (void);
extern int alphabetic (int);
extern int crlf (void);
extern char **completion_matches (char *, rl_compentry_func_t *);
extern char *username_completion_function (const char *, int);
extern char *filename_completion_function (const char *, int);
#endif
/* **************************************************************** */
/* */
/* Well Published Variables */
/* */
/* **************************************************************** */
/* The version of this incarnation of the readline library. */
extern const char *rl_library_version; /* e.g., "4.2" */
extern int rl_readline_version; /* e.g., 0x0402 */
/* True if this is real GNU readline. */
extern int rl_gnu_readline_p;
/* Flags word encapsulating the current readline state. */
extern unsigned long rl_readline_state;
/* Says which editing mode readline is currently using. 1 means emacs mode;
0 means vi mode. */
extern int rl_editing_mode;
/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means
overwrite mode. Reset to insert mode on each input line. */
extern int rl_insert_mode;
/* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */
extern const char *rl_readline_name;
/* The prompt readline uses. This is set from the argument to
readline (), and should not be assigned to directly. */
extern char *rl_prompt;
/* The prompt string that is actually displayed by rl_redisplay. Public so
applications can more easily supply their own redisplay functions. */
extern char *rl_display_prompt;
/* The line buffer that is in use. */
extern char *rl_line_buffer;
/* The location of point, and end. */
extern int rl_point;
extern int rl_end;
/* The mark, or saved cursor position. */
extern int rl_mark;
/* Flag to indicate that readline has finished with the current input
line and should return it. */
extern int rl_done;
/* Flag to indicate that readline has read an EOF character or read has
returned 0 or error, and is returning a NULL line as a result. */
extern int rl_eof_found;
/* If set to a character value, that will be the next keystroke read. */
extern int rl_pending_input;
/* Non-zero if we called this function from _rl_dispatch(). It's present
so functions can find out whether they were called from a key binding
or directly from an application. */
extern int rl_dispatching;
/* Non-zero if the user typed a numeric argument before executing the
current function. */
extern int rl_explicit_arg;
/* The current value of the numeric argument specified by the user. */
extern int rl_numeric_arg;
/* The address of the last command function Readline executed. */
extern rl_command_func_t *rl_last_func;
/* The name of the terminal to use. */
extern const char *rl_terminal_name;
/* The input and output streams. */
extern FILE *rl_instream;
extern FILE *rl_outstream;
/* If non-zero, Readline gives values of LINES and COLUMNS from the environment
greater precedence than values fetched from the kernel when computing the
screen dimensions. */
extern int rl_prefer_env_winsize;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
extern rl_hook_func_t *rl_startup_hook;
/* If non-zero, this is the address of a function to call just before
readline_internal_setup () returns and readline_internal starts
reading input characters. */
extern rl_hook_func_t *rl_pre_input_hook;
/* The address of a function to call periodically while Readline is
awaiting character input, or NULL, for no event handling. */
extern rl_hook_func_t *rl_event_hook;
/* The address of a function to call if a read is interrupted by a signal. */
extern rl_hook_func_t *rl_signal_event_hook;
extern rl_hook_func_t *rl_timeout_event_hook;
/* The address of a function to call if Readline needs to know whether or not
there is data available from the current input source. */
extern rl_hook_func_t *rl_input_available_hook;
/* The address of the function to call to fetch a character from the current
Readline input stream */
extern rl_getc_func_t *rl_getc_function;
extern rl_voidfunc_t *rl_redisplay_function;
extern rl_vintfunc_t *rl_prep_term_function;
extern rl_voidfunc_t *rl_deprep_term_function;
/* Dispatch variables. */
extern Keymap rl_executing_keymap;
extern Keymap rl_binding_keymap;
extern int rl_executing_key;
extern char *rl_executing_keyseq;
extern int rl_key_sequence_length;
/* Display variables. */
/* If non-zero, readline will erase the entire line, including any prompt,
if the only thing typed on an otherwise-blank line is something bound to
rl_newline. */
extern int rl_erase_empty_line;
/* If non-zero, the application has already printed the prompt (rl_prompt)
before calling readline, so readline should not output it the first time
redisplay is done. */
extern int rl_already_prompted;
/* A non-zero value means to read only this many characters rather than
up to a character bound to accept-line. */
extern int rl_num_chars_to_read;
/* The text of a currently-executing keyboard macro. */
extern char *rl_executing_macro;
/* Variables to control readline signal handling. */
/* If non-zero, readline will install its own signal handlers for
SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
extern int rl_catch_signals;
/* If non-zero, readline will install a signal handler for SIGWINCH
that also attempts to call any calling application's SIGWINCH signal
handler. Note that the terminal is not cleaned up before the
application's signal handler is called; use rl_cleanup_after_signal()
to do that. */
extern int rl_catch_sigwinch;
/* If non-zero, the readline SIGWINCH handler will modify LINES and
COLUMNS in the environment. */
extern int rl_change_environment;
/* Completion variables. */
/* Pointer to the generator function for completion_matches ().
NULL means to use rl_filename_completion_function (), the default
filename completer. */
extern rl_compentry_func_t *rl_completion_entry_function;
/* Optional generator for menu completion. Default is
rl_completion_entry_function (rl_filename_completion_function). */
extern rl_compentry_func_t *rl_menu_completion_entry_function;
/* If rl_ignore_some_completions_function is non-NULL it is the address
of a function to call after all of the possible matches have been
generated, but before the actual completion is done to the input line.
The function is called with one argument; a NULL terminated array
of (char *). If your function removes any of the elements, they
must be free()'ed. */
extern rl_compignore_func_t *rl_ignore_some_completions_function;
/* Pointer to alternative function to create matches.
Function is called with TEXT, START, and END.
START and END are indices in RL_LINE_BUFFER saying what the boundaries
of TEXT are.
If this function exists and returns NULL then call the value of
rl_completion_entry_function to try to match, otherwise use the
array of strings returned. */
extern rl_completion_func_t *rl_attempted_completion_function;
/* The basic list of characters that signal a break between words for the
completer routine. The initial contents of this variable is what
breaks words in the shell, i.e. "n\"\\'`@$>". */
extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
extern const char *rl_completer_word_break_characters;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
extern rl_cpvfunc_t *rl_completion_word_break_hook;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
rl_completer_word_break_characters are treated as any other character,
unless they also appear within this list. */
extern const char *rl_completer_quote_characters;
/* List of quote characters which cause a word break. */
extern const char *rl_basic_quote_characters;
/* List of characters that need to be quoted in filenames by the completer. */
extern const char *rl_filename_quote_characters;
/* List of characters that are word break characters, but should be left
in TEXT when it is passed to the completion function. The shell uses
this to help determine what kind of completing to do. */
extern const char *rl_special_prefixes;
/* If non-zero, then this is the address of a function to call when
completing on a directory name. The function is called with
the address of a string (the current directory name) as an arg. It
changes what is displayed when the possible completions are printed
or inserted. The directory completion hook should perform
any necessary dequoting. This function should return 1 if it modifies
the directory name pointer passed as an argument. If the directory
completion hook returns 0, it should not modify the directory name
pointer passed as an argument. */
extern rl_icppfunc_t *rl_directory_completion_hook;
/* If non-zero, this is the address of a function to call when completing
a directory name. This function takes the address of the directory name
to be modified as an argument. Unlike rl_directory_completion_hook, it
only modifies the directory name used in opendir(2), not what is displayed
when the possible completions are printed or inserted. If set, it takes
precedence over rl_directory_completion_hook. The directory rewrite
hook should perform any necessary dequoting. This function has the same
return value properties as the directory_completion_hook.
I'm not happy with how this works yet, so it's undocumented. I'm trying
it in bash to see how well it goes. */
extern rl_icppfunc_t *rl_directory_rewrite_hook;
/* If non-zero, this is the address of a function for the completer to call
before deciding which character to append to a completed name. It should
modify the directory name passed as an argument if appropriate, and return
non-zero if it modifies the name. This should not worry about dequoting
the filename; that has already happened by the time it gets here. */
extern rl_icppfunc_t *rl_filename_stat_hook;
/* If non-zero, this is the address of a function to call when reading
directory entries from the filesystem for completion and comparing
them to the partial word to be completed. The function should
either return its first argument (if no conversion takes place) or
newly-allocated memory. This can, for instance, convert filenames
between character sets for comparison against what's typed at the
keyboard. The returned value is what is added to the list of
matches. The second argument is the length of the filename to be
converted. */
extern rl_dequote_func_t *rl_filename_rewrite_hook;
/* Backwards compatibility with previous versions of readline. */
#define rl_symbolic_link_hook rl_directory_completion_hook
/* If non-zero, then this is the address of a function to call when
completing a word would normally display the list of possible matches.
This function is called instead of actually doing the display.
It takes three arguments: (char **matches, int num_matches, int max_length)
where MATCHES is the array of strings that matched, NUM_MATCHES is the
number of strings in that array, and MAX_LENGTH is the length of the
longest string in that array. */
extern rl_compdisp_func_t *rl_completion_display_matches_hook;
/* Non-zero means that the results of the matches are to be treated
as filenames. This is ALWAYS zero on entry, and can only be changed
within a completion entry finder function. */
extern int rl_filename_completion_desired;
/* Non-zero means that the results of the matches are to be quoted using
double quotes (or an application-specific quoting mechanism) if the
filename contains any characters in rl_word_break_chars. This is
ALWAYS non-zero on entry, and can only be changed within a completion
entry finder function. */
extern int rl_filename_quoting_desired;
/* Set to a function to quote a filename in an application-specific fashion.
Called with the text to quote, the type of match found (single or multiple)
and a pointer to the quoting character to be used, which the function can
reset if desired. */
extern rl_quote_func_t *rl_filename_quoting_function;
/* Function to call to remove quoting characters from a filename. Called
before completion is attempted, so the embedded quotes do not interfere
with matching names in the file system. */
extern rl_dequote_func_t *rl_filename_dequoting_function;
/* Function to call to decide whether or not a word break character is
quoted. If a character is quoted, it does not break words for the
completer. */
extern rl_linebuf_func_t *rl_char_is_quoted_p;
/* Non-zero means to suppress normal filename completion after the
user-specified completion function has been called. */
extern int rl_attempted_completion_over;
/* Set to a character describing the type of completion being attempted by
rl_complete_internal; available for use by application completion
functions. */
extern int rl_completion_type;
/* Set to the last key used to invoke one of the completion functions */
extern int rl_completion_invoking_key;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items;
/* Character appended to completed words when at the end of the line. The
default is a space. Nothing is added if this is '\0'. */
extern int rl_completion_append_character;
/* If set to non-zero by an application completion function,
rl_completion_append_character will not be appended. */
extern int rl_completion_suppress_append;
/* Set to any quote character readline thinks it finds before any application
completion function is called. */
extern int rl_completion_quote_character;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
extern int rl_completion_found_quote;
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
extern int rl_completion_suppress_quote;
/* If non-zero, readline will sort the completion matches. On by default. */
extern int rl_sort_completion_matches;
/* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the
mark-directories variable (which is user-settable). This exists so
that application completion functions can override the user's preference
(set via the mark-symlinked-directories variable) if appropriate.
It's set to the value of _rl_complete_mark_symlink_dirs in
rl_complete_internal before any application-specific completion
function is called, so without that function doing anything, the user's
preferences are honored. */
extern int rl_completion_mark_symlink_dirs;
/* If non-zero, then disallow duplicates in the matches. */
extern int rl_ignore_completion_duplicates;
/* If this is non-zero, completion is (temporarily) inhibited, and the
completion character will be inserted as any other. */
extern int rl_inhibit_completion;
/* 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. */
extern int rl_persistent_signal_handlers;
/* Input error; can be returned by (*rl_getc_function) if readline is reading
a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */
#define READERR (-2)
/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE '\001'
#define RL_PROMPT_END_IGNORE '\002'
/* Possible values for do_replace argument to rl_filename_quoting_function,
called by rl_complete_internal. */
#define NO_MATCH 0
#define SINGLE_MATCH 1
#define MULT_MATCH 2
/* Possible state values for rl_readline_state */
#define RL_STATE_NONE 0x000000 /* no state; before first call */
#define RL_STATE_INITIALIZING 0x0000001 /* initializing */
#define RL_STATE_INITIALIZED 0x0000002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x0000004 /* terminal is prepped */
#define RL_STATE_READCMD 0x0000008 /* reading a command key */
#define RL_STATE_METANEXT 0x0000010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x0000020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x0000040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x0000080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x0000100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x0000200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x0000400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x0000800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x0001000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x0002000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x0004000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x0008000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x0010000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x0020000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x0040000 /* tty special chars saved */
#define RL_STATE_CALLBACK 0x0080000 /* using the callback interface */
#define RL_STATE_VIMOTION 0x0100000 /* reading vi motion arg */
#define RL_STATE_MULTIKEY 0x0200000 /* reading multiple-key command */
#define RL_STATE_VICMDONCE 0x0400000 /* entered vi command mode at least once */
#define RL_STATE_CHARSEARCH 0x0800000 /* vi mode char search */
#define RL_STATE_REDISPLAYING 0x1000000 /* updating terminal display */
#define RL_STATE_DONE 0x2000000 /* done; accepted line */
#define RL_STATE_TIMEOUT 0x4000000 /* done; timed out */
#define RL_STATE_EOF 0x8000000 /* done; got eof on read */
#define RL_SETSTATE(x) (rl_readline_state |= (x))
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
#define RL_ISSTATE(x) (rl_readline_state & (x))
struct readline_state {
/* line state */
int point;
int end;
int mark;
int buflen;
char *buffer;
UNDO_LIST *ul;
char *prompt;
/* global state */
int rlstate;
int done;
Keymap kmap;
/* input state */
rl_command_func_t *lastfunc;
int insmode;
int edmode;
char *kseq;
int kseqlen;
int pendingin;
FILE *inf;
FILE *outf;
char *macro;
/* signal state */
int catchsigs;
int catchsigwinch;
/* search state */
/* completion state */
rl_compentry_func_t *entryfunc;
rl_compentry_func_t *menuentryfunc;
rl_compignore_func_t *ignorefunc;
rl_completion_func_t *attemptfunc;
const char *wordbreakchars;
/* options state */
/* hook state */
/* reserved for future expansion, so the struct size doesn't change */
char reserved[64];
};
extern int rl_save_state (struct readline_state *);
extern int rl_restore_state (struct readline_state *);
#ifdef __cplusplus
}
#endif
#endif /* _READLINE_H_ */

79
third_party/readline/rlconf.h vendored Normal file
View file

@ -0,0 +1,79 @@
/* rlconf.h -- readline configuration definitions */
/* Copyright (C) 1992-2015 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 (_RLCONF_H_)
#define _RLCONF_H_
/* Define this if you want the vi-mode editing available. */
#define VI_MODE
/* Define this to get an indication of file type when listing completions. */
#define VISIBLE_STATS
/* Define this to get support for colors when listing completions and in
other places. */
#define COLOR_SUPPORT
/* This definition is needed by readline.c, rltty.c, and signals.c. */
/* If on, then readline handles signals in a way that doesn't suck. */
#define HANDLE_SIGNALS
/* Ugly but working hack for binding prefix meta. */
#define PREFIX_META_HACK
/* The next-to-last-ditch effort file name for a user-specific init file. */
#define DEFAULT_INPUTRC "~/.inputrc"
/* The ultimate last-ditch filename for an init file -- system-wide. */
#define SYS_INPUTRC "/etc/inputrc"
/* If defined, expand tabs to spaces. */
#define DISPLAY_TABS
/* If defined, use the terminal escape sequence to move the cursor forward
over a character when updating the line rather than rewriting it. */
/* #define HACK_TERMCAP_MOTION */
/* The string inserted by the `insert comment' command. */
#define RL_COMMENT_BEGIN_DEFAULT "#"
/* Define this if you want code that allows readline to be used in an
X `callback' style. */
#define READLINE_CALLBACKS
/* Define this if you want the cursor to indicate insert or overwrite mode. */
/* #define CURSOR_MODE */
/* Define this if you want to enable code that talks to the Linux kernel
tty auditing system. */
/* #define ENABLE_TTY_AUDIT_SUPPORT */
/* Defaults for the various editing mode indicators, inserted at the beginning
of the last (maybe only) line of the prompt if show-mode-in-prompt is on */
#define RL_EMACS_MODESTR_DEFAULT "@"
#define RL_EMACS_MODESTR_DEFLEN 1
#define RL_VI_INS_MODESTR_DEFAULT "(ins)"
#define RL_VI_INS_MODESTR_DEFLEN 5
#define RL_VI_CMD_MODESTR_DEFAULT "(cmd)"
#define RL_VI_CMD_MODESTR_DEFLEN 5
#endif /* _RLCONF_H_ */

166
third_party/readline/rldefs.h vendored Normal file
View file

@ -0,0 +1,166 @@
/* rldefs.h -- an attempt to isolate some of the system-specific defines
for readline. This should be included after any files that define
system-specific constants like _POSIX_VERSION or USG. */
/* 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/>.
*/
#if !defined (_RLDEFS_H_)
#define _RLDEFS_H_
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include "rlstdc.h"
#if defined (STRCOLL_BROKEN)
# undef HAVE_STRCOLL
#endif
#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
# define TERMIOS_TTY_DRIVER
#else
# if defined (HAVE_TERMIO_H)
# define TERMIO_TTY_DRIVER
# else
# if !defined (__MINGW32__)
# define NEW_TTY_DRIVER
# else
# define NO_TTY_DRIVER
# endif
# endif
#endif
/* Posix macro to check file in statbuf for directory-ness.
This requires that <sys/stat.h> be included before this test. */
#if defined (S_IFDIR) && !defined (S_ISDIR)
# define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
#endif
/* Decide which flavor of the header file describing the C library
string functions to include and include it. */
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if !defined (strchr) && !defined (__STDC__)
extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
# if defined (PREFER_VARARGS)
# include <varargs.h>
# endif
#endif
#if defined (HAVE_STRCASECMP)
#define _rl_stricmp strcasecmp
#define _rl_strnicmp strncasecmp
#else
extern int _rl_stricmp (const char *, const char *);
extern int _rl_strnicmp (const char *, const char *, int);
#endif
#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE)
# define _rl_strpbrk(a,b) strpbrk((a),(b))
#else
extern char *_rl_strpbrk (const char *, const char *);
#endif
#if !defined (emacs_mode)
# define no_mode -1
# define vi_mode 0
# define emacs_mode 1
#endif
#if !defined (RL_IM_INSERT)
# define RL_IM_INSERT 1
# define RL_IM_OVERWRITE 0
#
# define RL_IM_DEFAULT RL_IM_INSERT
#endif
/* If you cast map[key].function to type (Keymap) on a Cray,
the compiler takes the value of map[key].function and
divides it by 4 to convert between pointer types (pointers
to functions and pointers to structs are different sizes).
This is not what is wanted. */
#if defined (CRAY)
# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function)
# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data))
#else
# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data)
#endif
#ifndef savestring
#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
#endif
/* Possible values for _rl_bell_preference. */
#define NO_BELL 0
#define AUDIBLE_BELL 1
#define VISIBLE_BELL 2
/* Definitions used when searching the line for characters. */
/* NOTE: it is necessary that opposite directions are inverses */
#define FTO 1 /* forward to */
#define BTO -1 /* backward to */
#define FFIND 2 /* forward find */
#define BFIND -2 /* backward find */
/* Possible values for the found_quote flags word used by the completion
functions. It says what kind of (shell-like) quoting we found anywhere
in the line. */
#define RL_QF_SINGLE_QUOTE 0x01
#define RL_QF_DOUBLE_QUOTE 0x02
#define RL_QF_BACKSLASH 0x04
#define RL_QF_OTHER_QUOTE 0x08
/* Default readline line buffer length. */
#define DEFAULT_BUFFER_SIZE 256
#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
#if !defined (RL_STRLEN)
# define RL_STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0)
#endif
#if !defined (FREE)
# define FREE(x) if (x) free (x)
#endif
#if !defined (SWAP)
# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
#endif
/* CONFIGURATION SECTION */
#include "rlconf.h"
#endif /* !_RLDEFS_H_ */

225
third_party/readline/rlmbutil.h vendored Normal file
View file

@ -0,0 +1,225 @@
/* rlmbutil.h -- utility functions for multibyte characters. */
/* Copyright (C) 2001-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/>.
*/
#if !defined (_RL_MBUTIL_H_)
#define _RL_MBUTIL_H_
#include "rlstdc.h"
/************************************************/
/* check multibyte capability for I18N code */
/************************************************/
/* For platforms which support the ISO C amendment 1 functionality we
support user defined character classes. */
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H)
# include <wchar.h>
# include <wctype.h>
# if defined (HAVE_ISWCTYPE) && \
defined (HAVE_ISWLOWER) && \
defined (HAVE_ISWUPPER) && \
defined (HAVE_MBSRTOWCS) && \
defined (HAVE_MBRTOWC) && \
defined (HAVE_MBRLEN) && \
defined (HAVE_TOWLOWER) && \
defined (HAVE_TOWUPPER) && \
defined (HAVE_WCHAR_T) && \
defined (HAVE_WCWIDTH)
/* system is supposed to support XPG5 */
# define HANDLE_MULTIBYTE 1
# endif
#endif
/* If we don't want multibyte chars even on a system that supports them, let
the configuring user turn multibyte support off. */
#if defined (NO_MULTIBYTE_SUPPORT)
# undef HANDLE_MULTIBYTE
#endif
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
# define mbstate_t int
#endif
/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to
handle multibyte chars (some systems define MB_LEN_MAX as 1) */
#ifdef HANDLE_MULTIBYTE
# include <limits.h>
# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
# undef MB_LEN_MAX
# endif
# if !defined (MB_LEN_MAX)
# define MB_LEN_MAX 16
# endif
#endif
/************************************************/
/* end of multibyte capability checks for I18N */
/************************************************/
/*
* wchar_t doesn't work for 32-bit values on Windows using MSVC
*/
#ifdef WCHAR_T_BROKEN
# define WCHAR_T char32_t
# define MBRTOWC mbrtoc32
# define WCRTOMB c32rtomb
#else /* normal systems */
# define WCHAR_T wchar_t
# define MBRTOWC mbrtowc
# define WCRTOMB wcrtomb
#endif
/*
* Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar:
*
* MB_FIND_ANY find any multibyte character
* MB_FIND_NONZERO find a non-zero-width multibyte character
*/
#define MB_FIND_ANY 0x00
#define MB_FIND_NONZERO 0x01
extern int _rl_find_prev_mbchar (char *, int, int);
extern int _rl_find_next_mbchar (char *, int, int, int);
#ifdef HANDLE_MULTIBYTE
extern int _rl_compare_chars (char *, int, mbstate_t *, char *, int, mbstate_t *);
extern int _rl_get_char_len (char *, mbstate_t *);
extern int _rl_adjust_point (char *, int, mbstate_t *);
extern int _rl_read_mbchar (char *, int);
extern int _rl_read_mbstring (int, char *, int);
extern int _rl_is_mbchar_matched (char *, int, int, char *, int);
extern WCHAR_T _rl_char_value (char *, int);
extern int _rl_walphabetic (WCHAR_T);
#define _rl_to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc))
#define _rl_to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc))
#define MB_NEXTCHAR(b,s,c,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
? _rl_find_next_mbchar ((b), (s), (c), (f)) \
: ((s) + (c)))
#define MB_PREVCHAR(b,s,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
? _rl_find_prev_mbchar ((b), (s), (f)) \
: ((s) - 1))
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
#define MB_NULLWCH(x) ((x) == 0)
/* Try and shortcut the printable ascii characters to cut down the number of
calls to a libc wcwidth() */
static inline int
_rl_wcwidth (WCHAR_T wc)
{
switch (wc)
{
case ' ': case '!': case '"': case '#': case '%':
case '&': case '\'': case '(': case ')': case '*':
case '+': case ',': case '-': case '.': case '/':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case ':': case ';': case '<': case '=': case '>':
case '?':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case '[': case '\\': case ']': case '^': case '_':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z': case '{': case '|': case '}': case '~':
return 1;
default:
return wcwidth (wc);
}
}
/* Unicode combining characters range from U+0300 to U+036F */
#define UNICODE_COMBINING_CHAR(x) ((x) >= 768 && (x) <= 879)
#if defined (WCWIDTH_BROKEN)
# define WCWIDTH(wc) ((_rl_utf8locale && UNICODE_COMBINING_CHAR(wc)) ? 0 : _rl_wcwidth(wc))
#else
# define WCWIDTH(wc) _rl_wcwidth(wc)
#endif
#if defined (WCWIDTH_BROKEN)
# define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0 && iswcntrl(x) == 0)
#else
# define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0)
#endif
#define UTF8_SINGLEBYTE(c) (((c) & 0x80) == 0)
#define UTF8_MBFIRSTCHAR(c) (((c) & 0xc0) == 0xc0)
#define UTF8_MBCHAR(c) (((c) & 0xc0) == 0x80)
#else /* !HANDLE_MULTIBYTE */
#undef MB_LEN_MAX
#undef MB_CUR_MAX
#define MB_LEN_MAX 1
#define MB_CUR_MAX 1
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
#define _rl_char_value(buf,ind) ((buf)[(ind)])
#define _rl_walphabetic(c) (rl_alphabetic (c))
#define _rl_to_wupper(c) (_rl_to_upper (c))
#define _rl_to_wlower(c) (_rl_to_lower (c))
#define MB_NEXTCHAR(b,s,c,f) ((s) + (c))
#define MB_PREVCHAR(b,s,f) ((s) - 1)
#define MB_INVALIDCH(x) (0)
#define MB_NULLWCH(x) (0)
#define UTF8_SINGLEBYTE(c) (1)
#if !defined (HAVE_WCHAR_T) && !defined (wchar_t)
# define wchar_t int
#endif
#endif /* !HANDLE_MULTIBYTE */
extern int rl_byte_oriented;
#endif /* _RL_MBUTIL_H_ */

633
third_party/readline/rlprivate.h vendored Normal file
View file

@ -0,0 +1,633 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999-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/>.
*/
#if !defined (_RL_PRIVATE_H_)
#define _RL_PRIVATE_H_
#include "rlconf.h" /* for VISIBLE_STATS */
#include "rlstdc.h"
#include "posixjmp.h" /* defines procenv_t */
#include "rlmbutil.h" /* for HANDLE_MULTIBYTE */
/*************************************************************************
* *
* Convenience definitions *
* *
*************************************************************************/
#define EMACS_MODE() (rl_editing_mode == emacs_mode)
#define VI_COMMAND_MODE() (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
#define VI_INSERT_MODE() (rl_editing_mode == vi_mode && _rl_keymap == vi_insertion_keymap)
#define RL_CHECK_SIGNALS() \
do { \
if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \
} while (0)
#define RL_SIG_RECEIVED() (_rl_caught_signal != 0)
#define RL_SIGINT_RECEIVED() (_rl_caught_signal == SIGINT)
#define RL_SIGWINCH_RECEIVED() (_rl_caught_signal == SIGWINCH)
#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
/*************************************************************************
* *
* Global structs undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/* search types */
#define RL_SEARCH_ISEARCH 0x01 /* incremental search */
#define RL_SEARCH_NSEARCH 0x02 /* non-incremental search */
#define RL_SEARCH_CSEARCH 0x04 /* intra-line char search */
/* search flags */
#define SF_REVERSE 0x01
#define SF_FOUND 0x02
#define SF_FAILED 0x04
#define SF_CHGKMAP 0x08
#define SF_PATTERN 0x10
#define SF_NOCASE 0x20 /* unused so far */
typedef struct __rl_search_context
{
int type;
int sflags;
char *search_string;
int search_string_index;
int search_string_size;
char **lines;
char *allocated_line;
int hlen;
int hindex;
int save_point;
int save_mark;
int save_line;
int last_found_line;
char *prev_line_found;
UNDO_LIST *save_undo_list;
Keymap keymap; /* used when dispatching commands in search string */
Keymap okeymap; /* original keymap */
int history_pos;
int direction;
int prevc;
int lastc;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
char pmb[MB_LEN_MAX];
#endif
char *sline;
int sline_len;
int sline_index;
char *search_terminators;
} _rl_search_cxt;
struct _rl_cmd {
Keymap map;
int count;
int key;
rl_command_func_t *func;
};
extern struct _rl_cmd _rl_pending_command;
extern struct _rl_cmd *_rl_command_to_execute;
/* Callback data for reading numeric arguments */
#define NUM_SAWMINUS 0x01
#define NUM_SAWDIGITS 0x02
#define NUM_READONE 0x04
typedef int _rl_arg_cxt;
/* A context for reading key sequences longer than a single character when
using the callback interface. */
#define KSEQ_DISPATCHED 0x01
#define KSEQ_SUBSEQ 0x02
#define KSEQ_RECURSIVE 0x04
typedef struct __rl_keyseq_context
{
int flags;
int subseq_arg;
int subseq_retval; /* XXX */
int okey;
Keymap dmap;
Keymap oldmap;
struct __rl_keyseq_context *ocxt;
int childval;
} _rl_keyseq_cxt;
/* vi-mode commands that use result of motion command to define boundaries */
#define VIM_DELETE 0x01
#define VIM_CHANGE 0x02
#define VIM_YANK 0x04
/* various states for vi-mode commands that use motion commands. reflects
RL_READLINE_STATE */
#define VMSTATE_READ 0x01
#define VMSTATE_NUMARG 0x02
typedef struct __rl_vimotion_context
{
int op;
int state;
int flags; /* reserved */
_rl_arg_cxt ncxt;
int numeric_arg;
int start, end; /* rl_point, rl_end */
int key, motion; /* initial key, motion command */
} _rl_vimotion_cxt;
/* fill in more as needed */
/* `Generic' callback data and functions */
typedef struct __rl_callback_generic_arg
{
int count;
int i1, i2;
/* add here as needed */
} _rl_callback_generic_arg;
typedef int _rl_callback_func_t (_rl_callback_generic_arg *);
typedef void _rl_sigcleanup_func_t (int, void *);
/*************************************************************************
* *
* Global functions undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/*************************************************************************
* *
* Global variables undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/* complete.c */
extern int rl_complete_with_tilde_expansion;
#if defined (VISIBLE_STATS)
extern int rl_visible_stats;
#endif /* VISIBLE_STATS */
#if defined (COLOR_SUPPORT)
extern int _rl_colored_stats;
extern int _rl_colored_completion_prefix;
#endif
/* readline.c */
extern int rl_line_buffer_len;
extern int rl_arg_sign;
extern int rl_visible_prompt_length;
extern int rl_byte_oriented;
/* display.c */
extern int rl_display_fixed;
/* parens.c */
extern int rl_blink_matching_paren;
/*************************************************************************
* *
* Global functions and variables unused and undocumented *
* *
*************************************************************************/
/* kill.c */
extern int rl_set_retained_kills (int);
/* terminal.c */
extern void _rl_set_screen_size (int, int);
/* undo.c */
extern int _rl_fix_last_undo_of_type (int, int, int);
/* util.c */
extern char *_rl_savestring (const char *);
/*************************************************************************
* *
* Functions and variables private to the readline library *
* *
*************************************************************************/
/* NOTE: Functions and variables prefixed with `_rl_' are
pseudo-global: they are global so they can be shared
between files in the readline library, but are not intended
to be visible to readline callers. */
/*************************************************************************
* Undocumented private functions *
*************************************************************************/
#if defined(READLINE_CALLBACKS)
/* readline.c */
extern void readline_internal_setup (void);
extern char *readline_internal_teardown (int);
extern int readline_internal_char (void);
extern _rl_keyseq_cxt *_rl_keyseq_cxt_alloc (void);
extern void _rl_keyseq_cxt_dispose (_rl_keyseq_cxt *);
extern void _rl_keyseq_chain_dispose (void);
extern int _rl_dispatch_callback (_rl_keyseq_cxt *);
/* callback.c */
extern _rl_callback_generic_arg *_rl_callback_data_alloc (int);
extern void _rl_callback_data_dispose (_rl_callback_generic_arg *);
#endif /* READLINE_CALLBACKS */
/* bind.c */
extern char *_rl_untranslate_macro_value (char *, int);
/* complete.c */
extern void _rl_reset_completion_state (void);
extern char _rl_find_completion_word (int *, int *);
extern void _rl_free_match_list (char **);
/* display.c */
extern char *_rl_strip_prompt (char *);
extern void _rl_reset_prompt (void);
extern void _rl_move_vert (int);
extern void _rl_save_prompt (void);
extern void _rl_restore_prompt (void);
extern char *_rl_make_prompt_for_search (int);
extern void _rl_erase_at_end_of_line (int);
extern void _rl_clear_to_eol (int);
extern void _rl_clear_screen (int);
extern void _rl_update_final (void);
extern void _rl_optimize_redisplay (void);
extern void _rl_redisplay_after_sigwinch (void);
extern void _rl_clean_up_for_exit (void);
extern void _rl_erase_entire_line (void);
extern int _rl_current_display_line (void);
extern void _rl_refresh_line (void);
/* input.c */
extern int _rl_any_typein (void);
extern int _rl_input_available (void);
extern int _rl_nchars_available (void);
extern int _rl_input_queued (int);
extern void _rl_insert_typein (int);
extern int _rl_unget_char (int);
extern int _rl_pushed_input_available (void);
extern int _rl_timeout_init (void);
extern int _rl_timeout_handle_sigalrm (void);
#if defined (_POSIXSELECT_H_)
/* use as a sentinel for fd_set, struct timeval, and sigset_t definitions */
extern int _rl_timeout_select (int, fd_set *, fd_set *, fd_set *, const struct timeval *, const sigset_t *);
#endif
/* isearch.c */
extern _rl_search_cxt *_rl_scxt_alloc (int, int);
extern void _rl_scxt_dispose (_rl_search_cxt *, int);
extern int _rl_isearch_dispatch (_rl_search_cxt *, int);
extern int _rl_isearch_callback (_rl_search_cxt *);
extern int _rl_isearch_cleanup (_rl_search_cxt *, int);
extern int _rl_search_getchar (_rl_search_cxt *);
/* kill.c */
#ifndef BRACKETED_PASTE_DEFAULT
# define BRACKETED_PASTE_DEFAULT 1 /* XXX - for now */
#endif
#define BRACK_PASTE_PREF "\033[200~"
#define BRACK_PASTE_SUFF "\033[201~"
#define BRACK_PASTE_LAST '~'
#define BRACK_PASTE_SLEN 6
#define BRACK_PASTE_INIT "\033[?2004h"
#define BRACK_PASTE_FINI "\033[?2004l\r"
extern int _rl_read_bracketed_paste_prefix (int);
extern char *_rl_bracketed_text (size_t *);
extern int _rl_bracketed_read_key (void);
extern int _rl_bracketed_read_mbstring (char *, int);
/* macro.c */
extern void _rl_with_macro_input (char *);
extern int _rl_peek_macro_key (void);
extern int _rl_next_macro_key (void);
extern int _rl_prev_macro_key (void);
extern void _rl_push_executing_macro (void);
extern void _rl_pop_executing_macro (void);
extern void _rl_add_macro_char (int);
extern void _rl_kill_kbd_macro (void);
/* misc.c */
extern int _rl_arg_overflow (void);
extern void _rl_arg_init (void);
extern int _rl_arg_getchar (void);
extern int _rl_arg_callback (_rl_arg_cxt);
extern void _rl_reset_argument (void);
extern void _rl_start_using_history (void);
extern int _rl_free_saved_history_line (void);
extern void _rl_set_insert_mode (int, int);
extern void _rl_revert_previous_lines (void);
extern void _rl_revert_all_lines (void);
/* nls.c */
extern char *_rl_init_locale (void);
extern int _rl_init_eightbit (void);
extern void _rl_reset_locale (void);
/* parens.c */
extern void _rl_enable_paren_matching (int);
/* readline.c */
extern void _rl_init_line_state (void);
extern void _rl_set_the_line (void);
extern int _rl_dispatch (int, Keymap);
extern int _rl_dispatch_subseq (int, Keymap, int);
extern void _rl_internal_char_cleanup (void);
extern void _rl_init_executing_keyseq (void);
extern void _rl_term_executing_keyseq (void);
extern void _rl_end_executing_keyseq (void);
extern void _rl_add_executing_keyseq (int);
extern void _rl_del_executing_keyseq (void);
extern rl_command_func_t *_rl_executing_func;
/* rltty.c */
extern int _rl_disable_tty_signals (void);
extern int _rl_restore_tty_signals (void);
/* search.c */
extern int _rl_nsearch_callback (_rl_search_cxt *);
extern int _rl_nsearch_cleanup (_rl_search_cxt *, int);
/* signals.c */
extern void _rl_signal_handler (int);
extern void _rl_block_sigint (void);
extern void _rl_release_sigint (void);
extern void _rl_block_sigwinch (void);
extern void _rl_release_sigwinch (void);
/* terminal.c */
extern void _rl_get_screen_size (int, int);
extern void _rl_sigwinch_resize_terminal (void);
extern int _rl_init_terminal_io (const char *);
#ifdef _MINIX
extern void _rl_output_character_function (int);
#else
extern int _rl_output_character_function (int);
#endif
extern void _rl_cr (void);
extern void _rl_output_some_chars (const char *, int);
extern int _rl_backspace (int);
extern void _rl_enable_meta_key (void);
extern void _rl_disable_meta_key (void);
extern void _rl_control_keypad (int);
extern void _rl_set_cursor (int, int);
extern void _rl_standout_on (void);
extern void _rl_standout_off (void);
extern int _rl_reset_region_color (int, const char *);
extern void _rl_region_color_on (void);
extern void _rl_region_color_off (void);
/* text.c */
extern void _rl_fix_point (int);
extern void _rl_fix_mark (void);
extern int _rl_replace_text (const char *, int, int);
extern int _rl_forward_char_internal (int);
extern int _rl_backward_char_internal (int);
extern int _rl_insert_char (int, int);
extern int _rl_overwrite_char (int, int);
extern int _rl_overwrite_rubout (int, int);
extern int _rl_rubout_char (int, int);
#if defined (HANDLE_MULTIBYTE)
extern int _rl_char_search_internal (int, int, char *, int);
#else
extern int _rl_char_search_internal (int, int, int);
#endif
extern int _rl_set_mark_at_pos (int);
/* undo.c */
extern UNDO_LIST *_rl_copy_undo_entry (UNDO_LIST *);
extern UNDO_LIST *_rl_copy_undo_list (UNDO_LIST *);
extern void _rl_free_undo_list (UNDO_LIST *);
/* util.c */
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern void _rl_ttymsg (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
extern void _rl_errmsg (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
extern void _rl_trace (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
extern void _rl_ttymsg ();
extern void _rl_errmsg ();
extern void _rl_trace ();
#endif
extern void _rl_audit_tty (char *);
extern int _rl_tropen (void);
extern int _rl_abort_internal (void);
extern int _rl_null_function (int, int);
extern char *_rl_strindex (const char *, const char *);
extern int _rl_qsort_string_compare (char **, char **);
extern int (_rl_uppercase_p) (int);
extern int (_rl_lowercase_p) (int);
extern int (_rl_pure_alphabetic) (int);
extern int (_rl_digit_p) (int);
extern int (_rl_to_lower) (int);
extern int (_rl_to_upper) (int);
extern int (_rl_digit_value) (int);
/* vi_mode.c */
extern void _rl_vi_initialize_line (void);
extern void _rl_vi_reset_last (void);
extern void _rl_vi_set_last (int, int, int);
extern int _rl_vi_textmod_command (int);
extern int _rl_vi_motion_command (int);
extern void _rl_vi_done_inserting (void);
extern int _rl_vi_domove_callback (_rl_vimotion_cxt *);
extern int _rl_vi_domove_motion_cleanup (int, _rl_vimotion_cxt *);
/* Use HS_HISTORY_VERSION as the sentinel to see if we've included history.h
and so can use HIST_ENTRY */
#if defined (HS_HISTORY_VERSION)
extern void _rl_free_history_entry (HIST_ENTRY *);
#endif
/*************************************************************************
* Undocumented private variables *
*************************************************************************/
/* bind.c */
extern const char * const _rl_possible_control_prefixes[];
extern const char * const _rl_possible_meta_prefixes[];
/* callback.c */
extern _rl_callback_func_t *_rl_callback_func;
extern _rl_callback_generic_arg *_rl_callback_data;
/* complete.c */
extern int _rl_complete_show_all;
extern int _rl_complete_show_unmodified;
extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs;
extern int _rl_completion_prefix_display_length;
extern int _rl_completion_columns;
extern int _rl_print_completions_horizontally;
extern int _rl_completion_case_fold;
extern int _rl_completion_case_map;
extern int _rl_match_hidden_files;
extern int _rl_page_completions;
extern int _rl_skip_completed_text;
extern int _rl_menu_complete_prefix_first;
/* display.c */
extern int _rl_vis_botlin;
extern int _rl_last_c_pos;
extern int _rl_suppress_redisplay;
extern int _rl_want_redisplay;
extern char *_rl_emacs_mode_str;
extern int _rl_emacs_modestr_len;
extern char *_rl_vi_ins_mode_str;
extern int _rl_vi_ins_modestr_len;
extern char *_rl_vi_cmd_mode_str;
extern int _rl_vi_cmd_modestr_len;
/* isearch.c */
extern char *_rl_isearch_terminators;
extern _rl_search_cxt *_rl_iscxt;
/* macro.c */
extern char *_rl_executing_macro;
/* misc.c */
extern int _rl_history_preserve_point;
extern int _rl_history_saved_point;
extern _rl_arg_cxt _rl_argcxt;
/* nls.c */
extern int _rl_utf8locale;
/* readline.c */
extern int _rl_echoing_p;
extern int _rl_horizontal_scroll_mode;
extern int _rl_mark_modified_lines;
extern int _rl_bell_preference;
extern int _rl_meta_flag;
extern int _rl_convert_meta_chars_to_ascii;
extern int _rl_output_meta_chars;
extern int _rl_bind_stty_chars;
extern int _rl_revert_all_at_newline;
extern int _rl_echo_control_chars;
extern int _rl_show_mode_in_prompt;
extern int _rl_enable_bracketed_paste;
extern int _rl_enable_active_region;
extern char *_rl_active_region_start_color;
extern char *_rl_active_region_end_color;
extern char *_rl_comment_begin;
extern unsigned char _rl_parsing_conditionalized_out;
extern Keymap _rl_keymap;
extern FILE *_rl_in_stream;
extern FILE *_rl_out_stream;
extern int _rl_last_command_was_kill;
extern int _rl_eof_char;
extern procenv_t _rl_top_level;
extern _rl_keyseq_cxt *_rl_kscxt;
extern int _rl_keyseq_timeout;
extern int _rl_executing_keyseq_size;
extern rl_hook_func_t *_rl_internal_startup_hook;
/* search.c */
extern _rl_search_cxt *_rl_nscxt;
extern int _rl_history_search_pos;
/* signals.c */
extern int volatile _rl_caught_signal;
extern _rl_sigcleanup_func_t *_rl_sigcleanup;
extern void *_rl_sigcleanarg;
extern int _rl_echoctl;
extern int _rl_intr_char;
extern int _rl_quit_char;
extern int _rl_susp_char;
/* terminal.c */
extern int _rl_enable_keypad;
extern int _rl_enable_meta;
extern char *_rl_term_clreol;
extern char *_rl_term_clrpag;
extern char *_rl_term_clrscroll;
extern char *_rl_term_im;
extern char *_rl_term_ic;
extern char *_rl_term_ei;
extern char *_rl_term_DC;
extern char *_rl_term_up;
extern char *_rl_term_dc;
extern char *_rl_term_cr;
extern char *_rl_term_IC;
extern char *_rl_term_forward_char;
extern int _rl_screenheight;
extern int _rl_screenwidth;
extern int _rl_screenchars;
extern int _rl_terminal_can_insert;
extern int _rl_term_autowrap;
/* text.c */
extern int _rl_optimize_typeahead;
extern int _rl_keep_mark_active;
/* undo.c */
extern int _rl_doing_an_undo;
extern int _rl_undo_group_level;
/* vi_mode.c */
extern int _rl_vi_last_command;
extern int _rl_vi_redoing;
extern _rl_vimotion_cxt *_rl_vimvcxt;
/* Use HS_HISTORY_VERSION as the sentinel to see if we've included history.h
and so can use HIST_ENTRY */
#if defined (HS_HISTORY_VERSION)
extern HIST_ENTRY *_rl_saved_line_for_history;
#endif
#endif /* _RL_PRIVATE_H_ */

33
third_party/readline/rlshell.h vendored Normal file
View file

@ -0,0 +1,33 @@
/* rlshell.h -- utility functions normally provided by bash. */
/* Copyright (C) 1999-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/>.
*/
#if !defined (_RL_SHELL_H_)
#define _RL_SHELL_H_
#include "rlstdc.h"
extern char *sh_single_quote (char *);
extern void sh_set_lines_and_columns (int, int);
extern char *sh_get_env_value (const char *);
extern char *sh_get_home_dir (void);
extern int sh_unset_nodelay_mode (int);
#endif /* _RL_SHELL_H_ */

57
third_party/readline/rlstdc.h vendored Normal file
View file

@ -0,0 +1,57 @@
/* stdc.h -- macros to make source compile on both ANSI C and K&R C compilers. */
/* Copyright (C) 1993-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 (_RL_STDC_H_)
#define _RL_STDC_H_
/* Adapted from BSD /usr/include/sys/cdefs.h. */
/* A function can be defined using prototypes and compile on both ANSI C
and traditional C compilers with something like this:
extern char *func PARAMS((char *, char *, int)); */
#if !defined (PARAMS)
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
# define PARAMS(protos) protos
# else
# define PARAMS(protos) ()
# endif
#endif
#ifndef __attribute__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
# define __attribute__(x)
# endif
#endif
/* Moved from config.h.in because readline.h:rl_message depends on these
defines. */
#if defined (__STDC__) && defined (HAVE_STDARG_H)
# define PREFER_STDARG
# define USE_VARARGS
#else
# if defined (HAVE_VARARGS_H)
# define PREFER_VARARGS
# define USE_VARARGS
# endif
#endif
#endif /* !_RL_STDC_H_ */

995
third_party/readline/rltty.c vendored Normal file
View file

@ -0,0 +1,995 @@
/* rltty.c -- functions to prepare and restore the terminal for readline's
use. */
/* Copyright (C) 1992-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 <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include "rldefs.h"
#include "rltty.h"
#if defined (HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h> /* include for declaration of ioctl */
#endif
#include "readline.h"
#include "rlprivate.h"
#if !defined (errno)
extern int errno;
#endif /* !errno */
rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
static void set_winsize (int);
/* **************************************************************** */
/* */
/* Saving and Restoring the TTY */
/* */
/* **************************************************************** */
/* Non-zero means that the terminal is in a prepped state. There are several
flags that are OR'd in to denote whether or not we have sent various
init strings to the terminal. */
#define TPX_PREPPED 0x01
#define TPX_BRACKPASTE 0x02
#define TPX_METAKEY 0x04
static int terminal_prepped;
static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
and output is suspended. */
#if defined (__ksr1__)
static int ksrflow;
#endif
/* Dummy call to force a backgrounded readline to stop before it tries
to get the tty settings. */
static void
set_winsize (tty)
int tty;
{
#if defined (TIOCGWINSZ)
struct winsize w;
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
(void) ioctl (tty, TIOCSWINSZ, &w);
#endif /* TIOCGWINSZ */
}
#if defined (NO_TTY_DRIVER)
/* Nothing */
#elif defined (NEW_TTY_DRIVER)
/* Values for the `flags' field of a struct bsdtty. This tells which
elements of the struct bsdtty have been fetched from the system and
are valid. */
#define SGTTY_SET 0x01
#define LFLAG_SET 0x02
#define TCHARS_SET 0x04
#define LTCHARS_SET 0x08
struct bsdtty {
struct sgttyb sgttyb; /* Basic BSD tty driver information. */
int lflag; /* Local mode flags, like LPASS8. */
#if defined (TIOCGETC)
struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
#endif
#if defined (TIOCGLTC)
struct ltchars ltchars; /* 4.2 BSD editing characters */
#endif
int flags; /* Bitmap saying which parts of the struct are valid. */
};
#define TIOTYPE struct bsdtty
static TIOTYPE otio;
static void save_tty_chars (TIOTYPE *);
static int _get_tty_settings (int, TIOTYPE *);
static int get_tty_settings (int, TIOTYPE *);
static int _set_tty_settings (int, TIOTYPE *);
static int set_tty_settings (int, TIOTYPE *);
static void prepare_terminal_settings (int, TIOTYPE, TIOTYPE *);
static void set_special_char (Keymap, TIOTYPE *, int, rl_command_func_t *);
static void
save_tty_chars (TIOTYPE *tiop)
{
_rl_last_tty_chars = _rl_tty_chars;
if (tiop->flags & SGTTY_SET)
{
_rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
_rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
}
if (tiop->flags & TCHARS_SET)
{
_rl_intr_char = _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
_rl_quit_char = _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
_rl_tty_chars.t_start = tiop->tchars.t_startc;
_rl_tty_chars.t_stop = tiop->tchars.t_stopc;
_rl_tty_chars.t_eof = tiop->tchars.t_eofc;
_rl_tty_chars.t_eol = '\n';
_rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
}
if (tiop->flags & LTCHARS_SET)
{
_rl_susp_char = _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
_rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
_rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
_rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
_rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
_rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
}
_rl_tty_chars.t_status = -1;
}
static int
get_tty_settings (int tty, TIOTYPE *tiop)
{
set_winsize (tty);
tiop->flags = tiop->lflag = 0;
errno = 0;
if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
return -1;
tiop->flags |= SGTTY_SET;
#if defined (TIOCLGET)
if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
tiop->flags |= LFLAG_SET;
#endif
#if defined (TIOCGETC)
if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
tiop->flags |= TCHARS_SET;
#endif
#if defined (TIOCGLTC)
if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
tiop->flags |= LTCHARS_SET;
#endif
return 0;
}
static int
set_tty_settings (int tty, TIOTYPE *tiop)
{
if (tiop->flags & SGTTY_SET)
{
ioctl (tty, TIOCSETN, &(tiop->sgttyb));
tiop->flags &= ~SGTTY_SET;
}
_rl_echoing_p = 1;
#if defined (TIOCLSET)
if (tiop->flags & LFLAG_SET)
{
ioctl (tty, TIOCLSET, &(tiop->lflag));
tiop->flags &= ~LFLAG_SET;
}
#endif
#if defined (TIOCSETC)
if (tiop->flags & TCHARS_SET)
{
ioctl (tty, TIOCSETC, &(tiop->tchars));
tiop->flags &= ~TCHARS_SET;
}
#endif
#if defined (TIOCSLTC)
if (tiop->flags & LTCHARS_SET)
{
ioctl (tty, TIOCSLTC, &(tiop->ltchars));
tiop->flags &= ~LTCHARS_SET;
}
#endif
return 0;
}
static void
prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop)
{
_rl_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
_rl_echoctl = (oldtio.sgttyb.sg_flags & ECHOCTL);
/* Copy the original settings to the structure we're going to use for
our settings. */
tiop->sgttyb = oldtio.sgttyb;
tiop->lflag = oldtio.lflag;
#if defined (TIOCGETC)
tiop->tchars = oldtio.tchars;
#endif
#if defined (TIOCGLTC)
tiop->ltchars = oldtio.ltchars;
#endif
tiop->flags = oldtio.flags;
/* First, the basic settings to put us into character-at-a-time, no-echo
input mode. */
tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
tiop->sgttyb.sg_flags |= CBREAK;
/* If this terminal doesn't care how the 8th bit is used, then we can
use it for the meta-key. If only one of even or odd parity is
specified, then the terminal is using parity, and we cannot. */
#if !defined (ANYP)
# define ANYP (EVENP | ODDP)
#endif
if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
((oldtio.sgttyb.sg_flags & ANYP) == 0))
{
tiop->sgttyb.sg_flags |= ANYP;
/* Hack on local mode flags if we can. */
#if defined (TIOCLGET)
# if defined (LPASS8)
tiop->lflag |= LPASS8;
# endif /* LPASS8 */
#endif /* TIOCLGET */
}
#if defined (TIOCGETC)
# if defined (USE_XON_XOFF)
/* Get rid of terminal output start and stop characters. */
tiop->tchars.t_stopc = -1; /* C-s */
tiop->tchars.t_startc = -1; /* C-q */
/* If there is an XON character, bind it to restart the output. */
if (oldtio.tchars.t_startc != -1)
rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
# endif /* USE_XON_XOFF */
/* If there is an EOF char, bind _rl_eof_char to it. */
if (oldtio.tchars.t_eofc != -1)
_rl_eof_char = oldtio.tchars.t_eofc;
# if defined (NO_KILL_INTR)
/* Get rid of terminal-generated SIGQUIT and SIGINT. */
tiop->tchars.t_quitc = -1; /* C-\ */
tiop->tchars.t_intrc = -1; /* C-c */
# endif /* NO_KILL_INTR */
#endif /* TIOCGETC */
#if defined (TIOCGLTC)
/* Make the interrupt keys go away. Just enough to make people happy. */
tiop->ltchars.t_dsuspc = -1; /* C-y */
tiop->ltchars.t_lnextc = -1; /* C-v */
#endif /* TIOCGLTC */
}
#else /* !defined (NEW_TTY_DRIVER) */
#if !defined (VMIN)
# define VMIN VEOF
#endif
#if !defined (VTIME)
# define VTIME VEOL
#endif
#if defined (TERMIOS_TTY_DRIVER)
# define TIOTYPE struct termios
# define DRAIN_OUTPUT(fd) tcdrain (fd)
# define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
# ifdef M_UNIX
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
# else
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
# endif /* !M_UNIX */
#else
# define TIOTYPE struct termio
# define DRAIN_OUTPUT(fd)
# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
#endif /* !TERMIOS_TTY_DRIVER */
static TIOTYPE otio;
static void save_tty_chars (TIOTYPE *);
static int _get_tty_settings (int, TIOTYPE *);
static int get_tty_settings (int, TIOTYPE *);
static int _set_tty_settings (int, TIOTYPE *);
static int set_tty_settings (int, TIOTYPE *);
static void prepare_terminal_settings (int, TIOTYPE, TIOTYPE *);
static void set_special_char (Keymap, TIOTYPE *, int, rl_command_func_t *);
static void _rl_bind_tty_special_chars (Keymap, TIOTYPE);
#if defined (FLUSHO)
# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
#else
# define OUTPUT_BEING_FLUSHED(tp) 0
#endif
static void
save_tty_chars (TIOTYPE *tiop)
{
_rl_last_tty_chars = _rl_tty_chars;
_rl_tty_chars.t_eof = tiop->c_cc[VEOF];
_rl_tty_chars.t_eol = tiop->c_cc[VEOL];
#ifdef VEOL2
_rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
#endif
_rl_tty_chars.t_erase = tiop->c_cc[VERASE];
#ifdef VWERASE
_rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
#endif
_rl_tty_chars.t_kill = tiop->c_cc[VKILL];
#ifdef VREPRINT
_rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
#endif
_rl_intr_char = _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
_rl_quit_char = _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
#ifdef VSUSP
_rl_susp_char = _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
#endif
#ifdef VDSUSP
_rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
#endif
#ifdef VSTART
_rl_tty_chars.t_start = tiop->c_cc[VSTART];
#endif
#ifdef VSTOP
_rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
#endif
#ifdef VLNEXT
_rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
#endif
#ifdef VDISCARD
_rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
#endif
#ifdef VSTATUS
_rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
#endif
}
#if defined (_AIX) || defined (_AIX41)
/* Currently this is only used on AIX */
static void
rltty_warning (char *msg)
{
_rl_errmsg ("warning: %s", msg);
}
#endif
#if defined (_AIX)
void
setopost (TIOTYPE *tp)
{
if ((tp->c_oflag & OPOST) == 0)
{
_rl_errmsg ("warning: turning on OPOST for terminal\r");
tp->c_oflag |= OPOST|ONLCR;
}
}
#endif
static int
_get_tty_settings (int tty, TIOTYPE *tiop)
{
int ioctl_ret;
while (1)
{
ioctl_ret = GETATTR (tty, tiop);
if (ioctl_ret < 0)
{
if (errno != EINTR)
return -1;
else
continue;
}
if (OUTPUT_BEING_FLUSHED (tiop))
{
#if defined (FLUSHO)
_rl_errmsg ("warning: turning off output flushing");
tiop->c_lflag &= ~FLUSHO;
break;
#else
continue;
#endif
}
break;
}
return 0;
}
static int
get_tty_settings (int tty, TIOTYPE *tiop)
{
set_winsize (tty);
errno = 0;
if (_get_tty_settings (tty, tiop) < 0)
return -1;
#if defined (_AIX)
setopost(tiop);
#endif
return 0;
}
static int
_set_tty_settings (int tty, TIOTYPE *tiop)
{
while (SETATTR (tty, tiop) < 0)
{
if (errno != EINTR)
return -1;
errno = 0;
}
return 0;
}
static int
set_tty_settings (int tty, TIOTYPE *tiop)
{
if (_set_tty_settings (tty, tiop) < 0)
return -1;
#if 0
#if defined (TERMIOS_TTY_DRIVER)
# if defined (__ksr1__)
if (ksrflow)
{
ksrflow = 0;
tcflow (tty, TCOON);
}
# else /* !ksr1 */
tcflow (tty, TCOON); /* Simulate a ^Q. */
# endif /* !ksr1 */
#else
ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
#endif /* !TERMIOS_TTY_DRIVER */
#endif /* 0 */
return 0;
}
static void
prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop)
{
int sc;
Keymap kmap;
_rl_echoing_p = (oldtio.c_lflag & ECHO);
#if defined (ECHOCTL)
_rl_echoctl = (oldtio.c_lflag & ECHOCTL);
#endif
tiop->c_lflag &= ~(ICANON | ECHO);
if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
_rl_eof_char = oldtio.c_cc[VEOF];
#if defined (USE_XON_XOFF)
#if defined (IXANY)
tiop->c_iflag &= ~(IXON | IXANY);
#else
/* `strict' Posix systems do not define IXANY. */
tiop->c_iflag &= ~IXON;
#endif /* IXANY */
#endif /* USE_XON_XOFF */
/* Only turn this off if we are using all 8 bits. */
if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
tiop->c_iflag &= ~(ISTRIP | INPCK);
/* Make sure we differentiate between CR and NL on input. */
tiop->c_iflag &= ~(ICRNL | INLCR);
#if !defined (HANDLE_SIGNALS)
tiop->c_lflag &= ~ISIG;
#else
tiop->c_lflag |= ISIG;
#endif
tiop->c_cc[VMIN] = 1;
tiop->c_cc[VTIME] = 0;
#if defined (FLUSHO)
if (OUTPUT_BEING_FLUSHED (tiop))
{
tiop->c_lflag &= ~FLUSHO;
oldtio.c_lflag &= ~FLUSHO;
}
#endif
/* Turn off characters that we need on Posix systems with job control,
just to be sure. This includes ^Y and ^V. This should not really
be necessary. */
#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
#if defined (VLNEXT)
tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
#endif
#if defined (VDSUSP)
tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif
/* Conditionally disable some other tty special characters if there is a
key binding for them in the current keymap. Readline ordinarily doesn't
bind these characters, but an application or user might. */
#if defined (VI_MODE)
kmap = (rl_editing_mode == vi_mode) ? vi_insertion_keymap : _rl_keymap;
#else
kmap = _rl_keymap;
#endif
#if defined (VDISCARD)
sc = tiop->c_cc[VDISCARD];
if (sc != _POSIX_VDISABLE && kmap[(unsigned char)sc].type == ISFUNC)
tiop->c_cc[VDISCARD] = _POSIX_VDISABLE;
#endif /* VDISCARD */
#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
}
#endif /* !NEW_TTY_DRIVER */
/* Put the terminal in CBREAK mode so that we can detect key presses. */
#if defined (NO_TTY_DRIVER)
void
rl_prep_terminal (int meta_flag)
{
_rl_echoing_p = 1;
}
void
rl_deprep_terminal (void)
{
}
#else /* ! NO_TTY_DRIVER */
void
rl_prep_terminal (int meta_flag)
{
int tty, nprep;
TIOTYPE tio;
if (terminal_prepped)
return;
/* Try to keep this function from being INTerrupted. */
_rl_block_sigint ();
tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
if (get_tty_settings (tty, &tio) < 0)
{
#if defined (ENOTSUP)
/* MacOS X and Linux, at least, lie about the value of errno if
tcgetattr fails. */
if (errno == ENOTTY || errno == EINVAL || errno == ENOTSUP)
#else
if (errno == ENOTTY || errno == EINVAL)
#endif
_rl_echoing_p = 1; /* XXX */
_rl_release_sigint ();
return;
}
otio = tio;
if (_rl_bind_stty_chars)
{
#if defined (VI_MODE)
/* If editing in vi mode, make sure we restore the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
rl_tty_unset_default_bindings (vi_insertion_keymap);
else
#endif
rl_tty_unset_default_bindings (_rl_keymap);
}
save_tty_chars (&otio);
RL_SETSTATE(RL_STATE_TTYCSAVED);
if (_rl_bind_stty_chars)
{
#if defined (VI_MODE)
/* If editing in vi mode, make sure we set the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
else
#endif
_rl_bind_tty_special_chars (_rl_keymap, tio);
}
prepare_terminal_settings (meta_flag, otio, &tio);
if (set_tty_settings (tty, &tio) < 0)
{
_rl_release_sigint ();
return;
}
if (_rl_enable_keypad)
_rl_control_keypad (1);
nprep = TPX_PREPPED;
if (_rl_enable_bracketed_paste)
{
fprintf (rl_outstream, BRACK_PASTE_INIT);
nprep |= TPX_BRACKPASTE;
}
fflush (rl_outstream);
terminal_prepped = nprep;
RL_SETSTATE(RL_STATE_TERMPREPPED);
_rl_release_sigint ();
}
/* Restore the terminal's normal settings and modes. */
void
rl_deprep_terminal (void)
{
int tty;
if (terminal_prepped == 0)
return;
/* Try to keep this function from being interrupted. */
_rl_block_sigint ();
tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
if (terminal_prepped & TPX_BRACKPASTE)
{
fprintf (rl_outstream, BRACK_PASTE_FINI);
/* Since the last character in BRACK_PASTE_FINI is \r */
_rl_last_c_pos = 0;
if (rl_eof_found && (RL_ISSTATE (RL_STATE_TIMEOUT) == 0))
fprintf (rl_outstream, "\n");
else if (_rl_echoing_p == 0)
fprintf (rl_outstream, "\n");
}
if (_rl_enable_keypad)
_rl_control_keypad (0);
fflush (rl_outstream);
if (set_tty_settings (tty, &otio) < 0)
{
_rl_release_sigint ();
return;
}
terminal_prepped = 0;
RL_UNSETSTATE(RL_STATE_TERMPREPPED);
_rl_release_sigint ();
}
#endif /* !NO_TTY_DRIVER */
/* Set readline's idea of whether or not it is echoing output to the terminal,
returning the old value. */
int
rl_tty_set_echoing (int u)
{
int o;
o = _rl_echoing_p;
_rl_echoing_p = u;
return o;
}
/* **************************************************************** */
/* */
/* Bogus Flow Control */
/* */
/* **************************************************************** */
int
rl_restart_output (int count, int key)
{
#if defined (__MINGW32__)
return 0;
#else /* !__MING32__ */
int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
#if defined (apollo)
ioctl (&fildes, TIOCSTART, 0);
#else
ioctl (fildes, TIOCSTART, 0);
#endif /* apollo */
#else /* !TIOCSTART */
# if defined (TERMIOS_TTY_DRIVER)
# if defined (__ksr1__)
if (ksrflow)
{
ksrflow = 0;
tcflow (fildes, TCOON);
}
# else /* !ksr1 */
tcflow (fildes, TCOON); /* Simulate a ^Q. */
# endif /* !ksr1 */
# else /* !TERMIOS_TTY_DRIVER */
# if defined (TCXONC)
ioctl (fildes, TCXONC, TCOON);
# endif /* TCXONC */
# endif /* !TERMIOS_TTY_DRIVER */
#endif /* !TIOCSTART */
return 0;
#endif /* !__MINGW32__ */
}
int
rl_stop_output (int count, int key)
{
#if defined (__MINGW32__)
return 0;
#else
int fildes = fileno (rl_instream);
#if defined (TIOCSTOP)
# if defined (apollo)
ioctl (&fildes, TIOCSTOP, 0);
# else
ioctl (fildes, TIOCSTOP, 0);
# endif /* apollo */
#else /* !TIOCSTOP */
# if defined (TERMIOS_TTY_DRIVER)
# if defined (__ksr1__)
ksrflow = 1;
# endif /* ksr1 */
tcflow (fildes, TCOOFF);
# else
# if defined (TCXONC)
ioctl (fildes, TCXONC, TCOON);
# endif /* TCXONC */
# endif /* !TERMIOS_TTY_DRIVER */
#endif /* !TIOCSTOP */
return 0;
#endif /* !__MINGW32__ */
}
/* **************************************************************** */
/* */
/* Default Key Bindings */
/* */
/* **************************************************************** */
#if !defined (NO_TTY_DRIVER)
#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
#endif
#if defined (NO_TTY_DRIVER)
#define SET_SPECIAL(sc, func)
#define RESET_SPECIAL(c)
#elif defined (NEW_TTY_DRIVER)
static void
set_special_char (Keymap kmap, TIOTYPE *tiop, int sc, rl_command_func_t *func)
{
if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
kmap[(unsigned char)sc].function = func;
}
#define RESET_SPECIAL(c) \
if (c != -1 && kmap[(unsigned char)c].type == ISFUNC) \
kmap[(unsigned char)c].function = rl_insert;
static void
_rl_bind_tty_special_chars (Keymap kmap, TIOTYPE ttybuff)
{
if (ttybuff.flags & SGTTY_SET)
{
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
}
# if defined (TIOCGLTC)
if (ttybuff.flags & LTCHARS_SET)
{
SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
}
# endif /* TIOCGLTC */
}
#else /* !NEW_TTY_DRIVER */
static void
set_special_char (Keymap kmap, TIOTYPE *tiop, int sc, rl_command_func_t *func)
{
unsigned char uc;
uc = tiop->c_cc[sc];
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
kmap[uc].function = func;
}
/* used later */
#define RESET_SPECIAL(uc) \
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
kmap[uc].function = rl_insert;
static void
_rl_bind_tty_special_chars (Keymap kmap, TIOTYPE ttybuff)
{
SET_SPECIAL (VERASE, rl_rubout);
SET_SPECIAL (VKILL, rl_unix_line_discard);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VLNEXT, rl_quoted_insert);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
# if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
SET_SPECIAL (VWERASE, rl_vi_unix_word_rubout);
else
# endif
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#endif /* !NEW_TTY_DRIVER */
/* Set the system's default editing characters to their readline equivalents
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
void
rltty_set_default_bindings (Keymap kmap)
{
#if !defined (NO_TTY_DRIVER)
TIOTYPE ttybuff;
int tty;
tty = fileno (rl_instream);
if (get_tty_settings (tty, &ttybuff) == 0)
_rl_bind_tty_special_chars (kmap, ttybuff);
#endif
}
/* New public way to set the system default editing chars to their readline
equivalents. */
void
rl_tty_set_default_bindings (Keymap kmap)
{
rltty_set_default_bindings (kmap);
}
/* Rebind all of the tty special chars that readline worries about back
to self-insert. Call this before saving the current terminal special
chars with save_tty_chars(). This only works on POSIX termios or termio
systems. */
void
rl_tty_unset_default_bindings (Keymap kmap)
{
/* Don't bother before we've saved the tty special chars at least once. */
if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
return;
RESET_SPECIAL (_rl_tty_chars.t_erase);
RESET_SPECIAL (_rl_tty_chars.t_kill);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_lnext);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_werase);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#if defined (HANDLE_SIGNALS)
#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
int
_rl_disable_tty_signals (void)
{
return 0;
}
int
_rl_restore_tty_signals (void)
{
return 0;
}
#else
static TIOTYPE sigstty, nosigstty;
static int tty_sigs_disabled = 0;
int
_rl_disable_tty_signals (void)
{
if (tty_sigs_disabled)
return 0;
if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
return -1;
nosigstty = sigstty;
nosigstty.c_lflag &= ~ISIG;
nosigstty.c_iflag &= ~IXON;
if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
return (_set_tty_settings (fileno (rl_instream), &sigstty));
tty_sigs_disabled = 1;
return 0;
}
int
_rl_restore_tty_signals (void)
{
int r;
if (tty_sigs_disabled == 0)
return 0;
r = _set_tty_settings (fileno (rl_instream), &sigstty);
if (r == 0)
tty_sigs_disabled = 0;
return r;
}
#endif /* !NEW_TTY_DRIVER */
#endif /* HANDLE_SIGNALS */

80
third_party/readline/rltty.h vendored Normal file
View file

@ -0,0 +1,80 @@
/* rltty.h - tty driver-related definitions used by some library files. */
/* Copyright (C) 1995-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 (_RLTTY_H_)
#define _RLTTY_H_
/* Posix systems use termios and the Posix signal functions. */
#if defined (TERMIOS_TTY_DRIVER)
# include <termios.h>
#endif /* TERMIOS_TTY_DRIVER */
/* System V machines use termio. */
#if defined (TERMIO_TTY_DRIVER)
# include <termio.h>
# if !defined (TCOON)
# define TCOON 1
# endif
#endif /* TERMIO_TTY_DRIVER */
/* Other (BSD) machines use sgtty. */
#if defined (NEW_TTY_DRIVER)
# include <sgtty.h>
#endif
#include "rlwinsize.h"
/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
it is not already defined. It is used both to determine if a
special character is disabled and to disable certain special
characters. Posix systems should set to 0, USG systems to -1. */
#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
# if defined (_SVR4_VDISABLE)
# define _POSIX_VDISABLE _SVR4_VDISABLE
# else
# if defined (_POSIX_VERSION)
# define _POSIX_VDISABLE 0
# else /* !_POSIX_VERSION */
# define _POSIX_VDISABLE -1
# endif /* !_POSIX_VERSION */
# endif /* !_SVR4_DISABLE */
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
typedef struct _rl_tty_chars {
unsigned char t_eof;
unsigned char t_eol;
unsigned char t_eol2;
unsigned char t_erase;
unsigned char t_werase;
unsigned char t_kill;
unsigned char t_reprint;
unsigned char t_intr;
unsigned char t_quit;
unsigned char t_susp;
unsigned char t_dsusp;
unsigned char t_start;
unsigned char t_stop;
unsigned char t_lnext;
unsigned char t_flush;
unsigned char t_status;
} _RL_TTY_CHARS;
#endif /* _RLTTY_H_ */

100
third_party/readline/rltypedefs.h vendored Normal file
View file

@ -0,0 +1,100 @@
/* rltypedefs.h -- Type declarations for readline 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/>.
*/
#ifndef _RL_TYPEDEFS_H_
#define _RL_TYPEDEFS_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Old-style, attempt to mark as deprecated in some way people will notice. */
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
#if defined(__GNUC__) || defined(__clang__)
typedef int Function () __attribute__((deprecated));
typedef void VFunction () __attribute__((deprecated));
typedef char *CPFunction () __attribute__((deprecated));
typedef char **CPPFunction () __attribute__((deprecated));
#else
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();
typedef char **CPPFunction ();
#endif
#endif /* _FUNCTION_DEF */
/* New style. */
#if !defined (_RL_FUNCTION_TYPEDEF)
# define _RL_FUNCTION_TYPEDEF
/* Bindable functions */
typedef int rl_command_func_t (int, int);
/* Typedefs for the completion system */
typedef char *rl_compentry_func_t (const char *, int);
typedef char **rl_completion_func_t (const char *, int, int);
typedef char *rl_quote_func_t (char *, int, char *);
typedef char *rl_dequote_func_t (char *, int);
typedef int rl_compignore_func_t (char **);
typedef void rl_compdisp_func_t (char **, int, int);
/* Type for input and pre-read hook functions like rl_event_hook */
typedef int rl_hook_func_t (void);
/* Input function type */
typedef int rl_getc_func_t (FILE *);
/* Generic function that takes a character buffer (which could be the readline
line buffer) and an index into it (which could be rl_point) and returns
an int. */
typedef int rl_linebuf_func_t (char *, int);
/* `Generic' function pointer typedefs */
typedef int rl_intfunc_t (int);
#define rl_ivoidfunc_t rl_hook_func_t
typedef int rl_icpfunc_t (char *);
typedef int rl_icppfunc_t (char **);
typedef void rl_voidfunc_t (void);
typedef void rl_vintfunc_t (int);
typedef void rl_vcpfunc_t (char *);
typedef void rl_vcppfunc_t (char **);
typedef char *rl_cpvfunc_t (void);
typedef char *rl_cpifunc_t (int);
typedef char *rl_cpcpfunc_t (char *);
typedef char *rl_cpcppfunc_t (char **);
#endif /* _RL_FUNCTION_TYPEDEF */
#ifdef __cplusplus
}
#endif
#endif /* _RL_TYPEDEFS_H_ */

58
third_party/readline/rlwinsize.h vendored Normal file
View file

@ -0,0 +1,58 @@
/* rlwinsize.h -- an attempt to isolate some of the system-specific defines
for `struct winsize' and TIOCGWINSZ. */
/* Copyright (C) 1997-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 (_RLWINSIZE_H_)
#define _RLWINSIZE_H_
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */
#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
# include <termios.h>
#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
/* Not in either of the standard places, look around. */
#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
# if defined (HAVE_SYS_STREAM_H)
# include <sys/stream.h>
# endif /* HAVE_SYS_STREAM_H */
# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */
# include <sys/ptem.h>
# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */
# endif /* HAVE_SYS_PTEM_H */
# if defined (HAVE_SYS_PTE_H) /* ??? */
# include <sys/pte.h>
# endif /* HAVE_SYS_PTE_H */
#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
#if defined (M_UNIX) && !defined (_SCO_DS) && !defined (tcflow)
# define tcflow(fd, action) ioctl(fd, TCXONC, action)
#endif
#endif /* _RL_WINSIZE_H */

707
third_party/readline/search.c vendored Normal file
View file

@ -0,0 +1,707 @@
/* search.c - code for non-incremental searching in emacs and vi modes. */
/* Copyright (C) 1992-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 <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h"
#include "history.h"
#include "histlib.h"
#include "rlprivate.h"
#include "xmalloc.h"
#ifdef abs
# undef abs
#endif
#define abs(x) (((x) >= 0) ? (x) : -(x))
_rl_search_cxt *_rl_nscxt = 0;
static char *noninc_search_string = (char *) NULL;
static int noninc_history_pos;
static char *prev_line_found = (char *) NULL;
static int _rl_history_search_len;
/*static*/ int _rl_history_search_pos;
static int _rl_history_search_flags;
static char *history_search_string;
static int history_string_size;
static void make_history_line_current (HIST_ENTRY *);
static int noninc_search_from_pos (char *, int, int, int, int *);
static int noninc_dosearch (char *, int, int);
static int noninc_search (int, int);
static int rl_history_search_internal (int, int);
static void rl_history_search_reinit (int);
static _rl_search_cxt *_rl_nsearch_init (int, int);
static void _rl_nsearch_abort (_rl_search_cxt *);
static int _rl_nsearch_dispatch (_rl_search_cxt *, int);
/* Make the data from the history entry ENTRY be the contents of the
current line. This doesn't do anything with rl_point; the caller
must set it. */
static void
make_history_line_current (HIST_ENTRY *entry)
{
UNDO_LIST *xlist;
xlist = _rl_saved_line_for_history ? (UNDO_LIST *)_rl_saved_line_for_history->data : 0;
/* At this point, rl_undo_list points to a private search string list. */
if (rl_undo_list && rl_undo_list != (UNDO_LIST *)entry->data && rl_undo_list != xlist)
rl_free_undo_list ();
/* Now we create a new undo list with a single insert for this text.
WE DON'T CHANGE THE ORIGINAL HISTORY ENTRY UNDO LIST */
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
/* POSIX.2 says that the `U' command doesn't affect the copy of any
command lines to the edit line. We're going to implement that by
making the undo list start after the matching line is copied to the
current editing buffer. */
rl_free_undo_list ();
#endif
/* This will need to free the saved undo list associated with the original
(pre-search) line buffer.
XXX - look at _rl_free_saved_history_line and consider calling it if
rl_undo_list != xlist (or calling rl_free_undo list directly on
_rl_saved_line_for_history->data) */
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Search the history list for STRING starting at absolute history position
POS. If STRING begins with `^', the search must match STRING at the
beginning of a history line, otherwise a full substring match is performed
for STRING. DIR < 0 means to search backwards through the history list,
DIR >= 0 means to search forward. */
static int
noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp)
{
int ret, old, sflags;
char *s;
if (pos < 0)
return -1;
old = where_history ();
if (history_set_pos (pos) == 0)
return -1;
RL_SETSTATE(RL_STATE_SEARCH);
/* These functions return the match offset in the line; history_offset gives
the matching line in the history list */
if (flags & SF_PATTERN)
{
s = string;
sflags = 0; /* Non-anchored search */
if (*s == '^')
{
sflags |= ANCHORED_SEARCH;
s++;
}
ret = _hs_history_patsearch (s, dir, sflags);
}
else if (*string == '^')
ret = history_search_prefix (string + 1, dir);
else
ret = history_search (string, dir);
RL_UNSETSTATE(RL_STATE_SEARCH);
if (ncp)
*ncp = ret; /* caller will catch -1 to indicate no-op */
if (ret != -1)
ret = where_history ();
history_set_pos (old);
return (ret);
}
/* Search for a line in the history containing STRING. If DIR is < 0, the
search is backwards through previous entries, else through subsequent
entries. Returns 1 if the search was successful, 0 otherwise. */
static int
noninc_dosearch (char *string, int dir, int flags)
{
int oldpos, pos, ind;
HIST_ENTRY *entry;
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
{
rl_ding ();
return 0;
}
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, &ind);
if (pos == -1)
{
/* Search failed, current history position unchanged. */
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = 0;
rl_ding ();
return 0;
}
noninc_history_pos = pos;
oldpos = where_history ();
history_set_pos (noninc_history_pos);
entry = current_history (); /* will never be NULL after successful search */
#if defined (VI_MODE)
if (rl_editing_mode != vi_mode)
#endif
history_set_pos (oldpos);
make_history_line_current (entry);
if (_rl_enable_active_region && ((flags & SF_PATTERN) == 0) && ind > 0 && ind < rl_end)
{
rl_point = ind;
rl_mark = ind + strlen (string);
if (rl_mark > rl_end)
rl_mark = rl_end; /* can't happen? */
rl_activate_mark ();
}
else
{
rl_point = 0;
rl_mark = rl_end;
}
rl_clear_message ();
return 1;
}
static _rl_search_cxt *
_rl_nsearch_init (int dir, int pchar)
{
_rl_search_cxt *cxt;
char *p;
cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
if (dir < 0)
cxt->sflags |= SF_REVERSE; /* not strictly needed */
#if defined (VI_MODE)
if (VI_COMMAND_MODE() && (pchar == '?' || pchar == '/'))
cxt->sflags |= SF_PATTERN;
#endif
cxt->direction = dir;
cxt->history_pos = cxt->save_line;
rl_maybe_save_line ();
/* Clear the undo list, since reading the search string should create its
own undo list, and the whole list will end up being freed when we
finish reading the search string. */
rl_undo_list = 0;
/* Use the line buffer to read the search string. */
rl_line_buffer[0] = 0;
rl_end = rl_point = 0;
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
rl_message ("%s", p);
xfree (p);
RL_SETSTATE(RL_STATE_NSEARCH);
_rl_nscxt = cxt;
return cxt;
}
int
_rl_nsearch_cleanup (_rl_search_cxt *cxt, int r)
{
_rl_scxt_dispose (cxt, 0);
_rl_nscxt = 0;
RL_UNSETSTATE(RL_STATE_NSEARCH);
return (r != 1);
}
static void
_rl_nsearch_abort (_rl_search_cxt *cxt)
{
rl_maybe_unsave_line ();
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt ();
rl_clear_message ();
_rl_fix_point (1);
RL_UNSETSTATE (RL_STATE_NSEARCH);
}
/* Process just-read character C according to search context CXT. Return -1
if the caller should abort the search, 0 if we should break out of the
loop, and 1 if we should continue to read characters. */
static int
_rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
{
int n;
if (c < 0)
c = CTRL ('C');
switch (c)
{
case CTRL('W'):
rl_unix_word_rubout (1, c);
break;
case CTRL('U'):
rl_unix_line_discard (1, c);
break;
case RETURN:
case NEWLINE:
return 0;
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
_rl_nsearch_abort (cxt);
return -1;
}
_rl_rubout_char (1, c);
break;
case CTRL('C'):
case CTRL('G'):
rl_ding ();
_rl_nsearch_abort (cxt);
return -1;
case ESC:
/* XXX - experimental code to allow users to bracketed-paste into the
search string. Similar code is in isearch.c:_rl_isearch_dispatch().
The difference here is that the bracketed paste sometimes doesn't
paste everything, so checking for the prefix and the suffix in the
input queue doesn't work well. We just have to check to see if the
number of chars in the input queue is enough for the bracketed paste
prefix and hope for the best. */
if (_rl_enable_bracketed_paste && ((n = _rl_nchars_available ()) >= (BRACK_PASTE_SLEN-1)))
{
if (_rl_read_bracketed_paste_prefix (c) == 1)
rl_bracketed_paste_begin (1, c);
else
{
c = rl_read_key (); /* get the ESC that got pushed back */
_rl_insert_char (1, c);
}
}
else
_rl_insert_char (1, c);
break;
default:
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (cxt->mb);
else
#endif
_rl_insert_char (1, c);
break;
}
(*rl_redisplay_function) ();
rl_deactivate_mark ();
return 1;
}
/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return
-1 if the search should be aborted, any other value means to clean up
using _rl_nsearch_cleanup (). Returns 1 if the search was successful,
0 otherwise. */
static int
_rl_nsearch_dosearch (_rl_search_cxt *cxt)
{
rl_mark = cxt->save_mark;
/* If rl_point == 0, we want to re-use the previous search string and
start from the saved history position. If there's no previous search
string, punt. */
if (rl_point == 0)
{
if (noninc_search_string == 0)
{
rl_ding ();
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
return -1;
}
}
else
{
/* We want to start the search from the current history position. */
noninc_history_pos = cxt->save_line;
FREE (noninc_search_string);
noninc_search_string = savestring (rl_line_buffer);
/* If we don't want the subsequent undo list generated by the search
matching a history line to include the contents of the search string,
we need to clear rl_line_buffer here. For now, we just clear the
undo list generated by reading the search string. (If the search
fails, the old undo list will be restored by rl_maybe_unsave_line.) */
rl_free_undo_list ();
}
rl_restore_prompt ();
return (noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN));
}
/* Search non-interactively through the history list. DIR < 0 means to
search backwards through the history of previous commands; otherwise
the search is for commands subsequent to the current position in the
history list. PCHAR is the character to use for prompting when reading
the search string; if not specified (0), it defaults to `:'. */
static int
noninc_search (int dir, int pchar)
{
_rl_search_cxt *cxt;
int c, r;
cxt = _rl_nsearch_init (dir, pchar);
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
/* Read the search string. */
r = 0;
while (1)
{
c = _rl_search_getchar (cxt);
if (c < 0)
{
_rl_nsearch_abort (cxt);
return 1;
}
if (c == 0)
break;
r = _rl_nsearch_dispatch (cxt, c);
if (r < 0)
return 1;
else if (r == 0)
break;
}
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
/* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */
int
rl_noninc_forward_search (int count, int key)
{
return noninc_search (1, (key == '?') ? '?' : 0);
}
/* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */
int
rl_noninc_reverse_search (int count, int key)
{
return noninc_search (-1, (key == '/') ? '/' : 0);
}
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. If the vi-mode code
calls this, KEY will be `N'. */
int
rl_noninc_forward_search_again (int count, int key)
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (1);
}
#if defined (VI_MODE)
if (VI_COMMAND_MODE() && key == 'N')
r = noninc_dosearch (noninc_search_string, 1, SF_PATTERN);
else
#endif
r = noninc_dosearch (noninc_search_string, 1, 0);
return (r != 1);
}
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. If the vi-mode code
calls this, KEY will be `n'. */
int
rl_noninc_reverse_search_again (int count, int key)
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (1);
}
#if defined (VI_MODE)
if (VI_COMMAND_MODE() && key == 'n')
r = noninc_dosearch (noninc_search_string, -1, SF_PATTERN);
else
#endif
r = noninc_dosearch (noninc_search_string, -1, 0);
return (r != 1);
}
#if defined (READLINE_CALLBACKS)
int
_rl_nsearch_callback (_rl_search_cxt *cxt)
{
int c, r;
c = _rl_search_getchar (cxt);
if (c <= 0)
{
if (c < 0)
_rl_nsearch_abort (cxt);
return 1;
}
r = _rl_nsearch_dispatch (cxt, c);
if (r != 0)
return 1;
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
#endif
static int
rl_history_search_internal (int count, int dir)
{
HIST_ENTRY *temp;
int ret, oldpos, newcol;
int had_saved_line;
char *t;
had_saved_line = _rl_saved_line_for_history != 0;
rl_maybe_save_line ();
temp = (HIST_ENTRY *)NULL;
/* Search COUNT times through the history for a line matching
history_search_string. If history_search_string[0] == '^', the
line must match from the start; otherwise any substring can match.
When this loop finishes, TEMP, if non-null, is the history line to
copy into the line buffer. */
while (count)
{
RL_CHECK_SIGNALS ();
ret = noninc_search_from_pos (history_search_string, _rl_history_search_pos + dir, dir, 0, &newcol);
if (ret == -1)
break;
/* Get the history entry we found. */
_rl_history_search_pos = ret;
oldpos = where_history ();
history_set_pos (_rl_history_search_pos);
temp = current_history (); /* will never be NULL after successful search */
history_set_pos (oldpos);
/* Don't find multiple instances of the same line. */
if (prev_line_found && STREQ (prev_line_found, temp->line))
continue;
prev_line_found = temp->line;
count--;
}
/* If we didn't find anything at all, return. */
if (temp == 0)
{
/* XXX - check had_saved_line here? */
rl_maybe_unsave_line ();
rl_ding ();
/* If you don't want the saved history line (last match) to show up
in the line buffer after the search fails, change the #if 0 to
#if 1 */
#if 0
if (rl_point > _rl_history_search_len)
{
rl_point = rl_end = _rl_history_search_len;
rl_line_buffer[rl_end] = '\0';
rl_mark = 0;
}
#else
rl_point = _rl_history_search_len; /* rl_maybe_unsave_line changes it */
rl_mark = rl_end;
#endif
return 1;
}
/* Copy the line we found into the current line buffer. */
make_history_line_current (temp);
/* decide where to put rl_point -- need to change this for pattern search */
if (_rl_history_search_flags & ANCHORED_SEARCH)
rl_point = _rl_history_search_len; /* easy case */
else
{
#if 0
t = strstr (rl_line_buffer, history_search_string); /* XXX */
rl_point = t ? (int)(t - rl_line_buffer) + _rl_history_search_len : rl_end;
#else
rl_point = (newcol >= 0) ? newcol : rl_end;
#endif
}
rl_mark = rl_end;
return 0;
}
static void
rl_history_search_reinit (int flags)
{
int sind;
_rl_history_search_pos = where_history ();
_rl_history_search_len = rl_point;
_rl_history_search_flags = flags;
prev_line_found = (char *)NULL;
if (rl_point)
{
/* Allocate enough space for anchored and non-anchored searches */
if (_rl_history_search_len >= history_string_size - 2)
{
history_string_size = _rl_history_search_len + 2;
history_search_string = (char *)xrealloc (history_search_string, history_string_size);
}
sind = 0;
if (flags & ANCHORED_SEARCH)
history_search_string[sind++] = '^';
strncpy (history_search_string + sind, rl_line_buffer, rl_point);
history_search_string[rl_point + sind] = '\0';
}
_rl_free_saved_history_line (); /* XXX rl_undo_list? */
}
/* Search forward in the history for the string of characters
from the start of the line to rl_point. This is a non-incremental
search. The search is anchored to the beginning of the history line. */
int
rl_history_search_forward (int count, int ignore)
{
if (count == 0)
return (0);
if (rl_last_func != rl_history_search_forward &&
rl_last_func != rl_history_search_backward)
rl_history_search_reinit (ANCHORED_SEARCH);
if (_rl_history_search_len == 0)
return (rl_get_next_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
}
/* Search backward through the history for the string of characters
from the start of the line to rl_point. This is a non-incremental
search. */
int
rl_history_search_backward (int count, int ignore)
{
if (count == 0)
return (0);
if (rl_last_func != rl_history_search_forward &&
rl_last_func != rl_history_search_backward)
rl_history_search_reinit (ANCHORED_SEARCH);
if (_rl_history_search_len == 0)
return (rl_get_previous_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
}
/* Search forward in the history for the string of characters
from the start of the line to rl_point. This is a non-incremental
search. The search succeeds if the search string is present anywhere
in the history line. */
int
rl_history_substr_search_forward (int count, int ignore)
{
if (count == 0)
return (0);
if (rl_last_func != rl_history_substr_search_forward &&
rl_last_func != rl_history_substr_search_backward)
rl_history_search_reinit (NON_ANCHORED_SEARCH);
if (_rl_history_search_len == 0)
return (rl_get_next_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
}
/* Search backward through the history for the string of characters
from the start of the line to rl_point. This is a non-incremental
search. */
int
rl_history_substr_search_backward (int count, int ignore)
{
if (count == 0)
return (0);
if (rl_last_func != rl_history_substr_search_forward &&
rl_last_func != rl_history_substr_search_backward)
rl_history_search_reinit (NON_ANCHORED_SEARCH);
if (_rl_history_search_len == 0)
return (rl_get_previous_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
}

214
third_party/readline/shell.c vendored Normal file
View file

@ -0,0 +1,214 @@
/* shell.c -- readline utility functions that are normally provided by
bash when readline is linked as part of the shell. */
/* Copyright (C) 1997-2009,2017,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 <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (HAVE_LIMITS_H)
# include <limits.h>
#endif
#if defined (HAVE_FCNTL_H)
#include <fcntl.h>
#endif
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
#include <stdio.h>
#include "rlstdc.h"
#include "rlshell.h"
#include "rldefs.h"
#include "xmalloc.h"
#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid (uid_t);
#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */
#ifndef NULL
# define NULL 0
#endif
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
/* Nonzero if the integer type T is signed. */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
/* Bound on length of the string representing an integer value of type T.
Subtract one for the sign bit if T is signed;
302 / 1000 is log10 (2) rounded up;
add one for integer division truncation;
add one more for a minus sign if t is signed. */
#define INT_STRLEN_BOUND(t) \
((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
+ 1 + TYPE_SIGNED (t))
/* All of these functions are resolved from bash if we are linking readline
as part of bash. */
/* Does shell-like quoting using single quotes. */
char *
sh_single_quote (char *string)
{
register int c;
char *result, *r, *s;
result = (char *)xmalloc (3 + (4 * strlen (string)));
r = result;
*r++ = '\'';
for (s = string; s && (c = *s); s++)
{
*r++ = c;
if (c == '\'')
{
*r++ = '\\'; /* insert escaped single quote */
*r++ = '\'';
*r++ = '\''; /* start new quoted string */
}
}
*r++ = '\'';
*r = '\0';
return (result);
}
/* Set the environment variables LINES and COLUMNS to lines and cols,
respectively. */
static char setenv_buf[INT_STRLEN_BOUND (int) + 1];
static char putenv_buf1[INT_STRLEN_BOUND (int) + 6 + 1]; /* sizeof("LINES=") == 6 */
static char putenv_buf2[INT_STRLEN_BOUND (int) + 8 + 1]; /* sizeof("COLUMNS=") == 8 */
void
sh_set_lines_and_columns (int lines, int cols)
{
#if defined (HAVE_SETENV)
sprintf (setenv_buf, "%d", lines);
setenv ("LINES", setenv_buf, 1);
sprintf (setenv_buf, "%d", cols);
setenv ("COLUMNS", setenv_buf, 1);
#else /* !HAVE_SETENV */
# if defined (HAVE_PUTENV)
sprintf (putenv_buf1, "LINES=%d", lines);
putenv (putenv_buf1);
sprintf (putenv_buf2, "COLUMNS=%d", cols);
putenv (putenv_buf2);
# endif /* HAVE_PUTENV */
#endif /* !HAVE_SETENV */
}
char *
sh_get_env_value (const char *varname)
{
return ((char *)getenv (varname));
}
char *
sh_get_home_dir (void)
{
static char *home_dir = (char *)NULL;
struct passwd *entry;
if (home_dir)
return (home_dir);
home_dir = (char *)NULL;
#if defined (HAVE_GETPWUID)
# if defined (__TANDEM)
entry = getpwnam (getlogin ());
# else
entry = getpwuid (getuid ());
# endif
if (entry)
home_dir = savestring (entry->pw_dir);
#endif
#if defined (HAVE_GETPWENT)
endpwent (); /* some systems need this */
#endif
return (home_dir);
}
#if !defined (O_NDELAY)
# if defined (FNDELAY)
# define O_NDELAY FNDELAY
# endif
#endif
int
sh_unset_nodelay_mode (int fd)
{
#if defined (HAVE_FCNTL)
int flags, bflags;
if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
return -1;
bflags = 0;
#ifdef O_NONBLOCK
bflags |= O_NONBLOCK;
#endif
#ifdef O_NDELAY
bflags |= O_NDELAY;
#endif
if (flags & bflags)
{
flags &= ~bflags;
return (fcntl (fd, F_SETFL, flags));
}
#endif
return 0;
}

754
third_party/readline/signals.c vendored Normal file
View file

@ -0,0 +1,754 @@
/* signals.c -- signal handling support for readline. */
/* 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
#include <stdio.h> /* Just for NULL. Yuck. */
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#if defined (GWINSZ_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#if defined (HANDLE_SIGNALS)
#define SIGHANDLER_RETURN return
/* This typedef is equivalent to the one for Function; it allows us
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
typedef void SigHandler (int);
#if defined (HAVE_POSIX_SIGNALS)
typedef struct sigaction sighandler_cxt;
# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
#else
typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
static SigHandler *rl_set_sighandler (int, SigHandler *, sighandler_cxt *);
static void rl_maybe_set_sighandler (int, SigHandler *, sighandler_cxt *);
static void rl_maybe_restore_sighandler (int, sighandler_cxt *);
static void rl_signal_handler (int);
static void _rl_handle_signal (int);
/* Exported variables for use by applications. */
/* If non-zero, readline will install its own signal handlers for
SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
int rl_catch_signals = 1;
/* If non-zero, readline will install a signal handler for SIGWINCH. */
#ifdef SIGWINCH
int rl_catch_sigwinch = 1;
#else
int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
#endif
/* Private variables. */
int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
/* If non-zero, print characters corresponding to received signals as long as
the user has indicated his desire to do so (_rl_echo_control_chars). */
int _rl_echoctl = 0;
int _rl_intr_char = 0;
int _rl_quit_char = 0;
int _rl_susp_char = 0;
static int signals_set_flag;
static int sigwinch_set_flag;
#if defined (HAVE_POSIX_SIGNALS)
sigset_t _rl_orig_sigset;
#endif /* !HAVE_POSIX_SIGNALS */
/* **************************************************************** */
/* */
/* Signal Handling */
/* */
/* **************************************************************** */
static sighandler_cxt old_int, old_term, old_hup, old_alrm, old_quit;
#if defined (SIGTSTP)
static sighandler_cxt old_tstp, old_ttou, old_ttin;
#endif
#if defined (SIGWINCH)
static sighandler_cxt old_winch;
#endif
_rl_sigcleanup_func_t *_rl_sigcleanup;
void *_rl_sigcleanarg;
/* Readline signal handler functions. */
/* Called from RL_CHECK_SIGNALS() macro to run signal handling code. */
void
_rl_signal_handler (int sig)
{
_rl_caught_signal = 0; /* XXX */
#if defined (SIGWINCH)
if (sig == SIGWINCH)
{
RL_SETSTATE(RL_STATE_SIGHANDLER);
rl_resize_terminal ();
/* XXX - experimental for now */
/* Call a signal hook because though we called the original signal handler
in rl_sigwinch_handler below, we will not resend the signal to
ourselves. */
if (rl_signal_event_hook)
(*rl_signal_event_hook) ();
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
}
else
#endif
_rl_handle_signal (sig);
SIGHANDLER_RETURN;
}
static void
rl_signal_handler (int sig)
{
_rl_caught_signal = sig;
SIGHANDLER_RETURN;
}
/* This is called to handle a signal when it is safe to do so (out of the
signal handler execution path). Called by _rl_signal_handler for all the
signals readline catches except SIGWINCH. */
static void
_rl_handle_signal (int sig)
{
int block_sig;
#if defined (HAVE_POSIX_SIGNALS)
sigset_t set, oset;
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
long omask;
# else /* !HAVE_BSD_SIGNALS */
sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
RL_SETSTATE(RL_STATE_SIGHANDLER);
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
/* Since the signal will not be blocked while we are in the signal
handler, ignore it until rl_clear_signals resets the catcher. */
# if defined (SIGALRM)
if (sig == SIGINT || sig == SIGALRM)
# else
if (sig == SIGINT)
# endif
rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
/* If there's a sig cleanup function registered, call it and `deregister'
the cleanup function to avoid multiple calls */
if (_rl_sigcleanup)
{
(*_rl_sigcleanup) (sig, _rl_sigcleanarg);
_rl_sigcleanup = 0;
_rl_sigcleanarg = 0;
}
#if defined (HAVE_POSIX_SIGNALS)
/* Get the current set of blocked signals. If we want to block a signal for
the duration of the cleanup functions, make sure to add it to SET and
set block_sig = 1 (see the SIGHUP case below). */
block_sig = 0; /* sentinel to block signals with sigprocmask */
sigemptyset (&set);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
#endif
switch (sig)
{
case SIGINT:
/* We will end up blocking SIGTTOU while we are resetting the tty, so
watch out for this if it causes problems. We could prevent this by
setting block_sig to 1 without modifying SET. */
_rl_reset_completion_state ();
rl_free_line_state ();
#if defined (READLINE_CALLBACKS)
rl_callback_sigcleanup ();
#endif
/* FALLTHROUGH */
#if defined (SIGTSTP)
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
# if defined (HAVE_POSIX_SIGNALS)
/* Block SIGTTOU so we can restore the terminal settings to something
sane without stopping on SIGTTOU if we have been placed into the
background. Even trying to get the current terminal pgrp with
tcgetpgrp() will generate SIGTTOU, so we don't bother. We still do
this even if we've been stopped on SIGTTOU, since we handle signals
when we have returned from the signal handler and the signal is no
longer blocked. */
if (block_sig == 0)
{
sigaddset (&set, SIGTTOU);
block_sig = 1;
}
# endif
#endif /* SIGTSTP */
/* Any signals that should be blocked during cleanup should go here. */
#if defined (SIGHUP)
case SIGHUP:
# if defined (_AIX)
if (block_sig == 0)
{
sigaddset (&set, sig);
block_sig = 1;
}
# endif // _AIX
#endif
/* Signals that don't require blocking during cleanup should go here. */
case SIGTERM:
#if defined (SIGALRM)
case SIGALRM:
if (sig == SIGALRM)
_rl_timeout_handle_sigalrm ();
#endif
#if defined (SIGQUIT)
case SIGQUIT:
#endif
#if defined (HAVE_POSIX_SIGNALS)
if (block_sig)
sigprocmask (SIG_BLOCK, &set, &oset);
#endif
rl_echo_signal_char (sig);
rl_cleanup_after_signal ();
/* At this point, the application's signal handler, if any, is the
current handler. */
#if defined (HAVE_POSIX_SIGNALS)
/* Unblock any signal(s) blocked above */
if (block_sig)
sigprocmask (SIG_UNBLOCK, &oset, (sigset_t *)NULL);
#endif
/* We don't have to bother unblocking the signal because we are not
running in a signal handler context. */
#if defined (__EMX__)
signal (sig, SIG_ACK);
#endif
#if defined (HAVE_KILL)
kill (getpid (), sig);
#else
raise (sig); /* assume we have raise */
#endif
/* We don't need to modify the signal mask now that this is not run in
a signal handler context. */
rl_reset_after_signal ();
}
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN;
}
#if defined (SIGWINCH)
static void
rl_sigwinch_handler (int sig)
{
SigHandler *oh;
#if defined (MUST_REINSTALL_SIGHANDLERS)
sighandler_cxt dummy_winch;
/* We don't want to change old_winch -- it holds the state of SIGWINCH
disposition set by the calling application. We need this state
because we call the application's SIGWINCH handler after updating
our own idea of the screen size. */
rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
#endif
RL_SETSTATE(RL_STATE_SIGHANDLER);
_rl_caught_signal = sig;
/* If another sigwinch handler has been installed, call it. */
oh = (SigHandler *)old_winch.sa_handler;
if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
(*oh) (sig);
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN;
}
#endif /* SIGWINCH */
/* Functions to manage signal handling. */
#if !defined (HAVE_POSIX_SIGNALS)
static int
rl_sigaction (int sig, sighandler_cxt *nh, sighandler_cxt *oh)
{
oh->sa_handler = signal (sig, nh->sa_handler);
return 0;
}
#endif /* !HAVE_POSIX_SIGNALS */
/* Set up a readline-specific signal handler, saving the old signal
information in OHANDLER. Return the old signal handler, like
signal(). */
static SigHandler *
rl_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
{
sighandler_cxt old_handler;
#if defined (HAVE_POSIX_SIGNALS)
struct sigaction act;
act.sa_handler = handler;
# if defined (SIGWINCH)
act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
# else
act.sa_flags = 0;
# endif /* SIGWINCH */
sigemptyset (&act.sa_mask);
sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, &old_handler);
#else
old_handler.sa_handler = (SigHandler *)signal (sig, handler);
#endif /* !HAVE_POSIX_SIGNALS */
/* XXX -- assume we have memcpy */
/* If rl_set_signals is called twice in a row, don't set the old handler to
rl_signal_handler, because that would cause infinite recursion. */
if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
return (ohandler->sa_handler);
}
/* Set disposition of SIG to HANDLER, returning old state in OHANDLER. Don't
change disposition if OHANDLER indicates the signal was ignored. */
static void
rl_maybe_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler)
{
sighandler_cxt dummy;
SigHandler *oh;
sigemptyset (&dummy.sa_mask);
dummy.sa_flags = 0;
oh = rl_set_sighandler (sig, handler, ohandler);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (sig, ohandler, &dummy);
}
/* Set the disposition of SIG to HANDLER, if HANDLER->sa_handler indicates the
signal was not being ignored. MUST only be called for signals whose
disposition was changed using rl_maybe_set_sighandler or for which the
SIG_IGN check was performed inline (e.g., SIGALRM below). */
static void
rl_maybe_restore_sighandler (int sig, sighandler_cxt *handler)
{
sighandler_cxt dummy;
sigemptyset (&dummy.sa_mask);
dummy.sa_flags = 0;
if (handler->sa_handler != SIG_IGN)
rl_sigaction (sig, handler, &dummy);
}
int
rl_set_signals (void)
{
sighandler_cxt dummy;
SigHandler *oh;
#if defined (HAVE_POSIX_SIGNALS)
static int sigmask_set = 0;
static sigset_t bset, oset;
#endif
#if defined (HAVE_POSIX_SIGNALS)
if (rl_catch_signals && sigmask_set == 0)
{
sigemptyset (&bset);
sigaddset (&bset, SIGINT);
sigaddset (&bset, SIGTERM);
#if defined (SIGHUP)
sigaddset (&bset, SIGHUP);
#endif
#if defined (SIGQUIT)
sigaddset (&bset, SIGQUIT);
#endif
#if defined (SIGALRM)
sigaddset (&bset, SIGALRM);
#endif
#if defined (SIGTSTP)
sigaddset (&bset, SIGTSTP);
#endif
#if defined (SIGTTIN)
sigaddset (&bset, SIGTTIN);
#endif
#if defined (SIGTTOU)
sigaddset (&bset, SIGTTOU);
#endif
sigmask_set = 1;
}
#endif /* HAVE_POSIX_SIGNALS */
if (rl_catch_signals && signals_set_flag == 0)
{
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&_rl_orig_sigset);
sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset);
#endif
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#if defined (SIGHUP)
rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
#endif
#if defined (SIGQUIT)
rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
#endif
#if defined (SIGALRM)
oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
/* If the application using readline has already installed a signal
handler with SA_RESTART, SIGALRM will cause reads to be restarted
automatically, so readline should just get out of the way. Since
we tested for SIG_IGN above, we can just test for SIG_DFL here. */
if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif /* HAVE_POSIX_SIGNALS */
#endif /* SIGALRM */
#if defined (SIGTSTP)
rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
#endif /* SIGTSTP */
#if defined (SIGTTOU)
rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
#endif /* SIGTTOU */
#if defined (SIGTTIN)
rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
#endif /* SIGTTIN */
signals_set_flag = 1;
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &_rl_orig_sigset, (sigset_t *)NULL);
#endif
}
else if (rl_catch_signals == 0)
{
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&_rl_orig_sigset);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &_rl_orig_sigset);
#endif
}
#if defined (SIGWINCH)
if (rl_catch_sigwinch && sigwinch_set_flag == 0)
{
rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
sigwinch_set_flag = 1;
}
#endif /* SIGWINCH */
return 0;
}
int
rl_clear_signals (void)
{
sighandler_cxt dummy;
if (rl_catch_signals && signals_set_flag == 1)
{
/* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler,
we should in theory not have to restore a handler where
old_xxx.sa_handler == SIG_IGN. That's what rl_maybe_restore_sighandler
does. Fewer system calls should reduce readline's per-line
overhead */
rl_maybe_restore_sighandler (SIGINT, &old_int);
rl_maybe_restore_sighandler (SIGTERM, &old_term);
#if defined (SIGHUP)
rl_maybe_restore_sighandler (SIGHUP, &old_hup);
#endif
#if defined (SIGQUIT)
rl_maybe_restore_sighandler (SIGQUIT, &old_quit);
#endif
#if defined (SIGALRM)
rl_maybe_restore_sighandler (SIGALRM, &old_alrm);
#endif
#if defined (SIGTSTP)
rl_maybe_restore_sighandler (SIGTSTP, &old_tstp);
#endif /* SIGTSTP */
#if defined (SIGTTOU)
rl_maybe_restore_sighandler (SIGTTOU, &old_ttou);
#endif /* SIGTTOU */
#if defined (SIGTTIN)
rl_maybe_restore_sighandler (SIGTTIN, &old_ttin);
#endif /* SIGTTIN */
signals_set_flag = 0;
}
#if defined (SIGWINCH)
if (rl_catch_sigwinch && sigwinch_set_flag == 1)
{
sigemptyset (&dummy.sa_mask);
rl_sigaction (SIGWINCH, &old_winch, &dummy);
sigwinch_set_flag = 0;
}
#endif
return 0;
}
/* Clean up the terminal and readline state after catching a signal, before
resending it to the calling application. */
void
rl_cleanup_after_signal (void)
{
_rl_clean_up_for_exit ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
rl_clear_pending_input ();
rl_clear_signals ();
}
/* Reset the terminal and readline state after a signal handler returns. */
void
rl_reset_after_signal (void)
{
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
rl_set_signals ();
}
/* Free up the readline variable line state for the current line (undo list,
any partial history entry, any keyboard macros in progress, and any
numeric arguments in process) after catching a signal, before calling
rl_cleanup_after_signal(). */
void
rl_free_line_state (void)
{
register HIST_ENTRY *entry;
rl_free_undo_list ();
entry = current_history ();
if (entry)
entry->data = (char *)NULL;
_rl_kill_kbd_macro ();
rl_clear_message ();
_rl_reset_argument ();
}
int
rl_pending_signal (void)
{
return (_rl_caught_signal);
}
void
rl_check_signals (void)
{
RL_CHECK_SIGNALS ();
}
#endif /* HANDLE_SIGNALS */
/* **************************************************************** */
/* */
/* SIGINT Management */
/* */
/* **************************************************************** */
#if defined (HAVE_POSIX_SIGNALS)
static sigset_t sigint_set, sigint_oset;
static sigset_t sigwinch_set, sigwinch_oset;
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
static int sigint_oldmask;
static int sigwinch_oldmask;
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
static int sigint_blocked;
static int sigwinch_blocked;
/* Cause SIGINT to not be delivered until the corresponding call to
release_sigint(). */
void
_rl_block_sigint (void)
{
if (sigint_blocked)
return;
sigint_blocked = 1;
}
/* Allow SIGINT to be delivered. */
void
_rl_release_sigint (void)
{
if (sigint_blocked == 0)
return;
sigint_blocked = 0;
RL_CHECK_SIGNALS ();
}
/* Cause SIGWINCH to not be delivered until the corresponding call to
release_sigwinch(). */
void
_rl_block_sigwinch (void)
{
if (sigwinch_blocked)
return;
#if defined (SIGWINCH)
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&sigwinch_set);
sigemptyset (&sigwinch_oset);
sigaddset (&sigwinch_set, SIGWINCH);
sigprocmask (SIG_BLOCK, &sigwinch_set, &sigwinch_oset);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
sigwinch_oldmask = sigblock (sigmask (SIGWINCH));
# else /* !HAVE_BSD_SIGNALS */
# if defined (HAVE_USG_SIGHOLD)
sighold (SIGWINCH);
# endif /* HAVE_USG_SIGHOLD */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
#endif /* SIGWINCH */
sigwinch_blocked = 1;
}
/* Allow SIGWINCH to be delivered. */
void
_rl_release_sigwinch (void)
{
if (sigwinch_blocked == 0)
return;
#if defined (SIGWINCH)
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &sigwinch_oset, (sigset_t *)NULL);
#else
# if defined (HAVE_BSD_SIGNALS)
sigsetmask (sigwinch_oldmask);
# else /* !HAVE_BSD_SIGNALS */
# if defined (HAVE_USG_SIGHOLD)
sigrelse (SIGWINCH);
# endif /* HAVE_USG_SIGHOLD */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
#endif /* SIGWINCH */
sigwinch_blocked = 0;
}
/* **************************************************************** */
/* */
/* Echoing special control characters */
/* */
/* **************************************************************** */
void
rl_echo_signal_char (int sig)
{
char cstr[3];
int cslen, c;
if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
return;
switch (sig)
{
case SIGINT: c = _rl_intr_char; break;
#if defined (SIGQUIT)
case SIGQUIT: c = _rl_quit_char; break;
#endif
#if defined (SIGTSTP)
case SIGTSTP: c = _rl_susp_char; break;
#endif
default: return;
}
if (CTRL_CHAR (c) || c == RUBOUT)
{
cstr[0] = '^';
cstr[1] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
cstr[cslen = 2] = '\0';
}
else
{
cstr[0] = c;
cstr[cslen = 1] = '\0';
}
_rl_output_some_chars (cstr, cslen);
}

60
third_party/readline/tcap.h vendored Normal file
View file

@ -0,0 +1,60 @@
/* tcap.h -- termcap library functions and variables. */
/* Copyright (C) 1996-2015 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 (_RLTCAP_H_)
#define _RLTCAP_H_
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#if defined (HAVE_TERMCAP_H)
# if defined (__linux__) && !defined (SPEED_T_IN_SYS_TYPES)
# include "rltty.h"
# endif
# include <termcap.h>
#elif defined (HAVE_NCURSES_TERMCAP_H)
# include "third_party/ncurses/termcap.h"
#else
/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
Unfortunately, PC is a global variable used by the termcap library. */
#ifdef PC
# undef PC
#endif
extern char PC;
extern char *UP, *BC;
extern short ospeed;
extern int tgetent ();
extern int tgetflag ();
extern int tgetnum ();
extern char *tgetstr ();
extern int tputs ();
extern char *tgoto ();
#endif /* HAVE_TERMCAP_H */
#endif /* !_RLTCAP_H_ */

939
third_party/readline/terminal.c vendored Normal file
View file

@ -0,0 +1,939 @@
/* terminal.c -- controlling the terminal with termcap. */
/* Copyright (C) 1996-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 <sys/types.h>
#include "posixstat.h"
#include <fcntl.h>
#if defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_LOCALE_H)
# include <locale.h>
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#ifdef __MSDOS__
# include <pc.h>
#endif
#include "rltty.h"
#if defined (HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h> /* include for declaration of ioctl */
#endif
#include "tcap.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
#if defined (__MINGW32__)
# include <windows.h>
# include <wincon.h>
static void _win_get_screensize (int *, int *);
#endif
#if defined (__EMX__)
static void _emx_get_screensize (int *, int *);
#endif
/* If the calling application sets this to a non-zero value, readline will
use the $LINES and $COLUMNS environment variables to set its idea of the
window size before interrogating the kernel. */
int rl_prefer_env_winsize = 0;
/* If this is non-zero, readline will set LINES and COLUMNS in the
environment when it handles SIGWINCH. */
int rl_change_environment = 1;
/* **************************************************************** */
/* */
/* Terminal and Termcap */
/* */
/* **************************************************************** */
#ifndef __MSDOS__
static char *term_buffer = (char *)NULL;
static char *term_string_buffer = (char *)NULL;
#endif
static int tcap_initialized;
#if !defined (__linux__) && !defined (NCURSES_VERSION)
# if defined (__EMX__) || defined (NEED_EXTERN_PC)
extern
# endif /* __EMX__ || NEED_EXTERN_PC */
char PC, *BC, *UP;
#endif /* !__linux__ && !NCURSES_VERSION */
/* Some strings to control terminal actions. These are output by tputs (). */
char *_rl_term_clreol;
char *_rl_term_clrpag;
char *_rl_term_clrscroll;
char *_rl_term_cr;
char *_rl_term_backspace;
char *_rl_term_goto;
char *_rl_term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */
int _rl_terminal_can_insert = 0;
/* How to insert characters. */
char *_rl_term_im;
char *_rl_term_ei;
char *_rl_term_ic;
char *_rl_term_ip;
char *_rl_term_IC;
/* How to delete characters. */
char *_rl_term_dc;
char *_rl_term_DC;
/* How to move forward a char, non-destructively */
char *_rl_term_forward_char;
/* How to go up a line. */
char *_rl_term_up;
/* A visible bell; char if the terminal can be made to flash the screen. */
static char *_rl_visible_bell;
/* Non-zero means the terminal can auto-wrap lines. */
int _rl_term_autowrap = -1;
/* Non-zero means that this terminal has a meta key. */
static int term_has_meta;
/* The sequences to write to turn on and off the meta key, if this
terminal has one. */
static char *_rl_term_mm;
static char *_rl_term_mo;
/* The sequences to enter and exit standout mode. */
static char *_rl_term_so;
static char *_rl_term_se;
/* The key sequences output by the arrow keys, if this terminal has any. */
static char *_rl_term_ku;
static char *_rl_term_kd;
static char *_rl_term_kr;
static char *_rl_term_kl;
/* How to initialize and reset the arrow keys, if this terminal has any. */
static char *_rl_term_ks;
static char *_rl_term_ke;
/* The key sequences sent by the Home and End keys, if any. */
static char *_rl_term_kh;
static char *_rl_term_kH;
static char *_rl_term_at7; /* @7 */
/* Delete key */
static char *_rl_term_kD;
/* Insert key */
static char *_rl_term_kI;
/* Page up and page down keys */
static char *_rl_term_kP;
static char *_rl_term_kN;
/* Cursor control */
static char *_rl_term_vs; /* very visible */
static char *_rl_term_ve; /* normal */
/* User-settable color sequences to begin and end the active region. Defaults
are rl_term_so and rl_term_se on non-dumb terminals. */
char *_rl_active_region_start_color = NULL;
char *_rl_active_region_end_color = NULL;
/* It's not clear how HPUX is so broken here. */
#ifdef TGETENT_BROKEN
# define TGETENT_SUCCESS 0
#else
# define TGETENT_SUCCESS 1
#endif
#ifdef TGETFLAG_BROKEN
# define TGETFLAG_SUCCESS 0
#else
# define TGETFLAG_SUCCESS 1
#endif
#define TGETFLAG(cap) (tgetflag (cap) == TGETFLAG_SUCCESS)
static void bind_termcap_arrow_keys (Keymap);
/* Variables that hold the screen dimensions, used by the display code. */
int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
/* Non-zero means the user wants to enable the keypad. */
int _rl_enable_keypad;
/* Non-zero means the user wants to enable a meta key. */
int _rl_enable_meta = 1;
#if defined (__EMX__)
static void
_emx_get_screensize (int *swp, int *shp)
{
int sz[2];
_scrsize (sz);
if (swp)
*swp = sz[0];
if (shp)
*shp = sz[1];
}
#endif
#if defined (__MINGW32__)
static void
_win_get_screensize (int *swp, int *shp)
{
HANDLE hConOut;
CONSOLE_SCREEN_BUFFER_INFO scr;
hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
if (hConOut != INVALID_HANDLE_VALUE)
{
if (GetConsoleScreenBufferInfo (hConOut, &scr))
{
*swp = scr.dwSize.X;
*shp = scr.srWindow.Bottom - scr.srWindow.Top + 1;
}
}
}
#endif
/* Get readline's idea of the screen size. TTY is a file descriptor open
to the terminal. If IGNORE_ENV is true, we do not pay attention to the
values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
non-null serve to check whether or not we have initialized termcap. */
void
_rl_get_screen_size (int tty, int ignore_env)
{
char *ss;
#if defined (TIOCGWINSZ)
struct winsize window_size;
#endif /* TIOCGWINSZ */
int wr, wc;
wr = wc = -1;
#if defined (TIOCGWINSZ)
if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
{
wc = (int) window_size.ws_col;
wr = (int) window_size.ws_row;
}
#endif /* TIOCGWINSZ */
#if defined (__EMX__)
_emx_get_screensize (&wc, &wr);
#elif defined (__MINGW32__)
_win_get_screensize (&wc, &wr);
#endif
if (ignore_env || rl_prefer_env_winsize == 0)
{
_rl_screenwidth = wc;
_rl_screenheight = wr;
}
else
_rl_screenwidth = _rl_screenheight = -1;
/* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
is unset. If we prefer the environment, check it first before
assigning the value returned by the kernel. */
if (_rl_screenwidth <= 0)
{
if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
_rl_screenwidth = atoi (ss);
if (_rl_screenwidth <= 0)
_rl_screenwidth = wc;
#if defined (__DJGPP__)
if (_rl_screenwidth <= 0)
_rl_screenwidth = ScreenCols ();
#else
if (_rl_screenwidth <= 0 && term_string_buffer)
_rl_screenwidth = tgetnum ("co");
#endif
}
/* Environment variable LINES overrides setting of "li" if IGNORE_ENV
is unset. */
if (_rl_screenheight <= 0)
{
if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
_rl_screenheight = atoi (ss);
if (_rl_screenheight <= 0)
_rl_screenheight = wr;
#if defined (__DJGPP__)
if (_rl_screenheight <= 0)
_rl_screenheight = ScreenRows ();
#else
if (_rl_screenheight <= 0 && term_string_buffer)
_rl_screenheight = tgetnum ("li");
#endif
}
/* If all else fails, default to 80x24 terminal. */
if (_rl_screenwidth <= 1)
_rl_screenwidth = 80;
if (_rl_screenheight <= 0)
_rl_screenheight = 24;
/* If we're being compiled as part of bash, set the environment
variables $LINES and $COLUMNS to new values. Otherwise, just
do a pair of putenv () or setenv () calls. */
if (rl_change_environment)
sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
if (_rl_term_autowrap == 0)
_rl_screenwidth--;
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
}
void
_rl_set_screen_size (int rows, int cols)
{
if (_rl_term_autowrap == -1)
_rl_init_terminal_io (rl_terminal_name);
if (rows > 0)
_rl_screenheight = rows;
if (cols > 0)
{
_rl_screenwidth = cols;
if (_rl_term_autowrap == 0)
_rl_screenwidth--;
}
if (rows > 0 || cols > 0)
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
}
void
rl_set_screen_size (int rows, int cols)
{
_rl_set_screen_size (rows, cols);
}
void
rl_get_screen_size (int *rows, int *cols)
{
if (rows)
*rows = _rl_screenheight;
if (cols)
*cols = _rl_screenwidth;
}
void
rl_reset_screen_size (void)
{
_rl_get_screen_size (fileno (rl_instream), 0);
}
void
_rl_sigwinch_resize_terminal (void)
{
_rl_get_screen_size (fileno (rl_instream), 1);
}
void
rl_resize_terminal (void)
{
int width, height;
width = _rl_screenwidth;
height = _rl_screenheight;
_rl_get_screen_size (fileno (rl_instream), 1);
if (_rl_echoing_p && (width != _rl_screenwidth || height != _rl_screenheight))
{
if (CUSTOM_REDISPLAY_FUNC ())
rl_forced_update_display ();
else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0)
_rl_redisplay_after_sigwinch ();
}
}
struct _tc_string {
const char * const tc_var;
char **tc_value;
};
/* This should be kept sorted, just in case we decide to change the
search algorithm to something smarter. */
static const struct _tc_string tc_strings[] =
{
{ "@7", &_rl_term_at7 },
{ "DC", &_rl_term_DC },
{ "E3", &_rl_term_clrscroll },
{ "IC", &_rl_term_IC },
{ "ce", &_rl_term_clreol },
{ "cl", &_rl_term_clrpag },
{ "cr", &_rl_term_cr },
{ "dc", &_rl_term_dc },
{ "ei", &_rl_term_ei },
{ "ic", &_rl_term_ic },
{ "im", &_rl_term_im },
{ "kD", &_rl_term_kD }, /* delete */
{ "kH", &_rl_term_kH }, /* home down ?? */
{ "kI", &_rl_term_kI }, /* insert */
{ "kN", &_rl_term_kN }, /* page down */
{ "kP", &_rl_term_kP }, /* page up */
{ "kd", &_rl_term_kd },
{ "ke", &_rl_term_ke }, /* end keypad mode */
{ "kh", &_rl_term_kh }, /* home */
{ "kl", &_rl_term_kl },
{ "kr", &_rl_term_kr },
{ "ks", &_rl_term_ks }, /* start keypad mode */
{ "ku", &_rl_term_ku },
{ "le", &_rl_term_backspace },
{ "mm", &_rl_term_mm },
{ "mo", &_rl_term_mo },
{ "nd", &_rl_term_forward_char },
{ "pc", &_rl_term_pc },
{ "se", &_rl_term_se },
{ "so", &_rl_term_so },
{ "up", &_rl_term_up },
{ "vb", &_rl_visible_bell },
{ "vs", &_rl_term_vs },
{ "ve", &_rl_term_ve },
};
#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
/* Read the desired terminal capability strings into BP. The capabilities
are described in the TC_STRINGS table. */
static void
get_term_capabilities (char **bp)
{
#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
register int i;
for (i = 0; i < NUM_TC_STRINGS; i++)
*(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
#endif
tcap_initialized = 1;
}
int
_rl_init_terminal_io (const char *terminal_name)
{
const char *term;
char *buffer;
int tty, tgetent_ret, dumbterm, reset_region_colors;
term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
_rl_term_clrpag = _rl_term_cr = _rl_term_clreol = _rl_term_clrscroll = (char *)NULL;
tty = rl_instream ? fileno (rl_instream) : 0;
if (term == 0)
term = "dumb";
dumbterm = STREQ (term, "dumb");
reset_region_colors = 1;
#ifdef __MSDOS__
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
_rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
_rl_term_mm = _rl_term_mo = (char *)NULL;
_rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0;
_rl_term_cr = "\r";
_rl_term_backspace = (char *)NULL;
_rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL;
_rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL;
_rl_term_kN = _rl_term_kP = (char *)NULL;
_rl_term_so = _rl_term_se = (char *)NULL;
#if defined(HACK_TERMCAP_MOTION)
_rl_term_forward_char = (char *)NULL;
#endif
_rl_get_screen_size (tty, 0);
#else /* !__MSDOS__ */
/* I've separated this out for later work on not calling tgetent at all
if the calling application has supplied a custom redisplay function,
(and possibly if the application has supplied a custom input function). */
if (CUSTOM_REDISPLAY_FUNC())
{
tgetent_ret = -1;
}
else
{
if (term_string_buffer == 0)
term_string_buffer = (char *)xmalloc(2032);
if (term_buffer == 0)
term_buffer = (char *)xmalloc(4080);
buffer = term_string_buffer;
tgetent_ret = tgetent (term_buffer, term);
}
if (tgetent_ret != TGETENT_SUCCESS)
{
FREE (term_string_buffer);
FREE (term_buffer);
buffer = term_buffer = term_string_buffer = (char *)NULL;
_rl_term_autowrap = 0; /* used by _rl_get_screen_size */
/* Allow calling application to set default height and width, using
rl_set_screen_size */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
{
#if defined (__EMX__)
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
_rl_screenwidth--;
#else /* !__EMX__ */
_rl_get_screen_size (tty, 0);
#endif /* !__EMX__ */
}
/* Defaults. */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
{
_rl_screenwidth = 79;
_rl_screenheight = 24;
}
/* Everything below here is used by the redisplay code (tputs). */
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
_rl_term_cr = "\r";
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
_rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL;
_rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
_rl_term_kN = _rl_term_kP = (char *)NULL;
_rl_term_mm = _rl_term_mo = (char *)NULL;
_rl_term_ve = _rl_term_vs = (char *)NULL;
_rl_term_forward_char = (char *)NULL;
_rl_term_so = _rl_term_se = (char *)NULL;
_rl_terminal_can_insert = term_has_meta = 0;
/* Assume generic unknown terminal can't handle the enable/disable
escape sequences */
_rl_enable_bracketed_paste = 0;
/* No terminal so/se capabilities. */
_rl_enable_active_region = 0;
_rl_reset_region_color (0, NULL);
_rl_reset_region_color (1, NULL);
/* Reasonable defaults for tgoto(). Readline currently only uses
tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
change that later... */
PC = '\0';
BC = _rl_term_backspace = "\b";
UP = _rl_term_up;
return 0;
}
get_term_capabilities (&buffer);
/* Set up the variables that the termcap library expects the application
to provide. */
PC = _rl_term_pc ? *_rl_term_pc : 0;
BC = _rl_term_backspace;
UP = _rl_term_up;
if (_rl_term_cr == 0)
_rl_term_cr = "\r";
_rl_term_autowrap = TGETFLAG ("am") && TGETFLAG ("xn");
/* Allow calling application to set default height and width, using
rl_set_screen_size */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
_rl_get_screen_size (tty, 0);
/* "An application program can assume that the terminal can do
character insertion if *any one of* the capabilities `IC',
`im', `ic' or `ip' is provided." But we can't do anything if
only `ip' is provided, so... */
_rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
/* Check to see if this terminal has a meta key and clear the capability
variables if there is none. */
term_has_meta = TGETFLAG ("km");
if (term_has_meta == 0)
_rl_term_mm = _rl_term_mo = (char *)NULL;
#endif /* !__MSDOS__ */
/* Attempt to find and bind the arrow keys. Do not override already
bound keys in an overzealous attempt, however. */
bind_termcap_arrow_keys (emacs_standard_keymap);
#if defined (VI_MODE)
bind_termcap_arrow_keys (vi_movement_keymap);
bind_termcap_arrow_keys (vi_insertion_keymap);
#endif /* VI_MODE */
/* There's no way to determine whether or not a given terminal supports
bracketed paste mode, so we assume a terminal named "dumb" does not. */
if (dumbterm)
_rl_enable_bracketed_paste = _rl_enable_active_region = 0;
if (reset_region_colors)
{
_rl_reset_region_color (0, _rl_term_so);
_rl_reset_region_color (1, _rl_term_se);
}
return 0;
}
/* Bind the arrow key sequences from the termcap description in MAP. */
static void
bind_termcap_arrow_keys (Keymap map)
{
Keymap xkeymap;
xkeymap = _rl_keymap;
_rl_keymap = map;
rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
rl_bind_keyseq_if_unbound (_rl_term_kI, rl_overwrite_mode); /* Insert */
rl_bind_keyseq_if_unbound (_rl_term_kN, rl_history_search_forward); /* Page Down */
rl_bind_keyseq_if_unbound (_rl_term_kP, rl_history_search_backward); /* Page Up */
_rl_keymap = xkeymap;
}
char *
rl_get_termcap (const char *cap)
{
register int i;
if (tcap_initialized == 0)
return ((char *)NULL);
for (i = 0; i < NUM_TC_STRINGS; i++)
{
if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
return *(tc_strings[i].tc_value);
}
return ((char *)NULL);
}
/* Re-initialize the terminal considering that the TERM/TERMCAP variable
has changed. */
int
rl_reset_terminal (const char *terminal_name)
{
_rl_screenwidth = _rl_screenheight = 0;
_rl_init_terminal_io (terminal_name);
return 0;
}
/* A function for the use of tputs () */
#ifdef _MINIX
void
_rl_output_character_function (int c)
{
putc (c, _rl_out_stream);
}
#else /* !_MINIX */
int
_rl_output_character_function (int c)
{
return putc (c, _rl_out_stream);
}
#endif /* !_MINIX */
/* Write COUNT characters from STRING to the output stream. */
void
_rl_output_some_chars (const char *string, int count)
{
fwrite (string, 1, count, _rl_out_stream);
}
/* Move the cursor back. */
int
_rl_backspace (int count)
{
register int i;
#ifndef __MSDOS__
if (_rl_term_backspace)
for (i = 0; i < count; i++)
tputs (_rl_term_backspace, 1, _rl_output_character_function);
else
#endif
for (i = 0; i < count; i++)
putc ('\b', _rl_out_stream);
return 0;
}
/* Move to the start of the next line. */
int
rl_crlf (void)
{
#if defined (NEW_TTY_DRIVER) || defined (__MINT__)
if (_rl_term_cr)
tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif /* NEW_TTY_DRIVER || __MINT__ */
putc ('\n', _rl_out_stream);
return 0;
}
void
_rl_cr (void)
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
#else
tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif
}
/* Ring the terminal bell. */
int
rl_ding (void)
{
if (_rl_echoing_p)
{
switch (_rl_bell_preference)
{
case NO_BELL:
default:
break;
case VISIBLE_BELL:
if (_rl_visible_bell)
{
#ifdef __DJGPP__
ScreenVisualBell ();
#else
tputs (_rl_visible_bell, 1, _rl_output_character_function);
#endif
break;
}
/* FALLTHROUGH */
case AUDIBLE_BELL:
fprintf (stderr, "\007");
fflush (stderr);
break;
}
return (0);
}
return (-1);
}
/* **************************************************************** */
/* */
/* Entering and leaving terminal standout mode */
/* */
/* **************************************************************** */
void
_rl_standout_on (void)
{
#ifndef __MSDOS__
if (_rl_term_so && _rl_term_se)
tputs (_rl_term_so, 1, _rl_output_character_function);
#endif
}
void
_rl_standout_off (void)
{
#ifndef __MSDOS__
if (_rl_term_so && _rl_term_se)
tputs (_rl_term_se, 1, _rl_output_character_function);
#endif
}
/* **************************************************************** */
/* */
/* Controlling color for a portion of the line */
/* */
/* **************************************************************** */
/* Reset the region color variables to VALUE depending on WHICH (0 == start,
1 == end). This is where all the memory allocation for the color variable
strings is performed. We might want to pass a flag saying whether or not
to translate VALUE like a key sequence, but it doesn't really matter. */
int
_rl_reset_region_color (int which, const char *value)
{
int len;
if (which == 0)
{
xfree (_rl_active_region_start_color);
if (value && *value)
{
_rl_active_region_start_color = (char *)xmalloc (2 * strlen (value) + 1);
rl_translate_keyseq (value, _rl_active_region_start_color, &len);
_rl_active_region_start_color[len] = '\0';
}
else
_rl_active_region_start_color = NULL;
}
else
{
xfree (_rl_active_region_end_color);
if (value && *value)
{
_rl_active_region_end_color = (char *)xmalloc (2 * strlen (value) + 1);
rl_translate_keyseq (value, _rl_active_region_end_color, &len);
_rl_active_region_end_color[len] = '\0';
}
else
_rl_active_region_end_color = NULL;
}
return 0;
}
void
_rl_region_color_on (void)
{
#ifndef __MSDOS__
if (_rl_active_region_start_color && _rl_active_region_end_color)
tputs (_rl_active_region_start_color, 1, _rl_output_character_function);
#endif
}
void
_rl_region_color_off (void)
{
#ifndef __MSDOS__
if (_rl_active_region_start_color && _rl_active_region_end_color)
tputs (_rl_active_region_end_color, 1, _rl_output_character_function);
#endif
}
/* **************************************************************** */
/* */
/* Controlling the Meta Key and Keypad */
/* */
/* **************************************************************** */
static int enabled_meta = 0; /* flag indicating we enabled meta mode */
void
_rl_enable_meta_key (void)
{
#if !defined (__DJGPP__)
if (term_has_meta && _rl_term_mm)
{
tputs (_rl_term_mm, 1, _rl_output_character_function);
enabled_meta = 1;
}
#endif
}
void
_rl_disable_meta_key (void)
{
#if !defined (__DJGPP__)
if (term_has_meta && _rl_term_mo && enabled_meta)
{
tputs (_rl_term_mo, 1, _rl_output_character_function);
enabled_meta = 0;
}
#endif
}
void
_rl_control_keypad (int on)
{
#if !defined (__DJGPP__)
if (on && _rl_term_ks)
tputs (_rl_term_ks, 1, _rl_output_character_function);
else if (!on && _rl_term_ke)
tputs (_rl_term_ke, 1, _rl_output_character_function);
#endif
}
/* **************************************************************** */
/* */
/* Controlling the Cursor */
/* */
/* **************************************************************** */
/* Set the cursor appropriately depending on IM, which is one of the
insert modes (insert or overwrite). Insert mode gets the normal
cursor. Overwrite mode gets a very visible cursor. Only does
anything if we have both capabilities. */
void
_rl_set_cursor (int im, int force)
{
#ifndef __MSDOS__
if (_rl_term_ve && _rl_term_vs)
{
if (force || im != rl_insert_mode)
{
if (im == RL_IM_OVERWRITE)
tputs (_rl_term_vs, 1, _rl_output_character_function);
else
tputs (_rl_term_ve, 1, _rl_output_character_function);
}
}
#endif
}

1888
third_party/readline/text.c vendored Normal file

File diff suppressed because it is too large Load diff

493
third_party/readline/tilde.c vendored Normal file
View file

@ -0,0 +1,493 @@
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
/* Copyright (C) 1988-2020 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
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <sys/types.h>
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
#include "tilde.h"
#if defined (TEST) || defined (STATIC_MALLOC)
static void *xmalloc (), *xrealloc ();
#else
# include "xmalloc.h"
#endif /* TEST || STATIC_MALLOC */
#if !defined (HAVE_GETPW_DECLS)
# if defined (HAVE_GETPWUID)
extern struct passwd *getpwuid (uid_t);
# endif
# if defined (HAVE_GETPWNAM)
extern struct passwd *getpwnam (const char *);
# endif
#endif /* !HAVE_GETPW_DECLS */
#if !defined (savestring)
#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
#endif /* !savestring */
#if !defined (NULL)
# if defined (__STDC__)
# define NULL ((void *) 0)
# else
# define NULL 0x0
# endif /* !__STDC__ */
#endif /* !NULL */
/* If being compiled as part of bash, these will be satisfied from
variables.o. If being compiled as part of readline, they will
be satisfied from shell.o. */
extern char *sh_get_home_dir (void);
extern char *sh_get_env_value (const char *);
/* The default value of tilde_additional_prefixes. This is set to
whitespace preceding a tilde so that simple programs which do not
perform any word separation get desired behaviour. */
static const char *default_prefixes[] =
{ " ~", "\t~", (const char *)NULL };
/* The default value of tilde_additional_suffixes. This is set to
whitespace or newline so that simple programs which do not
perform any word separation get desired behaviour. */
static const char *default_suffixes[] =
{ " ", "\n", (const char *)NULL };
/* If non-null, this contains the address of a function that the application
wants called before trying the standard tilde expansions. The function
is called with the text sans tilde, and returns a malloc()'ed string
which is the expansion, or a NULL pointer if the expansion fails. */
tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL;
/* If non-null, this contains the address of a function to call if the
standard meaning for expanding a tilde fails. The function is called
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
which is the expansion, or a NULL pointer if there is no expansion. */
tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
char **tilde_additional_prefixes = (char **)default_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
char **tilde_additional_suffixes = (char **)default_suffixes;
static int tilde_find_prefix (const char *, int *);
static int tilde_find_suffix (const char *);
static char *isolate_tilde_prefix (const char *, int *);
static char *glue_prefix_and_suffix (char *, const char *, int);
/* Find the start of a tilde expansion in STRING, and return the index of
the tilde which starts the expansion. Place the length of the text
which identified this tilde starter in LEN, excluding the tilde itself. */
static int
tilde_find_prefix (const char *string, int *len)
{
register int i, j, string_len;
register char **prefixes;
prefixes = tilde_additional_prefixes;
string_len = strlen (string);
*len = 0;
if (*string == '\0' || *string == '~')
return (0);
if (prefixes)
{
for (i = 0; i < string_len; i++)
{
for (j = 0; prefixes[j]; j++)
{
if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
{
*len = strlen (prefixes[j]) - 1;
return (i + *len);
}
}
}
}
return (string_len);
}
/* Find the end of a tilde expansion in STRING, and return the index of
the character which ends the tilde definition. */
static int
tilde_find_suffix (const char *string)
{
register int i, j, string_len;
register char **suffixes;
suffixes = tilde_additional_suffixes;
string_len = strlen (string);
for (i = 0; i < string_len; i++)
{
#if defined (__MSDOS__)
if (string[i] == '/' || string[i] == '\\' /* || !string[i] */)
#else
if (string[i] == '/' /* || !string[i] */)
#endif
break;
for (j = 0; suffixes && suffixes[j]; j++)
{
if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
return (i);
}
}
return (i);
}
/* Return a new string which is the result of tilde expanding STRING. */
char *
tilde_expand (const char *string)
{
char *result;
int result_size, result_index;
result_index = result_size = 0;
if (result = strchr (string, '~'))
result = (char *)xmalloc (result_size = (strlen (string) + 16));
else
result = (char *)xmalloc (result_size = (strlen (string) + 1));
/* Scan through STRING expanding tildes as we come to them. */
while (1)
{
register int start, end;
char *tilde_word, *expansion;
int len;
/* Make START point to the tilde which starts the expansion. */
start = tilde_find_prefix (string, &len);
/* Copy the skipped text into the result. */
if ((result_index + start + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
strncpy (result + result_index, string, start);
result_index += start;
/* Advance STRING to the starting tilde. */
string += start;
/* Make END be the index of one after the last character of the
username. */
end = tilde_find_suffix (string);
/* If both START and END are zero, we are all done. */
if (!start && !end)
break;
/* Expand the entire tilde word, and copy it into RESULT. */
tilde_word = (char *)xmalloc (1 + end);
strncpy (tilde_word, string, end);
tilde_word[end] = '\0';
string += end;
expansion = tilde_expand_word (tilde_word);
if (expansion == 0)
expansion = tilde_word;
else
xfree (tilde_word);
len = strlen (expansion);
#ifdef __CYGWIN__
/* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when
$HOME for `user' is /. On cygwin, // denotes a network drive. */
if (len > 1 || *expansion != '/' || *string != '/')
#endif
{
if ((result_index + len + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
strcpy (result + result_index, expansion);
result_index += len;
}
xfree (expansion);
}
result[result_index] = '\0';
return (result);
}
/* Take FNAME and return the tilde prefix we want expanded. If LENP is
non-null, the index of the end of the prefix into FNAME is returned in
the location it points to. */
static char *
isolate_tilde_prefix (const char *fname, int *lenp)
{
char *ret;
int i;
ret = (char *)xmalloc (strlen (fname));
#if defined (__MSDOS__)
for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++)
#else
for (i = 1; fname[i] && fname[i] != '/'; i++)
#endif
ret[i - 1] = fname[i];
ret[i - 1] = '\0';
if (lenp)
*lenp = i;
return ret;
}
#if 0
/* Public function to scan a string (FNAME) beginning with a tilde and find
the portion of the string that should be passed to the tilde expansion
function. Right now, it just calls tilde_find_suffix and allocates new
memory, but it can be expanded to do different things later. */
char *
tilde_find_word (const char *fname, int flags, int *lenp)
{
int x;
char *r;
x = tilde_find_suffix (fname);
if (x == 0)
{
r = savestring (fname);
if (lenp)
*lenp = 0;
}
else
{
r = (char *)xmalloc (1 + x);
strncpy (r, fname, x);
r[x] = '\0';
if (lenp)
*lenp = x;
}
return r;
}
#endif
/* Return a string that is PREFIX concatenated with SUFFIX starting at
SUFFIND. */
static char *
glue_prefix_and_suffix (char *prefix, const char *suffix, int suffind)
{
char *ret;
int plen, slen;
plen = (prefix && *prefix) ? strlen (prefix) : 0;
slen = strlen (suffix + suffind);
ret = (char *)xmalloc (plen + slen + 1);
if (plen)
strcpy (ret, prefix);
strcpy (ret + plen, suffix + suffind);
return ret;
}
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook.
This always returns a newly-allocated string, never static storage. */
char *
tilde_expand_word (const char *filename)
{
char *dirname, *expansion, *username;
int user_len;
struct passwd *user_entry;
if (filename == 0)
return ((char *)NULL);
if (*filename != '~')
return (savestring (filename));
/* A leading `~/' or a bare `~' is *always* translated to the value of
$HOME or the home directory of the current user, regardless of any
preexpansion hook. */
if (filename[1] == '\0' || filename[1] == '/')
{
/* Prefix $HOME to the rest of the string. */
expansion = sh_get_env_value ("HOME");
#if defined (_WIN32)
if (expansion == 0)
expansion = sh_get_env_value ("APPDATA");
#endif
/* If there is no HOME variable, look up the directory in
the password database. */
if (expansion == 0)
expansion = sh_get_home_dir ();
return (glue_prefix_and_suffix (expansion, filename, 1));
}
username = isolate_tilde_prefix (filename, &user_len);
if (tilde_expansion_preexpansion_hook)
{
expansion = (*tilde_expansion_preexpansion_hook) (username);
if (expansion)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
xfree (username);
xfree (expansion);
return (dirname);
}
}
/* No preexpansion hook, or the preexpansion hook failed. Look in the
password database. */
dirname = (char *)NULL;
#if defined (HAVE_GETPWNAM)
user_entry = getpwnam (username);
#else
user_entry = 0;
#endif
if (user_entry == 0)
{
/* If the calling program has a special syntax for expanding tildes,
and we couldn't find a standard expansion, then let them try. */
if (tilde_expansion_failure_hook)
{
expansion = (*tilde_expansion_failure_hook) (username);
if (expansion)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
xfree (expansion);
}
}
/* If we don't have a failure hook, or if the failure hook did not
expand the tilde, return a copy of what we were passed. */
if (dirname == 0)
dirname = savestring (filename);
}
#if defined (HAVE_GETPWENT)
else
dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
#endif
xfree (username);
#if defined (HAVE_GETPWENT)
endpwent ();
#endif
return (dirname);
}
#if defined (TEST)
#undef NULL
#include <stdio.h>
main (int argc, char **argv)
{
char *result, line[512];
int done = 0;
while (!done)
{
printf ("~expand: ");
fflush (stdout);
if (!gets (line))
strcpy (line, "done");
if ((strcmp (line, "done") == 0) ||
(strcmp (line, "quit") == 0) ||
(strcmp (line, "exit") == 0))
{
done = 1;
break;
}
result = tilde_expand (line);
printf (" --> %s\n", result);
free (result);
}
exit (0);
}
static void memory_error_and_abort (void);
static void *
xmalloc (size_t bytes)
{
void *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static void *
xrealloc (void *pointer, int bytes)
{
void *temp;
if (!pointer)
temp = malloc (bytes);
else
temp = realloc (pointer, bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static void
memory_error_and_abort (void)
{
fprintf (stderr, "readline: out of virtual memory\n");
abort ();
}
/*
* Local variables:
* compile-command: "gcc -g -DTEST -o tilde tilde.c"
* end:
*/
#endif /* TEST */

68
third_party/readline/tilde.h vendored Normal file
View file

@ -0,0 +1,68 @@
/* tilde.h: Externally available variables and function in libtilde.a. */
/* Copyright (C) 1992-2009,2021 Free Software Foundation, Inc.
This file contains the Readline Library (Readline), a set of
routines for providing Emacs style line input to programs that ask
for it.
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 (_TILDE_H_)
# define _TILDE_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef char *tilde_hook_func_t (char *);
/* If non-null, this contains the address of a function that the application
wants called before trying the standard tilde expansions. The function
is called with the text sans tilde, and returns a malloc()'ed string
which is the expansion, or a NULL pointer if the expansion fails. */
extern tilde_hook_func_t *tilde_expansion_preexpansion_hook;
/* If non-null, this contains the address of a function to call if the
standard meaning for expanding a tilde fails. The function is called
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
which is the expansion, or a NULL pointer if there is no expansion. */
extern tilde_hook_func_t *tilde_expansion_failure_hook;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
extern char **tilde_additional_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
extern char **tilde_additional_suffixes;
/* Return a new string which is the result of tilde expanding STRING. */
extern char *tilde_expand (const char *);
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
extern char *tilde_expand_word (const char *);
/* Find the portion of the string beginning with ~ that should be expanded. */
extern char *tilde_find_word (const char *, int, int *);
#ifdef __cplusplus
}
#endif
#endif /* _TILDE_H_ */

365
third_party/readline/undo.c vendored Normal file
View file

@ -0,0 +1,365 @@
/* undo.c - manage list of changes to lines, offering opportunity to undo them */
/* 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
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
#include "histlib.h"
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
the undo list. */
int _rl_doing_an_undo = 0;
/* How many unclosed undo groups we currently have. */
int _rl_undo_group_level = 0;
/* The current undo list for THE_LINE. */
UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
/* **************************************************************** */
/* */
/* Undo, and Undoing */
/* */
/* **************************************************************** */
static UNDO_LIST *
alloc_undo_entry (enum undo_code what, int start, int end, char *text)
{
UNDO_LIST *temp;
temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
temp->what = what;
temp->start = start;
temp->end = end;
temp->text = text;
temp->next = (UNDO_LIST *)NULL;
return temp;
}
/* Remember how to undo something. Concatenate some undos if that
seems right. */
void
rl_add_undo (enum undo_code what, int start, int end, char *text)
{
UNDO_LIST *temp;
temp = alloc_undo_entry (what, start, end, text);
temp->next = rl_undo_list;
rl_undo_list = temp;
}
/* Free an UNDO_LIST */
void
_rl_free_undo_list (UNDO_LIST *ul)
{
UNDO_LIST *release;
while (ul)
{
release = ul;
ul = ul->next;
if (release->what == UNDO_DELETE)
xfree (release->text);
xfree (release);
}
}
/* Free the existing undo list. */
void
rl_free_undo_list (void)
{
UNDO_LIST *release, *orig_list;
orig_list = rl_undo_list;
_rl_free_undo_list (rl_undo_list);
rl_undo_list = (UNDO_LIST *)NULL;
_hs_replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
}
UNDO_LIST *
_rl_copy_undo_entry (UNDO_LIST *entry)
{
UNDO_LIST *new;
new = alloc_undo_entry (entry->what, entry->start, entry->end, (char *)NULL);
new->text = entry->text ? savestring (entry->text) : 0;
return new;
}
UNDO_LIST *
_rl_copy_undo_list (UNDO_LIST *head)
{
UNDO_LIST *list, *new, *roving, *c;
if (head == 0)
return head;
list = head;
new = 0;
while (list)
{
c = _rl_copy_undo_entry (list);
if (new == 0)
roving = new = c;
else
{
roving->next = c;
roving = roving->next;
}
list = list->next;
}
roving->next = 0;
return new;
}
/* Undo the next thing in the list. Return 0 if there
is nothing to undo, or non-zero if there was. */
int
rl_do_undo (void)
{
UNDO_LIST *release, *search;
int waiting_for_begin, start, end;
HIST_ENTRY *cur, *temp;
#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))
start = end = waiting_for_begin = 0;
do
{
if (rl_undo_list == 0)
return (0);
_rl_doing_an_undo = 1;
RL_SETSTATE(RL_STATE_UNDOING);
/* To better support vi-mode, a start or end value of -1 means
rl_point, and a value of -2 means rl_end. */
if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT)
{
start = TRANS (rl_undo_list->start);
end = TRANS (rl_undo_list->end);
}
switch (rl_undo_list->what)
{
/* Undoing deletes means inserting some text. */
case UNDO_DELETE:
rl_point = start;
_rl_fix_point (1);
rl_insert_text (rl_undo_list->text);
xfree (rl_undo_list->text);
break;
/* Undoing inserts means deleting some text. */
case UNDO_INSERT:
rl_delete_text (start, end);
rl_point = start;
_rl_fix_point (1);
break;
/* Undoing an END means undoing everything 'til we get to a BEGIN. */
case UNDO_END:
waiting_for_begin++;
break;
/* Undoing a BEGIN means that we are done with this group. */
case UNDO_BEGIN:
if (waiting_for_begin)
waiting_for_begin--;
else
rl_ding ();
break;
}
_rl_doing_an_undo = 0;
RL_UNSETSTATE(RL_STATE_UNDOING);
release = rl_undo_list;
rl_undo_list = rl_undo_list->next;
release->next = 0; /* XXX */
/* If we are editing a history entry, make sure the change is replicated
in the history entry's line */
cur = current_history ();
if (cur && cur->data && (UNDO_LIST *)cur->data == release)
{
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
xfree (temp->line);
FREE (temp->timestamp);
xfree (temp);
}
/* Make sure there aren't any history entries with that undo list */
_hs_replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
/* And make sure this list isn't anywhere in the saved line for history */
if (_rl_saved_line_for_history && _rl_saved_line_for_history->data)
{
/* Brute force; no finesse here */
search = (UNDO_LIST *)_rl_saved_line_for_history->data;
if (search == release)
_rl_saved_line_for_history->data = rl_undo_list;
else
{
while (search->next)
{
if (search->next == release)
{
search->next = rl_undo_list;
break;
}
search = search->next;
}
}
}
xfree (release);
}
while (waiting_for_begin);
return (1);
}
#undef TRANS
int
_rl_fix_last_undo_of_type (int type, int start, int end)
{
UNDO_LIST *rl;
for (rl = rl_undo_list; rl; rl = rl->next)
{
if (rl->what == type)
{
rl->start = start;
rl->end = end;
return 0;
}
}
return 1;
}
/* Begin a group. Subsequent undos are undone as an atomic operation. */
int
rl_begin_undo_group (void)
{
rl_add_undo (UNDO_BEGIN, 0, 0, 0);
_rl_undo_group_level++;
return 0;
}
/* End an undo group started with rl_begin_undo_group (). */
int
rl_end_undo_group (void)
{
rl_add_undo (UNDO_END, 0, 0, 0);
_rl_undo_group_level--;
return 0;
}
/* Save an undo entry for the text from START to END. */
int
rl_modifying (int start, int end)
{
if (start > end)
{
SWAP (start, end);
}
if (start != end)
{
char *temp = rl_copy_text (start, end);
rl_begin_undo_group ();
rl_add_undo (UNDO_DELETE, start, end, temp);
rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
rl_end_undo_group ();
}
return 0;
}
/* Revert the current line to its previous state. */
int
rl_revert_line (int count, int key)
{
if (rl_undo_list == 0)
rl_ding ();
else
{
while (rl_undo_list)
rl_do_undo ();
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
rl_point = rl_mark = 0; /* rl_end should be set correctly */
#endif
}
return 0;
}
/* Do some undoing of things that were done. */
int
rl_undo_command (int count, int key)
{
if (count < 0)
return 0; /* Nothing to do. */
while (count)
{
if (rl_do_undo ())
count--;
else
{
rl_ding ();
break;
}
}
return 0;
}

577
third_party/readline/util.c vendored Normal file
View file

@ -0,0 +1,577 @@
/* util.c -- readline utility functions */
/* 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/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include <sys/types.h>
#include <fcntl.h>
#include "posixjmp.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
#include <ctype.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
#if defined (TIOCSTAT_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* TIOCSTAT_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
#include "rlshell.h"
/* **************************************************************** */
/* */
/* Utility Functions */
/* */
/* **************************************************************** */
/* Return 0 if C is not a member of the class of characters that belong
in words, or 1 if it is. */
int _rl_allow_pathname_alphabetic_chars = 0;
static const char * const pathname_alphabetic_chars = "/-_=~.#$";
int
rl_alphabetic (int c)
{
if (_rl_alphabetic_p (c))
return (1);
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
#if defined (HANDLE_MULTIBYTE)
int
_rl_walphabetic (WCHAR_T wc)
{
int c;
if (iswalnum (wc))
return (1);
c = wc & 0177;
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
#endif
/* How to abort things. */
int
_rl_abort_internal (void)
{
if (RL_ISSTATE (RL_STATE_TIMEOUT) == 0)
rl_ding (); /* Don't ring the bell on a timeout */
rl_clear_message ();
_rl_reset_argument ();
rl_clear_pending_input ();
rl_deactivate_mark ();
while (rl_executing_macro)
_rl_pop_executing_macro ();
_rl_kill_kbd_macro ();
RL_UNSETSTATE (RL_STATE_MULTIKEY); /* XXX */
rl_last_func = (rl_command_func_t *)NULL;
_rl_longjmp (_rl_top_level, 1);
return (0);
}
int
rl_abort (int count, int key)
{
return (_rl_abort_internal ());
}
int
_rl_null_function (int count, int key)
{
return 0;
}
int
rl_tty_status (int count, int key)
{
#if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0);
rl_refresh_line (count, key);
#else
rl_ding ();
#endif
return 0;
}
/* Return a copy of the string between FROM and TO.
FROM is inclusive, TO is not. */
char *
rl_copy_text (int from, int to)
{
register int length;
char *copy;
/* Fix it if the caller is confused. */
if (from > to)
SWAP (from, to);
length = to - from;
copy = (char *)xmalloc (1 + length);
strncpy (copy, rl_line_buffer + from, length);
copy[length] = '\0';
return (copy);
}
/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
LEN characters. */
void
rl_extend_line_buffer (int len)
{
while (len >= rl_line_buffer_len)
{
rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
}
_rl_set_the_line ();
}
/* A function for simple tilde expansion. */
int
rl_tilde_expand (int ignore, int key)
{
register int start, end;
char *homedir, *temp;
int len;
end = rl_point;
start = end - 1;
if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
{
homedir = tilde_expand ("~");
_rl_replace_text (homedir, start, end);
xfree (homedir);
return (0);
}
else if (start >= 0 && rl_line_buffer[start] != '~')
{
for (; start >= 0 && !whitespace (rl_line_buffer[start]); start--)
;
start++;
}
else if (start < 0)
start = 0;
end = start;
do
end++;
while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
if (whitespace (rl_line_buffer[end]) || end >= rl_end)
end--;
/* If the first character of the current word is a tilde, perform
tilde expansion and insert the result. If not a tilde, do
nothing. */
if (rl_line_buffer[start] == '~')
{
len = end - start + 1;
temp = (char *)xmalloc (len + 1);
strncpy (temp, rl_line_buffer + start, len);
temp[len] = '\0';
homedir = tilde_expand (temp);
xfree (temp);
_rl_replace_text (homedir, start, end);
xfree (homedir);
}
return (0);
}
#if defined (USE_VARARGS)
void
#if defined (PREFER_STDARG)
_rl_ttymsg (const char *format, ...)
#else
_rl_ttymsg (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
fprintf (stderr, "readline: ");
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
va_end (args);
rl_forced_update_display ();
}
void
#if defined (PREFER_STDARG)
_rl_errmsg (const char *format, ...)
#else
_rl_errmsg (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
fprintf (stderr, "readline: ");
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
va_end (args);
}
#else /* !USE_VARARGS */
void
_rl_ttymsg (format, arg1, arg2)
char *format;
{
fprintf (stderr, "readline: ");
fprintf (stderr, format, arg1, arg2);
fprintf (stderr, "\n");
rl_forced_update_display ();
}
void
_rl_errmsg (format, arg1, arg2)
char *format;
{
fprintf (stderr, "readline: ");
fprintf (stderr, format, arg1, arg2);
fprintf (stderr, "\n");
}
#endif /* !USE_VARARGS */
/* **************************************************************** */
/* */
/* String Utility Functions */
/* */
/* **************************************************************** */
/* Determine if s2 occurs in s1. If so, return a pointer to the
match in s1. The compare is case insensitive. */
char *
_rl_strindex (const char *s1, const char *s2)
{
register int i, l, len;
for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
if (_rl_strnicmp (s1 + i, s2, l) == 0)
return ((char *) (s1 + i));
return ((char *)NULL);
}
#ifndef HAVE_STRPBRK
/* Find the first occurrence in STRING1 of any character from STRING2.
Return a pointer to the character in STRING1. */
char *
_rl_strpbrk (const char *string1, const char *string2)
{
register const char *scan;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
register int i, v;
memset (&ps, 0, sizeof (mbstate_t));
#endif
for (; *string1; string1++)
{
for (scan = string2; *scan; scan++)
{
if (*string1 == *scan)
return ((char *)string1);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
v = _rl_get_char_len (string1, &ps);
if (v > 1)
string1 += v - 1; /* -1 to account for auto-increment in loop */
}
#endif
}
return ((char *)NULL);
}
#endif
#if !defined (HAVE_STRCASECMP)
/* Compare at most COUNT characters from string1 to string2. Case
doesn't matter (strncasecmp). */
int
_rl_strnicmp (const char *string1, const char *string2, int count)
{
register const char *s1;
register const char *s2;
register int d;
if (count <= 0 || (string1 == string2))
return 0;
s1 = string1;
s2 = string2;
do
{
d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
if (d != 0)
return d;
if (*s1++ == '\0')
break;
s2++;
}
while (--count != 0);
return (0);
}
/* strcmp (), but caseless (strcasecmp). */
int
_rl_stricmp (const char *string1, const char *string2)
{
register const char *s1;
register const char *s2;
register int d;
s1 = string1;
s2 = string2;
if (s1 == s2)
return 0;
while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
{
if (*s1++ == '\0')
return 0;
s2++;
}
return (d);
}
#endif /* !HAVE_STRCASECMP */
/* Stupid comparison routine for qsort () ing strings. */
int
_rl_qsort_string_compare (char **s1, char **s2)
{
#if defined (HAVE_STRCOLL)
return (strcoll (*s1, *s2));
#else
int result;
result = **s1 - **s2;
if (result == 0)
result = strcmp (*s1, *s2);
return result;
#endif
}
/* Function equivalents for the macros defined in chardefs.h. */
#define FUNCTION_FOR_MACRO(f) int (f) (int c) { return f (c); }
FUNCTION_FOR_MACRO (_rl_digit_p)
FUNCTION_FOR_MACRO (_rl_digit_value)
FUNCTION_FOR_MACRO (_rl_lowercase_p)
FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
FUNCTION_FOR_MACRO (_rl_to_lower)
FUNCTION_FOR_MACRO (_rl_to_upper)
FUNCTION_FOR_MACRO (_rl_uppercase_p)
/* A convenience function, to force memory deallocation to be performed
by readline. DLLs on Windows apparently require this. */
void
rl_free (void *mem)
{
if (mem)
free (mem);
}
/* Backwards compatibility, now that savestring has been removed from
all `public' readline header files. */
#undef _rl_savestring
char *
_rl_savestring (const char *s)
{
return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
}
#if defined (DEBUG)
#if defined (USE_VARARGS)
static FILE *_rl_tracefp;
void
#if defined (PREFER_STDARG)
_rl_trace (const char *format, ...)
#else
_rl_trace (va_alist)
va_dcl
#endif
{
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
if (_rl_tracefp == 0)
_rl_tropen ();
vfprintf (_rl_tracefp, format, args);
fprintf (_rl_tracefp, "\n");
fflush (_rl_tracefp);
va_end (args);
}
int
_rl_tropen (void)
{
char fnbuf[128], *x;
if (_rl_tracefp)
fclose (_rl_tracefp);
#if defined (_WIN32) && !defined (__CYGWIN__)
x = sh_get_env_value ("TEMP");
if (x == 0)
x = ".";
#else
x = "/var/tmp";
#endif
snprintf (fnbuf, sizeof (fnbuf), "%s/rltrace.%ld", x, (long)getpid());
unlink(fnbuf);
_rl_tracefp = fopen (fnbuf, "w+");
return _rl_tracefp != 0;
}
int
_rl_trclose (void)
{
int r;
r = fclose (_rl_tracefp);
_rl_tracefp = 0;
return r;
}
void
_rl_settracefp (FILE *fp)
{
_rl_tracefp = fp;
}
#endif
#endif /* DEBUG */
#if HAVE_DECL_AUDIT_USER_TTY && defined (HAVE_LIBAUDIT_H) && defined (ENABLE_TTY_AUDIT_SUPPORT)
#include <sys/socket.h>
#include <libaudit.h>
#include <linux/audit.h>
#include <linux/netlink.h>
/* Report STRING to the audit system. */
void
_rl_audit_tty (char *string)
{
struct audit_message req;
struct sockaddr_nl addr;
size_t size;
int fd;
fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
if (fd < 0)
return;
size = strlen (string) + 1;
if (NLMSG_SPACE (size) > MAX_AUDIT_MESSAGE_LENGTH)
return;
memset (&req, 0, sizeof(req));
req.nlh.nlmsg_len = NLMSG_SPACE (size);
req.nlh.nlmsg_type = AUDIT_USER_TTY;
req.nlh.nlmsg_flags = NLM_F_REQUEST;
req.nlh.nlmsg_seq = 0;
if (size && string)
memcpy (NLMSG_DATA(&req.nlh), string, size);
memset (&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_pid = 0;
addr.nl_groups = 0;
sendto (fd, &req, req.nlh.nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
close (fd);
}
#endif

875
third_party/readline/vi_keymap.inc vendored Normal file
View file

@ -0,0 +1,875 @@
/* vi_keymap.c -- the keymap for vi_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"
#if 0
extern KEYMAP_ENTRY_ARRAY vi_escape_keymap;
#endif
/* The keymap arrays for handling vi mode. */
KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
/* The regular control keys come first. */
{ 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_vi_eof_maybe }, /* Control-d */
{ ISFUNC, rl_emacs_editing_mode }, /* Control-e */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
{ ISFUNC, rl_abort }, /* Control-g */
{ ISFUNC, rl_backward_char }, /* Control-h */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 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_command_func_t *)0x0 }, /* 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_vi_unix_word_rubout }, /* Control-w */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ /* vi_escape_keymap */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
{ ISFUNC, rl_vi_undo }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, rl_forward_char }, /* SPACE */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* " */
{ ISFUNC, rl_insert_comment }, /* # */
{ ISFUNC, rl_end_of_line }, /* $ */
{ ISFUNC, rl_vi_match }, /* % */
{ ISFUNC, rl_vi_tilde_expand }, /* & */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ( */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ) */
{ ISFUNC, rl_vi_complete }, /* * */
{ ISFUNC, rl_get_next_history}, /* + */
{ ISFUNC, rl_vi_char_search }, /* , */
{ ISFUNC, rl_get_previous_history }, /* - */
{ ISFUNC, rl_vi_redo }, /* . */
{ ISFUNC, rl_vi_search }, /* / */
/* Regular digits. */
{ ISFUNC, rl_beg_of_line }, /* 0 */
{ ISFUNC, rl_vi_arg_digit }, /* 1 */
{ ISFUNC, rl_vi_arg_digit }, /* 2 */
{ ISFUNC, rl_vi_arg_digit }, /* 3 */
{ ISFUNC, rl_vi_arg_digit }, /* 4 */
{ ISFUNC, rl_vi_arg_digit }, /* 5 */
{ ISFUNC, rl_vi_arg_digit }, /* 6 */
{ ISFUNC, rl_vi_arg_digit }, /* 7 */
{ ISFUNC, rl_vi_arg_digit }, /* 8 */
{ ISFUNC, rl_vi_arg_digit }, /* 9 */
/* A little more punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* : */
{ ISFUNC, rl_vi_char_search }, /* ; */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* < */
{ ISFUNC, rl_vi_complete }, /* = */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* > */
{ ISFUNC, rl_vi_search }, /* ? */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
/* Uppercase alphabet. */
{ ISFUNC, rl_vi_append_eol }, /* A */
{ ISFUNC, rl_vi_prev_word}, /* B */
{ ISFUNC, rl_vi_change_to }, /* C */
{ ISFUNC, rl_vi_delete_to }, /* D */
{ ISFUNC, rl_vi_end_word }, /* E */
{ ISFUNC, rl_vi_char_search }, /* F */
{ ISFUNC, rl_vi_fetch_history }, /* G */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* H */
{ ISFUNC, rl_vi_insert_beg }, /* 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_vi_search_again }, /* N */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* O */
{ ISFUNC, rl_vi_put }, /* P */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Q */
{ ISFUNC, rl_vi_replace }, /* R */
{ ISFUNC, rl_vi_subst }, /* S */
{ ISFUNC, rl_vi_char_search }, /* T */
{ ISFUNC, rl_revert_line }, /* U */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* V */
{ ISFUNC, rl_vi_next_word }, /* W */
{ ISFUNC, rl_vi_rubout }, /* X */
{ ISFUNC, rl_vi_yank_to }, /* Y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Z */
/* Some more punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* [ */
{ ISFUNC, rl_vi_complete }, /* \ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
{ ISFUNC, rl_vi_first_print }, /* ^ */
{ ISFUNC, rl_vi_yank_arg }, /* _ */
{ ISFUNC, rl_vi_goto_mark }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, rl_vi_append_mode }, /* a */
{ ISFUNC, rl_vi_prev_word }, /* b */
{ ISFUNC, rl_vi_change_to }, /* c */
{ ISFUNC, rl_vi_delete_to }, /* d */
{ ISFUNC, rl_vi_end_word }, /* e */
{ ISFUNC, rl_vi_char_search }, /* f */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* g */
{ ISFUNC, rl_backward_char }, /* h */
{ ISFUNC, rl_vi_insert_mode }, /* i */
{ ISFUNC, rl_get_next_history }, /* j */
{ ISFUNC, rl_get_previous_history }, /* k */
{ ISFUNC, rl_forward_char }, /* l */
{ ISFUNC, rl_vi_set_mark }, /* m */
{ ISFUNC, rl_vi_search_again }, /* n */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* o */
{ ISFUNC, rl_vi_put }, /* p */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* q */
{ ISFUNC, rl_vi_change_char }, /* r */
{ ISFUNC, rl_vi_subst }, /* s */
{ ISFUNC, rl_vi_char_search }, /* t */
{ ISFUNC, rl_vi_undo }, /* u */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* v */
{ ISFUNC, rl_vi_next_word }, /* w */
{ ISFUNC, rl_vi_delete }, /* x */
{ ISFUNC, rl_vi_yank_to }, /* y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* z */
/* Final punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* { */
{ ISFUNC, rl_vi_column }, /* | */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* } */
{ ISFUNC, rl_vi_change_case }, /* ~ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 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 vi_insertion_keymap = {
/* The regular control keys come first. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
{ ISFUNC, rl_insert }, /* Control-a */
{ ISFUNC, rl_insert }, /* Control-b */
{ ISFUNC, rl_insert }, /* Control-c */
{ ISFUNC, rl_vi_eof_maybe }, /* Control-d */
{ ISFUNC, rl_insert }, /* Control-e */
{ ISFUNC, rl_insert }, /* Control-f */
{ ISFUNC, rl_insert }, /* Control-g */
{ ISFUNC, rl_rubout }, /* Control-h */
{ ISFUNC, rl_complete }, /* Control-i */
{ ISFUNC, rl_newline }, /* Control-j */
{ ISFUNC, rl_insert }, /* Control-k */
{ ISFUNC, rl_insert }, /* Control-l */
{ ISFUNC, rl_newline }, /* Control-m */
{ ISFUNC, rl_menu_complete}, /* Control-n */
{ ISFUNC, rl_insert }, /* Control-o */
{ ISFUNC, rl_backward_menu_complete }, /* Control-p */
{ ISFUNC, rl_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_vi_unix_word_rubout }, /* Control-w */
{ ISFUNC, rl_insert }, /* Control-x */
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, rl_insert }, /* Control-z */
{ ISFUNC, rl_vi_movement_mode }, /* Control-[ */
{ ISFUNC, rl_insert }, /* Control-\ */
{ ISFUNC, rl_insert }, /* Control-] */
{ ISFUNC, rl_insert }, /* Control-^ */
{ ISFUNC, rl_vi_undo }, /* 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 */
};
/* Unused for the time being. */
#if 0
KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
/* The regular control keys come first. */
{ 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_command_func_t *)0x0 }, /* Control-g */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */
{ ISFUNC, rl_tab_insert}, /* Control-i */
{ ISFUNC, rl_emacs_editing_mode}, /* Control-j */
{ ISFUNC, rl_kill_line }, /* Control-k */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */
{ ISFUNC, rl_emacs_editing_mode}, /* 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_command_func_t *)0x0 }, /* Control-r */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-u */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
{ ISFUNC, rl_vi_movement_mode }, /* Control-[ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
{ ISFUNC, rl_vi_undo }, /* 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_command_func_t *)0x0 }, /* ( */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ) */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* * */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* + */
{ 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_vi_arg_digit }, /* 0 */
{ ISFUNC, rl_vi_arg_digit }, /* 1 */
{ ISFUNC, rl_vi_arg_digit }, /* 2 */
{ ISFUNC, rl_vi_arg_digit }, /* 3 */
{ ISFUNC, rl_vi_arg_digit }, /* 4 */
{ ISFUNC, rl_vi_arg_digit }, /* 5 */
{ ISFUNC, rl_vi_arg_digit }, /* 6 */
{ ISFUNC, rl_vi_arg_digit }, /* 7 */
{ ISFUNC, rl_vi_arg_digit }, /* 8 */
{ ISFUNC, rl_vi_arg_digit }, /* 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_arrow_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 }, /* ` */
/* 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_command_func_t *)0x0 }, /* 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_arrow_keys }, /* 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_word }, /* 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 */
};
#endif

2415
third_party/readline/vi_mode.c vendored Normal file

File diff suppressed because it is too large Load diff

49
third_party/readline/xfree.c vendored Normal file
View file

@ -0,0 +1,49 @@
/* xfree.c -- safe version of free that ignores attempts to free NUL */
/* Copyright (C) 1991-2010,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/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
#include "config.h"
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Memory Deallocation. */
/* */
/* **************************************************************** */
/* Use this as the function to call when adding unwind protects so we
don't need to know what free() returns. */
void
xfree (PTR_T string)
{
if (string)
free (string);
}

75
third_party/readline/xmalloc.c vendored Normal file
View file

@ -0,0 +1,75 @@
/* xmalloc.c -- safe versions of malloc and realloc */
/* Copyright (C) 1991-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/>.
*/
#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 */
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Memory Allocation and Deallocation. */
/* */
/* **************************************************************** */
static void
memory_error_and_abort (char *fname)
{
fprintf (stderr, "%s: out of virtual memory\n", fname);
exit (2);
}
/* Return a pointer to free()able block of memory large enough
to hold BYTES number of bytes. If the memory cannot be allocated,
print an error message and abort. */
PTR_T
xmalloc (size_t bytes)
{
PTR_T temp;
temp = malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xmalloc");
return (temp);
}
PTR_T
xrealloc (PTR_T pointer, size_t bytes)
{
PTR_T temp;
temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xrealloc");
return (temp);
}

45
third_party/readline/xmalloc.h vendored Normal file
View file

@ -0,0 +1,45 @@
/* xmalloc.h -- memory allocation that aborts on errors. */
/* Copyright (C) 1999-2009,2010-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/>.
*/
#if !defined (_XMALLOC_H_)
#define _XMALLOC_H_
#if defined (READLINE_LIBRARY)
# include "rlstdc.h"
#else
# include "third_party/readline/rlstdc.h"
#endif
#ifndef PTR_T
#ifdef __STDC__
# define PTR_T void *
#else
# define PTR_T char *
#endif
#endif /* !PTR_T */
extern PTR_T xmalloc (size_t);
extern PTR_T xrealloc (void *, size_t);
extern void xfree (void *);
#endif /* _XMALLOC_H_ */