summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1994-05-09 23:24:44 +0000
committerache <ache@FreeBSD.org>1994-05-09 23:24:44 +0000
commite8a676a6906c1eef339632bd8fe549bfbce3e139 (patch)
treef28f2d52bb4b856ef6a375919e9f851bd131a2ec /gnu
parent5ffff78a1ac63d71c5fd5b7b42f98b23104e8517 (diff)
downloadFreeBSD-src-e8a676a6906c1eef339632bd8fe549bfbce3e139.zip
FreeBSD-src-e8a676a6906c1eef339632bd8fe549bfbce3e139.tar.gz
Merged with new readline 2.0 from bash
Diffstat (limited to 'gnu')
-rw-r--r--gnu/lib/libreadline/COPYING368
-rw-r--r--gnu/lib/libreadline/ChangeLog382
-rw-r--r--gnu/lib/libreadline/Makefile8
-rw-r--r--gnu/lib/libreadline/README.FreeBSD1
-rw-r--r--gnu/lib/libreadline/bind.c1378
-rw-r--r--gnu/lib/libreadline/complete.c1326
-rw-r--r--gnu/lib/libreadline/display.c818
-rw-r--r--gnu/lib/libreadline/doc/Makefile36
-rw-r--r--gnu/lib/libreadline/doc/hstech.texinfo3
-rw-r--r--gnu/lib/libreadline/doc/hsuser.texinfo8
-rw-r--r--gnu/lib/libreadline/doc/rluser.texinfo134
-rw-r--r--gnu/lib/libreadline/doc/texindex.c1606
-rw-r--r--gnu/lib/libreadline/emacs_keymap.c467
-rw-r--r--gnu/lib/libreadline/examples/fileman.c50
-rw-r--r--gnu/lib/libreadline/funmap.c56
-rw-r--r--gnu/lib/libreadline/history.c477
-rw-r--r--gnu/lib/libreadline/isearch.c377
-rw-r--r--gnu/lib/libreadline/keymaps.c63
-rw-r--r--gnu/lib/libreadline/parens.c117
-rw-r--r--gnu/lib/libreadline/posixstat.h149
-rw-r--r--gnu/lib/libreadline/readline.c4765
-rw-r--r--gnu/lib/libreadline/readline/chardefs.h52
-rw-r--r--gnu/lib/libreadline/readline/history.h14
-rw-r--r--gnu/lib/libreadline/readline/keymaps.h44
-rw-r--r--gnu/lib/libreadline/readline/readline.h61
-rw-r--r--gnu/lib/libreadline/rldefs.h176
-rw-r--r--gnu/lib/libreadline/rltty.c668
-rw-r--r--gnu/lib/libreadline/search.c275
-rw-r--r--gnu/lib/libreadline/signals.c298
-rw-r--r--gnu/lib/libreadline/tcsh_hack.readme65
-rw-r--r--gnu/lib/libreadline/tilde.c398
-rw-r--r--gnu/lib/libreadline/vi_keymap.c451
-rw-r--r--gnu/lib/libreadline/vi_mode.c527
-rw-r--r--gnu/lib/libreadline/xmalloc.c78
34 files changed, 10469 insertions, 5227 deletions
diff --git a/gnu/lib/libreadline/COPYING b/gnu/lib/libreadline/COPYING
index a43ea21..1bb82d1 100644
--- a/gnu/lib/libreadline/COPYING
+++ b/gnu/lib/libreadline/COPYING
@@ -1,40 +1,46 @@
+
GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
+ Version 1, February 1989
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
+The Free Software Foundation has exempted Bash from the requirement of
+Paragraph 2c of the General Public License. This is to say, there is
+no requirement for Bash to print a notice when it is started
+interactively in the usual way. We made this exception because users
+and standards expect shells not to print such messages. This
+exception applies to any program that serves as a shell and that is
+based primarily on Bash as opposed to other GNU software.
+
Preamble
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
+ The license agreements of most software companies try to keep users
+at the mercy of those companies. By contrast, our General Public
License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
+software--to make sure the software is free for all its users. The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for 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
-this service 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.
+price. Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, 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 make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
- For example, if you distribute copies of such a program, whether
+ For example, if you distribute copies of a such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. 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.
+source code. And you must tell them their rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
@@ -47,209 +53,122 @@ want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
+ 0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License. The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications. Each
+licensee is addressed as "you".
+
+ 1. You may copy and distribute 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 and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program. You may charge a fee for the physical act of
+transferring a copy.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating that
+ you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish, that
+ in whole or in part contains the Program or any part thereof, either
+ with or without modifications, to be licensed at no charge to all
+ third parties under the terms of this General Public License (except
+ that you may choose to grant warranty protection to some or all
+ third parties, at your option).
+
+ c) If the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the simplest and most usual way, to print or display an
+ announcement including an appropriate copyright notice and a notice
+ that there is no warranty (or else, saying that you provide a
+ warranty) and that users may redistribute the program under these
+ conditions, and telling the user how to view a copy of this General
+ Public License.
+
+ d) You may charge a fee for the physical act of transferring a
+ copy, and you may at your option offer warranty protection in
+ exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
+ 3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+ a) accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal charge
+ for the cost of distribution) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
+ received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it. For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+ 4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License. However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+ 5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-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
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions. You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
+ 7. The Free Software Foundation may publish revised and/or new versions
of the 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 a version number of this License which applies to it and "any
+Each version is given a distinguishing version number. If the Program
+specifies a version number of the license which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
+the license, you may choose any version ever published by the Free Software
Foundation.
- 10. If you wish to incorporate parts of the Program into other free
+ 8. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
+to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
@@ -257,7 +176,7 @@ of promoting the sharing and reuse of software generally.
NO WARRANTY
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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
@@ -267,7 +186,7 @@ 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.
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
@@ -282,21 +201,22 @@ POSSIBILITY OF SUCH DAMAGES.
Appendix: 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.
+possible use to humanity, 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
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
+ 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 convey
+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) 19yy <name of author>
+ Copyright (C) 19yy <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 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; either version 1, 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
@@ -312,28 +232,26 @@ Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
- Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision version 69, Copyright (C) 19xx name of author
Gnomovision 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, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
+necessary. Here a sample; alter the names:
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (a program to direct compilers to make passes
+ at assemblers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
-This 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 Library General
-Public License instead of this License.
+That's all there is to it!
diff --git a/gnu/lib/libreadline/ChangeLog b/gnu/lib/libreadline/ChangeLog
index c238e0a..1cf0c00 100644
--- a/gnu/lib/libreadline/ChangeLog
+++ b/gnu/lib/libreadline/ChangeLog
@@ -1,217 +1,171 @@
-Fri Oct 22 07:55:08 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+Tue Mar 23 14:36:51 1993 Brian Fox (bfox@eos.crseo.ucsb.edu)
- * configure.in: Add * to end of all OS names.
+ * readline.c (rl_copy): Changed name to rl_copy_text.
-Tue Oct 5 12:33:51 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+Mon Mar 22 19:16:05 1993 Brian Fox (bfox@eos.crseo.ucsb.edu)
- * readline.c: Add stuff for HIUX to place where we detect termio
- vs. sgtty (ugh, but I don't see a simple better way).
+ * dispose_cmd.c, several other files. Declare dispose_xxx () as
+ "void".
-Wed Sep 29 11:02:58 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+ * builtins/hashcom.h: Make declarations of hashed_filenames be
+ "extern" to keep the SGI compiler happy.
- * readline.c (parser_if): Free tname when done with it (change
- imported from from bash 1.12 readline).
+ * readline.c (rl_initialize_everything): Assign values to
+ out_stream and in_stream immediately, since
+ output_character_function () can be called before
+ readline_internal () is called.
-Tue Sep 7 17:15:37 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+Tue Dec 8 09:30:56 1992 Brian Fox (bfox@cubit)
- * configure.in (m88k-*-sysvr4*): Comment out previous change.
+ * readline.c (rl_init_terminal) Set PC from BC, not from *buffer.
-Fri Jul 2 11:05:34 1993 Ian Lance Taylor (ian@cygnus.com)
+Mon Nov 30 09:35:47 1992 Brian Fox (bfox@cubit)
- * configure.in (*-*-riscos*): New entry; use mh-sysv.
+ * readline.c (invoking_keyseqs_in_map, rl_parse_and_bind) Allow
+ backslash to quote characters, such as backslash, double quote,
+ and space. Backslash quotes all character indiscriminately.
-Wed Jun 23 13:00:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+ * funmap.c (vi_keymap) Fix type in "vi-replace" declaration.
- * configure.in: Add comment.
+Fri Nov 20 10:55:05 1992 Brian Fox (bfox@cubit)
-Mon Jun 14 14:28:55 1993 Jim Kingdon (kingdon@eric)
+ * readline.c (init_terminal_io, rl_prep_terminal): FINALLY!
+ Declare and use termcap variable `ospeed' when setting up terminal
+ parameters.
- * configure.in (m88k-*-sysvr4*): Use sysdep-norm.h.
+Thu Oct 8 08:53:07 1992 Brian J. Fox (bfox@helios)
-Sun Jun 13 13:04:09 1993 Jim Kingdon (kingdon@cygnus.com)
+ * Makefile, this directory: Include (as links to the canonical
+ sources), tilde.c, tilde.h, posixstat.h and xmalloc.c.
- * Makefile.in ({real,dist}clean): Remove sysdep.h.
+Tue Sep 29 13:07:21 1992 Brian J. Fox (bfox@helios)
-Thu Jun 10 11:22:41 1993 Jim Kingdon (kingdon@cygnus.com)
+ * readline.c (init_terminal_io) Don't set arrow keys if the key
+ sequences that represent them are already set.
- * Makefile.in: Add mostlyclean, distclean, and realclean targets.
+ * readline.c (rl_function_of_keyseq) New function returns the first
+ function (or macro) found while searching a key sequence.
-Fri May 21 17:09:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+Mon Sep 28 00:34:04 1992 Brian J. Fox (bfox@helios)
- * config/mh-isc: New file.
- * configure.in: Use it.
+ * readline.c (LibraryVersion) New static char * contains current
+ version number. Version is at 2.0.
-Sat Apr 17 00:40:12 1993 Jim Kingdon (kingdon at calvin)
+ * readline.c (rl_complete_internal): Incorporated clean changes
+ from gilmore (gnu@cygnus.com) to support quoted substrings within
+ completion functions.
- * readline.c, history.c: Don't include sys/types.h; sysdep.h does.
+ * readline.c (many locations) Added support for the _GO32_,
+ whatever that is. Patches supplied by Cygnus, typed in by hand,
+ with cleanups.
- * config/mh-sysv: Define TIOCGWINSZ_BROKEN.
- readline.c: Check it.
+Sun Aug 16 12:46:24 1992 Brian Fox (bfox@cubit)
-Wed Mar 24 02:06:15 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+ * readline.c (init_terminal_io): Find out the values of the keypad
+ arrows and bind them to appropriate RL functions if present.
- * Makefile.in: add installcheck & dvi targets
+Mon Aug 10 18:13:24 1992 Brian Fox (bfox@cubit)
-Fri Mar 12 18:36:53 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+ * history.c (stifle_history): A negative argument to stifle
+ becomes zero.
- * configure.in: recognize *-*-solaris2* instead of *-*-solaris* (a
- number of people want to call SunOS 4.1.2 "solaris1.0"
- and get it right)
+Tue Jul 28 09:28:41 1992 Brian Fox (bfox@cubit)
-Tue Mar 2 21:25:36 1993 Fred Fish (fnf@cygnus.com)
+ * readline.c (rl_variable_bind): New local structure describes
+ booleans by name and address; code in rl_variable_bind () looks at
+ structure to set simple variables.
- * sysdep-sysv4.h: New file for SVR4.
- * configure.in (*-*-sysv4*): Use sysdep-sysv4.h.
+ * parens.c (rl_insert_close): New variable rl_blink_matching_paren
+ is non-zero if we want to blink the matching open when a close is
+ inserted. If FD_SET is defined, rl_blink_matching_paren defaults
+ to 1, else 0. If FD_SET is not defined, and
+ rl_blink_matching_paren is non-zero, the close character(s) are/is
+ simply inserted.
- * configure.in (*-*-ultrix2): Add triplet from Michael Rendell
- (michael@mercury.cs.mun.ca)
+Wed Jul 22 20:03:59 1992 Brian Fox (bfox@cubit)
-Tue Dec 15 12:38:16 1992 Ian Lance Taylor (ian@cygnus.com)
+ * history.c, readline.c, vi_mode.c: Cause the functions strchr ()
+ and strrchr () to be used instead of index () and rindex ()
+ throughout the source.
- * configure.in (i[34]86-*-sco3.2v4*): use mh-sco4.
- * config/mh-sco4: New file, like mh-sco but without defining
- _POSIX_SOURCE.
+Mon Jul 13 11:34:07 1992 Brian Fox (bfox@cubit)
-Wed Nov 11 21:20:14 1992 John Gilmore (gnu@cygnus.com)
+ * readline.c: (rl_variable_bind) New variable "meta-flag" if "on"
+ means force the use of the 8th bit as Meta bit. Internal variable
+ is called meta_flag.
- * configure.in: Reformat to one-case-per-line.
- Handle SunOS 3.5, as per Karl Berry, <karl@claude.cs.umb.edu>.
+Thu Jul 9 10:37:56 1992 Brian Fox (bfox@cubit)
-Wed Nov 4 15:32:31 1992 Stu Grossman (grossman at cygnus.com)
+ * history.c (get_history_event) Change INDEX to LOCAL_INDEX. If
+ compiling for the shell, allow shell metacharacters to separate
+ history tokens as they would for shell tokens.
- * sysdep-norm.h: Remove some crud, install dire warning.
+Sat Jul 4 19:29:12 1992 Brian Fox (bfox@cubit)
-Thu Oct 22 01:08:13 1992 Stu Grossman (grossman at cygnus.com)
+ * vi_keymap.c: According to Posix, TAB self-inserts instead of
+ doing completion.
- * configure.in: Make SCO work again...
+ * vi_mode.c: (rl_vi_yank_arg) Enter VI insert mode after yanking
+ an arg from the previous line.
-Mon Oct 12 15:04:07 1992 Ian Lance Taylor (ian@cygnus.com)
+ * search.c: New file takes over vi style searching and implements
+ non-incremental searching the history.
- * readline.c (init_terminal_io): if tgetent returns 0, the
- terminal type is unknown.
+ Makefile: Add search.c and search.o.
-Thu Oct 1 23:44:14 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+ funmap.c: Add names for non-incremental-forward-search-history and
+ non-incremental-reverse-search-history.
- * configure.in: use cpu-vendor-os triple instead of nested cases
+ readline.h: Add extern definitions for non-incremental searching.
-Wed Sep 30 12:58:57 1992 Stu Grossman (grossman at cygnus.com)
+ vi_mode.c: Remove old search code; add calls to code in search.c.
- * readline.c (rl_complete_internal): Cast alloca to (char *) to
- avoid warning.
+Fri Jul 3 10:36:33 1992 Brian Fox (bfox@cubit)
-Fri Sep 25 12:45:05 1992 Stu Grossman (grossman at cygnus.com)
+ * readline.c (rl_delete_horizontal_space); New function deletes
+ all whitespace surrounding point.
- * readline.c (clear_to_eol, rl_generic_bind): Make static.
- (rl_digit_loop): Add arg to call to rl_message().
- * vi_mode.c (rl_vi_first_print): Add arg to call to
- rl_back_to_indent().
+ funmap.c: Add "delete-horizontal-space".
+ emacs_keymap.c: Put rl_delete_horizontal_space () on M-\.
-Wed Aug 19 14:59:07 1992 Ian Lance Taylor (ian@cygnus.com)
+ * readline.c (rl_set_signals, rl_clear_signals); New function
+ rl_set_sighandler () is either defined in a Posix way (if
+ HAVE_POSIX_SIGNALS is defined) or in a BSD way. Function is
+ called from rl_set_signals () and rl_clear_signals ().
- * Makefile.in: always create installation directories, use full
- file name for install target.
+Fri May 8 12:50:15 1992 Brian Fox (bfox@cubit)
-Wed Aug 12 15:50:57 1992 John Gilmore (gnu@cygnus.com)
+ * readline.c: (readline_default_bindings) Do comparisons with
+ _POSIX_VDISABLE casted to `unsigned char'. Change tty characters
+ to be unsigned char.
- * readline.c (last_readline_init_file): Fix typo made by Steve
- Chamberlain/DJ Delorie. Proper control file name is ~/.inputrc,
- not ~/inputrc.
+Thu Apr 30 12:36:35 1992 Brian Fox (bfox@cubit)
-Thu Jun 25 16:15:27 1992 Stu Grossman (grossman at cygnus.com)
+ * readline.c: (rl_getc) Handle "read would block" error on
+ non-blocking IO streams.
- * configure.in: Make bsd based systems use sysdep-obsd.h.
+ * readline.c: (rl_signal_handler): Unblock only the signal that we
+ have caught, not all signals.
-Tue Jun 23 23:22:53 1992 Per Bothner (bothner@cygnus.com)
+Sun Feb 23 03:33:09 1992 Brian Fox (bfox at gnuwest.fsf.org)
- * config/mh-posix: New file, for Posix-compliant systems.
- * configure.in: Use mh-posix for Linux (free Unix clone).
+ * readline.c: Many functions. Use only the macros META_CHAR and
+ UNMETA to deal with meta characters. Prior to this, we used
+ numeric values and tests.
-Tue Jun 23 21:59:20 1992 Fred Fish (fnf@cygnus.com)
+ * readline.c (rl_complete_internal) Report exactly the number of
+ possible completions, not the number + 1.
- * sysdep-norm.h (alloca): Protect against previous definition as
- a macro with arguments.
+ * vi_mode.c (rl_do_move) Do not change the cursor position when
+ using `cw' or `cW'.
-Fri Jun 19 15:48:54 1992 Stu Grossman (grossman at cygnus.com)
+ * vi_mode.c (rl_vi_complete) Enter insert mode after completing
+ with `*' or `\'.
- * sysdep-obsd.h: #include <sys/types.h> to make this more Kosher.
+Fri Feb 21 05:58:18 1992 Brian Fox (bfox at gnuwest.fsf.org)
-Fri Jun 19 12:53:28 1992 John Gilmore (gnu at cygnus.com)
-
- * config/mh-apollo68v, mh-sco, mh-sysv, mh-sysv4}: RANLIB=true.
-
-Mon Jun 15 13:50:34 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
-
- * configure.in: use mh-sysv4 on solaris2
-
-Mon Jun 15 12:28:24 1992 Fred Fish (fnf@cygnus.com)
-
- * config/mh-ncr3000 (INSTALL): Don't use /usr/ucb/install,
- it is broken on ncr 3000's.
- * config/mh-ncr3000 (RANLIB): Use RANLIB=true.
-
-Mon Jun 15 01:35:55 1992 John Gilmore (gnu at cygnus.com)
-
- * readline.c: Make new SIGNALS_* macros to parameterize the
- ugly changes in signal blocking. Use them throughout,
- reducing #ifdef HAVE_POSIX_SIGNALS and HAVE_BSD_SIGNALS clutter
- significantly. Make all such places use POSIX if available,
- to avoid losing with poor `sigsetmask' emulation from libiberty.
-
-Sun Jun 14 15:19:51 1992 Stu Grossman (grossman at cygnus.com)
-
- * readline.c (insert_some_chars): Return void.
-
-Thu Jun 11 01:27:45 1992 John Gilmore (gnu at cygnus.com)
-
- * readline.c: #undef PC, which Solaris2 defines in sys/types.h,
- clobbering the termcap global variable PC.
-
-Tue Jun 9 17:30:23 1992 Fred Fish (fnf@cygnus.com)
-
- * config/{mh-ncr3000, mh-sysv4}: Change INSTALL to use
- /usr/ucb/install.
-
-Mon Jun 8 23:10:07 1992 Fred Fish (fnf@cygnus.com)
-
- * readline.h (rl_completer_quote_characters): Add declaration.
- * readline.c (rl_completer_quote_characters): Add global var.
- * readline.c (strpbrk): Add prototype and function.
- * readline.c (rl_complete_internal): Add code to handle
- expansion of quoted strings.
-
-Mon May 11 12:39:30 1992 John Gilmore (gnu at cygnus.com)
-
- * readline.c: Can't initialize FILE *'s with stdin and stdout,
- because they might not be constant. Patch from Tom Quinn,
- trq@dinoysos.thphys.ox.ac.uk.
-
-Tue Apr 28 21:52:34 1992 John Gilmore (gnu at cygnus.com)
-
- * readline.h: Declare rl_event_hook (which already existed).
- Suggested by Christoph Tietz <tietz@zi.gmd.dbp.de>.
-
-Wed Apr 22 18:08:01 1992 K. Richard Pixley (rich@rtl.cygnus.com)
-
- * configure.in: remove subdirs declaration. The obsolete semantic
- for subdirs has been usurped by per's new meaning.
-
-Tue Apr 21 11:54:23 1992 K. Richard Pixley (rich@cygnus.com)
-
- * Makefile.in: rework CFLAGS so that they can be set on the
- command line to make. Remove MINUS_G. Default CFLAGS to -g.
-
-Fri Apr 10 23:02:27 1992 Fred Fish (fnf@cygnus.com)
-
- * configure.in: Recognize new ncr3000 config.
- * config/mh-ncr3000: New NCR 3000 config file.
-
-Wed Mar 25 10:46:30 1992 John Gilmore (gnu at cygnus.com)
-
- * history.c (stifle_history): Negative arg treated as zero.
-
-Tue Mar 24 23:46:20 1992 K. Richard Pixley (rich@cygnus.com)
-
- * config/mh-sysv: INSTALL_PROG -> INSTALL.
+ * readline.c (rl_dispatch) Increment rl_key_sequence_length for
+ meta characters that map onto ESC map.
Mon Feb 10 01:41:35 1992 Brian Fox (bfox at gnuwest.fsf.org)
@@ -219,108 +173,56 @@ Mon Feb 10 01:41:35 1992 Brian Fox (bfox at gnuwest.fsf.org)
to write and write them in one fell swoop (lower overhead than
calling write () for each line). Suggested by Peter Ho.
- * vi_mode.c (rl_vi_subst) Don't forget to end the undo group.
-
-Sat Mar 7 00:15:36 1992 K. Richard Pixley (rich@rtl.cygnus.com)
-
- * Makefile.in: remove FIXME's on info and install-info targets.
-
-Fri Mar 6 22:02:04 1992 K. Richard Pixley (rich@cygnus.com)
-
- * Makefile.in: added check target.
-
-Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
-
- * Makefile.in, configure.in: removed traces of namesubdir,
- -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
- copyrights to '92, changed some from Cygnus to FSF.
-
-Fri Feb 21 14:37:32 1992 Steve Chamberlain (sac at rtl.cygnus.com)
-
- * readline.c, examples/fileman.c: patches from DJ to support DOS
-
-Thu Feb 20 23:23:16 1992 Stu Grossman (grossman at cygnus.com)
+ * readline.c: Include hbullx20 as well as hpux for determining
+ USGr3ness.
- * readline.c (rl_read_init_file): Make sure that null filename is
- not passed to open() or else we end up opening the directory, and
- read a bunch of garbage into keymap[].
+ * readline.c (rl_unix_word_rubout) As per the "Now REMEMBER"
+ comment, pass arguments to rl_kill_text () in the correct order to
+ preserve prepending and appending of killed text.
-Mon Feb 17 17:15:09 1992 Fred Fish (fnf at cygnus.com)
+ * readline.c (rl_search_history) malloc (), realloc (), and free
+ () SEARCH_STRING so that there are no static limits on searching.
- * readline.c (readline_default_bindings): Only make use of VLNEXT
- when both VLNEXT and TERMIOS_TTY_DRIVER is defined. On SVR4
- <termio.h> includes <termios.h>, so VLNEXT is always defined.
-
- * sysdep-norm.h (_POSIX_VERSION): Define this for all SVR4
- systems so that <termios.h> gets used, instead of <termio.h>.
-
-Fri Dec 20 12:04:31 1991 Fred Fish (fnf at cygnus.com)
-
- * configure.in: Change svr4 references to sysv4.
-
-Tue Dec 10 04:07:20 1991 K. Richard Pixley (rich at rtl.cygnus.com)
-
- * Makefile.in: infodir belongs in datadir.
-
-Fri Dec 6 23:23:14 1991 K. Richard Pixley (rich at rtl.cygnus.com)
-
- * Makefile.in: remove spaces following hyphens, bsd make can't
- cope. added clean-info. added standards.text support. Don't
- know how to make info anymore.
-
- * configure.in: commontargets is no longer a recognized hook, so
- remove it. new subdir called doc.
-
-Thu Dec 5 22:46:10 1991 K. Richard Pixley (rich at rtl.cygnus.com)
-
- * Makefile.in: idestdir and ddestdir go away. Added copyrights
- and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
- and mandir now keyed off datadir by default.
-
-Fri Nov 22 09:02:32 1991 John Gilmore (gnu at cygnus.com)
-
- * sysdep-obsd.h: Rename from sysdep-newsos.h.
- * configure.in: Use sysdep-obsd for Mach as well as NEWs.
+ * vi_mode.c (rl_vi_subst) Don't forget to end the undo group.
- * sysdep-norm.h, sysdep-aix.h: Add <sys/types.h>, which POSIX
- requires to make <dirent.h> work. Improve Sun alloca decl.
+Fri Jan 31 14:51:02 1992 Brian Fox (bfox at gnuwest.fsf.org)
-Thu Nov 21 18:48:08 1991 John Gilmore (gnu at cygnus.com)
+ * readline.c (rl_signal_handler): Zero the current history entry's
+ pointer after freeing the undo_list when SIGINT received.
+ Reformat a couple of functions.
- * Makefile.in: Clean up ../glob/tilde.c -> tilde.o path.
- Clean up makefile a bit in general.
+Sat Jan 25 13:47:35 1992 Brian Fox (bfox at bears)
-Thu Nov 21 14:40:29 1991 Stu Grossman (grossman at cygnus.com)
+ * readline.c (parser_if): free () TNAME after use.
- * configure.in, config/mh-svr4: Make SVR4 work.
+Tue Jan 21 01:01:35 1992 Brian Fox (bfox at gnuwest.fsf.org)
- * readline.c: Move config stuff to sysdep.h, use typedef dirent
- consistently, remove refs to d_namlen (& D_NAMLEN) to improve
- portability. Also, update copyright notice.
- readline.h: remove config stuff that I added erroneously in the
- first place.
+ * readline.c (rl_redisplay) and (rl_character_len): Display
+ Control characters as "^c" and Meta characters as "\234", instead
+ of "C-C" and "M-C".
- * emacs_keymap.c, funmap.c, history.c, keymaps.c, vi_keymap.c,
- vi_mode.c: move config stuff to sysdep.h, update copyright notices.
+Sun Dec 29 10:59:00 1991 Brian Fox (bfox at gnuwest.fsf.org)
-Tue Nov 19 15:02:13 1991 Stu Grossman (grossman at cygnus.com)
+ * readline.c (init_terminal_io) Default to environment variables
+ LINES and COLUMNS before termcap entry values. If all else fails,
+ then assume 80x24 terminal.
- * history.c: #include "sysdep.h".
+Sat Dec 28 16:33:11 1991 Brian Fox (bfox at gnuwest.fsf.org)
-Tue Nov 19 10:49:17 1991 Fred Fish (fnf at cygnus.com)
+ * readline.c: If this machine is USG and it is hpux, then define
+ USGr3.
- * Makefile.in, config/hm-sysv, config/hm-sco: Change SYSV to
- USG to match current usage.
+ * history.c: Cosmetic fixes.
- * readline.c: Add USGr4 to list of defined things to check for
- to use <dirent.h> style directory access.
+Thu Nov 21 00:10:12 1991 Brian Fox (bfox at gnuwest.fsf.org)
- * config/hm-svr4: New file for System V Release 4 (USGr4).
+ * vi_mode.c: (rl_do_move) Place cursor at end of line, never at
+ next to last character.
-Mon Nov 18 23:59:52 1991 Stu Grossman (grossman at cygnus.com)
+Thu Nov 14 05:08:01 1991 Brian Fox (bfox at gnuwest.fsf.org)
- * readline.c (filename_completion_function): use struct dirent
- instead of struct direct.
+ * history.c (get_history_event) Non-anchored searches can have a
+ return index of greater than zero from get_history_event ().
Fri Nov 1 07:02:13 1991 Brian Fox (bfox at gnuwest.fsf.org)
diff --git a/gnu/lib/libreadline/Makefile b/gnu/lib/libreadline/Makefile
index 927ff75..5af037e 100644
--- a/gnu/lib/libreadline/Makefile
+++ b/gnu/lib/libreadline/Makefile
@@ -1,14 +1,16 @@
-# $Id: Makefile,v 1.1 1993/12/28 07:54:51 ache Exp $
+# $Id: Makefile,v 1.3 1994/05/09 20:35:26 ache Exp $
SHLIB_MAJOR=1
SHLIB_MINOR=0
CFLAGS+= -I${.CURDIR} -I${.CURDIR}/readline -DVOID_SIGHANDLER \
- -DHAVE_UNISTD_H -DSTATIC_MALLOC \
+ -DHAVE_UNISTD_H -DHAVE_STRING_H -DHAVE_STDLIB_H \
-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp
LIB= readline
-SRCS+= readline.c history.c funmap.c keymaps.c
+SRCS+= readline.c funmap.c keymaps.c vi_mode.c parens.c \
+ rltty.c complete.c bind.c isearch.c display.c signals.c \
+ history.c search.c tilde.c xmalloc.c
NOMAN= noman
beforeinstall:
diff --git a/gnu/lib/libreadline/README.FreeBSD b/gnu/lib/libreadline/README.FreeBSD
index 5defcc4..541a6ab 100644
--- a/gnu/lib/libreadline/README.FreeBSD
+++ b/gnu/lib/libreadline/README.FreeBSD
@@ -12,5 +12,6 @@ with same winsize structure: it does nothing expect polling
process from background. Look tcsh_hack.readme for details.
Here is megred version with readline comes from gdb4.11
+and with readline 2.0 comes from bash
ache@astral.msk.su
diff --git a/gnu/lib/libreadline/bind.c b/gnu/lib/libreadline/bind.c
new file mode 100644
index 0000000..ee54398
--- /dev/null
+++ b/gnu/lib/libreadline/bind.c
@@ -0,0 +1,1378 @@
+/* bind.c -- key binding and startup file support for the readline library. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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 1, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if !defined (NO_SYS_FILE)
+# include <sys/file.h>
+#endif /* !NO_SYS_FILE */
+#include <signal.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 */
+
+#include <errno.h>
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#if !defined (strchr) && !defined (__STDC__)
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+extern char *tilde_expand ();
+
+extern int _rl_horizontal_scroll_mode;
+extern int _rl_mark_modified_lines;
+extern int _rl_prefer_visible_bell;
+extern int _rl_meta_flag;
+extern int rl_blink_matching_paren;
+extern int _rl_convert_meta_chars_to_ascii;
+#if defined (VISIBLE_STATS)
+extern int rl_visible_stats;
+#endif /* VISIBLE_STATS */
+extern int rl_complete_with_tilde_expansion;
+extern int rl_completion_query_items;
+
+extern int rl_explicit_arg;
+extern int rl_editing_mode;
+extern unsigned short _rl_parsing_conditionalized_out;
+extern Keymap _rl_keymap;
+
+extern char *possible_control_prefixes[], *possible_meta_prefixes[];
+
+extern char **rl_funmap_names ();
+
+static int glean_key_from_name ();
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+/* **************************************************************** */
+/* */
+/* Binding keys */
+/* */
+/* **************************************************************** */
+
+/* rl_add_defun (char *name, Function *function, int key)
+ Add NAME to the list of named functions. Make FUNCTION be the function
+ that gets called. If KEY is not -1, then bind it. */
+rl_add_defun (name, function, key)
+ char *name;
+ Function *function;
+ int key;
+{
+ if (key != -1)
+ rl_bind_key (key, function);
+ rl_add_funmap_entry (name, function);
+}
+
+/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */
+int
+rl_bind_key (key, function)
+ int key;
+ Function *function;
+{
+ if (key < 0)
+ return (key);
+
+ if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
+ {
+ if (_rl_keymap[ESC].type == ISKMAP)
+ {
+#if defined (CRAY)
+ Keymap escmap = (Keymap)((int)_rl_keymap[ESC].function);
+#else
+ Keymap escmap = (Keymap)_rl_keymap[ESC].function;
+#endif
+
+ key = UNMETA (key);
+ escmap[key].type = ISFUNC;
+ escmap[key].function = function;
+ return (0);
+ }
+ return (key);
+ }
+
+ _rl_keymap[key].type = ISFUNC;
+ _rl_keymap[key].function = function;
+ return (0);
+}
+
+/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid
+ KEY. */
+int
+rl_bind_key_in_map (key, function, map)
+ int key;
+ Function *function;
+ Keymap map;
+{
+ int result;
+ Keymap oldmap = _rl_keymap;
+
+ _rl_keymap = map;
+ result = rl_bind_key (key, function);
+ _rl_keymap = oldmap;
+ return (result);
+}
+
+/* Make KEY do nothing in the currently selected keymap.
+ Returns non-zero in case of error. */
+int
+rl_unbind_key (key)
+ int key;
+{
+ return (rl_bind_key (key, (Function *)NULL));
+}
+
+/* Make KEY do nothing in MAP.
+ Returns non-zero in case of error. */
+int
+rl_unbind_key_in_map (key, map)
+ int key;
+ Keymap map;
+{
+ return (rl_bind_key_in_map (key, (Function *)NULL, map));
+}
+
+/* Bind the key sequence represented by the string KEYSEQ to
+ FUNCTION. This makes new keymaps as necessary. The initial
+ place to do bindings is in MAP. */
+rl_set_key (keyseq, function, map)
+ char *keyseq;
+ Function *function;
+ Keymap map;
+{
+ rl_generic_bind (ISFUNC, keyseq, function, map);
+}
+
+/* Bind the key sequence represented by the string KEYSEQ to
+ the string of characters MACRO. This makes new keymaps as
+ necessary. The initial place to do bindings is in MAP. */
+rl_macro_bind (keyseq, macro, map)
+ char *keyseq, *macro;
+ Keymap map;
+{
+ char *macro_keys;
+ int macro_keys_len;
+
+ macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
+
+ if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
+ {
+ free (macro_keys);
+ return -1;
+ }
+ rl_generic_bind (ISMACR, keyseq, macro_keys, map);
+ return 0;
+}
+
+/* Bind the key sequence represented by the string KEYSEQ to
+ the arbitrary pointer DATA. TYPE says what kind of data is
+ pointed to by DATA, right now this can be a function (ISFUNC),
+ a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps
+ as necessary. The initial place to do bindings is in MAP. */
+rl_generic_bind (type, keyseq, data, map)
+ int type;
+ char *keyseq, *data;
+ Keymap map;
+{
+ char *keys;
+ int keys_len;
+ register int i;
+
+ /* If no keys to bind to, exit right away. */
+ if (!keyseq || !*keyseq)
+ {
+ if (type == ISMACR)
+ free (data);
+ return -1;
+ }
+
+ keys = xmalloc (1 + (2 * strlen (keyseq)));
+
+ /* Translate the ASCII representation of KEYSEQ into an array of
+ characters. Stuff the characters into KEYS, and the length of
+ KEYS into KEYS_LEN. */
+ if (rl_translate_keyseq (keyseq, keys, &keys_len))
+ {
+ free (keys);
+ return -1;
+ }
+
+ /* Bind keys, making new keymaps as necessary. */
+ for (i = 0; i < keys_len; i++)
+ {
+ int ic = (int) ((unsigned char)keys[i]);
+
+ if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))
+ {
+ ic = UNMETA (ic);
+ if (map[ESC].type == ISKMAP)
+ map = (Keymap) map[ESC].function;
+ }
+
+ if ((i + 1) < keys_len)
+ {
+ if (map[ic].type != ISKMAP)
+ {
+ if (map[ic].type == ISMACR)
+ free ((char *)map[ic].function);
+
+ map[ic].type = ISKMAP;
+ map[ic].function = (Function *)rl_make_bare_keymap ();
+ }
+ map = (Keymap)map[ic].function;
+ }
+ else
+ {
+ if (map[ic].type == ISMACR)
+ free ((char *)map[ic].function);
+
+ map[ic].function = (Function *)data;
+ map[ic].type = type;
+ }
+ }
+ free (keys);
+ return 0;
+}
+
+/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY,
+ an array of characters. LEN gets the final length of ARRAY. Return
+ non-zero if there was an error parsing SEQ. */
+rl_translate_keyseq (seq, array, len)
+ char *seq, *array;
+ int *len;
+{
+ register int i, c, l = 0;
+
+ for (i = 0; c = seq[i]; i++)
+ {
+ if (c == '\\')
+ {
+ c = seq[++i];
+
+ if (!c)
+ break;
+
+ if (((c == 'C' || c == 'M') && seq[i + 1] == '-') ||
+ (c == 'e'))
+ {
+ /* Handle special case of backwards define. */
+ if (strncmp (&seq[i], "C-\\M-", 5) == 0)
+ {
+ array[l++] = ESC;
+ i += 5;
+ array[l++] = CTRL (to_upper (seq[i]));
+ if (!seq[i])
+ i--;
+ continue;
+ }
+
+ switch (c)
+ {
+ case 'M':
+ i++;
+ array[l++] = ESC;
+ break;
+
+ case 'C':
+ i += 2;
+ /* Special hack for C-?... */
+ if (seq[i] == '?')
+ array[l++] = RUBOUT;
+ else
+ array[l++] = CTRL (to_upper (seq[i]));
+ break;
+
+ case 'e':
+ array[l++] = ESC;
+ }
+
+ continue;
+ }
+ }
+ array[l++] = c;
+ }
+
+ *len = l;
+ array[l] = '\0';
+ return (0);
+}
+
+/* Return a pointer to the function that STRING represents.
+ If STRING doesn't have a matching function, then a NULL pointer
+ is returned. */
+Function *
+rl_named_function (string)
+ char *string;
+{
+ register int i;
+
+ rl_initialize_funmap ();
+
+ for (i = 0; funmap[i]; i++)
+ if (stricmp (funmap[i]->name, string) == 0)
+ return (funmap[i]->function);
+ return ((Function *)NULL);
+}
+
+/* Return the function (or macro) definition which would be invoked via
+ KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is
+ used. TYPE, if non-NULL, is a pointer to an int which will receive the
+ type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap),
+ or ISMACR (macro). */
+Function *
+rl_function_of_keyseq (keyseq, map, type)
+ char *keyseq;
+ Keymap map;
+ int *type;
+{
+ register int i;
+
+ if (!map)
+ map = _rl_keymap;
+
+ for (i = 0; keyseq && keyseq[i]; i++)
+ {
+ int ic = keyseq[i];
+
+ if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
+ {
+ if (map[ESC].type != ISKMAP)
+ {
+ if (type)
+ *type = map[ESC].type;
+
+ return (map[ESC].function);
+ }
+ else
+ {
+ map = (Keymap)map[ESC].function;
+ ic = UNMETA (ic);
+ }
+ }
+
+ if (map[ic].type == ISKMAP)
+ {
+ /* If this is the last key in the key sequence, return the
+ map. */
+ if (!keyseq[i + 1])
+ {
+ if (type)
+ *type = ISKMAP;
+
+ return (map[ic].function);
+ }
+ else
+ map = (Keymap)map[ic].function;
+ }
+ else
+ {
+ if (type)
+ *type = map[ic].type;
+
+ return (map[ic].function);
+ }
+ }
+}
+
+/* The last key bindings file read. */
+static char *last_readline_init_file = (char *)NULL;
+
+/* Re-read the current keybindings file. */
+rl_re_read_init_file (count, ignore)
+ int count, ignore;
+{
+ return (rl_read_init_file ((char *)NULL));
+}
+
+/* The final, last-ditch effort file name for an init file. */
+#define DEFAULT_INPUTRC "~/.inputrc"
+
+/* Do key bindings from a file. If FILENAME is NULL it defaults
+ to `~/.inputrc'. If the file existed and could be opened and
+ read, 0 is returned, otherwise errno is returned. */
+int
+rl_read_init_file (filename)
+ char *filename;
+{
+ register int i;
+ char *buffer, *openname, *line, *end;
+ struct stat finfo;
+ int file;
+
+ /* Default the filename. */
+ if (!filename)
+ {
+ if (last_readline_init_file)
+ filename = last_readline_init_file;
+ else
+ filename = DEFAULT_INPUTRC;
+ }
+
+ openname = tilde_expand (filename);
+
+ if ((stat (openname, &finfo) < 0) ||
+ (file = open (openname, O_RDONLY, 0666)) < 0)
+ {
+ free (openname);
+ return (errno);
+ }
+ else
+ free (openname);
+
+ if (last_readline_init_file)
+ free (last_readline_init_file);
+
+ last_readline_init_file = savestring (filename);
+
+ /* Read the file into BUFFER. */
+ buffer = (char *)xmalloc ((int)finfo.st_size + 1);
+ i = read (file, buffer, finfo.st_size);
+ close (file);
+
+ if (i != finfo.st_size)
+ return (errno);
+
+ /* Loop over the lines in the file. Lines that start with `#' are
+ comments; all other lines are commands for readline initialization. */
+ line = buffer;
+ end = buffer + finfo.st_size;
+ while (line < end)
+ {
+ /* Find the end of this line. */
+ for (i = 0; line + i != end && line[i] != '\n'; i++);
+
+ /* Mark end of line. */
+ line[i] = '\0';
+
+ /* If the line is not a comment, then parse it. */
+ if (*line && *line != '#')
+ rl_parse_and_bind (line);
+
+ /* Move to the next line. */
+ line += i + 1;
+ }
+ free (buffer);
+ return (0);
+}
+
+/* **************************************************************** */
+/* */
+/* Parser Directives */
+/* */
+/* **************************************************************** */
+
+/* Conditionals. */
+
+/* Calling programs set this to have their argv[0]. */
+char *rl_readline_name = "other";
+
+/* Stack of previous values of parsing_conditionalized_out. */
+static unsigned char *if_stack = (unsigned char *)NULL;
+static int if_stack_depth = 0;
+static int if_stack_size = 0;
+
+/* Push _rl_parsing_conditionalized_out, and set parser state based
+ on ARGS. */
+static int
+parser_if (args)
+ char *args;
+{
+ register int i;
+
+ /* Push parser state. */
+ if (if_stack_depth + 1 >= if_stack_size)
+ {
+ if (!if_stack)
+ if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
+ else
+ if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
+ }
+ if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out;
+
+ /* If parsing is turned off, then nothing can turn it back on except
+ for finding the matching endif. In that case, return right now. */
+ if (_rl_parsing_conditionalized_out)
+ return 0;
+
+ /* Isolate first argument. */
+ for (i = 0; args[i] && !whitespace (args[i]); i++);
+
+ if (args[i])
+ args[i++] = '\0';
+
+ /* Handle "if term=foo" and "if mode=emacs" constructs. If this
+ isn't term=foo, or mode=emacs, then check to see if the first
+ word in ARGS is the same as the value stored in rl_readline_name. */
+ if (rl_terminal_name && strnicmp (args, "term=", 5) == 0)
+ {
+ char *tem, *tname;
+
+ /* Terminals like "aaa-60" are equivalent to "aaa". */
+ tname = savestring (rl_terminal_name);
+ tem = strrchr (tname, '-');
+ if (tem)
+ *tem = '\0';
+
+ /* Test the `long' and `short' forms of the terminal name so that
+ if someone has a `sun-cmd' and does not want to have bindings
+ that will be executed if the terminal is a `sun', they can put
+ `$if term=sun-cmd' into their .inputrc. */
+ if ((stricmp (args + 5, tname) == 0) ||
+ (stricmp (args + 5, rl_terminal_name) == 0))
+ _rl_parsing_conditionalized_out = 0;
+ else
+ _rl_parsing_conditionalized_out = 1;
+
+ free (tname);
+ }
+#if defined (VI_MODE)
+ else if (strnicmp (args, "mode=", 5) == 0)
+ {
+ int mode;
+
+ if (stricmp (args + 5, "emacs") == 0)
+ mode = emacs_mode;
+ else if (stricmp (args + 5, "vi") == 0)
+ mode = vi_mode;
+ else
+ mode = no_mode;
+
+ if (mode == rl_editing_mode)
+ _rl_parsing_conditionalized_out = 0;
+ else
+ _rl_parsing_conditionalized_out = 1;
+ }
+#endif /* VI_MODE */
+ /* Check to see if the first word in ARGS is the same as the
+ value stored in rl_readline_name. */
+ else if (stricmp (args, rl_readline_name) == 0)
+ _rl_parsing_conditionalized_out = 0;
+ else
+ _rl_parsing_conditionalized_out = 1;
+ return 0;
+}
+
+/* Invert the current parser state if there is anything on the stack. */
+static int
+parser_else (args)
+ char *args;
+{
+ register int i;
+
+ if (!if_stack_depth)
+ {
+ /* Error message? */
+ return 0;
+ }
+
+ /* Check the previous (n - 1) levels of the stack to make sure that
+ we haven't previously turned off parsing. */
+ for (i = 0; i < if_stack_depth - 1; i++)
+ if (if_stack[i] == 1)
+ return 0;
+
+ /* Invert the state of parsing if at top level. */
+ _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out;
+ return 0;
+}
+
+/* Terminate a conditional, popping the value of
+ _rl_parsing_conditionalized_out from the stack. */
+static int
+parser_endif (args)
+ char *args;
+{
+ if (if_stack_depth)
+ _rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
+ else
+ {
+ /* *** What, no error message? *** */
+ }
+ return 0;
+}
+
+/* Associate textual names with actual functions. */
+static struct {
+ char *name;
+ Function *function;
+} parser_directives [] = {
+ { "if", parser_if },
+ { "endif", parser_endif },
+ { "else", parser_else },
+ { (char *)0x0, (Function *)0x0 }
+};
+
+/* Handle a parser directive. STATEMENT is the line of the directive
+ without any leading `$'. */
+static int
+handle_parser_directive (statement)
+ char *statement;
+{
+ register int i;
+ char *directive, *args;
+
+ /* Isolate the actual directive. */
+
+ /* Skip whitespace. */
+ for (i = 0; whitespace (statement[i]); i++);
+
+ directive = &statement[i];
+
+ for (; statement[i] && !whitespace (statement[i]); i++);
+
+ if (statement[i])
+ statement[i++] = '\0';
+
+ for (; statement[i] && whitespace (statement[i]); i++);
+
+ args = &statement[i];
+
+ /* Lookup the command, and act on it. */
+ for (i = 0; parser_directives[i].name; i++)
+ if (stricmp (directive, parser_directives[i].name) == 0)
+ {
+ (*parser_directives[i].function) (args);
+ return (0);
+ }
+
+ /* *** Should an error message be output? */
+ return (1);
+}
+
+/* Ugly but working hack for binding prefix meta. */
+#define PREFIX_META_HACK
+
+static int substring_member_of_array ();
+
+/* Read the binding command from STRING and perform it.
+ A key binding command looks like: Keyname: function-name\0,
+ a variable binding command looks like: set variable value.
+ A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
+rl_parse_and_bind (string)
+ char *string;
+{
+ char *funname, *kname;
+ register int c, i;
+ int key, equivalency;
+
+ while (string && whitespace (*string))
+ string++;
+
+ if (!string || !*string || *string == '#')
+ return 0;
+
+ /* If this is a parser directive, act on it. */
+ if (*string == '$')
+ {
+ handle_parser_directive (&string[1]);
+ return 0;
+ }
+
+ /* If we aren't supposed to be parsing right now, then we're done. */
+ if (_rl_parsing_conditionalized_out)
+ return 0;
+
+ i = 0;
+ /* If this keyname is a complex key expression surrounded by quotes,
+ advance to after the matching close quote. This code allows the
+ backslash to quote characters in the key expression. */
+ if (*string == '"')
+ {
+ int passc = 0;
+
+ for (i = 1; c = string[i]; i++)
+ {
+ if (passc)
+ {
+ passc = 0;
+ continue;
+ }
+
+ if (c == '\\')
+ {
+ passc++;
+ continue;
+ }
+
+ if (c == '"')
+ break;
+ }
+ }
+
+ /* Advance to the colon (:) or whitespace which separates the two objects. */
+ for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
+
+ equivalency = (c == ':' && string[i + 1] == '=');
+
+ /* Mark the end of the command (or keyname). */
+ if (string[i])
+ string[i++] = '\0';
+
+ /* If doing assignment, skip the '=' sign as well. */
+ if (equivalency)
+ string[i++] = '\0';
+
+ /* If this is a command to set a variable, then do that. */
+ if (stricmp (string, "set") == 0)
+ {
+ char *var = string + i;
+ char *value;
+
+ /* Make VAR point to start of variable name. */
+ while (*var && whitespace (*var)) var++;
+
+ /* Make value point to start of value string. */
+ value = var;
+ while (*value && !whitespace (*value)) value++;
+ if (*value)
+ *value++ = '\0';
+ while (*value && whitespace (*value)) value++;
+
+ rl_variable_bind (var, value);
+ return 0;
+ }
+
+ /* Skip any whitespace between keyname and funname. */
+ for (; string[i] && whitespace (string[i]); i++);
+ funname = &string[i];
+
+ /* Now isolate funname.
+ For straight function names just look for whitespace, since
+ that will signify the end of the string. But this could be a
+ macro definition. In that case, the string is quoted, so skip
+ to the matching delimiter. We allow the backslash to quote the
+ delimiter characters in the macro body. */
+ /* This code exists to allow whitespace in macro expansions, which
+ would otherwise be gobbled up by the next `for' loop.*/
+ /* XXX - it may be desirable to allow backslash quoting only if " is
+ the quoted string delimiter, like the shell. */
+ if (*funname == '\'' || *funname == '"')
+ {
+ int delimiter = string[i++];
+ int passc = 0;
+
+ for (; c = string[i]; i++)
+ {
+ if (passc)
+ {
+ passc = 0;
+ continue;
+ }
+
+ if (c == '\\')
+ {
+ passc = 1;
+ continue;
+ }
+
+ if (c == delimiter)
+ break;
+ }
+ if (c)
+ i++;
+ }
+
+ /* Advance to the end of the string. */
+ for (; string[i] && !whitespace (string[i]); i++);
+
+ /* No extra whitespace at the end of the string. */
+ string[i] = '\0';
+
+ /* Handle equivalency bindings here. Make the left-hand side be exactly
+ whatever the right-hand evaluates to, including keymaps. */
+ if (equivalency)
+ {
+ return 0;
+ }
+
+ /* If this is a new-style key-binding, then do the binding with
+ rl_set_key (). Otherwise, let the older code deal with it. */
+ if (*string == '"')
+ {
+ char *seq = xmalloc (1 + strlen (string));
+ register int j, k = 0;
+ int passc = 0;
+
+ for (j = 1; string[j]; j++)
+ {
+ /* Allow backslash to quote characters, but leave them in place.
+ This allows a string to end with a backslash quoting another
+ backslash, or with a backslash quoting a double quote. The
+ backslashes are left in place for rl_translate_keyseq (). */
+ if (passc || (string[j] == '\\'))
+ {
+ seq[k++] = string[j];
+ passc = !passc;
+ continue;
+ }
+
+ if (string[j] == '"')
+ break;
+
+ seq[k++] = string[j];
+ }
+ seq[k] = '\0';
+
+ /* Binding macro? */
+ if (*funname == '\'' || *funname == '"')
+ {
+ j = strlen (funname);
+
+ /* Remove the delimiting quotes from each end of FUNNAME. */
+ if (j && funname[j - 1] == *funname)
+ funname[j - 1] = '\0';
+
+ rl_macro_bind (seq, &funname[1], _rl_keymap);
+ }
+ else
+ rl_set_key (seq, rl_named_function (funname), _rl_keymap);
+
+ free (seq);
+ return 0;
+ }
+
+ /* Get the actual character we want to deal with. */
+ kname = strrchr (string, '-');
+ if (!kname)
+ kname = string;
+ else
+ kname++;
+
+ key = glean_key_from_name (kname);
+
+ /* Add in control and meta bits. */
+ if (substring_member_of_array (string, possible_control_prefixes))
+ key = CTRL (to_upper (key));
+
+ if (substring_member_of_array (string, possible_meta_prefixes))
+ key = META (key);
+
+ /* Temporary. Handle old-style keyname with macro-binding. */
+ if (*funname == '\'' || *funname == '"')
+ {
+ char seq[2];
+ int fl = strlen (funname);
+
+ seq[0] = key; seq[1] = '\0';
+ if (fl && funname[fl - 1] == *funname)
+ funname[fl - 1] = '\0';
+
+ rl_macro_bind (seq, &funname[1], _rl_keymap);
+ }
+#if defined (PREFIX_META_HACK)
+ /* Ugly, but working hack to keep prefix-meta around. */
+ else if (stricmp (funname, "prefix-meta") == 0)
+ {
+ char seq[2];
+
+ seq[0] = key;
+ seq[1] = '\0';
+ rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap);
+ }
+#endif /* PREFIX_META_HACK */
+ else
+ rl_bind_key (key, rl_named_function (funname));
+ return 0;
+}
+
+/* Simple structure for boolean readline variables (i.e., those that can
+ have one of two values; either "On" or 1 for truth, or "Off" or 0 for
+ false. */
+
+static struct {
+ char *name;
+ int *value;
+} boolean_varlist [] = {
+ { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode },
+ { "mark-modified-lines", &_rl_mark_modified_lines },
+ { "prefer-visible-bell", &_rl_prefer_visible_bell },
+ { "meta-flag", &_rl_meta_flag },
+ { "blink-matching-paren", &rl_blink_matching_paren },
+ { "convert-meta", &_rl_convert_meta_chars_to_ascii },
+#if defined (VISIBLE_STATS)
+ { "visible-stats", &rl_visible_stats },
+#endif /* VISIBLE_STATS */
+ { "expand-tilde", &rl_complete_with_tilde_expansion },
+ { (char *)NULL, (int *)NULL }
+};
+
+rl_variable_bind (name, value)
+ char *name, *value;
+{
+ register int i;
+
+ /* Check for simple variables first. */
+ for (i = 0; boolean_varlist[i].name; i++)
+ {
+ if (stricmp (name, boolean_varlist[i].name) == 0)
+ {
+ /* A variable is TRUE if the "value" is "on", "1" or "". */
+ if ((!*value) ||
+ (stricmp (value, "On") == 0) ||
+ (value[0] == '1' && value[1] == '\0'))
+ *boolean_varlist[i].value = 1;
+ else
+ *boolean_varlist[i].value = 0;
+ return 0;
+ }
+ }
+
+ /* Not a boolean variable, so check for specials. */
+
+ /* Editing mode change? */
+ if (stricmp (name, "editing-mode") == 0)
+ {
+ if (strnicmp (value, "vi", 2) == 0)
+ {
+#if defined (VI_MODE)
+ _rl_keymap = vi_insertion_keymap;
+ rl_editing_mode = vi_mode;
+#else
+#if defined (NOTDEF)
+ ding ();
+#endif /* NOTDEF */
+#endif /* VI_MODE */
+ }
+ else if (strnicmp (value, "emacs", 5) == 0)
+ {
+ _rl_keymap = emacs_standard_keymap;
+ rl_editing_mode = emacs_mode;
+ }
+ }
+
+ /* Comment string change? */
+ else if (stricmp (name, "comment-begin") == 0)
+ {
+#if defined (VI_MODE)
+ extern char *rl_vi_comment_begin;
+
+ if (*value)
+ {
+ if (rl_vi_comment_begin)
+ free (rl_vi_comment_begin);
+
+ rl_vi_comment_begin = savestring (value);
+ }
+#endif /* VI_MODE */
+ }
+ else if (stricmp (name, "completion-query-items") == 0)
+ {
+ int nval = 100;
+ if (*value)
+ {
+ nval = atoi (value);
+ if (nval < 0)
+ nval = 0;
+ }
+ rl_completion_query_items = nval;
+ }
+ return 0;
+}
+
+/* Return the character which matches NAME.
+ For example, `Space' returns ' '. */
+
+typedef struct {
+ char *name;
+ int value;
+} assoc_list;
+
+static assoc_list name_key_alist[] = {
+ { "DEL", 0x7f },
+ { "ESC", '\033' },
+ { "Escape", '\033' },
+ { "LFD", '\n' },
+ { "Newline", '\n' },
+ { "RET", '\r' },
+ { "Return", '\r' },
+ { "Rubout", 0x7f },
+ { "SPC", ' ' },
+ { "Space", ' ' },
+ { "Tab", 0x09 },
+ { (char *)0x0, 0 }
+};
+
+static int
+glean_key_from_name (name)
+ char *name;
+{
+ register int i;
+
+ for (i = 0; name_key_alist[i].name; i++)
+ if (stricmp (name, name_key_alist[i].name) == 0)
+ return (name_key_alist[i].value);
+
+ return (*(unsigned char *)name); /* XXX was return (*name) */
+}
+
+/* Auxiliary functions to manage keymaps. */
+static struct {
+ char *name;
+ Keymap map;
+} keymap_names[] = {
+ { "emacs", emacs_standard_keymap },
+ { "emacs-standard", emacs_standard_keymap },
+ { "emacs-meta", emacs_meta_keymap },
+ { "emacs-ctlx", emacs_ctlx_keymap },
+#if defined (VI_MODE)
+ { "vi", vi_movement_keymap },
+ { "vi-move", vi_movement_keymap },
+ { "vi-command", vi_movement_keymap },
+ { "vi-insert", vi_insertion_keymap },
+#endif /* VI_MODE */
+ { (char *)0x0, (Keymap)0x0 }
+};
+
+Keymap
+rl_get_keymap_by_name (name)
+ char *name;
+{
+ register int i;
+
+ for (i = 0; keymap_names[i].name; i++)
+ if (strcmp (name, keymap_names[i].name) == 0)
+ return (keymap_names[i].map);
+ return ((Keymap) NULL);
+}
+
+void
+rl_set_keymap (map)
+ Keymap map;
+{
+ if (map)
+ _rl_keymap = map;
+}
+
+Keymap
+rl_get_keymap ()
+{
+ return (_rl_keymap);
+}
+
+void
+rl_set_keymap_from_edit_mode ()
+{
+ if (rl_editing_mode == emacs_mode)
+ _rl_keymap = emacs_standard_keymap;
+#if defined (VI_MODE)
+ else if (rl_editing_mode == vi_mode)
+ _rl_keymap = vi_insertion_keymap;
+#endif /* VI_MODE */
+}
+
+/* **************************************************************** */
+/* */
+/* Key Binding and Function Information */
+/* */
+/* **************************************************************** */
+
+/* Each of the following functions produces information about the
+ state of keybindings and functions known to Readline. The info
+ is always printed to rl_outstream, and in such a way that it can
+ be read back in (i.e., passed to rl_parse_and_bind (). */
+
+/* Print the names of functions known to Readline. */
+void
+rl_list_funmap_names (ignore)
+ int ignore;
+{
+ register int i;
+ char **funmap_names;
+
+ funmap_names = rl_funmap_names ();
+
+ if (!funmap_names)
+ return;
+
+ for (i = 0; funmap_names[i]; i++)
+ fprintf (rl_outstream, "%s\n", funmap_names[i]);
+
+ free (funmap_names);
+}
+
+/* Return a NULL terminated array of strings which represent the key
+ sequences that are used to invoke FUNCTION in MAP. */
+static char **
+invoking_keyseqs_in_map (function, map)
+ Function *function;
+ Keymap map;
+{
+ register int key;
+ char **result;
+ int result_index, result_size;
+
+ result = (char **)NULL;
+ result_index = result_size = 0;
+
+ for (key = 0; key < 128; key++)
+ {
+ switch (map[key].type)
+ {
+ case ISMACR:
+ /* Macros match, if, and only if, the pointers are identical.
+ Thus, they are treated exactly like functions in here. */
+ case ISFUNC:
+ /* If the function in the keymap is the one we are looking for,
+ then add the current KEY to the list of invoking keys. */
+ if (map[key].function == function)
+ {
+ char *keyname = (char *)xmalloc (5);
+
+ if (CTRL_P (key))
+ sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key)));
+ else if (key == RUBOUT)
+ sprintf (keyname, "\\C-?");
+ else if (key == '\\' || key == '"')
+ {
+ keyname[0] = '\\';
+ keyname[1] = (char) key;
+ keyname[2] = '\0';
+ }
+ else
+ {
+ keyname[0] = (char) key;
+ keyname[1] = '\0';
+ }
+
+ if (result_index + 2 > result_size)
+ result = (char **) xrealloc
+ (result, (result_size += 10) * sizeof (char *));
+
+ result[result_index++] = keyname;
+ result[result_index] = (char *)NULL;
+ }
+ break;
+
+ case ISKMAP:
+ {
+ char **seqs = (char **)NULL;
+
+ /* Find the list of keyseqs in this map which have FUNCTION as
+ their target. Add the key sequences found to RESULT. */
+ if (map[key].function)
+ seqs =
+#if defined (CRAY)
+ invoking_keyseqs_in_map (function, (Keymap)((int)map[key].function));
+#else
+ invoking_keyseqs_in_map (function, (Keymap)map[key].function);
+#endif
+
+ if (seqs)
+ {
+ register int i;
+
+ for (i = 0; seqs[i]; i++)
+ {
+ char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
+
+ if (key == ESC)
+ sprintf (keyname, "\\e");
+ else if (CTRL_P (key))
+ sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key)));
+ else if (key == RUBOUT)
+ sprintf (keyname, "\\C-?");
+ else if (key == '\\' || key == '"')
+ {
+ keyname[0] = '\\';
+ keyname[1] = (char) key;
+ keyname[2] = '\0';
+ }
+ else
+ {
+ keyname[0] = (char) key;
+ keyname[1] = '\0';
+ }
+
+ strcat (keyname, seqs[i]);
+ free (seqs[i]);
+
+ if (result_index + 2 > result_size)
+ result = (char **) xrealloc
+ (result, (result_size += 10) * sizeof (char *));
+
+ result[result_index++] = keyname;
+ result[result_index] = (char *)NULL;
+ }
+
+ free (seqs);
+ }
+ }
+ break;
+ }
+ }
+ return (result);
+}
+
+/* Return a NULL terminated array of strings which represent the key
+ sequences that can be used to invoke FUNCTION using the current keymap. */
+char **
+rl_invoking_keyseqs (function)
+ Function *function;
+{
+ return (invoking_keyseqs_in_map (function, _rl_keymap));
+}
+
+/* Print all of the current functions and their bindings to
+ rl_outstream. If an explicit argument is given, then print
+ the output in such a way that it can be read back in. */
+int
+rl_dump_functions (count)
+ int count;
+{
+ void rl_function_dumper ();
+
+ rl_function_dumper (rl_explicit_arg);
+ rl_on_new_line ();
+ return (0);
+}
+
+/* Print all of the functions and their bindings to rl_outstream. If
+ PRINT_READABLY is non-zero, then print the output in such a way
+ that it can be read back in. */
+void
+rl_function_dumper (print_readably)
+ int print_readably;
+{
+ register int i;
+ char **names;
+ char *name;
+
+ names = rl_funmap_names ();
+
+ fprintf (rl_outstream, "\n");
+
+ for (i = 0; name = names[i]; i++)
+ {
+ Function *function;
+ char **invokers;
+
+ function = rl_named_function (name);
+ invokers = invoking_keyseqs_in_map (function, _rl_keymap);
+
+ if (print_readably)
+ {
+ if (!invokers)
+ fprintf (rl_outstream, "# %s (not bound)\n", name);
+ else
+ {
+ register int j;
+
+ for (j = 0; invokers[j]; j++)
+ {
+ fprintf (rl_outstream, "\"%s\": %s\n",
+ invokers[j], name);
+ free (invokers[j]);
+ }
+
+ free (invokers);
+ }
+ }
+ else
+ {
+ if (!invokers)
+ fprintf (rl_outstream, "%s is not bound to any keys\n",
+ name);
+ else
+ {
+ register int j;
+
+ fprintf (rl_outstream, "%s can be found on ", name);
+
+ for (j = 0; invokers[j] && j < 5; j++)
+ {
+ fprintf (rl_outstream, "\"%s\"%s", invokers[j],
+ invokers[j + 1] ? ", " : ".\n");
+ }
+
+ if (j == 5 && invokers[j])
+ fprintf (rl_outstream, "...\n");
+
+ for (j = 0; invokers[j]; j++)
+ free (invokers[j]);
+
+ free (invokers);
+ }
+ }
+ }
+}
+
+
+/* **************************************************************** */
+/* */
+/* String Utility Functions */
+/* */
+/* **************************************************************** */
+
+static char *strindex ();
+
+/* Return non-zero if any members of ARRAY are a substring in STRING. */
+static int
+substring_member_of_array (string, array)
+ char *string, **array;
+{
+ while (*array)
+ {
+ if (strindex (string, *array))
+ return (1);
+ array++;
+ }
+ return (0);
+}
+
+/* Determine if s2 occurs in s1. If so, return a pointer to the
+ match in s1. The compare is case insensitive. */
+static char *
+strindex (s1, s2)
+ register char *s1, *s2;
+{
+ register int i, l = strlen (s2);
+ register int len = strlen (s1);
+
+ for (i = 0; (len - i) >= l; i++)
+ if (strnicmp (&s1[i], s2, l) == 0)
+ return (s1 + i);
+ return ((char *)NULL);
+}
diff --git a/gnu/lib/libreadline/complete.c b/gnu/lib/libreadline/complete.c
new file mode 100644
index 0000000..e5dba8d
--- /dev/null
+++ b/gnu/lib/libreadline/complete.c
@@ -0,0 +1,1326 @@
+/* complete.c -- filename completion for readline. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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 1, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if !defined (NO_SYS_FILE)
+# include <sys/file.h>
+#endif /* !NO_SYS_FILE */
+
+#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 */
+
+#include <errno.h>
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+/* These next are for filename completion. Perhaps this belongs
+ in a different place. */
+#include <pwd.h>
+#if defined (USG) && !defined (isc386) && !defined (sgi)
+extern struct passwd *getpwuid (), *getpwent ();
+#endif
+#if defined (isc386) && !defined (__STDC__) && defined (_POSIX_SOURCE)
+extern struct passwd *getpwent ();
+#endif
+
+/* #define HACK_TERMCAP_MOTION */
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+
+/* Possible values for do_replace in rl_complete_internal. */
+#define NO_MATCH 0
+#define SINGLE_MATCH 1
+#define MULT_MATCH 2
+
+#if !defined (strchr) && !defined (__STDC__)
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+extern char *tilde_expand ();
+extern char *rl_copy_text ();
+
+extern Function *rl_last_func;
+extern int rl_editing_mode;
+extern int screenwidth;
+
+/* Forward declarations for functions defined and used in this file. */
+char *filename_completion_function ();
+char **completion_matches ();
+
+static int compare_strings ();
+static char *rl_strpbrk ();
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+/* 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. */
+Function *rl_symbolic_link_hook = (Function *)NULL;
+
+/* Non-zero means readline completion functions perform tilde expansion. */
+int rl_complete_with_tilde_expansion = 0;
+
+#define VISIBLE_STATS
+
+#if defined (VISIBLE_STATS)
+# if !defined (X_OK)
+# define X_OK 1
+# endif
+
+static int stat_char ();
+
+/* Non-zero means add an additional character to each filename displayed
+ during listing completion iff rl_filename_completion_desired which helps
+ to indicate the type of file being listed. */
+int rl_visible_stats = 0;
+#endif /* VISIBLE_STATS */
+
+/* **************************************************************** */
+/* */
+/* Completion matching, from readline's point of view. */
+/* */
+/* **************************************************************** */
+
+/* Pointer to the generator function for completion_matches ().
+ NULL means to use filename_entry_function (), the default filename
+ completer. */
+Function *rl_completion_entry_function = (Function *)NULL;
+
+/* 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. */
+CPPFunction *rl_attempted_completion_function = (CPPFunction *)NULL;
+
+/* Local variable states what happened during the last completion attempt. */
+static int completion_changed_buffer = 0;
+
+/* Complete the word at or before point. You have supplied the function
+ that does the initial simple matching selection algorithm (see
+ completion_matches ()). The default is to do filename completion. */
+
+rl_complete (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ if (rl_last_func == rl_complete && !completion_changed_buffer)
+ rl_complete_internal ('?');
+ else
+ rl_complete_internal (TAB);
+}
+
+/* List the possible completions. See description of rl_complete (). */
+rl_possible_completions (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ rl_complete_internal ('?');
+}
+
+rl_insert_completions (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ rl_complete_internal ('*');
+}
+
+/* The user must press "y" or "n". Non-zero return means "y" pressed. */
+get_y_or_n ()
+{
+ int c;
+
+ for (;;)
+ {
+ c = rl_read_key ();
+ if (c == 'y' || c == 'Y')
+ return (1);
+ if (c == 'n' || c == 'N')
+ return (0);
+ if (c == ABORT_CHAR)
+ rl_abort ();
+ ding ();
+ }
+}
+
+/* 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. */
+int rl_completion_query_items = 100;
+
+/* The basic list of characters that signal a break between words for the
+ completer routine. The contents of this variable is what breaks words
+ in the shell, i.e. " \t\n\"\\'`@$><=" */
+char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
+
+/* 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. */
+char *rl_completer_word_break_characters = (char *)NULL;
+
+/* 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. */
+char *rl_completer_quote_characters = (char *)NULL;
+
+/* 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. */
+char *rl_special_prefixes = (char *)NULL;
+
+/* If non-zero, then disallow duplicates in the matches. */
+int rl_ignore_completion_duplicates = 1;
+
+/* 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. */
+int rl_filename_completion_desired = 0;
+
+/* This function, if defined, is called by the completer when real
+ filename completion is done, after all the matching names have been
+ generated. It is passed a (char**) known as matches in the code below.
+ It consists of a NULL-terminated array of pointers to potential
+ matching strings. The 1st element (matches[0]) is the maximal
+ substring that is common to all matches. This function can re-arrange
+ the list of matches as required, but all elements of the array must be
+ free()'d if they are deleted. The main intent of this function is
+ to implement FIGNORE a la SunOS csh. */
+Function *rl_ignore_some_completions_function = (Function *)NULL;
+
+#if defined (SHELL)
+/* A function to strip quotes that are not protected by backquotes. It
+ allows single quotes to appear within double quotes, and vice versa.
+ It should be smarter. It's fairly shell-specific, hence the SHELL
+ definition wrapper. */
+static char *
+_delete_quotes (text)
+ char *text;
+{
+ char *ret, *p, *r;
+ int l, quoted;
+
+ l = strlen (text);
+ ret = xmalloc (l + 1);
+ for (quoted = 0, p = text, r = ret; p && *p; p++)
+ {
+ /* Allow backslash-quoted characters to pass through unscathed. */
+ if (*p == '\\')
+ continue;
+ /* Close quote. */
+ if (quoted && *p == quoted)
+ {
+ quoted = 0;
+ continue;
+ }
+ /* Open quote. */
+ if (quoted == 0 && (*p == '\'' || *p == '"'))
+ {
+ quoted = *p;
+ continue;
+ }
+ *r++ = *p;
+ }
+ *r = '\0';
+ return ret;
+}
+#endif /* SHELL */
+
+/* Complete the word at or before point.
+ WHAT_TO_DO says what to do with the completion.
+ `?' means list the possible completions.
+ TAB means do standard completion.
+ `*' means insert all of the possible completions. */
+rl_complete_internal (what_to_do)
+ int what_to_do;
+{
+ char **matches;
+ Function *our_func;
+ int start, scan, end, delimiter = 0, pass_next;
+ char *text, *saved_line_buffer;
+ char *replacement;
+#if defined (SHELL)
+ int found_quote = 0;
+#endif
+ char quote_char = '\0';
+
+ if (rl_line_buffer)
+ saved_line_buffer = savestring (rl_line_buffer);
+ else
+ saved_line_buffer = (char *)NULL;
+
+ if (rl_completion_entry_function)
+ our_func = rl_completion_entry_function;
+ else
+ our_func = (Function *)filename_completion_function;
+
+ /* Only the completion entry function can change this. */
+ rl_filename_completion_desired = 0;
+
+ /* We now look backwards for the start of a filename/variable word. */
+ end = rl_point;
+
+ if (rl_point)
+ {
+ if (rl_completer_quote_characters)
+ {
+ /* We have a list of characters which can be used in pairs to
+ quote substrings for the completer. Try to find the start
+ of an unclosed quoted substring. */
+ /* FOUND_QUOTE is set so we know what kind of quotes we found. */
+ for (scan = pass_next = 0; scan < end; scan++)
+ {
+ if (pass_next)
+ {
+ pass_next = 0;
+ continue;
+ }
+
+ if (rl_line_buffer[scan] == '\\')
+ {
+ pass_next = 1;
+ continue;
+ }
+
+ if (quote_char != '\0')
+ {
+ /* Ignore everything until the matching close quote char. */
+ if (rl_line_buffer[scan] == quote_char)
+ {
+ /* Found matching close. Abandon this substring. */
+ quote_char = '\0';
+ rl_point = end;
+ }
+ }
+ else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
+ {
+ /* Found start of a quoted substring. */
+ quote_char = rl_line_buffer[scan];
+ rl_point = scan + 1;
+#if defined (SHELL)
+ if (quote_char == '\'')
+ found_quote |= 1;
+ else if (quote_char == '"')
+ found_quote |= 2;
+#endif
+ }
+ }
+ }
+
+ if (rl_point == end)
+ {
+ int quoted = 0;
+ /* We didn't find an unclosed quoted substring up which to do
+ completion, so use the word break characters to find the
+ substring on which to complete. */
+ while (--rl_point)
+ {
+#if defined (SHELL)
+ /* Don't let word break characters in quoted substrings break
+ words for the completer. */
+ if (found_quote)
+ {
+ if (strchr (rl_completer_quote_characters, rl_line_buffer[rl_point]))
+ {
+ quoted = !quoted;
+ continue;
+ }
+ if (quoted)
+ continue;
+ }
+#endif /* SHELL */
+ if (strchr (rl_completer_word_break_characters, rl_line_buffer[rl_point]))
+ break;
+ }
+ }
+
+ /* If we are at a word break, then advance past it. */
+ if (strchr (rl_completer_word_break_characters, rl_line_buffer[rl_point]))
+ {
+ /* If the character that caused the word break was a quoting
+ character, then remember it as the delimiter. */
+ if (strchr ("\"'", rl_line_buffer[rl_point]) && (end - rl_point) > 1)
+ delimiter = rl_line_buffer[rl_point];
+
+ /* If the character isn't needed to determine something special
+ about what kind of completion to perform, then advance past it. */
+ if (!rl_special_prefixes ||
+ !strchr (rl_special_prefixes, rl_line_buffer[rl_point]))
+ rl_point++;
+ }
+ }
+
+ /* At this point, we know we have an open quote if quote_char != '\0'. */
+ start = rl_point;
+ rl_point = end;
+ text = rl_copy_text (start, end);
+
+ /* If the user wants to TRY to complete, but then wants to give
+ up and use the default completion function, they set the
+ variable rl_attempted_completion_function. */
+ if (rl_attempted_completion_function)
+ {
+ matches = (*rl_attempted_completion_function) (text, start, end);
+
+ if (matches)
+ {
+ /* XXX - This is questionable code. - XXX */
+ if (matches == (char **)-1)
+ matches = (char **)NULL;
+ our_func = (Function *)NULL;
+ goto after_usual_completion;
+ }
+ }
+
+#if defined (SHELL)
+ /* Beware -- we're stripping the quotes here. Do this only if we know
+ we are doing filename completion. */
+ if (found_quote && our_func == (Function *)filename_completion_function)
+ {
+ /* delete single and double quotes */
+ replacement = _delete_quotes (text);
+ free (text);
+ text = replacement;
+ replacement = (char *)0;
+ }
+#endif /* SHELL */
+
+ matches = completion_matches (text, our_func);
+
+ after_usual_completion:
+ free (text);
+
+ if (!matches)
+ ding ();
+ else
+ {
+ register int i;
+
+ /* It seems to me that in all the cases we handle we would like
+ to ignore duplicate possiblilities. Scan for the text to
+ insert being identical to the other completions. */
+ if (rl_ignore_completion_duplicates)
+ {
+ char *lowest_common;
+ int j, newlen = 0;
+ char dead_slot;
+
+ /* Sort the items. */
+ /* It is safe to sort this array, because the lowest common
+ denominator found in matches[0] will remain in place. */
+ for (i = 0; matches[i]; i++);
+ qsort (matches, i, sizeof (char *), compare_strings);
+
+ /* Remember the lowest common denominator for it may be unique. */
+ lowest_common = savestring (matches[0]);
+
+ for (i = 0; matches[i + 1]; i++)
+ {
+ if (strcmp (matches[i], matches[i + 1]) == 0)
+ {
+ free (matches[i]);
+ matches[i] = (char *)&dead_slot;
+ }
+ else
+ newlen++;
+ }
+
+ /* We have marked all the dead slots with (char *)&dead_slot.
+ Copy all the non-dead entries into a new array. */
+ {
+ char **temp_array =
+ (char **)xmalloc ((3 + newlen) * sizeof (char *));
+
+ for (i = 1, j = 1; matches[i]; i++)
+ {
+ if (matches[i] != (char *)&dead_slot)
+ temp_array[j++] = matches[i];
+ }
+
+ temp_array[j] = (char *)NULL;
+
+ if (matches[0] != (char *)&dead_slot)
+ free (matches[0]);
+
+ free (matches);
+
+ matches = temp_array;
+ }
+
+ /* Place the lowest common denominator back in [0]. */
+ matches[0] = lowest_common;
+
+ /* If there is one string left, and it is identical to the
+ lowest common denominator, then the LCD is the string to
+ insert. */
+ if (j == 2 && strcmp (matches[0], matches[1]) == 0)
+ {
+ free (matches[1]);
+ matches[1] = (char *)NULL;
+ }
+ }
+
+ switch (what_to_do)
+ {
+ case TAB:
+ /* If we are matching filenames, then here is our chance to
+ do clever processing by re-examining the list. Call the
+ ignore function with the array as a parameter. It can
+ munge the array, deleting matches as it desires. */
+ if (rl_ignore_some_completions_function &&
+ our_func == (Function *)filename_completion_function)
+ (void)(*rl_ignore_some_completions_function)(matches);
+
+ /* If we are doing completion on quoted substrings, and any matches
+ contain any of the completer_word_break_characters, then auto-
+ matically prepend the substring with a quote character (just pick
+ the first one from the list of such) if it does not already begin
+ with a quote string. FIXME: Need to remove any such automatically
+ inserted quote character when it no longer is necessary, such as
+ if we change the string we are completing on and the new set of
+ matches don't require a quoted substring. */
+ replacement = matches[0];
+
+ if (matches[0] && rl_completer_quote_characters && !quote_char &&
+ rl_filename_completion_desired)
+ {
+ int do_replace;
+
+ do_replace = NO_MATCH;
+
+ /* If there is a single match, see if we need to quote it.
+ This also checks whether the common prefix of several
+ matches needs to be quoted. If the common prefix should
+ not be checked, add !matches[1] to the if clause. */
+ if (rl_strpbrk (matches[0], rl_completer_word_break_characters))
+ do_replace = matches[1] ? MULT_MATCH : SINGLE_MATCH;
+
+ if (do_replace != NO_MATCH)
+ {
+#if defined (SHELL)
+ /* XXX - experimental */
+ /* Quote the replacement, since we found an
+ embedded word break character in a potential
+ match. */
+ char *rtext, *mtext;
+ int rlen;
+ extern char *double_quote (); /* in builtins/common.c */
+
+ /* If DO_REPLACE == MULT_MATCH, it means that there is
+ more than one match. In this case, we do not add
+ the closing quote or attempt to perform tilde
+ expansion. If DO_REPLACE == SINGLE_MATCH, we try
+ to perform tilde expansion, because double quotes
+ inhibit tilde expansion by the shell. */
+
+ mtext = matches[0];
+ if (mtext[0] == '~' && do_replace == SINGLE_MATCH)
+ mtext = tilde_expand (matches[0]);
+ rtext = double_quote (mtext);
+ if (mtext != matches[0])
+ free (mtext);
+
+ rlen = strlen (rtext);
+ replacement = (char *)alloca (rlen + 1);
+ strcpy (replacement, rtext);
+ if (do_replace == MULT_MATCH)
+ replacement[rlen - 1] = '\0';
+ free (rtext);
+#else /* !SHELL */
+ /* Found an embedded word break character in a potential
+ match, so we need to prepend a quote character if we
+ are replacing the completion string. */
+ replacement = (char *)alloca (strlen (matches[0]) + 2);
+ quote_char = *rl_completer_quote_characters;
+ *replacement = quote_char;
+ strcpy (replacement + 1, matches[0]);
+#endif /* SHELL */
+ }
+ }
+
+ if (replacement)
+ {
+ rl_delete_text (start, rl_point);
+ rl_point = start;
+ rl_insert_text (replacement);
+ }
+
+ /* If there are more matches, ring the bell to indicate.
+ If this was the only match, and we are hacking files,
+ check the file to see if it was a directory. If so,
+ add a '/' to the name. If not, and we are at the end
+ of the line, then add a space. */
+ if (matches[1])
+ {
+ if (rl_editing_mode != vi_mode)
+ ding (); /* There are other matches remaining. */
+ }
+ else
+ {
+ char temp_string[4];
+ int temp_string_index = 0;
+
+ if (quote_char)
+ temp_string[temp_string_index++] = quote_char;
+
+ temp_string[temp_string_index++] = delimiter ? delimiter : ' ';
+ temp_string[temp_string_index++] = '\0';
+
+ if (rl_filename_completion_desired)
+ {
+ struct stat finfo;
+ char *filename = tilde_expand (matches[0]);
+
+ if ((stat (filename, &finfo) == 0) &&
+ S_ISDIR (finfo.st_mode))
+ {
+ if (rl_line_buffer[rl_point] != '/')
+ rl_insert_text ("/");
+ }
+ else
+ {
+ if (rl_point == rl_end)
+ rl_insert_text (temp_string);
+ }
+ free (filename);
+ }
+ else
+ {
+ if (rl_point == rl_end)
+ rl_insert_text (temp_string);
+ }
+ }
+ break;
+
+ case '*':
+ {
+ int i = 1;
+
+ rl_delete_text (start, rl_point);
+ rl_point = start;
+ rl_begin_undo_group ();
+ if (matches[1])
+ {
+ while (matches[i])
+ {
+ rl_insert_text (matches[i++]);
+ rl_insert_text (" ");
+ }
+ }
+ else
+ {
+ rl_insert_text (matches[0]);
+ rl_insert_text (" ");
+ }
+ rl_end_undo_group ();
+ }
+ break;
+
+ case '?':
+ {
+ int len, count, limit, max = 0;
+ int j, k, l;
+
+ /* Handle simple case first. What if there is only one answer? */
+ if (!matches[1])
+ {
+ char *temp = (char *)NULL;
+
+ if (rl_filename_completion_desired)
+ temp = strrchr (matches[0], '/');
+
+ if (!temp)
+ temp = matches[0];
+ else
+ temp++;
+
+ crlf ();
+ fprintf (rl_outstream, "%s", temp);
+#if defined (VISIBLE_STATS)
+ if (rl_filename_completion_desired && rl_visible_stats)
+ {
+ int extension_char;
+
+ extension_char = stat_char (matches[0]);
+ if (extension_char)
+ putc (extension_char, rl_outstream);
+ }
+#endif /* VISIBLE_STATS */
+ crlf ();
+ goto restart;
+ }
+
+ /* There is more than one answer. Find out how many there are,
+ and find out what the maximum printed length of a single entry
+ is. */
+ for (i = 1; matches[i]; i++)
+ {
+ char *temp;
+ int name_length;
+
+ /* If we are hacking filenames, then only count the characters
+ after the last slash in the pathname. */
+ if (rl_filename_completion_desired)
+ temp = strrchr (matches[i], '/');
+ else
+ temp = (char *)NULL;
+
+ if (!temp)
+ temp = matches[i];
+ else
+ temp++;
+
+ name_length = strlen (temp);
+
+ if (name_length > max)
+ max = name_length;
+ }
+
+ len = i - 1;
+
+ /* If there are many items, then ask the user if she
+ really wants to see them all. */
+ if (len >= rl_completion_query_items)
+ {
+ crlf ();
+ fprintf (rl_outstream,
+ "There are %d possibilities. Do you really", len);
+ crlf ();
+ fprintf (rl_outstream, "wish to see them all? (y or n)");
+ fflush (rl_outstream);
+ if (!get_y_or_n ())
+ {
+ crlf ();
+ goto restart;
+ }
+ }
+
+ /* How many items of MAX length can we fit in the screen window? */
+ max += 2;
+ limit = screenwidth / max;
+ if (limit != 1 && (limit * max == screenwidth))
+ limit--;
+
+ /* Avoid a possible floating exception. If max > screenwidth,
+ limit will be 0 and a divide-by-zero fault will result. */
+ if (limit == 0)
+ limit = 1;
+
+ /* How many iterations of the printing loop? */
+ count = (len + (limit - 1)) / limit;
+
+ /* Watch out for special case. If LEN is less than LIMIT, then
+ just do the inner printing loop. */
+ if (len < limit)
+ count = 1;
+
+ /* Sort the items if they are not already sorted. */
+ if (!rl_ignore_completion_duplicates)
+ qsort (matches, len, sizeof (char *), compare_strings);
+
+ /* Print the sorted items, up-and-down alphabetically, like
+ ls might. */
+ crlf ();
+
+ for (i = 1; i < count + 1; i++)
+ {
+ for (j = 0, l = i; j < limit; j++)
+ {
+ if (l > len || !matches[l])
+ {
+ break;
+ }
+ else
+ {
+ char *temp = (char *)NULL;
+ int printed_length;
+
+ if (rl_filename_completion_desired)
+ temp = strrchr (matches[l], '/');
+
+ if (!temp)
+ temp = matches[l];
+ else
+ temp++;
+
+ printed_length = strlen (temp);
+ fprintf (rl_outstream, "%s", temp);
+
+#if defined (VISIBLE_STATS)
+ if (rl_filename_completion_desired &&
+ rl_visible_stats)
+ {
+ int extension_char;
+
+ extension_char = stat_char (matches[l]);
+
+ if (extension_char)
+ {
+ putc (extension_char, rl_outstream);
+ printed_length++;
+ }
+ }
+#endif /* VISIBLE_STATS */
+
+ if (j + 1 < limit)
+ {
+ for (k = 0; k < max - printed_length; k++)
+ putc (' ', rl_outstream);
+ }
+ }
+ l += count;
+ }
+ crlf ();
+ }
+ restart:
+
+ rl_on_new_line ();
+ }
+ break;
+
+ default:
+ fprintf (stderr, "\r\nreadline: bad value for what_to_do in rl_complete\n");
+ abort ();
+ }
+
+ for (i = 0; matches[i]; i++)
+ free (matches[i]);
+ free (matches);
+ }
+
+ /* Check to see if the line has changed through all of this manipulation. */
+ if (saved_line_buffer)
+ {
+ if (strcmp (rl_line_buffer, saved_line_buffer) != 0)
+ completion_changed_buffer = 1;
+ else
+ completion_changed_buffer = 0;
+
+ free (saved_line_buffer);
+ }
+}
+
+#if defined (VISIBLE_STATS)
+/* Return the character which best describes FILENAME.
+ `@' for symbolic links
+ `/' for directories
+ `*' for executables
+ `=' for sockets */
+static int
+stat_char (filename)
+ char *filename;
+{
+ struct stat finfo;
+ int character = 0;
+
+ if (stat (filename, &finfo) == -1)
+ return (character);
+
+ if (S_ISDIR (finfo.st_mode))
+ character = '/';
+#if defined (S_ISLNK)
+ else if (S_ISLNK (finfo.st_mode))
+ character = '@';
+#endif /* S_ISLNK */
+#if defined (S_ISSOCK)
+ else if (S_ISSOCK (finfo.st_mode))
+ character = '=';
+#endif /* S_ISSOCK */
+ else if (S_ISREG (finfo.st_mode))
+ {
+ if (access (filename, X_OK) == 0)
+ character = '*';
+ }
+ return (character);
+}
+#endif /* VISIBLE_STATS */
+
+/* Stupid comparison routine for qsort () ing strings. */
+static int
+compare_strings (s1, s2)
+ char **s1, **s2;
+{
+ return (strcmp (*s1, *s2));
+}
+
+/* A completion function for usernames.
+ TEXT contains a partial username preceded by a random
+ character (usually `~'). */
+char *
+username_completion_function (text, state)
+ int state;
+ char *text;
+{
+#if defined (_GO32_)
+ return (char *)NULL;
+#else /* !_GO32_ */
+ static char *username = (char *)NULL;
+ static struct passwd *entry;
+ static int namelen, first_char, first_char_loc;
+
+ if (!state)
+ {
+ if (username)
+ free (username);
+
+ first_char = *text;
+
+ if (first_char == '~')
+ first_char_loc = 1;
+ else
+ first_char_loc = 0;
+
+ username = savestring (&text[first_char_loc]);
+ namelen = strlen (username);
+ setpwent ();
+ }
+
+ while (entry = getpwent ())
+ {
+ if (strncmp (username, entry->pw_name, namelen) == 0)
+ break;
+ }
+
+ if (!entry)
+ {
+ endpwent ();
+ return ((char *)NULL);
+ }
+ else
+ {
+ char *value = (char *)xmalloc (2 + strlen (entry->pw_name));
+
+ *value = *text;
+
+ strcpy (value + first_char_loc, entry->pw_name);
+
+ if (first_char == '~')
+ rl_filename_completion_desired = 1;
+
+ return (value);
+ }
+#endif /* !_GO32_ */
+}
+
+/* **************************************************************** */
+/* */
+/* Completion */
+/* */
+/* **************************************************************** */
+
+/* Non-zero means that case is not significant in completion. */
+int completion_case_fold = 0;
+
+/* Return an array of (char *) which is a list of completions for TEXT.
+ If there are no completions, return a NULL pointer.
+ The first entry in the returned array is the substitution for TEXT.
+ The remaining entries are the possible completions.
+ The array is terminated with a NULL pointer.
+
+ ENTRY_FUNCTION is a function of two args, and returns a (char *).
+ The first argument is TEXT.
+ The second is a state argument; it should be zero on the first call, and
+ non-zero on subsequent calls. It returns a NULL pointer to the caller
+ when there are no more matches.
+ */
+char **
+completion_matches (text, entry_function)
+ char *text;
+ CPFunction *entry_function;
+{
+ /* Number of slots in match_list. */
+ int match_list_size;
+
+ /* The list of matches. */
+ char **match_list =
+ (char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
+
+ /* Number of matches actually found. */
+ int matches = 0;
+
+ /* Temporary string binder. */
+ char *string;
+
+ match_list[1] = (char *)NULL;
+
+ while (string = (*entry_function) (text, matches))
+ {
+ if (matches + 1 == match_list_size)
+ match_list = (char **)xrealloc
+ (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
+
+ match_list[++matches] = string;
+ match_list[matches + 1] = (char *)NULL;
+ }
+
+ /* If there were any matches, then look through them finding out the
+ lowest common denominator. That then becomes match_list[0]. */
+ if (matches)
+ {
+ register int i = 1;
+ int low = 100000; /* Count of max-matched characters. */
+
+ /* If only one match, just use that. */
+ if (matches == 1)
+ {
+ match_list[0] = match_list[1];
+ match_list[1] = (char *)NULL;
+ }
+ else
+ {
+ /* Otherwise, compare each member of the list with
+ the next, finding out where they stop matching. */
+
+ while (i < matches)
+ {
+ register int c1, c2, si;
+
+ if (completion_case_fold)
+ {
+ for (si = 0;
+ (c1 = to_lower(match_list[i][si])) &&
+ (c2 = to_lower(match_list[i + 1][si]));
+ si++)
+ if (c1 != c2) break;
+ }
+ else
+ {
+ for (si = 0;
+ (c1 = match_list[i][si]) &&
+ (c2 = match_list[i + 1][si]);
+ si++)
+ if (c1 != c2) break;
+ }
+
+ if (low > si) low = si;
+ i++;
+ }
+ match_list[0] = (char *)xmalloc (low + 1);
+ strncpy (match_list[0], match_list[1], low);
+ match_list[0][low] = '\0';
+ }
+ }
+ else /* There were no matches. */
+ {
+ free (match_list);
+ match_list = (char **)NULL;
+ }
+ return (match_list);
+}
+
+/* Okay, now we write the entry_function for filename completion. In the
+ general case. Note that completion in the shell is a little different
+ because of all the pathnames that must be followed when looking up the
+ completion for a command. */
+char *
+filename_completion_function (text, state)
+ int state;
+ char *text;
+{
+ static DIR *directory;
+ static char *filename = (char *)NULL;
+ static char *dirname = (char *)NULL;
+ static char *users_dirname = (char *)NULL;
+ static int filename_len;
+
+ struct direct *entry = (struct direct *)NULL;
+
+ /* If we don't have any state, then do some initialization. */
+ if (!state)
+ {
+ char *temp;
+
+ if (dirname) free (dirname);
+ if (filename) free (filename);
+ if (users_dirname) free (users_dirname);
+
+ filename = savestring (text);
+ if (!*text) text = ".";
+ dirname = savestring (text);
+
+ temp = strrchr (dirname, '/');
+
+ if (temp)
+ {
+ strcpy (filename, ++temp);
+ *temp = '\0';
+ }
+ else
+ strcpy (dirname, ".");
+
+ /* We aren't done yet. We also support the "~user" syntax. */
+
+ /* Save the version of the directory that the user typed. */
+ users_dirname = savestring (dirname);
+ {
+ char *temp_dirname;
+
+ temp_dirname = tilde_expand (dirname);
+ free (dirname);
+ dirname = temp_dirname;
+
+ if (rl_symbolic_link_hook)
+ (*rl_symbolic_link_hook) (&dirname);
+ }
+ directory = opendir (dirname);
+ filename_len = strlen (filename);
+
+ rl_filename_completion_desired = 1;
+ }
+
+ /* At this point we should entertain the possibility of hacking wildcarded
+ filenames, like /usr/man/man<WILD>/te<TAB>. If the directory name
+ contains globbing characters, then build an array of directories, and
+ then map over that list while completing. */
+ /* *** UNIMPLEMENTED *** */
+
+ /* Now that we have some state, we can read the directory. */
+
+ while (directory && (entry = readdir (directory)))
+ {
+ /* Special case for no filename.
+ All entries except "." and ".." match. */
+ if (!filename_len)
+ {
+ if ((strcmp (entry->d_name, ".") != 0) &&
+ (strcmp (entry->d_name, "..") != 0))
+ break;
+ }
+ else
+ {
+ /* Otherwise, if these match upto the length of filename, then
+ it is a match. */
+ if (((int)D_NAMLEN (entry)) >= filename_len &&
+ (entry->d_name[0] == filename[0]) &&
+ (strncmp (filename, entry->d_name, filename_len) == 0))
+ {
+ break;
+ }
+ }
+ }
+
+ if (!entry)
+ {
+ if (directory)
+ {
+ closedir (directory);
+ directory = (DIR *)NULL;
+ }
+
+ if (dirname)
+ {
+ free (dirname);
+ dirname = (char *)NULL;
+ }
+ if (filename)
+ {
+ free (filename);
+ filename = (char *)NULL;
+ }
+ if (users_dirname)
+ {
+ free (users_dirname);
+ users_dirname = (char *)NULL;
+ }
+
+ return (char *)NULL;
+ }
+ else
+ {
+ char *temp;
+
+ if (dirname && (strcmp (dirname, ".") != 0))
+ {
+ if (rl_complete_with_tilde_expansion && *users_dirname == '~')
+ {
+ int dirlen = strlen (dirname);
+ temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
+ strcpy (temp, dirname);
+ /* Canonicalization cuts off any final slash present. We need
+ to add it back. */
+ if (dirname[dirlen - 1] != '/')
+ {
+ temp[dirlen] = '/';
+ temp[dirlen + 1] = '\0';
+ }
+ }
+ else
+ {
+ temp = (char *)
+ xmalloc (1 + strlen (users_dirname) + D_NAMLEN (entry));
+ strcpy (temp, users_dirname);
+ }
+
+ strcat (temp, entry->d_name);
+ }
+ else
+ {
+ temp = (savestring (entry->d_name));
+ }
+ return (temp);
+ }
+}
+
+/* A function for simple tilde expansion. */
+int
+rl_tilde_expand (ignore, key)
+ int ignore, key;
+{
+ register int start, end;
+ char *homedir;
+
+ end = rl_point;
+ start = end - 1;
+
+ if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
+ {
+ homedir = tilde_expand ("~");
+ goto insert;
+ }
+ else if (rl_line_buffer[start] != '~')
+ {
+ for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--);
+ start++;
+ }
+
+ end = start;
+ do
+ {
+ end++;
+ }
+ while (!whitespace (rl_line_buffer[end]) && 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] == '~')
+ {
+ char *temp;
+ int len;
+
+ len = end - start + 1;
+ temp = (char *)alloca (len + 1);
+ strncpy (temp, rl_line_buffer + start, len);
+ temp[len] = '\0';
+ homedir = tilde_expand (temp);
+
+ insert:
+ rl_begin_undo_group ();
+ rl_delete_text (start, end + 1);
+ rl_point = start;
+ rl_insert_text (homedir);
+ rl_end_undo_group ();
+ }
+
+ return (0);
+}
+
+/* Find the first occurrence in STRING1 of any character from STRING2.
+ Return a pointer to the character in STRING1. */
+static char *
+rl_strpbrk (string1, string2)
+ char *string1, *string2;
+{
+ register char *scan;
+
+ for (; *string1; string1++)
+ {
+ for (scan = string2; *scan; scan++)
+ {
+ if (*string1 == *scan)
+ {
+ return (string1);
+ }
+ }
+ }
+ return ((char *)NULL);
+}
+
+#if defined (STATIC_MALLOC)
+
+/* **************************************************************** */
+/* */
+/* xmalloc and xrealloc () */
+/* */
+/* **************************************************************** */
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+
+ return (temp);
+}
+
+static void
+memory_error_and_abort ()
+{
+ fprintf (stderr, "readline: Out of virtual memory!\n");
+ abort ();
+}
+#endif /* STATIC_MALLOC */
diff --git a/gnu/lib/libreadline/display.c b/gnu/lib/libreadline/display.c
new file mode 100644
index 0000000..6827621
--- /dev/null
+++ b/gnu/lib/libreadline/display.c
@@ -0,0 +1,818 @@
+/* display.c -- readline redisplay facility. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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 1, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#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 */
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#if !defined (strchr) && !defined (__STDC__)
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+/* Global and pseudo-global variables and functions
+ imported from readline.c. */
+extern char *rl_prompt;
+extern int readline_echoing_p;
+extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC;
+/* Termcap variables. */
+extern char *term_up, *term_dc, *term_cr, *term_IC;
+extern int screenheight, screenwidth, terminal_can_insert;
+
+extern void _rl_output_some_chars ();
+extern void _rl_output_character_function ();
+
+extern int _rl_convert_meta_chars_to_ascii;
+extern int _rl_horizontal_scroll_mode;
+extern int _rl_mark_modified_lines;
+extern int _rl_prefer_visible_bell;
+
+/* Pseudo-global functions (local to the readline library) exported
+ by this file. */
+void _rl_move_cursor_relative (), _rl_output_some_chars ();
+void _rl_move_vert ();
+
+static void update_line (), clear_to_eol ();
+static void delete_chars (), insert_some_chars ();
+
+extern char *xmalloc (), *xrealloc ();
+
+/* **************************************************************** */
+/* */
+/* Display stuff */
+/* */
+/* **************************************************************** */
+
+/* This is the stuff that is hard for me. I never seem to write good
+ display routines in C. Let's see how I do this time. */
+
+/* (PWP) Well... Good for a simple line updater, but totally ignores
+ the problems of input lines longer than the screen width.
+
+ update_line and the code that calls it makes a multiple line,
+ automatically wrapping line update. Carefull attention needs
+ to be paid to the vertical position variables.
+
+ handling of terminals with autowrap on (incl. DEC braindamage)
+ could be improved a bit. Right now I just cheat and decrement
+ screenwidth by one. */
+
+/* Keep two buffers; one which reflects the current contents of the
+ screen, and the other to draw what we think the new contents should
+ be. Then compare the buffers, and make whatever changes to the
+ screen itself that we should. Finally, make the buffer that we
+ just drew into be the one which reflects the current contents of the
+ screen, and place the cursor where it belongs.
+
+ Commands that want to can fix the display themselves, and then let
+ this function know that the display has been fixed by setting the
+ RL_DISPLAY_FIXED variable. This is good for efficiency. */
+
+/* Global variables declared here. */
+/* What YOU turn on when you have handled all redisplay yourself. */
+int rl_display_fixed = 0;
+
+/* The stuff that gets printed out before the actual text of the line.
+ This is usually pointing to rl_prompt. */
+char *rl_display_prompt = (char *)NULL;
+
+/* Pseudo-global variables declared here. */
+/* The visible cursor position. If you print some text, adjust this. */
+int _rl_last_c_pos = 0;
+int _rl_last_v_pos = 0;
+
+/* Number of lines currently on screen minus 1. */
+int _rl_vis_botlin = 0;
+
+/* Variables used only in this file. */
+/* The last left edge of text that was displayed. This is used when
+ doing horizontal scrolling. It shifts in thirds of a screenwidth. */
+static int last_lmargin = 0;
+
+/* The line display buffers. One is the line currently displayed on
+ the screen. The other is the line about to be displayed. */
+static char *visible_line = (char *)NULL;
+static char *invisible_line = (char *)NULL;
+
+/* A buffer for `modeline' messages. */
+static char msg_buf[128];
+
+/* Non-zero forces the redisplay even if we thought it was unnecessary. */
+static int forced_display = 0;
+
+/* Default and initial buffer size. Can grow. */
+static int line_size = 1024;
+
+/* Basic redisplay algorithm. */
+void
+rl_redisplay ()
+{
+ register int in, out, c, linenum;
+ register char *line = invisible_line;
+ char *prompt_this_line;
+ int c_pos = 0;
+ int inv_botlin = 0; /* Number of lines in newly drawn buffer. */
+
+ if (!readline_echoing_p)
+ return;
+
+ if (!rl_display_prompt)
+ rl_display_prompt = "";
+
+ if (!invisible_line)
+ {
+ visible_line = (char *)xmalloc (line_size);
+ invisible_line = (char *)xmalloc (line_size);
+ line = invisible_line;
+ for (in = 0; in < line_size; in++)
+ {
+ visible_line[in] = 0;
+ invisible_line[in] = 1;
+ }
+ rl_on_new_line ();
+ }
+
+ /* Draw the line into the buffer. */
+ c_pos = -1;
+
+ /* Mark the line as modified or not. We only do this for history
+ lines. */
+ out = 0;
+ if (_rl_mark_modified_lines && current_history () && rl_undo_list)
+ {
+ line[out++] = '*';
+ line[out] = '\0';
+ }
+
+ /* If someone thought that the redisplay was handled, but the currently
+ visible line has a different modification state than the one about
+ to become visible, then correct the caller's misconception. */
+ if (visible_line[0] != invisible_line[0])
+ rl_display_fixed = 0;
+
+ prompt_this_line = strrchr (rl_display_prompt, '\n');
+ if (!prompt_this_line)
+ prompt_this_line = rl_display_prompt;
+ else
+ {
+ prompt_this_line++;
+ if (forced_display)
+ _rl_output_some_chars
+ (rl_display_prompt, prompt_this_line - rl_display_prompt);
+ }
+
+ strncpy (line + out, prompt_this_line, strlen (prompt_this_line));
+ out += strlen (prompt_this_line);
+ line[out] = '\0';
+
+ for (in = 0; in < rl_end; in++)
+ {
+ c = (unsigned char)rl_line_buffer[in];
+
+ if (out + 8 >= line_size) /* XXX - 8 for \t */
+ {
+ line_size *= 2;
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ invisible_line = (char *)xrealloc (invisible_line, line_size);
+ line = invisible_line;
+ }
+
+ if (in == rl_point)
+ c_pos = out;
+
+ if (META_CHAR (c))
+ {
+ if (_rl_convert_meta_chars_to_ascii)
+ {
+ sprintf (line + out, "\\%o", c);
+ out += 4;
+ }
+ else
+ line[out++] = c;
+ }
+#define DISPLAY_TABS
+#if defined (DISPLAY_TABS)
+ else if (c == '\t')
+ {
+ register int newout = (out | (int)7) + 1;
+ while (out < newout)
+ line[out++] = ' ';
+ }
+#endif
+ else if (c < ' ')
+ {
+ line[out++] = '^';
+ line[out++] = UNCTRL (c); /* XXX was c ^ 0x40 */
+ }
+ else if (c == 127)
+ {
+ line[out++] = '^';
+ line[out++] = '?';
+ }
+ else
+ line[out++] = c;
+ }
+ line[out] = '\0';
+ if (c_pos < 0)
+ c_pos = out;
+
+ /* PWP: now is when things get a bit hairy. The visible and invisible
+ line buffers are really multiple lines, which would wrap every
+ (screenwidth - 1) characters. Go through each in turn, finding
+ the changed region and updating it. The line order is top to bottom. */
+
+ /* If we can move the cursor up and down, then use multiple lines,
+ otherwise, let long lines display in a single terminal line, and
+ horizontally scroll it. */
+
+ if (!_rl_horizontal_scroll_mode && term_up && *term_up)
+ {
+ int total_screen_chars = (screenwidth * screenheight);
+
+ if (!rl_display_fixed || forced_display)
+ {
+ forced_display = 0;
+
+ /* If we have more than a screenful of material to display, then
+ only display a screenful. We should display the last screen,
+ not the first. I'll fix this in a minute. */
+ if (out >= total_screen_chars)
+ out = total_screen_chars - 1;
+
+ /* Number of screen lines to display. */
+ inv_botlin = out / screenwidth;
+
+ /* For each line in the buffer, do the updating display. */
+ for (linenum = 0; linenum <= inv_botlin; linenum++)
+ update_line (linenum > _rl_vis_botlin ? ""
+ : &visible_line[linenum * screenwidth],
+ &invisible_line[linenum * screenwidth],
+ linenum);
+
+ /* We may have deleted some lines. If so, clear the left over
+ blank ones at the bottom out. */
+ if (_rl_vis_botlin > inv_botlin)
+ {
+ char *tt;
+ for (; linenum <= _rl_vis_botlin; linenum++)
+ {
+ tt = &visible_line[linenum * screenwidth];
+ _rl_move_vert (linenum);
+ _rl_move_cursor_relative (0, tt);
+ clear_to_eol
+ ((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
+ }
+ }
+ _rl_vis_botlin = inv_botlin;
+
+ /* Move the cursor where it should be. */
+ _rl_move_vert (c_pos / screenwidth);
+ _rl_move_cursor_relative (c_pos % screenwidth,
+ &invisible_line[(c_pos / screenwidth) * screenwidth]);
+ }
+ }
+ else /* Do horizontal scrolling. */
+ {
+ int lmargin;
+
+ /* Always at top line. */
+ _rl_last_v_pos = 0;
+
+ /* If the display position of the cursor would be off the edge
+ of the screen, start the display of this line at an offset that
+ leaves the cursor on the screen. */
+ if (c_pos - last_lmargin > screenwidth - 2)
+ lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);
+ else if (c_pos - last_lmargin < 1)
+ lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);
+ else
+ lmargin = last_lmargin;
+
+ /* If the first character on the screen isn't the first character
+ in the display line, indicate this with a special character. */
+ if (lmargin > 0)
+ line[lmargin] = '<';
+
+ if (lmargin + screenwidth < out)
+ line[lmargin + screenwidth - 1] = '>';
+
+ if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
+ {
+ forced_display = 0;
+ update_line (&visible_line[last_lmargin],
+ &invisible_line[lmargin], 0);
+
+ _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
+ last_lmargin = lmargin;
+ }
+ }
+ fflush (rl_outstream);
+
+ /* Swap visible and non-visible lines. */
+ {
+ char *temp = visible_line;
+ visible_line = invisible_line;
+ invisible_line = temp;
+ rl_display_fixed = 0;
+ }
+}
+
+/* PWP: update_line() is based on finding the middle difference of each
+ line on the screen; vis:
+
+ /old first difference
+ /beginning of line | /old last same /old EOL
+ v v v v
+old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
+new: eddie> Oh, my little buggy says to me, as lurgid as
+ ^ ^ ^ ^
+ \beginning of line | \new last same \new end of line
+ \new first difference
+
+ All are character pointers for the sake of speed. Special cases for
+ no differences, as well as for end of line additions must be handeled.
+
+ Could be made even smarter, but this works well enough */
+static void
+update_line (old, new, current_line)
+ register char *old, *new;
+ int current_line;
+{
+ register char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ int lendiff, wsatend;
+
+ /* Find first difference. */
+ for (ofd = old, nfd = new;
+ (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);
+ ofd++, nfd++)
+ ;
+
+ /* Move to the end of the screen line. */
+ for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++);
+ for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++);
+
+ /* If no difference, continue to next line. */
+ if (ofd == oe && nfd == ne)
+ return;
+
+ wsatend = 1; /* flag for trailing whitespace */
+ ols = oe - 1; /* find last same */
+ nls = ne - 1;
+ while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
+ {
+ if (*ols != ' ')
+ wsatend = 0;
+ ols--;
+ nls--;
+ }
+
+ if (wsatend)
+ {
+ ols = oe;
+ nls = ne;
+ }
+ else if (*ols != *nls)
+ {
+ if (*ols) /* don't step past the NUL */
+ ols++;
+ if (*nls)
+ nls++;
+ }
+
+ _rl_move_vert (current_line);
+ _rl_move_cursor_relative (ofd - old, old);
+
+ /* if (len (new) > len (old)) */
+ lendiff = (nls - nfd) - (ols - ofd);
+
+ /* Insert (diff (len (old), len (new)) ch. */
+ if (lendiff > 0)
+ {
+ if (terminal_can_insert)
+ {
+ /* Sometimes it is cheaper to print the characters rather than
+ use the terminal's capabilities. */
+ if ((2 * (ne - nfd)) < lendiff && !term_IC)
+ {
+ _rl_output_some_chars (nfd, (ne - nfd));
+ _rl_last_c_pos += (ne - nfd);
+ }
+ else
+ {
+ if (*ols)
+ {
+ insert_some_chars (nfd, lendiff);
+ _rl_last_c_pos += lendiff;
+ }
+ else
+ {
+ /* At the end of a line the characters do not have to
+ be "inserted". They can just be placed on the screen. */
+ _rl_output_some_chars (nfd, lendiff);
+ _rl_last_c_pos += lendiff;
+ }
+ /* Copy (new) chars to screen from first diff to last match. */
+ if (((nls - nfd) - lendiff) > 0)
+ {
+ _rl_output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
+ _rl_last_c_pos += ((nls - nfd) - lendiff);
+ }
+ }
+ }
+ else
+ { /* cannot insert chars, write to EOL */
+ _rl_output_some_chars (nfd, (ne - nfd));
+ _rl_last_c_pos += (ne - nfd);
+ }
+ }
+ else /* Delete characters from line. */
+ {
+ /* If possible and inexpensive to use terminal deletion, then do so. */
+ if (term_dc && (2 * (ne - nfd)) >= (-lendiff))
+ {
+ if (lendiff)
+ delete_chars (-lendiff); /* delete (diff) characters */
+
+ /* Copy (new) chars to screen from first diff to last match */
+ if ((nls - nfd) > 0)
+ {
+ _rl_output_some_chars (nfd, (nls - nfd));
+ _rl_last_c_pos += (nls - nfd);
+ }
+ }
+ /* Otherwise, print over the existing material. */
+ else
+ {
+ _rl_output_some_chars (nfd, (ne - nfd));
+ _rl_last_c_pos += (ne - nfd);
+ clear_to_eol ((oe - old) - (ne - new));
+ }
+ }
+}
+
+/* Tell the update routines that we have moved onto a new (empty) line. */
+rl_on_new_line ()
+{
+ if (visible_line)
+ visible_line[0] = '\0';
+
+ _rl_last_c_pos = _rl_last_v_pos = 0;
+ _rl_vis_botlin = last_lmargin = 0;
+}
+
+/* Actually update the display, period. */
+rl_forced_update_display ()
+{
+ if (visible_line)
+ {
+ register char *temp = visible_line;
+
+ while (*temp) *temp++ = '\0';
+ }
+ rl_on_new_line ();
+ forced_display++;
+ rl_redisplay ();
+}
+
+/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
+ DATA is the contents of the screen line of interest; i.e., where
+ the movement is being done. */
+void
+_rl_move_cursor_relative (new, data)
+ int new;
+ char *data;
+{
+ register int i;
+
+ /* It may be faster to output a CR, and then move forwards instead
+ of moving backwards. */
+ if (new + 1 < _rl_last_c_pos - new)
+ {
+ tputs (term_cr, 1, _rl_output_character_function);
+ _rl_last_c_pos = 0;
+ }
+
+ if (_rl_last_c_pos == new) return;
+
+ if (_rl_last_c_pos < new)
+ {
+ /* Move the cursor forward. We do it by printing the command
+ to move the cursor forward if there is one, else print that
+ portion of the output buffer again. Which is cheaper? */
+
+ /* The above comment is left here for posterity. It is faster
+ to print one character (non-control) than to print a control
+ sequence telling the terminal to move forward one character.
+ That kind of control is for people who don't know what the
+ data is underneath the cursor. */
+#if defined (HACK_TERMCAP_MOTION)
+ extern char *term_forward_char;
+
+ if (term_forward_char)
+ for (i = _rl_last_c_pos; i < new; i++)
+ tputs (term_forward_char, 1, _rl_output_character_function);
+ else
+ for (i = _rl_last_c_pos; i < new; i++)
+ putc (data[i], rl_outstream);
+#else
+ for (i = _rl_last_c_pos; i < new; i++)
+ putc (data[i], rl_outstream);
+#endif /* HACK_TERMCAP_MOTION */
+ }
+ else
+ backspace (_rl_last_c_pos - new);
+ _rl_last_c_pos = new;
+}
+
+/* PWP: move the cursor up or down. */
+void
+_rl_move_vert (to)
+ int to;
+{
+ register int delta, i;
+
+ if (_rl_last_v_pos == to || to > screenheight)
+ return;
+
+#if defined (_GO32_)
+ {
+ int row, col;
+
+ ScreenGetCursor (&row, &col);
+ ScreenSetCursor ((row + to - _rl_last_v_pos), col);
+ }
+#else /* !_GO32_ */
+
+ if ((delta = to - _rl_last_v_pos) > 0)
+ {
+ for (i = 0; i < delta; i++)
+ putc ('\n', rl_outstream);
+ tputs (term_cr, 1, _rl_output_character_function);
+ _rl_last_c_pos = 0;
+ }
+ else
+ { /* delta < 0 */
+ if (term_up && *term_up)
+ for (i = 0; i < -delta; i++)
+ tputs (term_up, 1, _rl_output_character_function);
+ }
+#endif /* !_GO32_ */
+ _rl_last_v_pos = to; /* Now TO is here */
+}
+
+/* Physically print C on rl_outstream. This is for functions which know
+ how to optimize the display. */
+rl_show_char (c)
+ int c;
+{
+ if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii)
+ {
+ fprintf (rl_outstream, "M-");
+ c = UNMETA (c);
+ }
+
+#if defined (DISPLAY_TABS)
+ if (c < 32 && c != '\t')
+#else
+ if (c < 32)
+#endif /* !DISPLAY_TABS */
+ {
+ c += 64;
+ }
+
+ putc (c, rl_outstream);
+ fflush (rl_outstream);
+}
+
+int
+rl_character_len (c, pos)
+ register int c, pos;
+{
+ if (META_CHAR (c))
+ return (_rl_convert_meta_chars_to_ascii ? 4 : 1);
+
+ if (c == '\t')
+ {
+#if defined (DISPLAY_TABS)
+ return (((pos | (int)7) + 1) - pos);
+#else
+ return (2);
+#endif /* !DISPLAY_TABS */
+ }
+
+ if (isprint (c))
+ return (1);
+ else
+ return (2);
+}
+
+/* How to print things in the "echo-area". The prompt is treated as a
+ mini-modeline. */
+
+#if defined (HAVE_VARARGS_H)
+rl_message (va_alist)
+ va_dcl
+{
+ char *format;
+ va_list args;
+
+ va_start (args);
+ format = va_arg (args, char *);
+ vsprintf (msg_buf, format, args);
+ va_end (args);
+
+ rl_display_prompt = msg_buf;
+ rl_redisplay ();
+}
+#else /* !HAVE_VARARGS_H */
+rl_message (format, arg1, arg2)
+ char *format;
+{
+ sprintf (msg_buf, format, arg1, arg2);
+ rl_display_prompt = msg_buf;
+ rl_redisplay ();
+}
+#endif /* !HAVE_VARARGS_H */
+
+/* How to clear things from the "echo-area". */
+rl_clear_message ()
+{
+ rl_display_prompt = rl_prompt;
+ rl_redisplay ();
+}
+
+rl_reset_line_state ()
+{
+ rl_on_new_line ();
+
+ rl_display_prompt = rl_prompt ? rl_prompt : "";
+ forced_display = 1;
+}
+
+/* Quick redisplay hack when erasing characters at the end of the line. */
+void
+_rl_erase_at_end_of_line (l)
+ int l;
+{
+ register int i;
+
+ backspace (l);
+ for (i = 0; i < l; i++)
+ putc (' ', rl_outstream);
+ backspace (l);
+ for (i = 0; i < l; i++)
+ visible_line[--_rl_last_c_pos] = '\0';
+ rl_display_fixed++;
+}
+
+/* Clear to the end of the line. COUNT is the minimum
+ number of character spaces to clear, */
+static void
+clear_to_eol (count)
+ int count;
+{
+#if !defined (_GO32_)
+ if (term_clreol)
+ {
+ tputs (term_clreol, 1, _rl_output_character_function);
+ }
+ else
+#endif /* !_GO32_ */
+ {
+ register int i;
+
+ /* Do one more character space. */
+ count++;
+
+ for (i = 0; i < count; i++)
+ putc (' ', rl_outstream);
+
+ backspace (count);
+ }
+}
+
+/* Insert COUNT characters from STRING to the output stream. */
+static void
+insert_some_chars (string, count)
+ char *string;
+ int count;
+{
+#if defined (_GO32_)
+ int row, col, width;
+ char *row_start;
+
+ ScreenGetCursor (&row, &col);
+ width = ScreenCols ();
+ row_start = ScreenPrimary + (row * width);
+
+ memcpy (row_start + col + count, row_start + col, width - col - count);
+
+ /* Place the text on the screen. */
+ _rl_output_some_chars (string, count);
+#else /* !_GO32 */
+
+ /* If IC is defined, then we do not have to "enter" insert mode. */
+ if (term_IC)
+ {
+ char *tgoto (), *buffer;
+ buffer = tgoto (term_IC, 0, count);
+ tputs (buffer, 1, _rl_output_character_function);
+ _rl_output_some_chars (string, count);
+ }
+ else
+ {
+ register int i;
+
+ /* If we have to turn on insert-mode, then do so. */
+ if (term_im && *term_im)
+ tputs (term_im, 1, _rl_output_character_function);
+
+ /* If there is a special command for inserting characters, then
+ use that first to open up the space. */
+ if (term_ic && *term_ic)
+ {
+ for (i = count; i--; )
+ tputs (term_ic, 1, _rl_output_character_function);
+ }
+
+ /* Print the text. */
+ _rl_output_some_chars (string, count);
+
+ /* If there is a string to turn off insert mode, we had best use
+ it now. */
+ if (term_ei && *term_ei)
+ tputs (term_ei, 1, _rl_output_character_function);
+ }
+#endif /* !_GO32_ */
+}
+
+/* Delete COUNT characters from the display line. */
+static void
+delete_chars (count)
+ int count;
+{
+#if defined (_GO32_)
+ int row, col, width;
+ char *row_start;
+
+ ScreenGetCursor (&row, &col);
+ width = ScreenCols ();
+ row_start = ScreenPrimary + (row * width);
+
+ memcpy (row_start + col, row_start + col + count, width - col - count);
+ memset (row_start + width - count, 0, count * 2);
+#else /* !_GO32 */
+
+ if (count > screenwidth)
+ return;
+
+ if (term_DC && *term_DC)
+ {
+ char *tgoto (), *buffer;
+ buffer = tgoto (term_DC, count, count);
+ tputs (buffer, count, _rl_output_character_function);
+ }
+ else
+ {
+ if (term_dc && *term_dc)
+ while (count--)
+ tputs (term_dc, 1, _rl_output_character_function);
+ }
+#endif /* !_GO32_ */
+}
diff --git a/gnu/lib/libreadline/doc/Makefile b/gnu/lib/libreadline/doc/Makefile
index 786e099..c79ad92 100644
--- a/gnu/lib/libreadline/doc/Makefile
+++ b/gnu/lib/libreadline/doc/Makefile
@@ -1,30 +1,34 @@
-# This makefile for Readline library documentation is in -*- text -*- mode.
+# This makefile for History library documentation is in -*- text -*- mode.
# Emacs likes it that way.
-DVIOBJ = readline.dvi history.dvi
-INFOBJ = readline.info history.info
+DOC_SUPPORT = ../../doc-support/
+TEXINDEX = $(DOC_SUPPORT)/texindex
-all: $(DVIOBJ) $(INFOBJ)
+TEX = tex
+DVIOBJ = history.dvi
+INFOBJ = history.info
-readline.dvi: rlman.texinfo rluser.texinfo rltech.texinfo
- tex rlman.texinfo
- tex rlman.texinfo
- mv rlman.dvi readline.dvi
+all: $(DVIOBJ) $(INFOBJ)
history.dvi: hist.texinfo hsuser.texinfo hstech.texinfo
- tex hist.texinfo
- tex hist.texinfo
+ $(TEX) hist.texinfo
+ $(TEXINDEX) hist.??
+ $(TEX) hist.texinfo
mv hist.dvi history.dvi
-readline.info: rlman.texinfo rluser.texinfo rltech.texinfo
- makeinfo rlman.texinfo
-
history.info: hist.texinfo hsuser.texinfo hstech.texinfo
makeinfo hist.texinfo
+./texinfo.tex: $(DOC_SUPPORT)texinfo.tex
+ ln -s $(DOC_SUPPORT)texinfo.tex .
+
+$(TEXINDEX):
+ (cd $(DOC_SUPPORT); $(MAKE) $(MFLAGS) CFLAGS='$(CFLAGS)' texindex)
+
clean:
- rm -f *.log *.cp *.ky *.tp *.vr *.fn *.aux *.pg *.toc core
+ rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
+ *.fns *.kys *.tps *.vrs *.o core texinfo.tex
squeaky-clean:
- rm -f *.log *.cp *.ky *.tp *.vr *.fn *.aux *.pg *.toc core *.dvi *.~* *.info
-
+ rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
+ *.dvi *.info *.info-* *.fns *.kys *.tps *.vrs *.o core
diff --git a/gnu/lib/libreadline/doc/hstech.texinfo b/gnu/lib/libreadline/doc/hstech.texinfo
index c3fe3f6..b5cbc2a 100644
--- a/gnu/lib/libreadline/doc/hstech.texinfo
+++ b/gnu/lib/libreadline/doc/hstech.texinfo
@@ -306,6 +306,3 @@ main ()
@}
@}
@end smallexample
-
-
-
diff --git a/gnu/lib/libreadline/doc/hsuser.texinfo b/gnu/lib/libreadline/doc/hsuser.texinfo
index cda0a68..a460165 100644
--- a/gnu/lib/libreadline/doc/hsuser.texinfo
+++ b/gnu/lib/libreadline/doc/hsuser.texinfo
@@ -26,10 +26,18 @@ into another language, under the above conditions for modified versions.
@node Using History Interactively
@chapter Using History Interactively
+@ifset BashFeatures
+This chapter describes how to use the GNU History Library interactively,
+from a user's standpoint. It should be considered a user's guide. For
+information on using the GNU History Library in your own programs,
+see the GNU Readline Library Manual.
+@end ifset
+@ifclear BashFeatures
This chapter describes how to use the GNU History Library interactively,
from a user's standpoint. It should be considered a user's guide. For
information on using the GNU History Library in your own programs,
@pxref{Programming with GNU History}.
+@end ifclear
@menu
* History Interaction:: What it feels like using History as a user.
diff --git a/gnu/lib/libreadline/doc/rluser.texinfo b/gnu/lib/libreadline/doc/rluser.texinfo
index 67fe64e..553c88e 100644
--- a/gnu/lib/libreadline/doc/rluser.texinfo
+++ b/gnu/lib/libreadline/doc/rluser.texinfo
@@ -1,3 +1,8 @@
+@comment %**start of header (This is for running Texinfo on a region.)
+@setfilename rluser.info
+@comment %**end of header (This is for running Texinfo on a region.)
+@setchapternewpage odd
+
@ignore
This file documents the end user interface to the GNU command line
editing feautres. It is to be an appendix to manuals for programs which
@@ -28,8 +33,11 @@ Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
+@comment If you are including this manual as an appendix, then set the
+@comment variable readline-appendix.
+
@node Command Line Editing
-@appendix Command Line Editing
+@chapter Command Line Editing
This text describes GNU's command line editing interface.
@@ -168,8 +176,8 @@ Kill from the cursor to the end of the current word, or if between
words, to the end of the next word.
@item M-DEL
-Kill from the cursor to the start of the previous word, or if between
-words, to the start of the previous word.
+Kill from the cursor the start of the previous word, or if between
+words, to the start of the previous word.
@item C-w
Kill from the cursor to the previous whitespace. This is different than
@@ -226,7 +234,7 @@ file is @file{~/.inputrc}.
When a program which uses the Readline library starts up, the
@file{~/.inputrc} file is read, and the keybindings are set.
-In addition, the @key{C-x C-r} command re-reads this init file, thus
+In addition, the @code{C-x C-r} command re-reads this init file, thus
incorporating any changes that you might have made to it.
@menu
@@ -305,8 +313,8 @@ Meta-Rubout: backward-kill-word
Control-o: ">&output"
@end example
-In the above example, @key{C-u} is bound to the function
-@code{universal-argument}, and @key{C-o} is bound to run the macro
+In the above example, @samp{C-u} is bound to the function
+@code{universal-argument}, and @samp{C-o} is bound to run the macro
expressed on the right hand side (that is, to insert the text
@samp{>&output} into the line).
@@ -322,10 +330,10 @@ following example:
"\e[11~": "Function Key 1"
@end example
-In the above example, @key{C-u} is bound to the function
+In the above example, @samp{C-u} is bound to the function
@code{universal-argument} (just as it was in the first example),
-@key{C-x C-r} is bound to the function @code{re-read-init-file}, and
-@key{ESC [ 1 1 ~} is bound to insert the text @samp{Function Key 1}.
+@samp{C-x C-r} is bound to the function @code{re-read-init-file}, and
+@samp{ESC [ 1 1 ~} is bound to insert the text @samp{Function Key 1}.
@end table
@end table
@@ -343,25 +351,25 @@ In the above example, @key{C-u} is bound to the function
@node Commands For Moving
@subsubsection Commands For Moving
@ftable @code
-@item beginning-of-line (@key{C-a})
+@item beginning-of-line (C-a)
Move to the start of the current line.
-@item end-of-line (@key{C-e})
+@item end-of-line (C-e)
Move to the end of the line.
-@item forward-char (@key{C-f})
+@item forward-char (C-f)
Move forward a character.
-@item backward-char (@key{C-b})
+@item backward-char (C-b)
Move back a character.
-@item forward-word (@key{M-f})
+@item forward-word (M-f)
Move forward to the end of the next word.
-@item backward-word (@key{M-b})
+@item backward-word (M-b)
Move back to the start of this, or the previous, word.
-@item clear-screen (@key{C-l})
+@item clear-screen (C-l)
Clear the screen leaving the current line at the top of the screen.
@end ftable
@@ -375,23 +383,23 @@ Accept the line regardless of where the cursor is. If this line is
non-empty, add it to the history list. If this line was a history
line, then restore the history line to its original state.
-@item previous-history (@key{C-p})
+@item previous-history (C-p)
Move `up' through the history list.
-@item next-history (@key{C-n})
+@item next-history (C-n)
Move `down' through the history list.
-@item beginning-of-history (@key{M-<})
+@item beginning-of-history (M-<)
Move to the first line in the history.
-@item end-of-history (@key{M->})
+@item end-of-history (M->)
Move to the end of the input history, i.e., the line you are entering!
-@item reverse-search-history (@key{C-r})
+@item reverse-search-history (C-r)
Search backward starting at the current line and moving `up' through
the history as necessary. This is an incremental search.
-@item forward-search-history (@key{C-s})
+@item forward-search-history (C-s)
Search forward starting at the current line and moving `down' through
the the history as neccessary.
@@ -401,45 +409,45 @@ the the history as neccessary.
@subsubsection Commands For Changing Text
@ftable @code
-@item delete-char (@key{C-d})
+@item delete-char (C-d)
Delete the character under the cursor. If the cursor is at the
beginning of the line, and there are no characters in the line, and
-the last character typed was not @key{C-d}, then return EOF.
+the last character typed was not C-d, then return EOF.
@item backward-delete-char (Rubout)
Delete the character behind the cursor. A numeric arg says to kill
the characters instead of deleting them.
-@item quoted-insert (@key{C-q}, @key{C-v})
+@item quoted-insert (C-q, C-v)
Add the next character that you type to the line verbatim. This is
-how to insert things like @key{C-q} for example.
+how to insert things like C-q for example.
-@item tab-insert (@key{M-TAB})
+@item tab-insert (M-TAB)
Insert a tab character.
@item self-insert (a, b, A, 1, !, ...)
Insert yourself.
-@item transpose-chars (@key{C-t})
+@item transpose-chars (C-t)
Drag the character before point forward over the character at point.
Point moves forward as well. If point is at the end of the line, then
transpose the two characters before point. Negative args don't work.
-@item transpose-words (@key{M-t})
+@item transpose-words (M-t)
Drag the word behind the cursor past the word in front of the cursor
moving the cursor over that word as well.
-@item upcase-word (@key{M-u})
-Uppercase all letters in the current (or following) word. With a
-negative argument, do the previous word, but do not move point.
+@item upcase-word (M-u)
+Uppercase the current (or following) word. With a negative argument,
+do the previous word, but do not move point.
-@item downcase-word (@key{M-l})
-Lowercase all letters in the current (or following) word. With a
-negative argument, do the previous word, but do not move point.
+@item downcase-word (M-l)
+Lowercase the current (or following) word. With a negative argument,
+do the previous word, but do not move point.
-@item capitalize-word (@key{M-c})
-Uppercase the first letter in the current (or following) word. With a
-negative argument, do the previous word, but do not move point.
+@item capitalize-word (M-c)
+Uppercase the current (or following) word. With a negative argument,
+do the previous word, but do not move point.
@end ftable
@@ -448,32 +456,32 @@ negative argument, do the previous word, but do not move point.
@ftable @code
-@item kill-line (@key{C-k})
+@item kill-line (C-k)
Kill the text from the current cursor position to the end of the line.
@item backward-kill-line ()
Kill backward to the beginning of the line. This is normally unbound.
-@item kill-word (@key{M-d})
+@item kill-word (M-d)
Kill from the cursor to the end of the current word, or if between
words, to the end of the next word.
-@item backward-kill-word (@key{M-DEL})
+@item backward-kill-word (M-DEL)
Kill the word behind the cursor.
-@item unix-line-discard (@key{C-u})
-Do what @key{C-u} used to do in Unix line input. We save the killed text on
+@item unix-line-discard (C-u)
+Do what C-u used to do in Unix line input. We save the killed text on
the kill-ring, though.
-@item unix-word-rubout (@key{C-w})
-Do what @key{C-w} used to do in Unix line input. The killed text is saved
+@item unix-word-rubout (C-w)
+Do what C-w used to do in Unix line input. The killed text is saved
on the kill-ring. This is different than backward-kill-word because
the word boundaries differ.
-@item yank (@key{C-y})
+@item yank (C-y)
Yank the top of the kill ring into the buffer at point.
-@item yank-pop (@key{M-y})
+@item yank-pop (M-y)
Rotate the kill-ring, and yank the new top. You can only do this if
the prior command is yank or yank-pop.
@end ftable
@@ -482,12 +490,12 @@ the prior command is yank or yank-pop.
@subsubsection Specifying Numeric Arguments
@ftable @code
-@item digit-argument (@key{M-0}, @key{M-1}, ... @key{M--})
+@item digit-argument (M-0, M-1, ... M--)
Add this digit to the argument already accumulating, or start a new
-argument. @key{M--} starts a negative argument.
+argument. M-- starts a negative argument.
@item universal-argument ()
-Do what @key{C-u} does in emacs. By default, this is not bound.
+Do what C-u does in emacs. By default, this is not bound.
@end ftable
@@ -511,30 +519,25 @@ List the possible completions of the text before point.
@subsubsection Some Miscellaneous Commands
@ftable @code
-@item re-read-init-file (@key{C-x} @key{C-r})
+@item re-read-init-file (C-x C-r)
Read in the contents of your @file{~/.inputrc} file, and incorporate
any bindings found there.
-@item abort (@key{C-g})
-Stop running the current editing command.
+@item abort (C-g)
+Ding! Stops things.
-@ignore
-@c I have no idea what this means, and can't figure it out by
-@c experiment, and can't find it in the readline source.
-@c pesch@cygnus.com, 20may1993.
-@item do-uppercase-version (@key{M-a}, @key{M-b}, ...)
+@item do-uppercase-version (M-a, M-b, ...)
Run the command that is bound to your uppercase brother.
-@end ignore
@item prefix-meta (ESC)
Make the next character that you type be metafied. This is for people
-without a meta key. Typing @key{ESC f} is equivalent to typing
-@key{M-f}.
+without a meta key. Typing @samp{ESC f} is equivalent to typing
+@samp{M-f}.
-@item undo (@key{C-_})
+@item undo (C-_)
Incremental undo, separately remembered for each line.
-@item revert-line (@key{M-r})
+@item revert-line (M-r)
Undo all changes made to this line. This is like typing the `undo'
command enough times to get back to the beginning.
@end ftable
@@ -542,17 +545,14 @@ command enough times to get back to the beginning.
@node Readline Vi Mode
@subsection Readline Vi Mode
-@cindex @code{vi} style command editing
-@kindex toggle-editing-mode
While the Readline library does not have a full set of Vi editing
functions, it does contain enough to allow simple editing of the line.
In order to switch interactively between Emacs and Vi editing modes, use
-the command @key{M-C-j} (toggle-editing-mode).
+the command M-C-j (toggle-editing-mode).
When you enter a line in Vi mode, you are already placed in `insertion'
mode, as if you had typed an `i'. Pressing @key{ESC} switches you into
`edit' mode, where you can edit the text of the line with the standard
Vi movement keys, move to previous history lines with `k', and following
lines with `j', and so forth.
-
diff --git a/gnu/lib/libreadline/doc/texindex.c b/gnu/lib/libreadline/doc/texindex.c
new file mode 100644
index 0000000..cb979da
--- /dev/null
+++ b/gnu/lib/libreadline/doc/texindex.c
@@ -0,0 +1,1606 @@
+/* Prepare Tex index dribble output into an actual index.
+ Copyright (C) 1987 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 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+extern int errno;
+
+#ifdef VMS
+#ifndef VAX11C
+#define noshare
+#endif
+
+#include <perror.h>
+#include <file.h>
+
+#define EXIT_SUCCESS ((1 << 28) | 1)
+#define EXIT_FATAL ((1 << 28) | 4)
+#define unlink delete
+#define tell(fd) lseek(fd, 0L, 1)
+
+#else /* Not VMS */
+
+#ifdef USG
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#endif
+#include <sys/file.h>
+
+#define EXIT_SUCCESS 0
+#define EXIT_FATAL 1
+
+#endif /* Not VMS */
+
+
+#ifndef L_XTND
+#define L_XTND 2
+#endif
+
+#ifdef VMS
+extern noshare int sys_nerr;
+extern noshare char *sys_errlist[];
+#else
+extern int sys_nerr;
+extern char *sys_errlist[];
+#endif
+
+/* When sorting in core, this structure describes one line
+ and the position and length of its first keyfield. */
+
+struct lineinfo
+ {
+ char *text; /* The actual text of the line */
+ union
+ { /* The start of the key (for textual comparison) */
+ char *text;
+ long number; /* or the numeric value (for numeric comparison) */
+ } key;
+ long keylen; /* Length of key field */
+ };
+
+/* This structure describes a field to use as a sort key */
+
+struct keyfield
+ {
+ int startwords; /* # words to skip */
+ int startchars; /* and # additional chars to skip, to start of field */
+ int endwords; /* similar, from beg (or end) of line, to find end of field */
+ int endchars;
+ char ignore_blanks; /* Ignore spaces and tabs within the field */
+ char fold_case; /* Convert upper case to lower before comparing */
+ char reverse; /* Compare in reverse order */
+ char numeric; /* Parse text as an integer and compare the integers */
+ char positional; /* Sort according to position within the file */
+ char braced; /* Count balanced-braced groupings as fields */
+ };
+
+/* Vector of keyfields to use */
+
+struct keyfield keyfields[3];
+
+/* Number of keyfields stored in that vector. */
+
+int num_keyfields = 3;
+
+/* Vector of input file names, terminated with a zero (null pointer) */
+
+char **infiles;
+
+/* Vector of corresponding output file names, or zero meaning default it */
+
+char **outfiles;
+
+/* Length of `infiles' */
+
+int num_infiles;
+
+/* Pointer to the array of pointers to lines being sorted */
+
+char **linearray;
+
+/* The allocated length of `linearray'. */
+
+long nlines;
+
+/* Directory to use for temporary files. On Unix, it ends with a slash. */
+
+char *tempdir;
+
+/* Start of filename to use for temporary files. */
+
+char *tempbase;
+
+/* Number of last temporary file. */
+
+int tempcount;
+
+/* Number of last temporary file already deleted.
+ Temporary files are deleted by `flush_tempfiles' in order of creation. */
+
+int last_deleted_tempcount;
+
+/* During in-core sort, this points to the base of the data block
+ which contains all the lines of data. */
+
+char *text_base;
+
+/* Additional command switches */
+
+int keep_tempfiles; /* Nonzero means do not delete tempfiles -- for debugging */
+
+/* Forward declarations of functions in this file */
+
+void decode_command ();
+void sort_in_core ();
+void sort_offline ();
+char **parsefile ();
+char *find_field ();
+char *find_pos ();
+long find_value ();
+char *find_braced_pos ();
+char *find_braced_end ();
+void writelines ();
+int compare_full ();
+long readline ();
+int merge_files ();
+int merge_direct ();
+char *concat ();
+char *maketempname ();
+void flush_tempfiles ();
+char *tempcopy ();
+
+extern char *mktemp ();
+
+#define MAX_IN_CORE_SORT 500000
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+
+ tempcount = 0;
+ last_deleted_tempcount = 0;
+
+ /* Describe the kind of sorting to do. */
+ /* The first keyfield uses the first braced field and folds case */
+ keyfields[0].braced = 1;
+ keyfields[0].fold_case = 1;
+ keyfields[0].endwords = -1;
+ keyfields[0].endchars = -1;
+ /* The second keyfield uses the second braced field, numerically */
+ keyfields[1].braced = 1;
+ keyfields[1].numeric = 1;
+ keyfields[1].startwords = 1;
+ keyfields[1].endwords = -1;
+ keyfields[1].endchars = -1;
+ /* The third keyfield (which is ignored while discarding duplicates)
+ compares the whole line */
+ keyfields[2].endwords = -1;
+ keyfields[2].endchars = -1;
+
+ decode_command (argc, argv);
+
+ tempbase = mktemp (concat ("txiXXXXXX", "", ""));
+
+ /* Process input files completely, one by one. */
+
+ for (i = 0; i < num_infiles; i++)
+ {
+ int desc;
+ long ptr;
+ char *outfile;
+ char *p;
+
+ desc = open (infiles[i], 0, 0);
+ if (desc < 0) pfatal_with_name (infiles[i]);
+ lseek (desc, 0, L_XTND);
+ ptr = tell (desc);
+ close (desc);
+
+ outfile = outfiles[i];
+ if (!outfile)
+ {
+ outfile = concat (infiles[i], "s", "");
+ }
+
+ if (ptr < MAX_IN_CORE_SORT)
+ /* Sort a small amount of data */
+ sort_in_core (infiles[i], ptr, outfile);
+ else
+ sort_offline (infiles[i], ptr, outfile);
+ }
+
+ flush_tempfiles (tempcount);
+ exit (EXIT_SUCCESS);
+}
+
+/* This page decodes the command line arguments to set the parameter variables
+ and set up the vector of keyfields and the vector of input files */
+
+void
+decode_command (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ char **ip;
+ char **op;
+
+ /* Store default values into parameter variables */
+
+#ifdef VMS
+ tempdir = "sys$scratch:";
+#else
+ tempdir = "/tmp/";
+#endif
+
+ keep_tempfiles = 0;
+
+ /* Allocate argc input files, which must be enough. */
+
+ infiles = (char **) xmalloc (argc * sizeof (char *));
+ outfiles = (char **) xmalloc (argc * sizeof (char *));
+ ip = infiles;
+ op = outfiles;
+
+ /* First find all switches that control the default kind-of-sort */
+
+ for (i = 1; i < argc; i++)
+ {
+ int tem = classify_arg (argv[i]);
+ char c;
+ char *p;
+
+ if (tem <= 0)
+ {
+ *ip++ = argv[i];
+ *op++ = 0;
+ continue;
+ }
+ if (tem > 1)
+ {
+ if (i + 1 == argc)
+ fatal ("switch %s given with no argument following it", argv[i]);
+ else if (!strcmp (argv[i], "-T"))
+ tempdir = argv[i + 1];
+ else if (!strcmp (argv[i], "-o"))
+ *(op - 1) = argv[i + 1];
+ i += tem - 1;
+ continue;
+ }
+
+ p = &argv[i][1];
+ while (c = *p++)
+ switch (c)
+ {
+ case 'k':
+ keep_tempfiles = 1;
+ break;
+
+ default:
+ fatal ("invalid command switch %c", c);
+ }
+ switchdone: ;
+ }
+
+ /* Record number of keyfields, terminate list of filenames */
+
+ num_infiles = ip - infiles;
+ *ip = 0;
+}
+
+/* Return 0 for an argument that is not a switch;
+ for a switch, return 1 plus the number of following arguments that the switch swallows.
+*/
+
+int
+classify_arg (arg)
+ char *arg;
+{
+ if (!strcmp (arg, "-T") || !strcmp (arg, "-o"))
+ return 2;
+ if (arg[0] == '-')
+ return 1;
+ return 0;
+}
+
+/* Create a name for a temporary file */
+
+char *
+maketempname (count)
+ int count;
+{
+ char tempsuffix[10];
+ sprintf (tempsuffix, "%d", count);
+ return concat (tempdir, tempbase, tempsuffix);
+}
+
+/* Delete all temporary files up to the specified count */
+
+void
+flush_tempfiles (to_count)
+ int to_count;
+{
+ if (keep_tempfiles) return;
+ while (last_deleted_tempcount < to_count)
+ unlink (maketempname (++last_deleted_tempcount));
+}
+
+/* Copy an input file into a temporary file, and return the temporary file name */
+
+#define BUFSIZE 1024
+
+char *
+tempcopy (idesc)
+ int idesc;
+{
+ char *outfile = maketempname (++tempcount);
+ int odesc;
+ char buffer[BUFSIZE];
+
+ odesc = open (outfile, O_WRONLY | O_CREAT, 0666);
+
+ if (odesc < 0) pfatal_with_name (outfile);
+
+ while (1)
+ {
+ int nread = read (idesc, buffer, BUFSIZE);
+ write (odesc, buffer, nread);
+ if (!nread) break;
+ }
+
+ close (odesc);
+
+ return outfile;
+}
+
+/* Compare two lines, provided as pointers to pointers to text,
+ according to the specified set of keyfields */
+
+int
+compare_full (line1, line2)
+ char **line1, **line2;
+{
+ int i;
+
+ /* Compare using the first keyfield;
+ if that does not distinguish the lines, try the second keyfield; and so on. */
+
+ for (i = 0; i < num_keyfields; i++)
+ {
+ long length1, length2;
+ char *start1 = find_field (&keyfields[i], *line1, &length1);
+ char *start2 = find_field (&keyfields[i], *line2, &length2);
+ int tem = compare_field (&keyfields[i], start1, length1, *line1 - text_base,
+ start2, length2, *line2 - text_base);
+ if (tem)
+ {
+ if (keyfields[i].reverse)
+ return - tem;
+ return tem;
+ }
+ }
+
+ return 0; /* Lines match exactly */
+}
+
+/* Compare two lines described by structures
+ in which the first keyfield is identified in advance.
+ For positional sorting, assumes that the order of the lines in core
+ reflects their nominal order. */
+
+int
+compare_prepared (line1, line2)
+ struct lineinfo *line1, *line2;
+{
+ int i;
+ int tem;
+ char *text1, *text2;
+
+ /* Compare using the first keyfield, which has been found for us already */
+ if (keyfields->positional)
+ {
+ if (line1->text - text_base > line2->text - text_base)
+ tem = 1;
+ else
+ tem = -1;
+ }
+ else if (keyfields->numeric)
+ tem = line1->key.number - line2->key.number;
+ else
+ tem = compare_field (keyfields, line1->key.text, line1->keylen, 0, line2->key.text, line2->keylen, 0);
+ if (tem)
+ {
+ if (keyfields->reverse)
+ return - tem;
+ return tem;
+ }
+
+ text1 = line1->text;
+ text2 = line2->text;
+
+ /* Compare using the second keyfield;
+ if that does not distinguish the lines, try the third keyfield; and so on. */
+
+ for (i = 1; i < num_keyfields; i++)
+ {
+ long length1, length2;
+ char *start1 = find_field (&keyfields[i], text1, &length1);
+ char *start2 = find_field (&keyfields[i], text2, &length2);
+ int tem = compare_field (&keyfields[i], start1, length1, text1 - text_base,
+ start2, length2, text2 - text_base);
+ if (tem)
+ {
+ if (keyfields[i].reverse)
+ return - tem;
+ return tem;
+ }
+ }
+
+ return 0; /* Lines match exactly */
+}
+
+/* Like compare_full but more general.
+ You can pass any strings, and you can say how many keyfields to use.
+ `pos1' and `pos2' should indicate the nominal positional ordering of
+ the two lines in the input. */
+
+int
+compare_general (str1, str2, pos1, pos2, use_keyfields)
+ char *str1, *str2;
+ long pos1, pos2;
+ int use_keyfields;
+{
+ int i;
+
+ /* Compare using the first keyfield;
+ if that does not distinguish the lines, try the second keyfield; and so on. */
+
+ for (i = 0; i < use_keyfields; i++)
+ {
+ long length1, length2;
+ char *start1 = find_field (&keyfields[i], str1, &length1);
+ char *start2 = find_field (&keyfields[i], str2, &length2);
+ int tem = compare_field (&keyfields[i], start1, length1, pos1, start2, length2, pos2);
+ if (tem)
+ {
+ if (keyfields[i].reverse)
+ return - tem;
+ return tem;
+ }
+ }
+
+ return 0; /* Lines match exactly */
+}
+
+/* Find the start and length of a field in `str' according to `keyfield'.
+ A pointer to the starting character is returned, and the length
+ is stored into the int that `lengthptr' points to. */
+
+char *
+find_field (keyfield, str, lengthptr)
+ struct keyfield *keyfield;
+ char *str;
+ long *lengthptr;
+{
+ char *start;
+ char *end;
+ char *(*fun) ();
+
+ if (keyfield->braced) fun = find_braced_pos;
+ else fun = find_pos;
+
+ start = ( *fun )(str, keyfield->startwords, keyfield->startchars,
+ keyfield->ignore_blanks);
+ if (keyfield->endwords < 0)
+ {
+ if (keyfield->braced)
+ end = find_braced_end (start);
+ else
+ {
+ end = start;
+ while (*end && *end != '\n') end++;
+ }
+ }
+ else
+ {
+ end = ( *fun )(str, keyfield->endwords, keyfield->endchars, 0);
+ if (end - str < start - str) end = start;
+ }
+ *lengthptr = end - start;
+ return start;
+}
+
+/* Find a pointer to a specified place within `str',
+ skipping (from the beginning) `words' words and then `chars' chars.
+ If `ignore_blanks' is nonzero, we skip all blanks
+ after finding the specified word. */
+
+char *
+find_pos (str, words, chars, ignore_blanks)
+ char *str;
+ int words, chars;
+ int ignore_blanks;
+{
+ int i;
+ char *p = str;
+
+ for (i = 0; i < words; i++)
+ {
+ char c;
+ /* Find next bunch of nonblanks and skip them. */
+ while ((c = *p) == ' ' || c == '\t') p++;
+ while ((c = *p) && c != '\n' && !(c == ' ' || c == '\t')) p++;
+ if (!*p || *p == '\n') return p;
+ }
+
+ while (*p == ' ' || *p == '\t') p++;
+
+ for (i = 0; i < chars; i++)
+ {
+ if (!*p || *p == '\n') break;
+ p++;
+ }
+ return p;
+}
+
+/* Like find_pos but assumes that each field is surrounded by braces
+ and that braces within fields are balanced. */
+
+char *
+find_braced_pos (str, words, chars, ignore_blanks)
+ char *str;
+ int words, chars;
+ int ignore_blanks;
+{
+ int i;
+ int bracelevel;
+ char *p = str;
+ char c;
+
+ for (i = 0; i < words; i++)
+ {
+ bracelevel = 1;
+ while ((c = *p++) != '{' && c != '\n' && c);
+ if (c != '{')
+ return p - 1;
+ while (bracelevel)
+ {
+ c = *p++;
+ if (c == '{') bracelevel++;
+ if (c == '}') bracelevel--;
+#if 0
+ if (c == '\\' || c == '@') c = *p++; /* \ quotes braces and \ */
+#endif
+ if (c == 0 || c == '\n') return p-1;
+ }
+ }
+
+ while ((c = *p++) != '{' && c != '\n' && c);
+
+ if (c != '{')
+ return p-1;
+
+ if (ignore_blanks)
+ while ((c = *p) == ' ' || c == '\t') p++;
+
+ for (i = 0; i < chars; i++)
+ {
+ if (!*p || *p == '\n') break;
+ p++;
+ }
+ return p;
+}
+
+/* Find the end of the balanced-brace field which starts at `str'.
+ The position returned is just before the closing brace. */
+
+char *
+find_braced_end (str)
+ char *str;
+{
+ int bracelevel;
+ char *p = str;
+ char c;
+
+ bracelevel = 1;
+ while (bracelevel)
+ {
+ c = *p++;
+ if (c == '{') bracelevel++;
+ if (c == '}') bracelevel--;
+#if 0
+ if (c == '\\' || c == '@') c = *p++;
+#endif
+ if (c == 0 || c == '\n') return p-1;
+ }
+ return p - 1;
+}
+
+long
+find_value (start, length)
+ char *start;
+ long length;
+{
+ while (length != 0L) {
+ if (isdigit(*start))
+ return atol(start);
+ length--;
+ start++;
+ }
+ return 0l;
+}
+
+/* Vector used to translate characters for comparison.
+ This is how we make all alphanumerics follow all else,
+ and ignore case in the first sorting. */
+int char_order[256];
+
+init_char_order ()
+{
+ int i;
+ for (i = 1; i < 256; i++)
+ char_order[i] = i;
+
+ for (i = '0'; i <= '9'; i++)
+ char_order[i] += 512;
+
+ for (i = 'a'; i <= 'z'; i++) {
+ char_order[i] = 512 + i;
+ char_order[i + 'A' - 'a'] = 512 + i;
+ }
+}
+
+/* Compare two fields (each specified as a start pointer and a character count)
+ according to `keyfield'. The sign of the value reports the relation between the fields */
+
+int
+compare_field (keyfield, start1, length1, pos1, start2, length2, pos2)
+ struct keyfield *keyfield;
+ char *start1;
+ long length1;
+ long pos1;
+ char *start2;
+ long length2;
+ long pos2;
+{
+ if (keyfields->positional)
+ {
+ if (pos1 > pos2)
+ return 1;
+ else
+ return -1;
+ }
+ if (keyfield->numeric)
+ {
+ long value = find_value (start1, length1) - find_value (start2, length2);
+ if (value > 0) return 1;
+ if (value < 0) return -1;
+ return 0;
+ }
+ else
+ {
+ char *p1 = start1;
+ char *p2 = start2;
+ char *e1 = start1 + length1;
+ char *e2 = start2 + length2;
+
+ int fold_case = keyfield->fold_case;
+
+ while (1)
+ {
+ int c1, c2;
+
+ if (p1 == e1) c1 = 0;
+ else c1 = *p1++;
+ if (p2 == e2) c2 = 0;
+ else c2 = *p2++;
+
+ if (char_order[c1] != char_order[c2])
+ return char_order[c1] - char_order[c2];
+ if (!c1) break;
+ }
+
+ /* Strings are equal except possibly for case. */
+ p1 = start1;
+ p2 = start2;
+ while (1)
+ {
+ int c1, c2;
+
+ if (p1 == e1) c1 = 0;
+ else c1 = *p1++;
+ if (p2 == e2) c2 = 0;
+ else c2 = *p2++;
+
+ if (c1 != c2)
+ /* Reverse sign here so upper case comes out last. */
+ return c2 - c1;
+ if (!c1) break;
+ }
+
+ return 0;
+ }
+}
+
+/* A `struct linebuffer' is a structure which holds a line of text.
+ `readline' reads a line from a stream into a linebuffer
+ and works regardless of the length of the line. */
+
+struct linebuffer
+ {
+ long size;
+ char *buffer;
+ };
+
+/* Initialize a linebuffer for use */
+
+void
+initbuffer (linebuffer)
+ struct linebuffer *linebuffer;
+{
+ linebuffer->size = 200;
+ linebuffer->buffer = (char *) xmalloc (200);
+}
+
+/* Read a line of text from `stream' into `linebuffer'.
+ Return the length of the line. */
+
+long
+readline (linebuffer, stream)
+ struct linebuffer *linebuffer;
+ FILE *stream;
+{
+ char *buffer = linebuffer->buffer;
+ char *p = linebuffer->buffer;
+ char *end = p + linebuffer->size;
+
+ while (1)
+ {
+ int c = getc (stream);
+ if (p == end)
+ {
+ buffer = (char *) xrealloc (buffer, linebuffer->size *= 2);
+ p += buffer - linebuffer->buffer;
+ end += buffer - linebuffer->buffer;
+ linebuffer->buffer = buffer;
+ }
+ if (c < 0 || c == '\n')
+ {
+ *p = 0;
+ break;
+ }
+ *p++ = c;
+ }
+
+ return p - buffer;
+}
+
+/* Sort an input file too big to sort in core. */
+
+void
+sort_offline (infile, nfiles, total, outfile)
+ char *infile;
+ long total;
+ char *outfile;
+{
+ int ntemps = 2 * (total + MAX_IN_CORE_SORT - 1) / MAX_IN_CORE_SORT; /* More than enough */
+ char **tempfiles = (char **) xmalloc (ntemps * sizeof (char *));
+ FILE *istream = fopen (infile, "r");
+ int i;
+ struct linebuffer lb;
+ long linelength;
+ int failure = 0;
+
+ initbuffer (&lb);
+
+ /* Read in one line of input data. */
+
+ linelength = readline (&lb, istream);
+
+ if (lb.buffer[0] != '\\' && lb.buffer[0] != '@')
+ {
+ error ("%s: not a texinfo index file", infile);
+ return;
+ }
+
+ /* Split up the input into `ntemps' temporary files, or maybe fewer,
+ and put the new files' names into `tempfiles' */
+
+ for (i = 0; i < ntemps; i++)
+ {
+ char *outname = maketempname (++tempcount);
+ FILE *ostream = fopen (outname, "w");
+ long tempsize = 0;
+
+ if (!ostream) pfatal_with_name (outname);
+ tempfiles[i] = outname;
+
+ /* Copy lines into this temp file as long as it does not make file "too big"
+ or until there are no more lines. */
+
+ while (tempsize + linelength + 1 <= MAX_IN_CORE_SORT)
+ {
+ tempsize += linelength + 1;
+ fputs (lb.buffer, ostream);
+ putc ('\n', ostream);
+
+ /* Read another line of input data. */
+
+ linelength = readline (&lb, istream);
+ if (!linelength && feof (istream)) break;
+
+ if (lb.buffer[0] != '\\' && lb.buffer[0] != '@')
+ {
+ error ("%s: not a texinfo index file", infile);
+ failure = 1;
+ goto fail;
+ }
+ }
+ fclose (ostream);
+ if (feof (istream)) break;
+ }
+
+ free (lb.buffer);
+
+ fail:
+ /* Record number of temp files we actually needed. */
+
+ ntemps = i;
+
+ /* Sort each tempfile into another tempfile.
+ Delete the first set of tempfiles and put the names of the second into `tempfiles' */
+
+ for (i = 0; i < ntemps; i++)
+ {
+ char *newtemp = maketempname (++tempcount);
+ sort_in_core (&tempfiles[i], MAX_IN_CORE_SORT, newtemp);
+ if (!keep_tempfiles)
+ unlink (tempfiles[i]);
+ tempfiles[i] = newtemp;
+ }
+
+ if (failure)
+ return;
+
+ /* Merge the tempfiles together and indexify */
+
+ merge_files (tempfiles, ntemps, outfile);
+}
+
+/* Sort `infile', whose size is `total',
+ assuming that is small enough to be done in-core,
+ then indexify it and send the output to `outfile' (or to stdout). */
+
+void
+sort_in_core (infile, total, outfile)
+ char *infile;
+ long total;
+ char *outfile;
+{
+ char **nextline;
+ char *data = (char *) xmalloc (total + 1);
+ char *file_data;
+ long file_size;
+ int i;
+ FILE *ostream = stdout;
+ struct lineinfo *lineinfo;
+
+ /* Read the contents of the file into the moby array `data' */
+
+ int desc = open (infile, 0, 0);
+
+ if (desc < 0)
+ fatal ("failure reopening %s", infile);
+ for (file_size = 0; ; )
+ {
+ if ((i = read (desc, data + file_size, total - file_size)) <= 0)
+ break;
+ file_size += i;
+ }
+ file_data = data;
+ data[file_size] = 0;
+
+ close (desc);
+
+ if (file_size > 0 && data[0] != '\\' && data[0] != '@')
+ {
+ error ("%s: not a texinfo index file", infile);
+ return;
+ }
+
+ init_char_order ();
+
+ /* Sort routines want to know this address */
+
+ text_base = data;
+
+ /* Create the array of pointers to lines, with a default size frequently enough. */
+
+ nlines = total / 50;
+ if (!nlines) nlines = 2;
+ linearray = (char **) xmalloc (nlines * sizeof (char *));
+
+ /* `nextline' points to the next free slot in this array.
+ `nlines' is the allocated size. */
+
+ nextline = linearray;
+
+ /* Parse the input file's data, and make entries for the lines. */
+
+ nextline = parsefile (infile, nextline, file_data, file_size);
+ if (nextline == 0)
+ {
+ error ("%s: not a texinfo index file", infile);
+ return;
+ }
+
+ /* Sort the lines */
+
+ /* If we have enough space, find the first keyfield of each line in advance.
+ Make a `struct lineinfo' for each line, which records the keyfield
+ as well as the line, and sort them. */
+
+ lineinfo = (struct lineinfo *) malloc ((nextline - linearray) * sizeof (struct lineinfo));
+
+ if (lineinfo)
+ {
+ struct lineinfo *lp;
+ char **p;
+
+ for (lp = lineinfo, p = linearray; p != nextline; lp++, p++)
+ {
+ lp->text = *p;
+ lp->key.text = find_field (keyfields, *p, &lp->keylen);
+ if (keyfields->numeric)
+ lp->key.number = find_value (lp->key.text, lp->keylen);
+ }
+
+ qsort (lineinfo, nextline - linearray, sizeof (struct lineinfo), compare_prepared);
+
+ for (lp = lineinfo, p = linearray; p != nextline; lp++, p++)
+ *p = lp->text;
+
+ free (lineinfo);
+ }
+ else
+ qsort (linearray, nextline - linearray, sizeof (char *), compare_full);
+
+ /* Open the output file */
+
+ if (outfile)
+ {
+ ostream = fopen (outfile, "w");
+ if (!ostream)
+ pfatal_with_name (outfile);
+ }
+
+ writelines (linearray, nextline - linearray, ostream);
+ if (outfile) fclose (ostream);
+
+ free (linearray);
+ free (data);
+}
+
+/* Parse an input string in core into lines.
+ DATA is the input string, and SIZE is its length.
+ Data goes in LINEARRAY starting at NEXTLINE.
+ The value returned is the first entry in LINEARRAY still unused.
+ Value 0 means input file contents are invalid. */
+
+char **
+parsefile (filename, nextline, data, size)
+ char *filename;
+ char **nextline;
+ char *data;
+ long size;
+{
+ char *p, *end;
+ char **line = nextline;
+
+ p = data;
+ end = p + size;
+ *end = 0;
+
+ while (p != end)
+ {
+ if (p[0] != '\\' && p[0] != '@')
+ return 0;
+
+ *line = p;
+ while (*p && *p != '\n') p++;
+ if (p != end) p++;
+
+ line++;
+ if (line == linearray + nlines)
+ {
+ char **old = linearray;
+ linearray = (char **) xrealloc (linearray, sizeof (char *) * (nlines *= 4));
+ line += linearray - old;
+ }
+ }
+
+ return line;
+}
+
+/* Indexification is a filter applied to the sorted lines
+ as they are being written to the output file.
+ Multiple entries for the same name, with different page numbers,
+ get combined into a single entry with multiple page numbers.
+ The first braced field, which is used for sorting, is discarded.
+ However, its first character is examined, folded to lower case,
+ and if it is different from that in the previous line fed to us
+ a \initial line is written with one argument, the new initial.
+
+ If an entry has four braced fields, then the second and third
+ constitute primary and secondary names.
+ In this case, each change of primary name
+ generates a \primary line which contains only the primary name,
+ and in between these are \secondary lines which contain
+ just a secondary name and page numbers.
+*/
+
+/* The last primary name we wrote a \primary entry for.
+ If only one level of indexing is being done, this is the last name seen */
+char *lastprimary;
+int lastprimarylength; /* Length of storage allocated for lastprimary */
+
+/* Similar, for the secondary name. */
+char *lastsecondary;
+int lastsecondarylength;
+
+/* Zero if we are not in the middle of writing an entry.
+ One if we have written the beginning of an entry but have not
+ yet written any page numbers into it.
+ Greater than one if we have written the beginning of an entry
+ plus at least one page number. */
+int pending;
+
+/* The initial (for sorting purposes) of the last primary entry written.
+ When this changes, a \initial {c} line is written */
+
+char * lastinitial;
+
+int lastinitiallength;
+
+/* When we need a string of length 1 for the value of lastinitial,
+ store it here. */
+
+char lastinitial1[2];
+
+/* Initialize static storage for writing an index */
+
+void
+init_index ()
+{
+ pending = 0;
+ lastinitial = lastinitial1;
+ lastinitial1[0] = 0;
+ lastinitial1[1] = 0;
+ lastinitiallength = 0;
+ lastprimarylength = 100;
+ lastprimary = (char *) xmalloc (lastprimarylength + 1);
+ bzero (lastprimary, lastprimarylength + 1);
+ lastsecondarylength = 100;
+ lastsecondary = (char *) xmalloc (lastsecondarylength + 1);
+ bzero (lastsecondary, lastsecondarylength + 1);
+}
+
+/* Indexify. Merge entries for the same name,
+ insert headers for each initial character, etc. */
+
+indexify (line, ostream)
+ char *line;
+ FILE *ostream;
+{
+ char *primary, *secondary, *pagenumber;
+ int primarylength, secondarylength, pagelength;
+ int len = strlen (line);
+ int nosecondary;
+ int initiallength;
+ char *initial;
+ char initial1[2];
+ register char *p;
+
+ /* First, analyze the parts of the entry fed to us this time */
+
+ p = find_braced_pos (line, 0, 0, 0);
+ if (*p == '{')
+ {
+ initial = p;
+ /* Get length of inner pair of braces starting at p,
+ including that inner pair of braces. */
+ initiallength = find_braced_end (p + 1) + 1 - p;
+ }
+ else
+ {
+ initial = initial1;
+ initial1[0] = *p;
+ initial1[1] = 0;
+ initiallength = 1;
+
+ if (initial1[0] >= 'a' && initial1[0] <= 'z')
+ initial1[0] -= 040;
+ }
+
+ pagenumber = find_braced_pos (line, 1, 0, 0);
+ pagelength = find_braced_end (pagenumber) - pagenumber;
+ if (pagelength == 0)
+ abort ();
+
+ primary = find_braced_pos (line, 2, 0, 0);
+ primarylength = find_braced_end (primary) - primary;
+
+ secondary = find_braced_pos (line, 3, 0, 0);
+ nosecondary = !*secondary;
+ if (!nosecondary)
+ secondarylength = find_braced_end (secondary) - secondary;
+
+ /* If the primary is different from before, make a new primary entry */
+ if (strncmp (primary, lastprimary, primarylength))
+ {
+ /* Close off current secondary entry first, if one is open */
+ if (pending)
+ {
+ fputs ("}\n", ostream);
+ pending = 0;
+ }
+
+ /* If this primary has a different initial, include an entry for the initial */
+ if (initiallength != lastinitiallength ||
+ strncmp (initial, lastinitial, initiallength))
+ {
+ fprintf (ostream, "\\initial {");
+ fwrite (initial, 1, initiallength, ostream);
+ fprintf (ostream, "}\n", initial);
+ if (initial == initial1)
+ {
+ lastinitial = lastinitial1;
+ *lastinitial1 = *initial1;
+ }
+ else
+ {
+ lastinitial = initial;
+ }
+ lastinitiallength = initiallength;
+ }
+
+ /* Make the entry for the primary. */
+ if (nosecondary)
+ fputs ("\\entry {", ostream);
+ else
+ fputs ("\\primary {", ostream);
+ fwrite (primary, primarylength, 1, ostream);
+ if (nosecondary)
+ {
+ fputs ("}{", ostream);
+ pending = 1;
+ }
+ else
+ fputs ("}\n", ostream);
+
+ /* Record name of most recent primary */
+ if (lastprimarylength < primarylength)
+ {
+ lastprimarylength = primarylength + 100;
+ lastprimary = (char *) xrealloc (lastprimary,
+ 1 + lastprimarylength);
+ }
+ strncpy (lastprimary, primary, primarylength);
+ lastprimary[primarylength] = 0;
+
+ /* There is no current secondary within this primary, now */
+ lastsecondary[0] = 0;
+ }
+
+ /* Should not have an entry with no subtopic following one with a subtopic */
+
+ if (nosecondary && *lastsecondary)
+ error ("entry %s follows an entry with a secondary name", line);
+
+ /* Start a new secondary entry if necessary */
+ if (!nosecondary && strncmp (secondary, lastsecondary, secondarylength))
+ {
+ if (pending)
+ {
+ fputs ("}\n", ostream);
+ pending = 0;
+ }
+
+ /* Write the entry for the secondary. */
+ fputs ("\\secondary {", ostream);
+ fwrite (secondary, secondarylength, 1, ostream);
+ fputs ("}{", ostream);
+ pending = 1;
+
+ /* Record name of most recent secondary */
+ if (lastsecondarylength < secondarylength)
+ {
+ lastsecondarylength = secondarylength + 100;
+ lastsecondary = (char *) xrealloc (lastsecondary,
+ 1 + lastsecondarylength);
+ }
+ strncpy (lastsecondary, secondary, secondarylength);
+ lastsecondary[secondarylength] = 0;
+ }
+
+ /* Here to add one more page number to the current entry */
+ if (pending++ != 1)
+ fputs (", ", ostream); /* Punctuate first, if this is not the first */
+ fwrite (pagenumber, pagelength, 1, ostream);
+}
+
+/* Close out any unfinished output entry */
+
+void
+finish_index (ostream)
+ FILE *ostream;
+{
+ if (pending)
+ fputs ("}\n", ostream);
+ free (lastprimary);
+ free (lastsecondary);
+}
+
+/* Copy the lines in the sorted order.
+ Each line is copied out of the input file it was found in. */
+
+void
+writelines (linearray, nlines, ostream)
+ char **linearray;
+ int nlines;
+ FILE *ostream;
+{
+ char **stop_line = linearray + nlines;
+ char **next_line;
+
+ init_index ();
+
+ /* Output the text of the lines, and free the buffer space */
+
+ for (next_line = linearray; next_line != stop_line; next_line++)
+ {
+ /* If -u was specified, output the line only if distinct from previous one. */
+ if (next_line == linearray
+ /* Compare previous line with this one, using only the explicitly specd keyfields */
+ || compare_general (*(next_line - 1), *next_line, 0L, 0L, num_keyfields - 1))
+ {
+ char *p = *next_line;
+ char c;
+ while ((c = *p++) && c != '\n');
+ *(p-1) = 0;
+ indexify (*next_line, ostream);
+ }
+ }
+
+ finish_index (ostream);
+}
+
+/* Assume (and optionally verify) that each input file is sorted;
+ merge them and output the result.
+ Returns nonzero if any input file fails to be sorted.
+
+ This is the high-level interface that can handle an unlimited number of files. */
+
+#define MAX_DIRECT_MERGE 10
+
+int
+merge_files (infiles, nfiles, outfile)
+ char **infiles;
+ int nfiles;
+ char *outfile;
+{
+ char **tempfiles;
+ int ntemps;
+ int i;
+ int value = 0;
+ int start_tempcount = tempcount;
+
+ if (nfiles <= MAX_DIRECT_MERGE)
+ return merge_direct (infiles, nfiles, outfile);
+
+ /* Merge groups of MAX_DIRECT_MERGE input files at a time,
+ making a temporary file to hold each group's result. */
+
+ ntemps = (nfiles + MAX_DIRECT_MERGE - 1) / MAX_DIRECT_MERGE;
+ tempfiles = (char **) xmalloc (ntemps * sizeof (char *));
+ for (i = 0; i < ntemps; i++)
+ {
+ int nf = MAX_DIRECT_MERGE;
+ if (i + 1 == ntemps)
+ nf = nfiles - i * MAX_DIRECT_MERGE;
+ tempfiles[i] = maketempname (++tempcount);
+ value |= merge_direct (&infiles[i * MAX_DIRECT_MERGE], nf, tempfiles[i]);
+ }
+
+ /* All temporary files that existed before are no longer needed
+ since their contents have been merged into our new tempfiles.
+ So delete them. */
+ flush_tempfiles (start_tempcount);
+
+ /* Now merge the temporary files we created. */
+
+ merge_files (tempfiles, ntemps, outfile);
+
+ free (tempfiles);
+
+ return value;
+}
+
+/* Assume (and optionally verify) that each input file is sorted;
+ merge them and output the result.
+ Returns nonzero if any input file fails to be sorted.
+
+ This version of merging will not work if the number of
+ input files gets too high. Higher level functions
+ use it only with a bounded number of input files. */
+
+int
+merge_direct (infiles, nfiles, outfile)
+ char **infiles;
+ int nfiles;
+ char *outfile;
+{
+ char **ip = infiles;
+ struct linebuffer *lb1, *lb2;
+ struct linebuffer **thisline, **prevline;
+ FILE **streams;
+ int i;
+ int nleft;
+ int lossage = 0;
+ int *file_lossage;
+ struct linebuffer *prev_out = 0;
+ FILE *ostream = stdout;
+
+ if (outfile)
+ {
+ ostream = fopen (outfile, "w");
+ }
+ if (!ostream) pfatal_with_name (outfile);
+
+ init_index ();
+
+ if (nfiles == 0)
+ {
+ if (outfile)
+ fclose (ostream);
+ return 0;
+ }
+
+ /* For each file, make two line buffers.
+ Also, for each file, there is an element of `thisline'
+ which points at any time to one of the file's two buffers,
+ and an element of `prevline' which points to the other buffer.
+ `thisline' is supposed to point to the next available line from the file,
+ while `prevline' holds the last file line used,
+ which is remembered so that we can verify that the file is properly sorted. */
+
+ /* lb1 and lb2 contain one buffer each per file */
+ lb1 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer));
+ lb2 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer));
+
+ /* thisline[i] points to the linebuffer holding the next available line in file i,
+ or is zero if there are no lines left in that file. */
+ thisline = (struct linebuffer **) xmalloc (nfiles * sizeof (struct linebuffer *));
+ /* prevline[i] points to the linebuffer holding the last used line from file i.
+ This is just for verifying that file i is properly sorted. */
+ prevline = (struct linebuffer **) xmalloc (nfiles * sizeof (struct linebuffer *));
+ /* streams[i] holds the input stream for file i. */
+ streams = (FILE **) xmalloc (nfiles * sizeof (FILE *));
+ /* file_lossage[i] is nonzero if we already know file i is not properly sorted. */
+ file_lossage = (int *) xmalloc (nfiles * sizeof (int));
+
+ /* Allocate and initialize all that storage */
+
+ for (i = 0; i < nfiles; i++)
+ {
+ initbuffer (&lb1[i]);
+ initbuffer (&lb2[i]);
+ thisline[i] = &lb1[i];
+ prevline[i] = &lb2[i];
+ file_lossage[i] = 0;
+ streams[i] = fopen (infiles[i], "r");
+ if (!streams[i])
+ pfatal_with_name (infiles[i]);
+
+ readline (thisline[i], streams[i]);
+ }
+
+ /* Keep count of number of files not at eof */
+ nleft = nfiles;
+
+ while (nleft)
+ {
+ struct linebuffer *best = 0;
+ struct linebuffer *exch;
+ int bestfile = -1;
+ int i;
+
+ /* Look at the next avail line of each file; choose the least one. */
+
+ for (i = 0; i < nfiles; i++)
+ {
+ if (thisline[i] &&
+ (!best ||
+ 0 < compare_general (best->buffer, thisline[i]->buffer,
+ (long) bestfile, (long) i, num_keyfields)))
+ {
+ best = thisline[i];
+ bestfile = i;
+ }
+ }
+
+ /* Output that line, unless it matches the previous one and we don't want duplicates */
+
+ if (!(prev_out &&
+ !compare_general (prev_out->buffer, best->buffer, 0L, 1L, num_keyfields - 1)))
+ indexify (best->buffer, ostream);
+ prev_out = best;
+
+ /* Now make the line the previous of its file, and fetch a new line from that file */
+
+ exch = prevline[bestfile];
+ prevline[bestfile] = thisline[bestfile];
+ thisline[bestfile] = exch;
+
+ while (1)
+ {
+ /* If the file has no more, mark it empty */
+
+ if (feof (streams[bestfile]))
+ {
+ thisline[bestfile] = 0;
+ nleft--; /* Update the number of files still not empty */
+ break;
+ }
+ readline (thisline[bestfile], streams[bestfile]);
+ if (thisline[bestfile]->buffer[0] || !feof (streams[bestfile])) break;
+ }
+ }
+
+ finish_index (ostream);
+
+ /* Free all storage and close all input streams */
+
+ for (i = 0; i < nfiles; i++)
+ {
+ fclose (streams[i]);
+ free (lb1[i].buffer);
+ free (lb2[i].buffer);
+ }
+ free (file_lossage);
+ free (lb1);
+ free (lb2);
+ free (thisline);
+ free (prevline);
+ free (streams);
+
+ if (outfile)
+ fclose (ostream);
+
+ return lossage;
+}
+
+/* Print error message and exit. */
+
+fatal (s1, s2)
+ char *s1, *s2;
+{
+ error (s1, s2);
+ exit (EXIT_FATAL);
+}
+
+/* Print error message. `s1' is printf control string, `s2' is arg for it. */
+
+error (s1, s2)
+ char *s1, *s2;
+{
+ printf ("texindex: ");
+ printf (s1, s2);
+ printf ("\n");
+}
+
+perror_with_name (name)
+ char *name;
+{
+ char *s;
+
+ if (errno < sys_nerr)
+ s = concat ("", sys_errlist[errno], " for %s");
+ else
+ s = "cannot open %s";
+ error (s, name);
+}
+
+pfatal_with_name (name)
+ char *name;
+{
+ char *s;
+
+ if (errno < sys_nerr)
+ s = concat ("", sys_errlist[errno], " for %s");
+ else
+ s = "cannot open %s";
+ fatal (s, name);
+}
+
+/* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
+
+char *
+concat (s1, s2, s3)
+ char *s1, *s2, *s3;
+{
+ int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
+ char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
+
+ strcpy (result, s1);
+ strcpy (result + len1, s2);
+ strcpy (result + len1 + len2, s3);
+ *(result + len1 + len2 + len3) = 0;
+
+ return result;
+}
+
+/* Like malloc but get fatal error if memory is exhausted. */
+
+int
+xmalloc (size)
+ int size;
+{
+ int result = malloc (size);
+ if (!result)
+ fatal ("virtual memory exhausted", 0);
+ return result;
+}
+
+
+int
+xrealloc (ptr, size)
+ char *ptr;
+ int size;
+{
+ int result = realloc (ptr, size);
+ if (!result)
+ fatal ("virtual memory exhausted");
+ return result;
+}
+
+bzero (b, length)
+ register char *b;
+ register int length;
+{
+#ifdef VMS
+ short zero = 0;
+ long max_str = 65535;
+ long len;
+
+ while (length > max_str)
+ {
+ (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
+ length -= max_str;
+ b += max_str;
+ }
+ len = length;
+ (void) LIB$MOVC5 (&zero, &zero, &zero, &len, b);
+#else
+ while (length-- > 0)
+ *b++ = 0;
+#endif /* not VMS */
+}
diff --git a/gnu/lib/libreadline/emacs_keymap.c b/gnu/lib/libreadline/emacs_keymap.c
index 37f93de..ebaaead 100644
--- a/gnu/lib/libreadline/emacs_keymap.c
+++ b/gnu/lib/libreadline/emacs_keymap.c
@@ -1,23 +1,30 @@
/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */
-/* Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
- This file is part of GNU Readline, a library for reading lines
- of text with interactive input and history editing.
+ This file is part of the GNU Readline Library, 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 2 of the License, or
+ The GNU Readline Library 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 1, 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
+ The GNU Readline Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#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
@@ -69,7 +76,11 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
{ ISFUNC, rl_insert }, /* & */
{ ISFUNC, rl_insert }, /* ' */
{ ISFUNC, rl_insert }, /* ( */
+#if defined (PAREN_MATCHING)
+ { ISFUNC, rl_insert_close }, /* ) */
+#else
{ ISFUNC, rl_insert }, /* ) */
+#endif /* !PAREN_MATCHING */
{ ISFUNC, rl_insert }, /* * */
{ ISFUNC, rl_insert }, /* + */
{ ISFUNC, rl_insert }, /* , */
@@ -129,7 +140,11 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
/* Some more punctuation. */
{ ISFUNC, rl_insert }, /* [ */
{ ISFUNC, rl_insert }, /* \ */
+#if defined (PAREN_MATCHING)
+ { ISFUNC, rl_insert_close }, /* ] */
+#else
{ ISFUNC, rl_insert }, /* ] */
+#endif /* !PAREN_MATCHING */
{ ISFUNC, rl_insert }, /* ^ */
{ ISFUNC, rl_insert }, /* _ */
{ ISFUNC, rl_insert }, /* ` */
@@ -165,9 +180,149 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
/* Final punctuation. */
{ ISFUNC, rl_insert }, /* { */
{ ISFUNC, rl_insert }, /* | */
+#if defined (PAREN_MATCHING)
+ { ISFUNC, rl_insert_close }, /* } */
+#else
{ ISFUNC, rl_insert }, /* } */
+#endif /* !PAREN_MATCHING */
{ ISFUNC, rl_insert }, /* ~ */
- { ISFUNC, rl_rubout } /* RUBOUT */
+ { 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 /* MEYMAP_SIZE > 128 */
};
KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
@@ -214,7 +369,7 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
{ ISFUNC, (Function *)0x0 }, /* Meta-# */
{ ISFUNC, (Function *)0x0 }, /* Meta-$ */
{ ISFUNC, (Function *)0x0 }, /* Meta-% */
- { ISFUNC, (Function *)0x0 }, /* Meta-& */
+ { ISFUNC, rl_tilde_expand }, /* Meta-& */
{ ISFUNC, (Function *)0x0 }, /* Meta-' */
{ ISFUNC, (Function *)0x0 }, /* Meta-( */
{ ISFUNC, (Function *)0x0 }, /* Meta-) */
@@ -275,12 +430,12 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
{ ISFUNC, rl_do_lowercase_version }, /* Meta-Z */
/* Some more punctuation. */
- { ISFUNC, rl_arrow_keys }, /* Meta-[ */
- { ISFUNC, (Function *)0x0 }, /* Meta-\ */
- { ISFUNC, (Function *)0x0 }, /* Meta-] */
- { ISFUNC, (Function *)0x0 }, /* Meta-^ */
- { ISFUNC, (Function *)0x0 }, /* Meta-_ */
- { ISFUNC, (Function *)0x0 }, /* Meta-` */
+ { ISFUNC, rl_arrow_keys }, /* Meta-[ */
+ { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-] */
+ { ISFUNC, (Function *)0x0 }, /* Meta-^ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-_ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-` */
/* Lowercase alphabet. */
{ ISFUNC, (Function *)0x0 }, /* Meta-a */
@@ -296,9 +451,9 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
{ ISFUNC, (Function *)0x0 }, /* Meta-k */
{ ISFUNC, rl_downcase_word }, /* Meta-l */
{ ISFUNC, (Function *)0x0 }, /* Meta-m */
- { ISFUNC, (Function *)0x0 }, /* Meta-n */
+ { ISFUNC, rl_noninc_forward_search }, /* Meta-n */
{ ISFUNC, rl_arrow_keys }, /* Meta-o */
- { ISFUNC, (Function *)0x0 }, /* Meta-p */
+ { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */
{ ISFUNC, (Function *)0x0 }, /* Meta-q */
{ ISFUNC, rl_revert_line }, /* Meta-r */
{ ISFUNC, (Function *)0x0 }, /* Meta-s */
@@ -315,7 +470,139 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
{ ISFUNC, (Function *)0x0 }, /* Meta-| */
{ ISFUNC, (Function *)0x0 }, /* Meta-} */
{ ISFUNC, (Function *)0x0 }, /* Meta-~ */
- { ISFUNC, rl_backward_kill_word } /* Meta-rubout */
+ { ISFUNC, rl_backward_kill_word }, /* Meta-rubout */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
};
KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
@@ -462,5 +749,137 @@ KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
{ ISFUNC, (Function *)0x0 }, /* | */
{ ISFUNC, (Function *)0x0 }, /* } */
{ ISFUNC, (Function *)0x0 }, /* ~ */
- { ISFUNC, rl_backward_kill_line } /* RUBOUT */
+ { ISFUNC, rl_backward_kill_line }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
};
diff --git a/gnu/lib/libreadline/examples/fileman.c b/gnu/lib/libreadline/examples/fileman.c
index 0adc2a1..d1e72c5 100644
--- a/gnu/lib/libreadline/examples/fileman.c
+++ b/gnu/lib/libreadline/examples/fileman.c
@@ -247,11 +247,7 @@ com_list (arg)
if (!arg)
arg = "*";
-#ifdef __GO32__
- sprintf (syscom, "ls -lp %s", arg);
-#else
sprintf (syscom, "ls -FClg %s", arg);
-#endif
system (syscom);
}
@@ -397,49 +393,3 @@ valid_argument (caller, arg)
* compile-command: "cc -g -I../.. -L.. -o fileman fileman.c -lreadline -ltermcap"
* end:
*/
-
-#ifdef __GO32__
-/* **************************************************************** */
-/* */
-/* xmalloc and xrealloc () */
-/* */
-/* **************************************************************** */
-
-static void memory_error_and_abort ();
-
-char *
-xmalloc (bytes)
- int bytes;
-{
- char *temp = (char *)malloc (bytes);
-
- if (!temp)
- memory_error_and_abort ();
- return (temp);
-}
-
-char *
-xrealloc (pointer, bytes)
- char *pointer;
- int bytes;
-{
- char *temp;
-
- if (!pointer)
- temp = (char *)xmalloc (bytes);
- else
- temp = (char *)realloc (pointer, bytes);
-
- if (!temp)
- memory_error_and_abort ();
-
- return (temp);
-}
-
-static void
-memory_error_and_abort ()
-{
- fprintf (stderr, "xmalloc: Out of virtual memory!\n");
- abort ();
-}
-#endif
diff --git a/gnu/lib/libreadline/funmap.c b/gnu/lib/libreadline/funmap.c
index d48d299..0ae1889 100644
--- a/gnu/lib/libreadline/funmap.c
+++ b/gnu/lib/libreadline/funmap.c
@@ -1,33 +1,40 @@
/* funmap.c -- attach names to functions. */
-/* Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
- This file is part of GNU Readline, a library for reading lines
- of text with interactive input and history editing.
+ This file is part of the GNU Readline Library, 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 2 of the License, or
+ The GNU Readline Library 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 1, 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
+ The GNU Readline Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* #define STATIC_MALLOC */
-#if !defined (STATIC_MALLOC)
-extern char *xmalloc (), *xrealloc ();
-#else
+#if defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
#endif /* STATIC_MALLOC */
-#include "sysdep.h"
+#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 "readline.h"
@@ -56,6 +63,7 @@ static FUNMAP default_funmap[] = {
{ "clear-screen", rl_clear_screen },
{ "complete", rl_complete },
{ "delete-char", rl_delete },
+ { "delete-horizontal-space", rl_delete_horizontal_space },
{ "digit-argument", rl_digit_argument },
{ "do-lowercase-version", rl_do_lowercase_version },
{ "downcase-word", rl_downcase_word },
@@ -66,9 +74,12 @@ static FUNMAP default_funmap[] = {
{ "forward-char", rl_forward },
{ "forward-search-history", rl_forward_search_history },
{ "forward-word", rl_forward_word },
+ { "insert-completions", rl_insert_completions },
{ "kill-line", rl_kill_line },
{ "kill-word", rl_kill_word },
{ "next-history", rl_get_next_history },
+ { "non-incremental-forward-search-history", rl_noninc_forward_search },
+ { "non-incremental-reverse-search-history", rl_noninc_reverse_search },
{ "possible-completions", rl_possible_completions },
{ "previous-history", rl_get_previous_history },
{ "quoted-insert", rl_quoted_insert },
@@ -107,7 +118,6 @@ static FUNMAP default_funmap[] = {
{ "vi-complete", rl_vi_complete },
{ "vi-delete", rl_vi_delete },
{ "vi-delete-to", rl_vi_delete_to },
- { "vi-dosearch", rl_vi_dosearch },
{ "vi-eWord", rl_vi_eWord },
{ "vi-editing-mode", rl_vi_editing_mode },
{ "vi-end-word", rl_vi_end_word },
@@ -125,7 +135,7 @@ static FUNMAP default_funmap[] = {
{ "vi-overstrike-delete", rl_vi_overstrike_delete },
{ "vi-prev-word", rl_vi_prev_word },
{ "vi-put", rl_vi_put },
- { "vi-replace, ", rl_vi_replace },
+ { "vi-replace", rl_vi_replace },
{ "vi-search", rl_vi_search },
{ "vi-search-again", rl_vi_search_again },
{ "vi-subst", rl_vi_subst },
@@ -158,6 +168,7 @@ rl_add_funmap_entry (name, function)
static int funmap_initialized = 0;
/* Make the funmap contain all of the default entries. */
+void
rl_initialize_funmap ()
{
register int i;
@@ -177,7 +188,12 @@ static int
qsort_string_compare (s1, s2)
register char **s1, **s2;
{
- return (strcmp (*s1, *s2));
+ int r;
+
+ r = **s1 - **s2;
+ if (r == 0)
+ r = strcmp (*s1, *s2);
+ return r;
}
/* Produce a NULL terminated array of known function names. The array
diff --git a/gnu/lib/libreadline/history.c b/gnu/lib/libreadline/history.c
index 115a8af..45c6c78 100644
--- a/gnu/lib/libreadline/history.c
+++ b/gnu/lib/libreadline/history.c
@@ -1,48 +1,79 @@
/* History.c -- standalone history library */
-/* Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
The Library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
- The Library 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.
+ The Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
/* 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. */
-/* Remove these declarations when we have a complete libgnu.a. */
-#if !defined (STATIC_MALLOC)
-extern char *xmalloc (), *xrealloc ();
-#else
+#if defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
-#endif
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
-#include "sysdep.h"
#include <stdio.h>
-#include <errno.h>
-#ifndef NO_SYS_FILE
+#include <sys/types.h>
#include <sys/file.h>
-#endif
#include <sys/stat.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
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+#include <errno.h>
+
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#if defined (__GNUC__)
+# undef alloca
+# define alloca __builtin_alloca
+#else
+# if defined (sparc) || defined (HAVE_ALLOCA_H)
+# include <alloca.h>
+# else
+extern char *alloca ();
+# endif /* sparc || HAVE_ALLOCA_H */
+#endif /* !__GNU_C__ */
#include "history.h"
#ifndef savestring
-#define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
+extern char *xmalloc ();
+# ifndef strcpy
+extern char *strcpy ();
+# endif
+#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif
#ifndef whitespace
@@ -54,9 +85,16 @@ static char *xmalloc (), *xrealloc ();
#endif
#ifndef member
-#define member(c, s) ((c) ? index ((s), (c)) : 0)
+# ifndef strchr
+extern char *strchr ();
+# endif
+#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
#endif
+static char error_pointer;
+
+static char *get_history_word_specifier ();
+
/* **************************************************************** */
/* */
/* History Functions */
@@ -108,6 +146,32 @@ char *history_no_expand_chars = " \t\n\r=";
/* 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 ()
+{
+ 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;
+
+ return (state);
+}
+
+/* Set the state of the current history array to STATE. */
+void
+history_set_history_state (state)
+ HISTORY_STATE *state;
+{
+ the_history = state->entries;
+ history_offset = state->offset;
+ history_length = state->length;
+ history_size = state->size;
+}
+
/* Begin a session in which the history functions might be used. This
initializes interactive variables. */
void
@@ -179,7 +243,7 @@ add_history (string)
xrealloc (the_history,
((history_size += DEFAULT_HISTORY_GROW_SIZE)
* sizeof (HIST_ENTRY *)));
- }
+ }
history_length++;
}
}
@@ -372,6 +436,7 @@ stifle_history (max)
{
if (max < 0)
max = 0;
+
if (history_length > max)
{
register int i, j;
@@ -382,12 +447,14 @@ stifle_history (max)
free (the_history[i]->line);
free (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 = max;
}
@@ -399,11 +466,13 @@ int
unstifle_history ()
{
int result = max_input_history;
+
if (history_stifled)
{
- result = - result;
+ result = -result;
history_stifled = 0;
}
+
return (result);
}
@@ -418,11 +487,18 @@ history_filename (filename)
if (!return_val)
{
- char *home = (char *)getenv ("HOME");
- if (!home) home = ".";
+ char *home;
+
+ home = getenv ("HOME");
+
+ if (!home)
+ home = ".";
+
return_val = (char *)xmalloc (2 + strlen (home) + strlen (".history"));
+
sprintf (return_val, "%s/.history", home);
}
+
return (return_val);
}
@@ -450,7 +526,6 @@ read_history_range (filename, from, to)
char *input, *buffer = (char *)NULL;
int file, current_line;
struct stat finfo;
- extern int errno;
input = history_filename (filename);
file = open (input, O_RDONLY, 0666);
@@ -459,7 +534,7 @@ read_history_range (filename, from, to)
(stat (input, &finfo) == -1))
goto error_and_exit;
- buffer = (char *)xmalloc (finfo.st_size + 1);
+ buffer = (char *)xmalloc ((int)finfo.st_size + 1);
if (read (file, buffer, finfo.st_size) != finfo.st_size)
error_and_exit:
@@ -467,6 +542,9 @@ read_history_range (filename, from, to)
if (file >= 0)
close (file);
+ if (input)
+ free (input);
+
if (buffer)
free (buffer);
@@ -511,17 +589,25 @@ read_history_range (filename, from, to)
line_start = line_end + 1;
}
+
+ if (input)
+ free (input);
+
+ if (buffer)
+ free (buffer);
+
return (0);
}
/* Truncate the history file FNAME, leaving only LINES trailing lines.
If FNAME is NULL, then use ~/.history. */
+int
history_truncate_file (fname, lines)
char *fname;
register int lines;
{
register int i;
- int file;
+ int file, chars_read;
char *buffer = (char *)NULL, *filename;
struct stat finfo;
@@ -534,13 +620,16 @@ history_truncate_file (fname, lines)
if (file == -1)
goto truncate_exit;
- buffer = (char *)xmalloc (finfo.st_size + 1);
- read (file, buffer, finfo.st_size);
+ buffer = (char *)xmalloc ((int)finfo.st_size + 1);
+ chars_read = read (file, buffer, finfo.st_size);
close (file);
+ if (chars_read <= 0)
+ goto truncate_exit;
+
/* Count backwards from the end of buffer until we have passed
LINES lines. */
- for (i = finfo.st_size; lines && i; i--)
+ for (i = chars_read - 1; lines && i; i--)
{
if (buffer[i] == '\n')
lines--;
@@ -572,6 +661,7 @@ history_truncate_file (fname, lines)
free (buffer);
free (filename);
+ return 0;
}
#define HISTORY_APPEND 0
@@ -585,8 +675,7 @@ history_do_write (filename, nelements, overwrite)
char *filename;
int nelements, overwrite;
{
- extern int errno;
- register int i, j;
+ register int i;
char *output = history_filename (filename);
int file, mode;
@@ -596,7 +685,12 @@ history_do_write (filename, nelements, overwrite)
mode = O_WRONLY | O_APPEND;
if ((file = open (output, mode, 0666)) == -1)
- return (errno);
+ {
+ if (output)
+ free (output);
+
+ return (errno);
+ }
if (nelements > history_length)
nelements = history_length;
@@ -627,9 +721,13 @@ history_do_write (filename, nelements, overwrite)
}
close (file);
+
+ if (output)
+ free (output);
+
return (0);
}
-
+
/* 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
@@ -700,13 +798,13 @@ HIST_ENTRY *
history_get (offset)
int offset;
{
- int index = offset - history_base;
+ int local_index = offset - history_base;
- if (index >= history_length ||
- index < 0 ||
+ if (local_index >= history_length ||
+ local_index < 0 ||
!the_history)
return ((HIST_ENTRY *)NULL);
- return (the_history[index]);
+ return (the_history[local_index]);
}
/* Search for STRING in the history list. DIR is < 0 for searching
@@ -801,7 +899,6 @@ get_history_event (string, caller_index, delimiting_quote)
}
/* Hack case of numeric line specification. */
- read_which:
if (string[i] == '-')
{
sign = -1;
@@ -834,7 +931,7 @@ get_history_event (string, caller_index, delimiting_quote)
a '?', then the string may be anywhere on the line. Otherwise,
the string must be found at the start of a line. */
{
- int index;
+ int local_index;
char *temp;
int substring_okay = 0;
@@ -844,17 +941,20 @@ get_history_event (string, caller_index, delimiting_quote)
i++;
}
- for (index = i; string[i]; i++)
+ for (local_index = i; string[i]; i++)
if (whitespace (string[i]) ||
string[i] == '\n' ||
string[i] == ':' ||
(substring_okay && string[i] == '?') ||
+#if defined (SHELL)
+ member (string[i], ";&()|<>") ||
+#endif /* SHELL */
string[i] == delimiting_quote)
break;
- temp = (char *)alloca (1 + (i - index));
- strncpy (temp, &string[index], (i - index));
- temp[i - index] = '\0';
+ temp = (char *)alloca (1 + (i - local_index));
+ strncpy (temp, &string[local_index], (i - local_index));
+ temp[i - local_index] = '\0';
if (string[i] == '?')
i++;
@@ -863,19 +963,18 @@ get_history_event (string, caller_index, delimiting_quote)
search_again:
- index = history_search_internal
+ local_index = history_search_internal
(temp, -1, substring_okay ? NON_ANCHORED_SEARCH : ANCHORED_SEARCH);
- if (index < 0)
+ if (local_index < 0)
search_lost:
{
history_offset = history_length;
return ((char *)NULL);
}
- if (index == 0)
+ if (local_index == 0 || substring_okay)
{
- search_won:
entry = current_history ();
history_offset = history_length;
@@ -900,6 +999,28 @@ get_history_event (string, caller_index, delimiting_quote)
}
}
+#if defined (SHELL)
+/* Function for extracting single-quoted strings. Used for inhibiting
+ history expansion within single quotes. */
+
+/* Extract the contents of STRING as if it is enclosed in single quotes.
+ SINDEX, when passed in, is the offset of the character immediately
+ following the opening single quote; on exit, SINDEX is left pointing
+ to the closing single quote. */
+static void
+rl_string_extract_single_quoted (string, sindex)
+ char *string;
+ int *sindex;
+{
+ register int i = *sindex;
+
+ while (string[i] && string[i] != '\'')
+ i++;
+
+ *sindex = i;
+}
+#endif /* SHELL */
+
/* Expand the string STRING, placing the result into OUTPUT, a pointer
to a string. Returns:
@@ -922,8 +1043,6 @@ history_expand (string, output)
char *word_spec, *event;
int starting_index, only_printing = 0, substitute_globally = 0;
- char *get_history_word_specifier (), *rindex ();
-
/* The output string, and its length. */
int len = 0;
char *result = (char *)NULL;
@@ -932,7 +1051,7 @@ history_expand (string, output)
char *temp, tt[2], tbl[3];
/* Prepare the buffer for printing error messages. */
- result = (char *)xmalloc (len = 255);
+ result = (char *)xmalloc (len = 256);
result[0] = tt[1] = tbl[2] = '\0';
tbl[0] = '\\';
@@ -964,11 +1083,37 @@ history_expand (string, output)
/* `!' followed by one of the characters in history_no_expand_chars
is NOT an expansion. */
for (i = 0; string[i]; i++)
- if (string[i] == history_expansion_char)
- if (!string[i + 1] || member (string[i + 1], history_no_expand_chars))
- continue;
- else
- goto grovel;
+ {
+ if (string[i] == history_expansion_char)
+ {
+ if (!string[i + 1] || member (string[i + 1], history_no_expand_chars))
+ continue;
+#if defined (SHELL)
+ /* The shell uses ! as a pattern negation character in globbing [...]
+ expressions, so let those pass without expansion. */
+ else if (i > 0 && (string[i - 1] == '[') && member (']', string + i))
+ continue;
+#endif /* SHELL */
+ else
+ goto grovel;
+ }
+#if defined (SHELL)
+ else if (string[i] == '\'')
+ {
+ /* If this is bash, single quotes inhibit history expansion. */
+ i++;
+ rl_string_extract_single_quoted (string, &i);
+ }
+ else if (string[i] == '\\')
+ {
+ /* If this is bash, allow backslashes to quote single quotes and
+ the history expansion character. */
+ if (string[i + 1] == '\'' || (string[i + 1] == history_expansion_char))
+ i++;
+ }
+#endif /* SHELL */
+ }
+
free (result);
*output = savestring (string);
@@ -978,10 +1123,18 @@ history_expand (string, output)
for (i = j = 0; i < l; i++)
{
+ int passc = 0;
int tchar = string[i];
+
if (tchar == history_expansion_char)
tchar = -3;
+ if (passc)
+ {
+ passc = 0;
+ goto add_char;
+ }
+
switch (tchar)
{
case '\\':
@@ -992,7 +1145,27 @@ history_expand (string, output)
goto do_add;
}
else
- goto add_char;
+ {
+ passc++;
+ goto add_char;
+ }
+
+#if defined (SHELL)
+ case '\'':
+ {
+ /* If this is bash, single quotes inhibit history expansion. */
+ int quote = i, slen;
+
+ ++i;
+ rl_string_extract_single_quoted (string, &i);
+
+ slen = i - quote + 2;
+ temp = (char *)alloca (slen);
+ strncpy (temp, string + quote, slen);
+ temp[slen - 1] = '\0';
+ goto do_add;
+ }
+#endif /* SHELL */
/* case history_expansion_char: */
case -3:
@@ -1041,14 +1214,13 @@ history_expand (string, output)
if (!event)
event_not_found:
{
- int l = 1 + (i - starting_index);
+ int ll = 1 + (i - starting_index);
- temp = (char *)alloca (1 + l);
- strncpy (temp, string + starting_index, l);
- temp[l - 1] = 0;
+ temp = (char *)alloca (1 + ll);
+ strncpy (temp, string + starting_index, ll);
+ temp[ll - 1] = 0;
sprintf (result, "%s: %s.", temp,
word_spec_error ? "Bad word specifier" : "Event not found");
- error_exit:
*output = result;
return (-1);
}
@@ -1061,12 +1233,11 @@ history_expand (string, output)
/* There is no such thing as a `malformed word specifier'. However,
it is possible for a specifier that has no match. In that case,
we complain. */
- if (word_spec == (char *)-1)
- bad_word_spec:
- {
- word_spec_error++;
- goto event_not_found;
- }
+ if (word_spec == (char *)&error_pointer)
+ {
+ word_spec_error++;
+ goto event_not_found;
+ }
/* If no word specifier, than the thing of interest was the event. */
if (!word_spec)
@@ -1097,28 +1268,28 @@ history_expand (string, output)
/* :t discards all but the last part of the pathname. */
case 't':
- tstr = rindex (temp, '/');
+ tstr = strrchr (temp, '/');
if (tstr)
temp = ++tstr;
goto next_special;
/* :h discards the last part of a pathname. */
case 'h':
- tstr = rindex (temp, '/');
+ tstr = strrchr (temp, '/');
if (tstr)
*tstr = '\0';
goto next_special;
/* :r discards the suffix. */
case 'r':
- tstr = rindex (temp, '.');
+ tstr = strrchr (temp, '.');
if (tstr)
*tstr = '\0';
goto next_special;
/* :e discards everything but the suffix. */
case 'e':
- tstr = rindex (temp, '.');
+ tstr = strrchr (temp, '.');
if (tstr)
temp = tstr;
goto next_special;
@@ -1126,12 +1297,19 @@ history_expand (string, output)
/* :s/this/that substitutes `this' for `that'. */
/* :gs/this/that substitutes `this' for `that' globally. */
case 'g':
+#ifdef NOTYET
+ /* :g/this/that is equivalent to :gs/this/that */
+ substitute_globally = 1;
+ if (string[i + 2] == 's')
+ i++;
+#else
if (string[i + 2] == 's')
{
i++;
substitute_globally = 1;
goto substitute;
}
+#endif
else
case 's':
@@ -1141,7 +1319,7 @@ history_expand (string, output)
int delimiter = 0;
int si, l_this, l_that, l_temp = strlen (temp);
- if (i + 2 < strlen (string))
+ if (i + 2 < (int)strlen (string))
delimiter = string[i + 2];
if (!delimiter)
@@ -1246,8 +1424,8 @@ history_expand (string, output)
do_add:
j += strlen (temp);
- while (j > len)
- result = (char *)xrealloc (result, (len += 255));
+ while (j > (len - 1))
+ result = (char *)xrealloc (result, (len += 256));
strcpy (result + (j - strlen (temp)), temp);
}
@@ -1265,11 +1443,11 @@ history_expand (string, output)
}
/* Return a consed string which is the word specified in SPEC, and found
- in FROM. NULL is returned if there is no spec. -1 is returned if
- the word specified cannot be found. CALLER_INDEX is the offset in
- SPEC to start looking; it is updated to point to just after the last
- character parsed. */
-char *
+ in FROM. NULL is returned if there is no spec. The address of
+ ERROR_POINTER is returned if the word specified cannot be found.
+ CALLER_INDEX is the offset in SPEC to start looking; it is updated
+ to point to just after the last character parsed. */
+static char *
get_history_word_specifier (spec, from, caller_index)
char *spec, *from;
int *caller_index;
@@ -1327,7 +1505,6 @@ get_history_word_specifier (spec, from, caller_index)
goto get_last;
}
- get_first:
if (digit (spec[i]) && expecting_word_spec)
{
sscanf (spec + i, "%d", &first);
@@ -1376,7 +1553,7 @@ get_history_word_specifier (spec, from, caller_index)
if (result)
return (result);
else
- return ((char *)-1);
+ return ((char *)&error_pointer);
}
}
@@ -1470,38 +1647,40 @@ history_tokenize (string)
if (!string[i] || string[i] == history_comment_char)
return (result);
- if (member (string[i], "()\n")) {
- i++;
- goto got_token;
- }
+ if (member (string[i], "()\n"))
+ {
+ i++;
+ goto got_token;
+ }
- if (member (string[i], "<>;&|")) {
- int peek = string[i + 1];
+ if (member (string[i], "<>;&|$"))
+ {
+ int peek = string[i + 1];
- if (peek == string[i]) {
- if (peek == '<') {
- if (string[1 + 2] == '-')
+ if (peek == string[i] && peek != '$')
+ {
+ if (peek == '<' && string[i + 2] == '-')
+ i++;
+ i += 2;
+ goto got_token;
+ }
+ else
+ {
+ if ((peek == '&' &&
+ (string[i] == '>' || string[i] == '<')) ||
+ ((peek == '>') && (string[i] == '&')) ||
+ ((peek == '(') && (string[i] == '$')))
+ {
+ i += 2;
+ goto got_token;
+ }
+ }
+ if (string[i] != '$')
+ {
i++;
- i += 2;
- goto got_token;
- }
-
- if (member (peek, ">:&|")) {
- i += 2;
- goto got_token;
- }
- } else {
- if ((peek == '&' &&
- (string[i] == '>' || string[i] == '<')) ||
- ((peek == '>') &&
- (string[i] == '&'))) {
- i += 2;
- goto got_token;
- }
+ goto got_token;
+ }
}
- i++;
- goto got_token;
- }
/* Get word from string + i; */
{
@@ -1510,46 +1689,53 @@ history_tokenize (string)
if (member (string[i], "\"'`"))
delimiter = string[i++];
- for (;string[i]; i++) {
-
- if (string[i] == '\\') {
-
- if (string[i + 1] == '\n') {
- i++;
- continue;
- } else {
- if (delimiter != '\'')
- if ((delimiter != '"') ||
- (member (string[i], slashify_in_quotes))) {
- i++;
- continue;
- }
- }
- }
+ for (;string[i]; i++)
+ {
+ if (string[i] == '\\')
+ {
+ if (string[i + 1] == '\n')
+ {
+ i++;
+ continue;
+ }
+ else
+ {
+ if (delimiter != '\'')
+ if ((delimiter != '"') ||
+ (member (string[i], slashify_in_quotes)))
+ {
+ i++;
+ continue;
+ }
+ }
+ }
- if (delimiter && string[i] == delimiter) {
- delimiter = 0;
- continue;
- }
+ if (delimiter && string[i] == delimiter)
+ {
+ delimiter = 0;
+ continue;
+ }
- if (!delimiter && (member (string[i], " \t\n;&()|<>")))
- goto got_token;
+ if (!delimiter && (member (string[i], " \t\n;&()|<>")))
+ goto got_token;
- if (!delimiter && member (string[i], "\"'`")) {
- delimiter = string[i];
- continue;
+ if (!delimiter && member (string[i], "\"'`"))
+ {
+ delimiter = string[i];
+ continue;
+ }
}
- }
got_token:
len = i - start;
- if (result_index + 2 >= size) {
- if (!size)
- result = (char **)xmalloc ((size = 10) * (sizeof (char *)));
- else
- result =
- (char **)xrealloc (result, ((size += 10) * (sizeof (char *))));
- }
+ if (result_index + 2 >= size)
+ {
+ if (!size)
+ result = (char **)xmalloc ((size = 10) * (sizeof (char *)));
+ else
+ result =
+ (char **)xrealloc (result, ((size += 10) * (sizeof (char *))));
+ }
result[result_index] = (char *)xmalloc (1 + len);
strncpy (result[result_index], string + start, len);
result[result_index][len] = '\0';
@@ -1608,7 +1794,6 @@ memory_error_and_abort ()
abort ();
}
#endif /* STATIC_MALLOC */
-
/* **************************************************************** */
/* */
@@ -1684,7 +1869,7 @@ main ()
}
}
-#endif /* TEST */
+#endif /* TEST */
/*
* Local variables:
diff --git a/gnu/lib/libreadline/isearch.c b/gnu/lib/libreadline/isearch.c
new file mode 100644
index 0000000..3222311
--- /dev/null
+++ b/gnu/lib/libreadline/isearch.c
@@ -0,0 +1,377 @@
+/* **************************************************************** */
+/* */
+/* I-Search and Searching */
+/* */
+/* **************************************************************** */
+
+/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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 1, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+
+#if defined (__GNUC__)
+# define alloca __builtin_alloca
+#else
+# if defined (sparc) || defined (HAVE_ALLOCA_H)
+# include <alloca.h>
+# endif
+#endif
+
+#include "readline.h"
+#include "history.h"
+
+extern Keymap _rl_keymap;
+extern HIST_ENTRY *saved_line_for_history;
+extern int rl_line_buffer_len;
+extern int rl_point, rl_end;
+extern char *rl_prompt, *rl_line_buffer;
+
+/* Remove these declarations when we have a complete libgnu.a. */
+extern char *xmalloc (), *xrealloc ();
+
+static void rl_search_history ();
+
+/* Search backwards through the history looking for a string which is typed
+ interactively. Start with the current line. */
+rl_reverse_search_history (sign, key)
+ int sign;
+ int key;
+{
+ rl_search_history (-sign, key);
+}
+
+/* Search forwards through the history looking for a string which is typed
+ interactively. Start with the current line. */
+rl_forward_search_history (sign, key)
+ int sign;
+ int key;
+{
+ 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 1 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 (search_string, reverse_p, where)
+ char *search_string;
+ int reverse_p, where;
+{
+ char *message = (char *)NULL;
+
+ message =
+ (char *)xmalloc (1 + (search_string ? strlen (search_string) : 0) + 30);
+
+ *message = '\0';
+
+#if defined (NOTDEF)
+ if (where != -1)
+ sprintf (message, "[%d]", where + history_base);
+#endif /* NOTDEF */
+
+ strcat (message, "(");
+
+ if (reverse_p)
+ strcat (message, "reverse-");
+
+ strcat (message, "i-search)`");
+
+ if (search_string)
+ strcat (message, search_string);
+
+ strcat (message, "': ");
+ rl_message ("%s", message, 0);
+ free (message);
+ rl_redisplay ();
+}
+
+/* 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 void
+rl_search_history (direction, invoking_key)
+ int direction;
+ int invoking_key;
+{
+ /* The string that the user types in to search for. */
+ char *search_string;
+
+ /* The current length of SEARCH_STRING. */
+ int search_string_index;
+
+ /* The amount of space that SEARCH_STRING has allocated to it. */
+ int search_string_size;
+
+ /* The list of lines to search through. */
+ char **lines;
+
+ /* The length of LINES. */
+ int hlen;
+
+ /* Where we get LINES from. */
+ HIST_ENTRY **hlist = history_list ();
+
+ register int i = 0;
+ int orig_point = rl_point;
+ int orig_line = where_history ();
+ int last_found_line = orig_line;
+ int c, done = 0;
+
+ /* The line currently being searched. */
+ char *sline;
+
+ /* Offset in that line. */
+ int index;
+
+ /* Non-zero if we are doing a reverse search. */
+ int reverse = (direction < 0);
+
+ /* Create an arrary of pointers to the lines that we want to search. */
+ maybe_replace_line ();
+ if (hlist)
+ for (i = 0; hlist[i]; i++);
+
+ /* Allocate space for this many lines, +1 for the current input line,
+ and remember those lines. */
+ lines = (char **)alloca ((1 + (hlen = i)) * sizeof (char *));
+ for (i = 0; i < hlen; i++)
+ lines[i] = hlist[i]->line;
+
+ if (saved_line_for_history)
+ lines[i] = saved_line_for_history->line;
+ else
+ /* So I have to type it in this way instead. */
+ {
+ char *alloced_line;
+
+ /* Keep that MIPS alloca () happy. */
+ alloced_line = (char *)alloca (1 + strlen (rl_line_buffer));
+ lines[i] = alloced_line;
+ strcpy (lines[i], &rl_line_buffer[0]);
+ }
+
+ hlen++;
+
+ /* The line where we start the search. */
+ i = orig_line;
+
+ /* Initialize search parameters. */
+ search_string = (char *)xmalloc (search_string_size = 128);
+ *search_string = '\0';
+ search_string_index = 0;
+
+ /* Normalize DIRECTION into 1 or -1. */
+ if (direction >= 0)
+ direction = 1;
+ else
+ direction = -1;
+
+ rl_display_search (search_string, reverse, -1);
+
+ sline = rl_line_buffer;
+ index = rl_point;
+
+ while (!done)
+ {
+ c = rl_read_key ();
+
+ /* Hack C to Do What I Mean. */
+ {
+ Function *f = (Function *)NULL;
+
+ if (_rl_keymap[c].type == ISFUNC)
+ {
+ f = _rl_keymap[c].function;
+
+ if (f == rl_reverse_search_history)
+ c = reverse ? -1 : -2;
+ else if (f == rl_forward_search_history)
+ c = !reverse ? -1 : -2;
+ }
+ }
+
+ switch (c)
+ {
+ case ESC:
+ done = 1;
+ continue;
+
+ /* case invoking_key: */
+ case -1:
+ goto search_again;
+
+ /* switch directions */
+ case -2:
+ direction = -direction;
+ reverse = (direction < 0);
+
+ goto do_search;
+
+ case CTRL ('G'):
+ strcpy (rl_line_buffer, lines[orig_line]);
+ rl_point = orig_point;
+ rl_end = strlen (rl_line_buffer);
+ rl_clear_message ();
+ return;
+
+ default:
+ if (c < 32 || c > 126)
+ {
+ rl_execute_next (c);
+ done = 1;
+ continue;
+ }
+ else
+ {
+ if (search_string_index + 2 >= search_string_size)
+ search_string = (char *)xrealloc
+ (search_string, (search_string_size += 128));
+ search_string[search_string_index++] = c;
+ search_string[search_string_index] = '\0';
+ goto do_search;
+
+ search_again:
+
+ if (!search_string_index)
+ continue;
+ else
+ {
+ if (reverse)
+ --index;
+ else
+ if (index != strlen (sline))
+ ++index;
+ else
+ ding ();
+ }
+ do_search:
+
+ while (1)
+ {
+ if (reverse)
+ {
+ while (index >= 0)
+ if (strncmp
+ (search_string, sline + index, search_string_index)
+ == 0)
+ goto string_found;
+ else
+ index--;
+ }
+ else
+ {
+ register int limit =
+ (strlen (sline) - search_string_index) + 1;
+
+ while (index < limit)
+ {
+ if (strncmp (search_string,
+ sline + index,
+ search_string_index) == 0)
+ goto string_found;
+ index++;
+ }
+ }
+
+ next_line:
+ i += direction;
+
+ /* At limit for direction? */
+ if ((reverse && i < 0) ||
+ (!reverse && i == hlen))
+ goto search_failed;
+
+ sline = lines[i];
+ if (reverse)
+ index = strlen (sline);
+ else
+ index = 0;
+
+ /* If the search string is longer than the current
+ line, no match. */
+ if (search_string_index > (int)strlen (sline))
+ goto next_line;
+
+ /* Start actually searching. */
+ if (reverse)
+ index -= search_string_index;
+ }
+
+ search_failed:
+ /* We cannot find the search string. Ding the bell. */
+ ding ();
+ i = last_found_line;
+ break;
+
+ string_found:
+ /* 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. */
+ {
+ int line_len;
+
+ line_len = strlen (lines[i]);
+
+ if (line_len >= rl_line_buffer_len)
+ rl_extend_line_buffer (line_len);
+
+ strcpy (rl_line_buffer, lines[i]);
+ rl_point = index;
+ rl_end = line_len;
+ last_found_line = i;
+ rl_display_search
+ (search_string, reverse, (i == orig_line) ? -1 : i);
+ }
+ }
+ }
+ }
+
+ /* 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
+ INDEX is -1, then that shows that the string searched for was not
+ found. We use this to determine where to place rl_point. */
+ {
+ int now = last_found_line;
+
+ /* First put back the original state. */
+ strcpy (rl_line_buffer, lines[orig_line]);
+
+ /* Free the search string. */
+ free (search_string);
+
+ if (now < orig_line)
+ rl_get_previous_history (orig_line - now);
+ else
+ rl_get_next_history (now - orig_line);
+
+ /* If the index of the "matched" string is less than zero, then the
+ final search string was never matched, so put point somewhere
+ reasonable. */
+ if (index < 0)
+ index = strlen (rl_line_buffer);
+
+ rl_point = index;
+ rl_clear_message ();
+ }
+}
diff --git a/gnu/lib/libreadline/keymaps.c b/gnu/lib/libreadline/keymaps.c
index fe3edd02..01ee3f2 100644
--- a/gnu/lib/libreadline/keymaps.c
+++ b/gnu/lib/libreadline/keymaps.c
@@ -1,27 +1,30 @@
/* keymaps.c -- Functions and keymaps for the GNU Readline library. */
-/* Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
This file is part of GNU 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 2 of the License, or
- (at your option) any later version.
+ 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 1, 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.
+ 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 this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ along with Readline; see the file COPYING. If not, write to the Free
+ Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
-#include "sysdep.h"
-#include <stdio.h>
-#include "readline.h"
#include "keymaps.h"
#include "emacs_keymap.c"
@@ -29,12 +32,10 @@
#include "vi_keymap.c"
#endif
-/* Remove these declarations when we have a complete libgnu.a. */
-/* #define STATIC_MALLOC */
-#if !defined (STATIC_MALLOC)
-extern char *xmalloc (), *xrealloc ();
-#else
+#if defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
#endif /* STATIC_MALLOC */
/* **************************************************************** */
@@ -50,9 +51,9 @@ Keymap
rl_make_bare_keymap ()
{
register int i;
- Keymap keymap = (Keymap)xmalloc (128 * sizeof (KEYMAP_ENTRY));
+ Keymap keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY));
- for (i = 0; i < 128; i++)
+ for (i = 0; i < KEYMAP_SIZE; i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = (Function *)NULL;
@@ -75,7 +76,7 @@ rl_copy_keymap (map)
register int i;
Keymap temp = rl_make_bare_keymap ();
- for (i = 0; i < 128; i++)
+ for (i = 0; i < KEYMAP_SIZE; i++)
{
temp[i].type = map[i].type;
temp[i].function = map[i].function;
@@ -89,13 +90,13 @@ rl_copy_keymap (map)
Keymap
rl_make_keymap ()
{
- extern rl_insert (), rl_rubout ();
+ extern int rl_insert (), rl_rubout ();
register int i;
Keymap newmap;
newmap = rl_make_bare_keymap ();
- /* All printing characters are self-inserting. */
+ /* All ASCII printing characters are self-inserting. */
for (i = ' '; i < 126; i++)
newmap[i].function = rl_insert;
@@ -103,6 +104,16 @@ rl_make_keymap ()
newmap[RUBOUT].function = rl_rubout;
newmap[CTRL('H')].function = rl_rubout;
+#if KEYMAP_SIZE > 128
+ /* Printing characters in some 8-bit character sets. */
+ for (i = 128; i < 160; i++)
+ newmap[i].function = rl_insert;
+
+ /* ISO Latin-1 printing characters should self-insert. */
+ for (i = 160; i < 256; i++)
+ newmap[i].function = rl_insert;
+#endif /* KEYMAP_SIZE > 128 */
+
return (newmap);
}
@@ -115,7 +126,7 @@ rl_discard_keymap (map)
if (!map)
return;
- for (i = 0; i < 128; i++)
+ for (i = 0; i < KEYMAP_SIZE; i++)
{
switch (map[i].type)
{
@@ -133,7 +144,7 @@ rl_discard_keymap (map)
}
}
-#ifdef STATIC_MALLOC
+#if defined (STATIC_MALLOC)
/* **************************************************************** */
/* */
diff --git a/gnu/lib/libreadline/parens.c b/gnu/lib/libreadline/parens.c
new file mode 100644
index 0000000..260bc4d
--- /dev/null
+++ b/gnu/lib/libreadline/parens.c
@@ -0,0 +1,117 @@
+/* parens.c -- Implemenation of matching parenthesis feature. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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 1, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#if defined (FD_SET)
+#include <sys/time.h>
+#endif
+#include "readline.h"
+
+/* Non-zero means try to blink the matching open parenthesis when the
+ close parenthesis is inserted. */
+#if defined (FD_SET)
+int rl_blink_matching_paren = 1;
+#else /* !FD_SET */
+int rl_blink_matching_paren = 0;
+#endif /* !FD_SET */
+
+static int find_matching_open ();
+
+rl_insert_close (count, invoking_key)
+ int count, invoking_key;
+{
+ extern int rl_explicit_arg;
+
+ if (rl_explicit_arg || !rl_blink_matching_paren)
+ rl_insert (count, invoking_key);
+ else
+ {
+#if defined (FD_SET)
+ int orig_point, match_point, ready;
+ struct timeval timer;
+ fd_set readfds;
+
+ rl_insert (1, invoking_key);
+ rl_redisplay ();
+ 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;
+
+ FD_ZERO (&readfds);
+ FD_SET (fileno (rl_instream), &readfds);
+ timer.tv_sec = 1;
+ timer.tv_usec = 500;
+
+ orig_point = rl_point;
+ rl_point = match_point;
+ rl_redisplay ();
+ ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
+ rl_point = orig_point;
+#else /* !FD_SET */
+ rl_insert (count, invoking_key);
+#endif /* !FD_SET */
+ }
+}
+
+static int
+find_matching_open (string, from, closer)
+ char *string;
+ int from, 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 ((string[i] == '\'') || (string[i] == '"'))
+ delimiter = rl_line_buffer[i];
+ else if (!delimiter && (string[i] == closer))
+ level++;
+ else if (!delimiter && (string[i] == opener))
+ level--;
+
+ if (!level)
+ break;
+ }
+ return (i);
+}
+
+
+
diff --git a/gnu/lib/libreadline/posixstat.h b/gnu/lib/libreadline/posixstat.h
new file mode 100644
index 0000000..7d1cece
--- /dev/null
+++ b/gnu/lib/libreadline/posixstat.h
@@ -0,0 +1,149 @@
+/* posixstat.h -- Posix stat(2) definitions for systems that
+ don't have them. */
+
+/* Copyright (C) 1987,1991 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 1, 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; see the file COPYING. If not, write to the Free
+ Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* 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 (isc386)
+# if !defined (S_IFDIR)
+# define S_IFDIR 0040000
+# endif /* !S_IFDIR */
+# if !defined (S_IFMT)
+# define S_IFMT 0170000
+# endif /* !S_IFMT */
+#endif /* isc386 */
+
+/* This text is taken directly from the Cadmus I was trying to
+ compile on:
+ the following MACROs are defined for X/OPEN compatibility
+ however, is the param correct ??
+ #define S_ISBLK(s) ((s.st_mode & S_IFMT) == S_IFBLK)
+
+ Well, the answer is no. Thus... */
+#if defined (BrainDeath)
+# undef S_ISBLK
+# undef S_ISCHR
+# undef S_ISDIR
+# undef S_ISFIFO
+# undef S_ISREG
+#endif /* BrainDeath */
+
+/* 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)
+#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 */
diff --git a/gnu/lib/libreadline/readline.c b/gnu/lib/libreadline/readline.c
index 8529c08..a23e344 100644
--- a/gnu/lib/libreadline/readline.c
+++ b/gnu/lib/libreadline/readline.c
@@ -1,244 +1,120 @@
/* readline.c -- a general facility for reading lines of input
- with emacs style editing and completion. */
+ with emacs style editing and completion. */
-/* Copyright 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
- This file contains the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
- The Library is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ The GNU Readline Library 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 1, or
(at your option) any later version.
- The Library 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
+ The GNU Readline Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* Remove these declarations when we have a complete libgnu.a. */
-/* #define STATIC_MALLOC */
-#if !defined (STATIC_MALLOC)
-extern char *xmalloc (), *xrealloc ();
-#else
-static char *xmalloc (), *xrealloc ();
-#endif /* STATIC_MALLOC */
-
-#include "sysdep.h"
#include <stdio.h>
+#include <sys/types.h>
#include <fcntl.h>
-#ifndef NO_SYS_FILE
-#include <sys/file.h>
-#endif
+#if !defined (NO_SYS_FILE)
+# include <sys/file.h>
+#endif /* !NO_SYS_FILE */
#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
+
+/* This is needed to include support for TIOCGWINSZ and window resizing. */
+#if defined (OSF1) || defined (BSD386) || defined (_386BSD) || \
+ defined (FreeBSD) || defined (NetBSD) || defined (AIX)
+# include <sys/ioctl.h>
+#endif /* OSF1 */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
-#endif
-
-#define NEW_TTY_DRIVER
-#define HAVE_BSD_SIGNALS
-/* #define USE_XON_XOFF */
-
-#ifdef __MSDOS__
-#undef NEW_TTY_DRIVER
-#undef HAVE_BSD_SIGNALS
-#endif
-
-/* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
-#if defined (USG) && !defined (hpux)
-#undef HAVE_BSD_SIGNALS
-#endif
-
-/* System V machines use termio. */
-#if !defined (_POSIX_VERSION)
-# if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX) || defined (__H3050R) || defined (__H3050RX)
-# undef NEW_TTY_DRIVER
-# define TERMIO_TTY_DRIVER
-# include <termio.h>
-# if !defined (TCOON)
-# define TCOON 1
-# endif
-# endif /* USG || hpux || Xenix || sgi || DUGX */
-#endif /* !_POSIX_VERSION */
-
-/* Posix systems use termios and the Posix signal functions. */
-#if defined (_POSIX_VERSION)
-# if !defined (TERMIOS_MISSING)
-# undef NEW_TTY_DRIVER
-# define TERMIOS_TTY_DRIVER
-# include <termios.h>
-# endif /* !TERMIOS_MISSING */
-# define HAVE_POSIX_SIGNALS
-# if !defined (O_NDELAY)
-# define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */
-# endif /* O_NDELAY */
-#endif /* _POSIX_VERSION */
-
-/* Other (BSD) machines use sgtty. */
-#if defined (NEW_TTY_DRIVER)
-#include <sgtty.h>
-#endif
-
-/* 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 (_POSIX_VERSION)
-# define _POSIX_VDISABLE 0
-# else /* !_POSIX_VERSION */
-# define _POSIX_VDISABLE -1
-# endif /* !_POSIX_VERSION */
-#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
-
-/* Define some macros for dealing with assorted signalling disciplines.
-
- These macros provide a way to use signal blocking and disabling
- without smothering your code in a pile of #ifdef's.
-
- SIGNALS_UNBLOCK; Stop blocking all signals.
-
- {
- SIGNALS_DECLARE_SAVED (name); Declare a variable to save the
- signal blocking state.
- ...
- SIGNALS_BLOCK (SIGSTOP, name); Block a signal, and save the previous
- state for restoration later.
- ...
- SIGNALS_RESTORE (name); Restore previous signals.
- }
-
-*/
-
-#ifdef HAVE_POSIX_SIGNALS
- /* POSIX signals */
-
-#define SIGNALS_UNBLOCK \
- do { sigset_t set; \
- sigemptyset (&set); \
- sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL); \
- } while (0)
-
-#define SIGNALS_DECLARE_SAVED(name) sigset_t name
-
-#define SIGNALS_BLOCK(SIG, saved) \
- do { sigset_t set; \
- sigemptyset (&set); \
- sigaddset (&set, SIG); \
- sigprocmask (SIG_BLOCK, &set, &saved); \
- } while (0)
-
-#define SIGNALS_RESTORE(saved) \
- sigprocmask (SIG_SETMASK, &saved, (sigset_t *)NULL)
-
-
-#else /* HAVE_POSIX_SIGNALS */
-#ifdef HAVE_BSD_SIGNALS
- /* BSD signals */
-
-#define SIGNALS_UNBLOCK sigsetmask (0)
-#define SIGNALS_DECLARE_SAVED(name) int name
-#define SIGNALS_BLOCK(SIG, saved) saved = sigblock (sigmask (SIG))
-#define SIGNALS_RESTORE(saved) sigsetmask (saved)
-
-
-#else /* HAVE_BSD_SIGNALS */
- /* None of the Above */
-
-#define SIGNALS_UNBLOCK /* nothing */
-#define SIGNALS_DECLARE_SAVED(name) /* nothing */
-#define SIGNALS_BLOCK(SIG, saved) /* nothing */
-#define SIGNALS_RESTORE(saved) /* nothing */
-
-
-#endif /* HAVE_BSD_SIGNALS */
-#endif /* HAVE_POSIX_SIGNALS */
-
-/* End of signal handling definitions. */
+#endif /* HAVE_UNISTD_H */
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
#include <errno.h>
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
extern int errno;
+#endif /* !errno */
#include <setjmp.h>
-#include <sys/stat.h>
-
-/* Posix macro to check file in statbuf for directory-ness. */
-#if defined (S_IFDIR) && !defined (S_ISDIR)
-#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
-#endif
-#ifndef __MSDOS__
-/* These next are for filename completion. Perhaps this belongs
- in a different place. */
-#include <pwd.h>
-#endif /* __MSDOS__ */
+/* #define HACK_TERMCAP_MOTION */
-#if defined (USG) && !defined (isc386) && !defined (sgi)
-struct passwd *getpwuid (), *getpwent ();
-#endif
+#include "posixstat.h"
-/* #define HACK_TERMCAP_MOTION */
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
-#ifndef digit
-#define digit(c) ((c) >= '0' && (c) <= '9')
-#endif
+/* 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. */
-#ifndef isletter
-#define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
-#endif
+/* Functions imported from other files in the library. */
+extern char *tgetstr ();
+extern void rl_prep_terminal (), rl_deprep_terminal ();
+extern void rl_vi_set_last ();
+extern Function *rl_function_of_keyseq ();
+extern char *tilde_expand ();
-#ifndef digit_value
-#define digit_value(c) ((c) - '0')
-#endif
+/* External redisplay functions and variables from display.c */
+extern void rl_redisplay ();
+extern void _rl_move_vert ();
-#ifndef member
-#define member(c, s) ((c) ? index ((s), (c)) : 0)
-#endif
+extern void _rl_erase_at_end_of_line ();
+extern void _rl_move_cursor_relative ();
-#ifndef isident
-#define isident(c) ((isletter(c) || digit(c) || c == '_'))
-#endif
+extern int _rl_vis_botlin;
+extern int _rl_last_c_pos;
+extern int rl_display_fixed;
-#ifndef exchange
-#define exchange(x, y) {int temp = x; x = y; y = temp;}
-#endif
+/* Variables imported from complete.c. */
+extern char *rl_completer_word_break_characters;
+extern char *rl_basic_word_break_characters;
+extern Function *rl_symbolic_link_hook;
+extern int rl_completion_query_items;
+extern int rl_complete_with_tilde_expansion;
-extern char *tilde_expand ();
+/* Forward declarations used in this file. */
+void rl_dispatch ();
+void free_history_entry ();
+void _rl_output_character_function ();
+void _rl_set_screen_size ();
+void free_undo_list (), rl_add_undo ();
-static update_line ();
-static delete_chars ();
-static void insert_some_chars ();
+#if !defined (_GO32_)
+static void readline_default_bindings ();
+#endif /* !_GO32_ */
-#if defined (VOID_SIGHANDLER)
-# define sighandler void
-#else
-# define sighandler int
-#endif /* VOID_SIGHANDLER */
+#if defined (_GO32_)
+# include <sys/pc.h>
+# undef HANDLE_SIGNALS
+#endif /* _GO32_ */
-/* This typedef is equivalant to the one for Function; it allows us
- to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
-typedef sighandler SigHandler ();
-
-/* If on, then readline handles signals in a way that doesn't screw. */
-#define HANDLE_SIGNALS
-
-#ifdef __GO32__
-#include <sys/pc.h>
-#undef HANDLE_SIGNALS
-#endif
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
/* **************************************************************** */
@@ -247,13 +123,11 @@ typedef sighandler SigHandler ();
/* */
/* **************************************************************** */
+static char *LibraryVersion = "2.0";
+
/* A pointer to the keymap that is currently in use.
By default, it is the standard emacs keymap. */
-Keymap keymap = emacs_standard_keymap;
-
-#define no_mode -1
-#define vi_mode 0
-#define emacs_mode 1
+Keymap _rl_keymap = emacs_standard_keymap;
/* The current style of editing. */
int rl_editing_mode = emacs_mode;
@@ -298,7 +172,8 @@ static jmp_buf readline_top_level;
static FILE *in_stream, *out_stream;
/* The names of the streams that we do input and output to. */
-FILE *rl_instream, *rl_outstream;
+FILE *rl_instream = (FILE *)NULL;
+FILE *rl_outstream = (FILE *)NULL;
/* Non-zero means echo characters as they are read. */
int readline_echoing_p = 1;
@@ -313,17 +188,12 @@ int rl_key_sequence_length = 0;
before readline_internal () prints the first prompt. */
Function *rl_startup_hook = (Function *)NULL;
-/* 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. */
-Function *rl_symbolic_link_hook = (Function *)NULL;
-
/* What we use internally. You should always refer to RL_LINE_BUFFER. */
static char *the_line;
/* The character that can generate an EOF. Really read from
the terminal driver... just defaulted here. */
-static int eof_char = CTRL ('D');
+int _rl_eof_char = CTRL ('D');
/* Non-zero makes this the next keystroke to read. */
int rl_pending_input = 0;
@@ -331,6 +201,17 @@ int rl_pending_input = 0;
/* Pointer to a useful terminal name. */
char *rl_terminal_name = (char *)NULL;
+/* Non-zero means to always use horizontal scrolling in line display. */
+int _rl_horizontal_scroll_mode = 0;
+
+/* Non-zero means to display an asterisk at the starts of history lines
+ which have been modified. */
+int _rl_mark_modified_lines = 0;
+
+/* Non-zero means to use a visible bell if one is available rather than
+ simply ringing the terminal bell. */
+int _rl_prefer_visible_bell = 0;
+
/* Line buffer and maintenence. */
char *rl_line_buffer = (char *)NULL;
int rl_line_buffer_len = 0;
@@ -345,20 +226,19 @@ int rl_line_buffer_len = 0;
/* Non-zero means do not parse any lines other than comments and
parser directives. */
-static unsigned char parsing_conditionalized_out = 0;
+unsigned char _rl_parsing_conditionalized_out = 0;
/* Non-zero means to save keys that we dispatch on in a kbd macro. */
static int defining_kbd_macro = 0;
-/* XXX this prevents to got editing mode from tcsh */
-static void wait_foreground(void)
-{
- struct winsize w;
- int tty = fileno (rl_instream);
+/* Non-zero means to convert characters with the meta bit set to
+ escape-prefixed characters so we can indirect through
+ emacs_meta_keymap or vi_escape_keymap. */
+int _rl_convert_meta_chars_to_ascii = 1;
- if (ioctl (tty, TIOCGWINSZ, &w) == 0)
- (void) ioctl (tty, TIOCSWINSZ, &w);
-}
+/* Non-zero tells rl_delete_text and rl_insert_text to not add to
+ the undo list. */
+static int doing_an_undo = 0;
/* **************************************************************** */
/* */
@@ -366,8 +246,8 @@ static void wait_foreground(void)
/* */
/* **************************************************************** */
-static void rl_prep_terminal (), rl_deprep_terminal ();
-static void clear_to_eol (), rl_generic_bind ();
+/* Non-zero means treat 0200 bit in terminal input as Meta bit. */
+int _rl_meta_flag = 0; /* Forward declaration */
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means
none. A return value of NULL means that EOF was encountered. */
@@ -388,7 +268,7 @@ readline (prompt)
}
rl_initialize ();
- rl_prep_terminal ();
+ rl_prep_terminal (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
rl_set_signals ();
@@ -442,7 +322,9 @@ readline_internal ()
while (!rl_done)
{
int lk = last_command_was_kill;
- int code = setjmp (readline_top_level);
+ int code;
+
+ code = setjmp (readline_top_level);
if (code)
rl_redisplay ();
@@ -460,16 +342,16 @@ readline_internal ()
if (c == EOF && rl_end)
c = NEWLINE;
- /* The character eof_char typed to blank line, and not as the
+ /* The character _rl_eof_char typed to blank line, and not as the
previous character is interpreted as EOF. */
- if (((c == eof_char && lastc != c) || c == EOF) && !rl_end)
+ if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end)
{
eof_found = 1;
break;
}
lastc = c;
- rl_dispatch (c, keymap);
+ rl_dispatch (c, _rl_keymap);
/* If there was no change in last_command_was_kill, then no kill
has taken place. Note that if input is pending we are reading
@@ -483,7 +365,7 @@ readline_internal ()
#if defined (VI_MODE)
/* In vi mode, when you exit insert mode, the cursor moves back
over the previous character. We explicitly check for that here. */
- if (rl_editing_mode == vi_mode && keymap == vi_movement_keymap)
+ if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
rl_vi_check ();
#endif /* VI_MODE */
@@ -519,152 +401,6 @@ readline_internal ()
else
return (savestring (the_line));
}
-
-
-/* **************************************************************** */
-/* */
-/* Signal Handling */
-/* */
-/* **************************************************************** */
-
-#if defined (SIGWINCH)
-static SigHandler *old_sigwinch = (SigHandler *)NULL;
-
-static sighandler
-rl_handle_sigwinch (sig)
- int sig;
-{
- char *term;
-
- term = rl_terminal_name;
-
- if (readline_echoing_p)
- {
- if (!term)
- term = getenv ("TERM");
- if (!term)
- term = "dumb";
- rl_reset_terminal (term);
-#if defined (NOTDEF)
- crlf ();
- rl_forced_update_display ();
-#endif /* NOTDEF */
- }
-
- if (old_sigwinch &&
- old_sigwinch != (SigHandler *)SIG_IGN &&
- old_sigwinch != (SigHandler *)SIG_DFL)
- (*old_sigwinch) (sig);
-#if !defined (VOID_SIGHANDLER)
- return (0);
-#endif /* VOID_SIGHANDLER */
-}
-#endif /* SIGWINCH */
-
-#if defined (HANDLE_SIGNALS)
-/* Interrupt handling. */
-static SigHandler
- *old_int = (SigHandler *)NULL,
- *old_tstp = (SigHandler *)NULL,
- *old_ttou = (SigHandler *)NULL,
- *old_ttin = (SigHandler *)NULL,
- *old_cont = (SigHandler *)NULL,
- *old_alrm = (SigHandler *)NULL;
-
-/* Handle an interrupt character. */
-static sighandler
-rl_signal_handler (sig)
- int sig;
-{
-#if !defined (HAVE_BSD_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 (sig == SIGINT)
- signal (sig, SIG_IGN);
-#endif /* !HAVE_BSD_SIGNALS */
-
- switch (sig)
- {
- case SIGINT:
- free_undo_list ();
- rl_clear_message ();
- rl_init_argument ();
-
-#if defined (SIGTSTP)
- case SIGTSTP:
- case SIGTTOU:
- case SIGTTIN:
-#endif /* SIGTSTP */
- case SIGALRM:
- rl_clean_up_for_exit ();
- rl_deprep_terminal ();
- rl_clear_signals ();
- rl_pending_input = 0;
-
- kill (getpid (), sig);
-
- SIGNALS_UNBLOCK;
-
- rl_prep_terminal ();
- rl_set_signals ();
- }
-
-#if !defined (VOID_SIGHANDLER)
- return (0);
-#endif /* !VOID_SIGHANDLER */
-}
-
-rl_set_signals ()
-{
- old_int = (SigHandler *)signal (SIGINT, rl_signal_handler);
- if (old_int == (SigHandler *)SIG_IGN)
- signal (SIGINT, SIG_IGN);
-
- old_alrm = (SigHandler *)signal (SIGALRM, rl_signal_handler);
- if (old_alrm == (SigHandler *)SIG_IGN)
- signal (SIGALRM, SIG_IGN);
-
-#if defined (SIGTSTP)
- old_tstp = (SigHandler *)signal (SIGTSTP, rl_signal_handler);
- if (old_tstp == (SigHandler *)SIG_IGN)
- signal (SIGTSTP, SIG_IGN);
-#endif
-#if defined (SIGTTOU)
- old_ttou = (SigHandler *)signal (SIGTTOU, rl_signal_handler);
- old_ttin = (SigHandler *)signal (SIGTTIN, rl_signal_handler);
-
- if (old_tstp == (SigHandler *)SIG_IGN)
- {
- signal (SIGTTOU, SIG_IGN);
- signal (SIGTTIN, SIG_IGN);
- }
-#endif
-
-#if defined (SIGWINCH)
- old_sigwinch = (SigHandler *)signal (SIGWINCH, rl_handle_sigwinch);
-#endif
-}
-
-rl_clear_signals ()
-{
- signal (SIGINT, old_int);
- signal (SIGALRM, old_alrm);
-
-#if defined (SIGTSTP)
- signal (SIGTSTP, old_tstp);
-#endif
-
-#if defined (SIGTTOU)
- signal (SIGTTOU, old_ttou);
- signal (SIGTTIN, old_ttin);
-#endif
-
-#if defined (SIGWINCH)
- signal (SIGWINCH, old_sigwinch);
-#endif
-}
-#endif /* HANDLE_SIGNALS */
-
/* **************************************************************** */
/* */
@@ -672,12 +408,6 @@ rl_clear_signals ()
/* */
/* **************************************************************** */
-#if defined (USE_XON_XOFF)
-/* If the terminal was in xoff state when we got to it, then xon_char
- contains the character that is supposed to start it again. */
-static int xon_char, xoff_state;
-#endif /* USE_XON_XOFF */
-
static int pop_index = 0, push_index = 0, ibuffer_len = 511;
static unsigned char ibuffer[512];
@@ -750,29 +480,33 @@ rl_unget_char (key)
/* If a character is available to be read, then read it
and stuff it into IBUFFER. Otherwise, just return. */
+void
rl_gather_tyi ()
{
-#ifdef __GO32__
+#if defined (_GO32_)
char input;
- if (isatty(0))
- {
- int i = rl_getc();
- if (i != EOF)
- rl_stuff_char(i);
- }
- else
- if (kbhit() && ibuffer_space())
- rl_stuff_char(getkey());
-#else
+
+ if (isatty (0))
+ {
+ int i = rl_getc ();
+
+ if (i != EOF)
+ rl_stuff_char (i);
+ }
+ else if (kbhit () && ibuffer_space ())
+ rl_stuff_char (getkey ());
+#else /* !_GO32_ */
+
int tty = fileno (in_stream);
register int tem, result = -1;
- long chars_avail;
+ int chars_avail;
char input;
#if defined (FIONREAD)
result = ioctl (tty, FIONREAD, &chars_avail);
#endif
+#if defined (O_NDELAY)
if (result == -1)
{
int flags;
@@ -786,6 +520,7 @@ rl_gather_tyi ()
if (chars_avail == -1 && errno == EAGAIN)
return;
}
+#endif /* O_NDELAY */
/* If there's nothing available, don't waste time trying to read
something. */
@@ -814,7 +549,7 @@ rl_gather_tyi ()
if (chars_avail)
rl_stuff_char (input);
}
-#endif /* def __GO32__/else */
+#endif /* !_GO32_ */
}
static int next_macro_key ();
@@ -856,26 +591,35 @@ rl_read_key ()
return (c);
}
-/* I'm beginning to hate the declaration rules for various compilers. */
+/* Found later in this file. */
static void add_macro_char (), with_macro_input ();
/* Do the command associated with KEY in MAP.
If the associated command is really a keymap, then read
another key, and dispatch into that map. */
+void
rl_dispatch (key, map)
register int key;
Keymap map;
{
+#if defined (VI_MODE)
+ extern int _rl_vi_last_command, _rl_vi_last_repeat, _rl_vi_last_arg_sign;
+#endif
if (defining_kbd_macro)
add_macro_char (key);
- if (key > 127 && key < 256)
+ if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
{
if (map[ESC].type == ISKMAP)
{
+#if defined (CRAY)
+ map = (Keymap)((int)map[ESC].function);
+#else
map = (Keymap)map[ESC].function;
- key -= 128;
+#endif
+ key = UNMETA (key);
+ rl_key_sequence_length += 2;
rl_dispatch (key, map);
}
else
@@ -921,7 +665,16 @@ rl_dispatch (key, map)
rl_key_sequence_length++;
newkey = rl_read_key ();
+#if defined (CRAY)
+ /* If you cast map[key].function to type (Keymap) on a Cray,
+ the compiler takes the value of may[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. */
+ rl_dispatch (newkey, (Keymap)((int)map[key].function));
+#else
rl_dispatch (newkey, (Keymap)map[key].function);
+#endif /* !CRAY */
}
else
{
@@ -941,6 +694,15 @@ rl_dispatch (key, map)
}
break;
}
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
+ rl_vi_textmod_command (key))
+ {
+ _rl_vi_last_command = key;
+ _rl_vi_last_repeat = rl_numeric_arg;
+ _rl_vi_last_arg_sign = rl_arg_sign;
+ }
+#endif
}
@@ -1113,10 +875,37 @@ rl_call_last_kbd_macro (count, ignore)
if (!current_macro)
rl_abort ();
+ if (defining_kbd_macro)
+ {
+ ding (); /* no recursive macros */
+ current_macro[--current_macro_index] = '\0'; /* erase this char */
+ return 0;
+ }
+
while (count--)
with_macro_input (savestring (current_macro));
}
+void
+_rl_kill_kbd_macro ()
+{
+ if (current_macro)
+ {
+ free (current_macro);
+ current_macro = (char *) NULL;
+ }
+ current_macro_size = current_macro_index = 0;
+
+ if (executing_macro)
+ {
+ free (executing_macro);
+ executing_macro = (char *) NULL;
+ }
+ executing_macro_index = 0;
+
+ defining_kbd_macro = 0;
+}
+
/* **************************************************************** */
/* */
@@ -1127,8 +916,6 @@ rl_call_last_kbd_macro (count, ignore)
/* Initliaze readline (and terminal if not already). */
rl_initialize ()
{
- extern char *rl_display_prompt;
-
/* If we have never been called before, initialize the
terminal and data structures. */
if (!rl_initialized)
@@ -1149,21 +936,13 @@ rl_initialize ()
start_using_history ();
/* Make the display buffer match the state of the line. */
- {
- extern char *rl_display_prompt;
- extern int forced_display;
-
- rl_on_new_line ();
-
- rl_display_prompt = rl_prompt ? rl_prompt : "";
- forced_display = 1;
- }
+ rl_reset_line_state ();
/* No such function typed yet. */
rl_last_func = (Function *)NULL;
/* Parsing of key-bindings begins in an enabled state. */
- parsing_conditionalized_out = 0;
+ _rl_parsing_conditionalized_out = 0;
}
/* Initialize the entire state of the world. */
@@ -1172,12 +951,18 @@ readline_initialize_everything ()
/* Find out if we are running in Emacs. */
running_in_emacs = getenv ("EMACS");
- /* Set up input and output if they aren't already. */
+ /* Set up input and output if they are not already set up. */
if (!rl_instream)
rl_instream = stdin;
+
if (!rl_outstream)
rl_outstream = stdout;
+ /* Bind in_stream and out_stream immediately. These values may change,
+ but they may also be used before readline_internal () is called. */
+ in_stream = rl_instream;
+ out_stream = rl_outstream;
+
/* Allocate data structures. */
if (!rl_line_buffer)
rl_line_buffer =
@@ -1186,8 +971,10 @@ readline_initialize_everything ()
/* Initialize the terminal interface. */
init_terminal_io ((char *)NULL);
+#if !defined (_GO32_)
/* Bind tty characters to readline functions. */
readline_default_bindings ();
+#endif /* !_GO32_ */
/* Initialize the function names. */
rl_initialize_funmap ();
@@ -1198,9 +985,6 @@ readline_initialize_everything ()
/* If the completion parser's default word break characters haven't
been set yet, then do so now. */
{
- extern char *rl_completer_word_break_characters;
- extern char *rl_basic_word_break_characters;
-
if (rl_completer_word_break_characters == (char *)NULL)
rl_completer_word_break_characters = rl_basic_word_break_characters;
}
@@ -1209,102 +993,10 @@ readline_initialize_everything ()
/* If this system allows us to look at the values of the regular
input editing characters, then bind them to their readline
equivalents, iff the characters are not bound to keymaps. */
+static void
readline_default_bindings ()
{
-#ifndef __GO32__
-
-#if defined (NEW_TTY_DRIVER)
- struct sgttyb ttybuff;
- int tty = fileno (rl_instream);
-
- if (ioctl (tty, TIOCGETP, &ttybuff) != -1)
- {
- int erase, kill;
-
- erase = ttybuff.sg_erase;
- kill = ttybuff.sg_kill;
-
- if (erase != -1 && keymap[erase].type == ISFUNC)
- keymap[erase].function = rl_rubout;
-
- if (kill != -1 && keymap[kill].type == ISFUNC)
- keymap[kill].function = rl_unix_line_discard;
- }
-
-#if defined (TIOCGLTC)
- {
- struct ltchars lt;
-
- if (ioctl (tty, TIOCGLTC, &lt) != -1)
- {
- int erase, nextc;
-
- erase = lt.t_werasc;
- nextc = lt.t_lnextc;
-
- if (erase != -1 && keymap[erase].type == ISFUNC)
- keymap[erase].function = rl_unix_word_rubout;
-
- if (nextc != -1 && keymap[nextc].type == ISFUNC)
- keymap[nextc].function = rl_quoted_insert;
- }
- }
-#endif /* TIOCGLTC */
-#else /* not NEW_TTY_DRIVER */
-
-#if defined (TERMIOS_TTY_DRIVER)
- struct termios ttybuff;
-#else
- struct termio ttybuff;
-#endif /* TERMIOS_TTY_DRIVER */
- int tty = fileno (rl_instream);
-
- wait_foreground (); /* XXX this prevents to got editing mode from tcsh */
-#if defined (TERMIOS_TTY_DRIVER)
- if (tcgetattr (tty, &ttybuff) != -1)
-#else
- if (ioctl (tty, TCGETA, &ttybuff) != -1)
-#endif /* !TERMIOS_TTY_DRIVER */
- {
- int erase, kill;
-
- erase = ttybuff.c_cc[VERASE];
- kill = ttybuff.c_cc[VKILL];
-
- if (erase != _POSIX_VDISABLE &&
- keymap[(unsigned char)erase].type == ISFUNC)
- keymap[(unsigned char)erase].function = rl_rubout;
-
- if (kill != _POSIX_VDISABLE &&
- keymap[(unsigned char)kill].type == ISFUNC)
- keymap[(unsigned char)kill].function = rl_unix_line_discard;
-
-#if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
- {
- int nextc;
-
- nextc = ttybuff.c_cc[VLNEXT];
-
- if (nextc != _POSIX_VDISABLE &&
- keymap[(unsigned char)nextc].type == ISFUNC)
- keymap[(unsigned char)nextc].function = rl_quoted_insert;
- }
-#endif /* VLNEXT && TERMIOS_TTY_DRIVER */
-
-#if defined (VWERASE)
- {
- int werase;
-
- werase = ttybuff.c_cc[VWERASE];
-
- if (werase != _POSIX_VDISABLE &&
- keymap[(unsigned char)werase].type == ISFUNC)
- keymap[(unsigned char)werase].function = rl_unix_word_rubout;
- }
-#endif /* VWERASE */
- }
-#endif /* !NEW_TTY_DRIVER */
-#endif /* def __GO32__ */
+ rltty_set_default_bindings (_rl_keymap);
}
@@ -1353,11 +1045,11 @@ rl_digit_loop ()
int key, c;
while (1)
{
- rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
+ rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
key = c = rl_read_key ();
- if (keymap[c].type == ISFUNC &&
- keymap[c].function == rl_universal_argument)
+ if (_rl_keymap[c].type == ISFUNC &&
+ _rl_keymap[c].function == rl_universal_argument)
{
rl_numeric_arg *= 4;
continue;
@@ -1381,632 +1073,12 @@ rl_digit_loop ()
else
{
rl_clear_message ();
- rl_dispatch (key, keymap);
+ rl_dispatch (key, _rl_keymap);
return;
}
}
}
}
-
-
-/* **************************************************************** */
-/* */
-/* Display stuff */
-/* */
-/* **************************************************************** */
-
-/* This is the stuff that is hard for me. I never seem to write good
- display routines in C. Let's see how I do this time. */
-
-/* (PWP) Well... Good for a simple line updater, but totally ignores
- the problems of input lines longer than the screen width.
-
- update_line and the code that calls it makes a multiple line,
- automatically wrapping line update. Carefull attention needs
- to be paid to the vertical position variables.
-
- handling of terminals with autowrap on (incl. DEC braindamage)
- could be improved a bit. Right now I just cheat and decrement
- screenwidth by one. */
-
-/* Keep two buffers; one which reflects the current contents of the
- screen, and the other to draw what we think the new contents should
- be. Then compare the buffers, and make whatever changes to the
- screen itself that we should. Finally, make the buffer that we
- just drew into be the one which reflects the current contents of the
- screen, and place the cursor where it belongs.
-
- Commands that want to can fix the display themselves, and then let
- this function know that the display has been fixed by setting the
- RL_DISPLAY_FIXED variable. This is good for efficiency. */
-
-/* Termcap variables: */
-extern char *term_up, *term_dc, *term_cr;
-extern int screenheight, screenwidth, terminal_can_insert;
-
-/* What YOU turn on when you have handled all redisplay yourself. */
-int rl_display_fixed = 0;
-
-/* The visible cursor position. If you print some text, adjust this. */
-int last_c_pos = 0;
-int last_v_pos = 0;
-
-/* The last left edge of text that was displayed. This is used when
- doing horizontal scrolling. It shifts in thirds of a screenwidth. */
-static int last_lmargin = 0;
-
-/* The line display buffers. One is the line currently displayed on
- the screen. The other is the line about to be displayed. */
-static char *visible_line = (char *)NULL;
-static char *invisible_line = (char *)NULL;
-
-/* Number of lines currently on screen minus 1. */
-int vis_botlin = 0;
-
-/* A buffer for `modeline' messages. */
-char msg_buf[128];
-
-/* Non-zero forces the redisplay even if we thought it was unnecessary. */
-int forced_display = 0;
-
-/* The stuff that gets printed out before the actual text of the line.
- This is usually pointing to rl_prompt. */
-char *rl_display_prompt = (char *)NULL;
-
-/* Default and initial buffer size. Can grow. */
-static int line_size = 1024;
-
-/* Non-zero means to always use horizontal scrolling in line display. */
-static int horizontal_scroll_mode = 0;
-
-/* Non-zero means to display an asterisk at the starts of history lines
- which have been modified. */
-static int mark_modified_lines = 0;
-
-/* Non-zero means to use a visible bell if one is available rather than
- simply ringing the terminal bell. */
-static int prefer_visible_bell = 0;
-
-/* I really disagree with this, but my boss (among others) insists that we
- support compilers that don't work. I don't think we are gaining by doing
- so; what is the advantage in producing better code if we can't use it? */
-/* The following two declarations belong inside the
- function block, not here. */
-static void move_cursor_relative ();
-static void output_some_chars ();
-void output_character_function ();
-static int compare_strings ();
-
-/* Basic redisplay algorithm. */
-rl_redisplay ()
-{
- register int in, out, c, linenum;
- register char *line = invisible_line;
- char *prompt_this_line;
- int c_pos = 0;
- int inv_botlin = 0; /* Number of lines in newly drawn buffer. */
-
- extern int readline_echoing_p;
-
- if (!readline_echoing_p)
- return;
-
- if (!rl_display_prompt)
- rl_display_prompt = "";
-
- if (!invisible_line)
- {
- visible_line = (char *)xmalloc (line_size);
- invisible_line = (char *)xmalloc (line_size);
- line = invisible_line;
- for (in = 0; in < line_size; in++)
- {
- visible_line[in] = 0;
- invisible_line[in] = 1;
- }
- rl_on_new_line ();
- }
-
- /* Draw the line into the buffer. */
- c_pos = -1;
-
- /* Mark the line as modified or not. We only do this for history
- lines. */
- out = 0;
- if (mark_modified_lines && current_history () && rl_undo_list)
- {
- line[out++] = '*';
- line[out] = '\0';
- }
-
- /* If someone thought that the redisplay was handled, but the currently
- visible line has a different modification state than the one about
- to become visible, then correct the callers misconception. */
- if (visible_line[0] != invisible_line[0])
- rl_display_fixed = 0;
-
- prompt_this_line = rindex (rl_display_prompt, '\n');
- if (!prompt_this_line)
- prompt_this_line = rl_display_prompt;
- else
- {
- prompt_this_line++;
- if (forced_display)
- output_some_chars (rl_display_prompt,
- prompt_this_line - rl_display_prompt);
- }
-
- strncpy (line + out, prompt_this_line, strlen (prompt_this_line));
- out += strlen (prompt_this_line);
- line[out] = '\0';
-
- for (in = 0; in < rl_end; in++)
- {
- c = (unsigned char)the_line[in];
-
- if (out + 1 >= line_size)
- {
- line_size *= 2;
- visible_line = (char *)xrealloc (visible_line, line_size);
- invisible_line = (char *)xrealloc (invisible_line, line_size);
- line = invisible_line;
- }
-
- if (in == rl_point)
- c_pos = out;
-
- if (c > 127)
- {
- line[out++] = 'M';
- line[out++] = '-';
- line[out++] = c - 128;
- }
-#define DISPLAY_TABS
-#if defined (DISPLAY_TABS)
- else if (c == '\t')
- {
- register int newout = (out | (int)7) + 1;
- while (out < newout)
- line[out++] = ' ';
- }
-#endif
- else if (c < 32)
- {
- line[out++] = 'C';
- line[out++] = '-';
- line[out++] = c + 64;
- }
- else if (c == 127)
- {
- line[out++] = 'C';
- line[out++] = '-';
- line[out++] = '?';
- }
- else
- line[out++] = c;
- }
- line[out] = '\0';
- if (c_pos < 0)
- c_pos = out;
-
- /* PWP: now is when things get a bit hairy. The visible and invisible
- line buffers are really multiple lines, which would wrap every
- (screenwidth - 1) characters. Go through each in turn, finding
- the changed region and updating it. The line order is top to bottom. */
-
- /* If we can move the cursor up and down, then use multiple lines,
- otherwise, let long lines display in a single terminal line, and
- horizontally scroll it. */
-
- if (!horizontal_scroll_mode && term_up && *term_up)
- {
- int total_screen_chars = (screenwidth * screenheight);
-
- if (!rl_display_fixed || forced_display)
- {
- forced_display = 0;
-
- /* If we have more than a screenful of material to display, then
- only display a screenful. We should display the last screen,
- not the first. I'll fix this in a minute. */
- if (out >= total_screen_chars)
- out = total_screen_chars - 1;
-
- /* Number of screen lines to display. */
- inv_botlin = out / screenwidth;
-
- /* For each line in the buffer, do the updating display. */
- for (linenum = 0; linenum <= inv_botlin; linenum++)
- update_line (linenum > vis_botlin ? ""
- : &visible_line[linenum * screenwidth],
- &invisible_line[linenum * screenwidth],
- linenum);
-
- /* We may have deleted some lines. If so, clear the left over
- blank ones at the bottom out. */
- if (vis_botlin > inv_botlin)
- {
- char *tt;
- for (; linenum <= vis_botlin; linenum++)
- {
- tt = &visible_line[linenum * screenwidth];
- move_vert (linenum);
- move_cursor_relative (0, tt);
- clear_to_eol ((linenum == vis_botlin)?
- strlen (tt) : screenwidth);
- }
- }
- vis_botlin = inv_botlin;
-
- /* Move the cursor where it should be. */
- move_vert (c_pos / screenwidth);
- move_cursor_relative (c_pos % screenwidth,
- &invisible_line[(c_pos / screenwidth) * screenwidth]);
- }
- }
- else /* Do horizontal scrolling. */
- {
- int lmargin;
-
- /* Always at top line. */
- last_v_pos = 0;
-
- /* If the display position of the cursor would be off the edge
- of the screen, start the display of this line at an offset that
- leaves the cursor on the screen. */
- if (c_pos - last_lmargin > screenwidth - 2)
- lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);
- else if (c_pos - last_lmargin < 1)
- lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);
- else
- lmargin = last_lmargin;
-
- /* If the first character on the screen isn't the first character
- in the display line, indicate this with a special character. */
- if (lmargin > 0)
- line[lmargin] = '<';
-
- if (lmargin + screenwidth < out)
- line[lmargin + screenwidth - 1] = '>';
-
- if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
- {
- forced_display = 0;
- update_line (&visible_line[last_lmargin],
- &invisible_line[lmargin], 0);
-
- move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
- last_lmargin = lmargin;
- }
- }
- fflush (out_stream);
-
- /* Swap visible and non-visible lines. */
- {
- char *temp = visible_line;
- visible_line = invisible_line;
- invisible_line = temp;
- rl_display_fixed = 0;
- }
-}
-
-/* PWP: update_line() is based on finding the middle difference of each
- line on the screen; vis:
-
- /old first difference
- /beginning of line | /old last same /old EOL
- v v v v
-old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
-new: eddie> Oh, my little buggy says to me, as lurgid as
- ^ ^ ^ ^
- \beginning of line | \new last same \new end of line
- \new first difference
-
- All are character pointers for the sake of speed. Special cases for
- no differences, as well as for end of line additions must be handeled.
-
- Could be made even smarter, but this works well enough */
-static
-update_line (old, new, current_line)
- register char *old, *new;
- int current_line;
-{
- register char *ofd, *ols, *oe, *nfd, *nls, *ne;
- int lendiff, wsatend;
-
- /* Find first difference. */
- for (ofd = old, nfd = new;
- (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);
- ofd++, nfd++)
- ;
-
- /* Move to the end of the screen line. */
- for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++);
- for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++);
-
- /* If no difference, continue to next line. */
- if (ofd == oe && nfd == ne)
- return;
-
- wsatend = 1; /* flag for trailing whitespace */
- ols = oe - 1; /* find last same */
- nls = ne - 1;
- while ((*ols == *nls) && (ols > ofd) && (nls > nfd))
- {
- if (*ols != ' ')
- wsatend = 0;
- ols--;
- nls--;
- }
-
- if (wsatend)
- {
- ols = oe;
- nls = ne;
- }
- else if (*ols != *nls)
- {
- if (*ols) /* don't step past the NUL */
- ols++;
- if (*nls)
- nls++;
- }
-
- move_vert (current_line);
- move_cursor_relative (ofd - old, old);
-
- /* if (len (new) > len (old)) */
- lendiff = (nls - nfd) - (ols - ofd);
-
- /* Insert (diff(len(old),len(new)) ch */
- if (lendiff > 0)
- {
- if (terminal_can_insert)
- {
- extern char *term_IC;
-
- /* Sometimes it is cheaper to print the characters rather than
- use the terminal's capabilities. */
- if ((2 * (ne - nfd)) < lendiff && !term_IC)
- {
- output_some_chars (nfd, (ne - nfd));
- last_c_pos += (ne - nfd);
- }
- else
- {
- if (*ols)
- {
- insert_some_chars (nfd, lendiff);
- last_c_pos += lendiff;
- }
- else
- {
- /* At the end of a line the characters do not have to
- be "inserted". They can just be placed on the screen. */
- output_some_chars (nfd, lendiff);
- last_c_pos += lendiff;
- }
- /* Copy (new) chars to screen from first diff to last match. */
- if (((nls - nfd) - lendiff) > 0)
- {
- output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
- last_c_pos += ((nls - nfd) - lendiff);
- }
- }
- }
- else
- { /* cannot insert chars, write to EOL */
- output_some_chars (nfd, (ne - nfd));
- last_c_pos += (ne - nfd);
- }
- }
- else /* Delete characters from line. */
- {
- /* If possible and inexpensive to use terminal deletion, then do so. */
- if (term_dc && (2 * (ne - nfd)) >= (-lendiff))
- {
- if (lendiff)
- delete_chars (-lendiff); /* delete (diff) characters */
-
- /* Copy (new) chars to screen from first diff to last match */
- if ((nls - nfd) > 0)
- {
- output_some_chars (nfd, (nls - nfd));
- last_c_pos += (nls - nfd);
- }
- }
- /* Otherwise, print over the existing material. */
- else
- {
- output_some_chars (nfd, (ne - nfd));
- last_c_pos += (ne - nfd);
- clear_to_eol ((oe - old) - (ne - new));
- }
- }
-}
-
-/* (PWP) tell the update routines that we have moved onto a
- new (empty) line. */
-rl_on_new_line ()
-{
- if (visible_line)
- visible_line[0] = '\0';
-
- last_c_pos = last_v_pos = 0;
- vis_botlin = last_lmargin = 0;
-}
-
-/* Actually update the display, period. */
-rl_forced_update_display ()
-{
- if (visible_line)
- {
- register char *temp = visible_line;
-
- while (*temp) *temp++ = '\0';
- }
- rl_on_new_line ();
- forced_display++;
- rl_redisplay ();
-}
-
-/* Move the cursor from last_c_pos to NEW, which are buffer indices.
- DATA is the contents of the screen line of interest; i.e., where
- the movement is being done. */
-static void
-move_cursor_relative (new, data)
- int new;
- char *data;
-{
- register int i;
-
- /* It may be faster to output a CR, and then move forwards instead
- of moving backwards. */
- if (new + 1 < last_c_pos - new)
- {
-#ifdef __MSDOS__
- putc('\r', out_stream);
-#else
- tputs (term_cr, 1, output_character_function);
-#endif
- last_c_pos = 0;
- }
-
- if (last_c_pos == new) return;
-
- if (last_c_pos < new)
- {
- /* Move the cursor forward. We do it by printing the command
- to move the cursor forward if there is one, else print that
- portion of the output buffer again. Which is cheaper? */
-
- /* The above comment is left here for posterity. It is faster
- to print one character (non-control) than to print a control
- sequence telling the terminal to move forward one character.
- That kind of control is for people who don't know what the
- data is underneath the cursor. */
-#if defined (HACK_TERMCAP_MOTION)
- extern char *term_forward_char;
-
- if (term_forward_char)
- for (i = last_c_pos; i < new; i++)
- tputs (term_forward_char, 1, output_character_function);
- else
- for (i = last_c_pos; i < new; i++)
- putc (data[i], out_stream);
-#else
- for (i = last_c_pos; i < new; i++)
- putc (data[i], out_stream);
-#endif /* HACK_TERMCAP_MOTION */
- }
- else
- backspace (last_c_pos - new);
- last_c_pos = new;
-}
-
-/* PWP: move the cursor up or down. */
-move_vert (to)
- int to;
-{
- register int delta, i;
-
- if (last_v_pos == to) return;
-
- if (to > screenheight)
- return;
-
-#ifdef __GO32__
- {
- int cur_r, cur_c;
- ScreenGetCursor(&cur_r, &cur_c);
- ScreenSetCursor(cur_r+to-last_v_pos, cur_c);
- }
-#else /* __GO32__ */
- if ((delta = to - last_v_pos) > 0)
- {
- for (i = 0; i < delta; i++)
- putc ('\n', out_stream);
- tputs (term_cr, 1, output_character_function);
- last_c_pos = 0;
- }
- else
- { /* delta < 0 */
- if (term_up && *term_up)
- for (i = 0; i < -delta; i++)
- tputs (term_up, 1, output_character_function);
- }
-#endif /* __GO32__ */
- last_v_pos = to; /* now to is here */
-}
-
-/* Physically print C on out_stream. This is for functions which know
- how to optimize the display. */
-rl_show_char (c)
- int c;
-{
- if (c > 127)
- {
- fprintf (out_stream, "M-");
- c -= 128;
- }
-
-#if defined (DISPLAY_TABS)
- if (c < 32 && c != '\t')
-#else
- if (c < 32)
-#endif
- {
-
- c += 64;
- }
-
- putc (c, out_stream);
- fflush (out_stream);
-}
-
-#if defined (DISPLAY_TABS)
-int
-rl_character_len (c, pos)
- register int c, pos;
-{
- if (c < ' ' || c > 126)
- {
- if (c == '\t')
- return (((pos | (int)7) + 1) - pos);
- else
- return (3);
- }
- else
- return (1);
-}
-#else
-int
-rl_character_len (c)
- int c;
-{
- if (c < ' ' || c > 126)
- return (3);
- else
- return (1);
-}
-#endif /* DISPLAY_TAB */
-
-/* How to print things in the "echo-area". The prompt is treated as a
- mini-modeline. */
-rl_message (string, arg1, arg2)
- char *string;
-{
- sprintf (msg_buf, string, arg1, arg2);
- rl_display_prompt = msg_buf;
- rl_redisplay ();
-}
-
-/* How to clear things from the "echo-area". */
-rl_clear_message ()
-{
- rl_display_prompt = rl_prompt;
- rl_redisplay ();
-}
/* **************************************************************** */
/* */
@@ -2019,14 +1091,14 @@ static char *term_string_buffer = (char *)NULL;
/* Non-zero means this terminal can't really do anything. */
int dumb_term = 0;
+/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
+ Unfortunately, PC is a global variable used by the termcap library. */
+#undef PC
-/* On Solaris2, sys/types.h brings in sys/reg.h,
- which screws up the Termcap variable PC, used below. */
-
-#undef PC
-
+#if !defined (__linux__)
char PC;
char *BC, *UP;
+#endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */
char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
@@ -2052,6 +1124,18 @@ char *term_up;
/* A visible bell, if the terminal can be made to flash the screen. */
char *visible_bell;
+/* Non-zero means that this terminal has a meta key. */
+int term_has_meta;
+
+/* The string to write to turn on the meta key, if this term has one. */
+char *term_mm;
+
+/* The string to write to turn off the meta key, if this term has one. */
+char *term_mo;
+
+/* The key sequences output by the arrow keys, if this terminal has any. */
+char *term_ku, *term_kd, *term_kr, *term_kl;
+
/* Re-initialize the terminal considering that the TERM/TERMCAP variable
has changed. */
rl_reset_terminal (terminal_name)
@@ -2060,26 +1144,93 @@ rl_reset_terminal (terminal_name)
init_terminal_io (terminal_name);
}
+/* Set 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_set_screen_size (tty, ignore_env)
+ int tty, ignore_env;
+{
+#if defined (TIOCGWINSZ)
+ struct winsize window_size;
+#endif /* TIOCGWINSZ */
+
+#if defined (TIOCGWINSZ)
+ if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
+ {
+ screenwidth = (int) window_size.ws_col;
+ screenheight = (int) window_size.ws_row;
+ }
+#endif /* TIOCGWINSZ */
+
+ /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
+ is unset. */
+ if (screenwidth <= 0)
+ {
+ char *sw;
+
+ if (!ignore_env && (sw = getenv ("COLUMNS")))
+ screenwidth = atoi (sw);
+
+ if (screenwidth <= 0 && term_string_buffer)
+ screenwidth = tgetnum ("co");
+ }
+
+ /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
+ is unset. */
+ if (screenheight <= 0)
+ {
+ char *sh;
+
+ if (!ignore_env && (sh = getenv ("LINES")))
+ screenheight = atoi (sh);
+
+ if (screenheight <= 0 && term_string_buffer)
+ screenheight = tgetnum ("li");
+ }
+
+ /* If all else fails, default to 80x24 terminal. */
+ if (screenwidth <= 0)
+ screenwidth = 80;
+
+ if (screenheight <= 0)
+ screenheight = 24;
+
+#if defined (SHELL)
+ /* If we're being compiled as part of bash, set the environment
+ variables $LINES and $COLUMNS to new values. */
+ set_lines_and_columns (screenheight, screenwidth);
+#endif
+
+ screenwidth--;
+}
+
init_terminal_io (terminal_name)
char *terminal_name;
{
-#ifdef __GO32__
- screenwidth = ScreenCols();
- screenheight = ScreenRows();
+#if defined (_GO32_)
+ screenwidth = ScreenCols ();
+ screenheight = ScreenRows ();
term_cr = "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
+
+ /* Does the _GO32_ have a meta key? I don't know. */
+ term_has_meta = 0;
+ term_mm = term_mo = (char *)NULL;
+
+ /* It probably has arrow keys, but I don't know what they are. */
+ term_ku = term_kd = term_kr = term_kl = (char *)NULL;
+
#if defined (HACK_TERMCAP_MOTION)
- term_forward_char = (char *)NULL;
-#endif
+ term_forward_char = (char *)NULL;
+#endif /* HACK_TERMCAP_MOTION */
terminal_can_insert = 0;
return;
-#else
- extern char *tgetstr ();
+#else /* !_GO32_ */
+
char *term, *buffer;
-#if defined (TIOCGWINSZ) && !defined (TIOCGWINSZ_BROKEN)
- struct winsize window_size;
-#endif
int tty;
term = terminal_name ? terminal_name : getenv ("TERM");
@@ -2105,11 +1256,12 @@ init_terminal_io (terminal_name)
term_cr = "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
+ term_ku = term_kd = term_kl = term_kr = (char *)NULL;
#if defined (HACK_TERMCAP_MOTION)
term_forward_char = (char *)NULL;
#endif
terminal_can_insert = 0;
- return;
+ return 0;
}
BC = tgetstr ("pc", &buffer);
@@ -2134,27 +1286,8 @@ init_terminal_io (terminal_name)
tty = 0;
screenwidth = screenheight = 0;
-#if defined (TIOCGWINSZ) && !defined (TIOCGWINSZ_BROKEN)
- if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
- {
- screenwidth = (int) window_size.ws_col;
- screenheight = (int) window_size.ws_row;
- }
-#endif
- if (screenwidth <= 0 || screenheight <= 0)
- {
- screenwidth = tgetnum ("co");
- screenheight = tgetnum ("li");
- }
-
- screenwidth--;
-
- if (screenwidth <= 0)
- screenwidth = 79;
-
- if (screenheight <= 0)
- screenheight = 24;
+ _rl_set_screen_size (tty, 0);
term_im = tgetstr ("im", &buffer);
term_ei = tgetstr ("ei", &buffer);
@@ -2172,103 +1305,85 @@ init_terminal_io (terminal_name)
term_DC = tgetstr ("DC", &buffer);
visible_bell = tgetstr ("vb", &buffer);
-#endif /* !__GO32__ */
-}
-/* A function for the use of tputs () */
-void
-output_character_function (c)
- int c;
-{
- putc (c, out_stream);
-}
-
-/* Write COUNT characters from STRING to the output stream. */
-static void
-output_some_chars (string, count)
- char *string;
- int count;
-{
- fwrite (string, 1, count, out_stream);
-}
-
-/* Delete COUNT characters from the display line. */
-static
-delete_chars (count)
- int count;
-{
-#ifdef __GO32__
- int r, c, w;
- ScreenGetCursor(&r, &c);
- w = ScreenCols();
- memcpy(ScreenPrimary+r*w+c, ScreenPrimary+r*w+c+count, w-c-count);
- memset(ScreenPrimary+r*w+w-count, 0, count*2);
-#else /* __GO32__ */
- if (count > screenwidth)
- return;
-
- if (term_DC && *term_DC)
+ /* Check to see if this terminal has a meta key. */
+ term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
+ if (term_has_meta)
{
- char *tgoto (), *buffer;
- buffer = tgoto (term_DC, 0, count);
- tputs (buffer, 1, output_character_function);
+ term_mm = tgetstr ("mm", &buffer);
+ term_mo = tgetstr ("mo", &buffer);
}
else
{
- if (term_dc && *term_dc)
- while (count--)
- tputs (term_dc, 1, output_character_function);
+ term_mm = (char *)NULL;
+ term_mo = (char *)NULL;
}
-#endif /* __GO32__ */
-}
-/* Insert COUNT characters from STRING to the output stream. */
-static void
-insert_some_chars (string, count)
- char *string;
- int count;
-{
-#ifdef __GO32__
- int r, c, w;
- ScreenGetCursor(&r, &c);
- w = ScreenCols();
- memcpy(ScreenPrimary+r*w+c+count, ScreenPrimary+r*w+c, w-c-count);
- /* Print the text. */
- output_some_chars (string, count);
-#else /* __GO32__ */
- /* If IC is defined, then we do not have to "enter" insert mode. */
- if (term_IC)
+ /* Attempt to find and bind the arrow keys. Do not override already
+ bound keys in an overzealous attempt, however. */
+ term_ku = tgetstr ("ku", &buffer);
+ term_kd = tgetstr ("kd", &buffer);
+ term_kr = tgetstr ("kr", &buffer);
+ term_kl = tgetstr ("kl", &buffer);
+
+ if (term_ku)
{
- char *tgoto (), *buffer;
- buffer = tgoto (term_IC, 0, count);
- tputs (buffer, 1, output_character_function);
- output_some_chars (string, count);
+ Function *func;
+
+ func = rl_function_of_keyseq (term_ku, _rl_keymap, (int *)NULL);
+
+ if (!func || func == rl_do_lowercase_version)
+ rl_set_key (term_ku, rl_get_previous_history, _rl_keymap);
}
- else
+
+ if (term_kd)
{
- register int i;
+ Function *func;
- /* If we have to turn on insert-mode, then do so. */
- if (term_im && *term_im)
- tputs (term_im, 1, output_character_function);
+ func = rl_function_of_keyseq (term_kd, _rl_keymap, (int *)NULL);
- /* If there is a special command for inserting characters, then
- use that first to open up the space. */
- if (term_ic && *term_ic)
- {
- for (i = count; i--; )
- tputs (term_ic, 1, output_character_function);
- }
+ if (!func || func == rl_do_lowercase_version)
+ rl_set_key (term_kd, rl_get_next_history, _rl_keymap);
+ }
+
+ if (term_kr)
+ {
+ Function *func;
+
+ func = rl_function_of_keyseq (term_kr, _rl_keymap, (int *)NULL);
+
+ if (!func || func == rl_do_lowercase_version)
+ rl_set_key (term_kr, rl_forward, _rl_keymap);
+ }
+
+ if (term_kl)
+ {
+ Function *func;
- /* Print the text. */
- output_some_chars (string, count);
+ func = rl_function_of_keyseq (term_kl, _rl_keymap, (int *)NULL);
- /* If there is a string to turn off insert mode, we had best use
- it now. */
- if (term_ei && *term_ei)
- tputs (term_ei, 1, output_character_function);
+ if (!func || func == rl_do_lowercase_version)
+ rl_set_key (term_kl, rl_backward, _rl_keymap);
}
-#endif /* __GO32__ */
+#endif /* !_GO32_ */
+ return 0;
+}
+
+/* A function for the use of tputs () */
+void
+_rl_output_character_function (c)
+ int c;
+{
+ putc (c, out_stream);
+}
+
+/* Write COUNT characters from STRING to the output stream. */
+void
+_rl_output_some_chars (string, count)
+ char *string;
+ int count;
+{
+ fwrite (string, 1, count, out_stream);
}
/* Move the cursor back. */
@@ -2277,12 +1392,12 @@ backspace (count)
{
register int i;
-#ifndef __GO32__
+#if !defined (_GO32_)
if (term_backspace)
for (i = 0; i < count; i++)
- tputs (term_backspace, 1, output_character_function);
+ tputs (term_backspace, 1, _rl_output_character_function);
else
-#endif /* !__GO32__ */
+#endif /* !_GO32_ */
for (i = 0; i < count; i++)
putc ('\b', out_stream);
}
@@ -2291,343 +1406,11 @@ backspace (count)
crlf ()
{
#if defined (NEW_TTY_DRIVER)
- tputs (term_cr, 1, output_character_function);
+ tputs (term_cr, 1, _rl_output_character_function);
#endif /* NEW_TTY_DRIVER */
putc ('\n', out_stream);
}
-/* Clear to the end of the line. COUNT is the minimum
- number of character spaces to clear, */
-static void
-clear_to_eol (count)
- int count;
-{
-#ifndef __GO32__
- if (term_clreol)
- {
- tputs (term_clreol, 1, output_character_function);
- }
- else
-#endif /* !__GO32__ */
- {
- register int i;
-
- /* Do one more character space. */
- count++;
-
- for (i = 0; i < count; i++)
- putc (' ', out_stream);
-
- backspace (count);
- }
-}
-
-
-/* **************************************************************** */
-/* */
-/* Saving and Restoring the TTY */
-/* */
-/* **************************************************************** */
-
-/* Non-zero means that the terminal is in a prepped state. */
-static int terminal_prepped = 0;
-
-#if defined (NEW_TTY_DRIVER)
-
-/* Standard flags, including ECHO. */
-static int original_tty_flags = 0;
-
-/* Local mode flags, like LPASS8. */
-static int local_mode_flags = 0;
-
-/* Terminal characters. This has C-s and C-q in it. */
-static struct tchars original_tchars;
-
-/* Local special characters. This has the interrupt characters in it. */
-#if defined (TIOCGLTC)
-static struct ltchars original_ltchars;
-#endif
-
-/* We use this to get and set the tty_flags. */
-static struct sgttyb the_ttybuff;
-
-/* Put the terminal in CBREAK mode so that we can detect key presses. */
-static void
-rl_prep_terminal ()
-{
-#ifndef __GO32__
- int tty = fileno (rl_instream);
- SIGNALS_DECLARE_SAVED (saved_signals);
-
- if (terminal_prepped)
- return;
-
- SIGNALS_BLOCK (SIGINT, saved_signals);
-
- /* We always get the latest tty values. Maybe stty changed them. */
- ioctl (tty, TIOCGETP, &the_ttybuff);
- original_tty_flags = the_ttybuff.sg_flags;
-
- readline_echoing_p = (original_tty_flags & ECHO);
-
-#if defined (TIOCLGET)
- ioctl (tty, TIOCLGET, &local_mode_flags);
-#endif
-
-#if !defined (ANYP)
-# define ANYP (EVENP | ODDP)
-#endif
-
- /* If this terminal doesn't care how the 8th bit is used,
- then we can use it for the meta-key. We check by seeing
- if BOTH odd and even parity are allowed. */
- if (the_ttybuff.sg_flags & ANYP)
- {
-#if defined (PASS8)
- the_ttybuff.sg_flags |= PASS8;
-#endif
-
- /* Hack on local mode flags if we can. */
-#if defined (TIOCLGET) && defined (LPASS8)
- {
- int flags;
- flags = local_mode_flags | LPASS8;
- ioctl (tty, TIOCLSET, &flags);
- }
-#endif /* TIOCLGET && LPASS8 */
- }
-
-#if defined (TIOCGETC)
- {
- struct tchars temp;
-
- ioctl (tty, TIOCGETC, &original_tchars);
- temp = original_tchars;
-
-#if defined (USE_XON_XOFF)
- /* Get rid of C-s and C-q.
- We remember the value of startc (C-q) so that if the terminal is in
- xoff state, the user can xon it by pressing that character. */
- xon_char = temp.t_startc;
- temp.t_stopc = -1;
- temp.t_startc = -1;
-
- /* If there is an XON character, bind it to restart the output. */
- if (xon_char != -1)
- rl_bind_key (xon_char, rl_restart_output);
-#endif /* USE_XON_XOFF */
-
- /* If there is an EOF char, bind eof_char to it. */
- if (temp.t_eofc != -1)
- eof_char = temp.t_eofc;
-
-#if defined (NO_KILL_INTR)
- /* Get rid of C-\ and C-c. */
- temp.t_intrc = temp.t_quitc = -1;
-#endif /* NO_KILL_INTR */
-
- ioctl (tty, TIOCSETC, &temp);
- }
-#endif /* TIOCGETC */
-
-#if defined (TIOCGLTC)
- {
- struct ltchars temp;
-
- ioctl (tty, TIOCGLTC, &original_ltchars);
- temp = original_ltchars;
-
- /* Make the interrupt keys go away. Just enough to make people
- happy. */
- temp.t_dsuspc = -1; /* C-y */
- temp.t_lnextc = -1; /* C-v */
-
- ioctl (tty, TIOCSLTC, &temp);
- }
-#endif /* TIOCGLTC */
-
- the_ttybuff.sg_flags &= ~(ECHO | CRMOD);
- the_ttybuff.sg_flags |= CBREAK;
- ioctl (tty, TIOCSETN, &the_ttybuff);
-
- terminal_prepped = 1;
-
- SIGNALS_RESTORE (saved_signals);
-#endif /* !__GO32__ */
-}
-
-/* Restore the terminal to its original state. */
-static void
-rl_deprep_terminal ()
-{
-#ifndef __GO32__
- int tty = fileno (rl_instream);
- SIGNALS_DECLARE_SAVED (saved_signals);
-
- if (!terminal_prepped)
- return;
-
- SIGNALS_BLOCK (SIGINT, saved_signals);
-
- the_ttybuff.sg_flags = original_tty_flags;
- ioctl (tty, TIOCSETN, &the_ttybuff);
- readline_echoing_p = 1;
-
-#if defined (TIOCLGET)
- ioctl (tty, TIOCLSET, &local_mode_flags);
-#endif
-
-#if defined (TIOCSLTC)
- ioctl (tty, TIOCSLTC, &original_ltchars);
-#endif
-
-#if defined (TIOCSETC)
- ioctl (tty, TIOCSETC, &original_tchars);
-#endif
- terminal_prepped = 0;
-
- SIGNALS_RESTORE (saved_signals);
-#endif /* !__GO32 */
-}
-
-#else /* !defined (NEW_TTY_DRIVER) */
-
-#if !defined (VMIN)
-#define VMIN VEOF
-#endif
-
-#if !defined (VTIME)
-#define VTIME VEOL
-#endif
-
-#ifndef __GO32__
-#if defined (TERMIOS_TTY_DRIVER)
-static struct termios otio;
-#else
-static struct termio otio;
-#endif /* !TERMIOS_TTY_DRIVER */
-#endif /* __GO32__ */
-
-static void
-rl_prep_terminal ()
-{
-#ifndef __GO32__
- int tty = fileno (rl_instream);
-#if defined (TERMIOS_TTY_DRIVER)
- struct termios tio;
-#else
- struct termio tio;
-#endif /* !TERMIOS_TTY_DRIVER */
-
- SIGNALS_DECLARE_SAVED (saved_signals);
-
- if (terminal_prepped)
- return;
-
- /* Try to keep this function from being INTerrupted. We can do it
- on POSIX and systems with BSD-like signal handling. */
- SIGNALS_BLOCK (SIGINT, saved_signals);
-
- wait_foreground (); /* XXX this prevents to got editing mode from tcsh */
-#if defined (TERMIOS_TTY_DRIVER)
- tcgetattr (tty, &tio);
-#else
- ioctl (tty, TCGETA, &tio);
-#endif /* !TERMIOS_TTY_DRIVER */
-
- otio = tio;
-
- readline_echoing_p = (tio.c_lflag & ECHO);
-
- tio.c_lflag &= ~(ICANON|ECHO);
-
- if (otio.c_cc[VEOF] != _POSIX_VDISABLE)
- eof_char = otio.c_cc[VEOF];
-
-#if defined (USE_XON_XOFF)
-#if defined (IXANY)
- tio.c_iflag &= ~(IXON|IXOFF|IXANY);
-#else
- /* `strict' Posix systems do not define IXANY. */
- tio.c_iflag &= ~(IXON|IXOFF);
-#endif /* IXANY */
-#endif /* USE_XON_XOFF */
-
- /* Only turn this off if we are using all 8 bits. */
- /* |ISTRIP|INPCK */
- tio.c_iflag &= ~(ISTRIP | INPCK);
-
- /* Make sure we differentiate between CR and NL on input. */
- tio.c_iflag &= ~(ICRNL | INLCR);
-
-#if !defined (HANDLE_SIGNALS)
- tio.c_lflag &= ~ISIG;
-#else
- tio.c_lflag |= ISIG;
-#endif
-
- tio.c_cc[VMIN] = 1;
- tio.c_cc[VTIME] = 0;
-
- /* 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_JOB_CONTROL)
-
-#if defined (VLNEXT)
- tio.c_cc[VLNEXT] = _POSIX_VDISABLE;
-#endif
-
-#if defined (VDSUSP)
- tio.c_cc[VDSUSP] = _POSIX_VDISABLE;
-#endif
-
-#endif /* POSIX && JOB_CONTROL */
-
-#if defined (TERMIOS_TTY_DRIVER)
- tcsetattr (tty, TCSADRAIN, &tio);
- tcflow (tty, TCOON); /* Simulate a ^Q. */
-#else
- ioctl (tty, TCSETAW, &tio);
- ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
-#endif /* !TERMIOS_TTY_DRIVER */
-
- terminal_prepped = 1;
-
- SIGNALS_RESTORE (saved_signals);
-#endif /* !__GO32__ */
-}
-
-static void
-rl_deprep_terminal ()
-{
-#ifndef __GO32__
- int tty = fileno (rl_instream);
-
- /* Try to keep this function from being INTerrupted. We can do it
- on POSIX and systems with BSD-like signal handling. */
- SIGNALS_DECLARE_SAVED (saved_signals);
-
- if (!terminal_prepped)
- return;
-
- SIGNALS_BLOCK (SIGINT, saved_signals);
-
-#if defined (TERMIOS_TTY_DRIVER)
- tcsetattr (tty, TCSADRAIN, &otio);
- tcflow (tty, TCOON); /* Simulate a ^Q. */
-#else /* TERMIOS_TTY_DRIVER */
- ioctl (tty, TCSETAW, &otio);
- ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
-#endif /* !TERMIOS_TTY_DRIVER */
-
- terminal_prepped = 0;
-
- SIGNALS_RESTORE (saved_signals);
-#endif /* !__GO32__ */
-}
-#endif /* NEW_TTY_DRIVER */
-
/* **************************************************************** */
/* */
@@ -2649,7 +1432,7 @@ alphabetic (c)
return (1);
if (allow_pathname_alphabetic_chars)
- return ((int)rindex (pathname_alphabetic_chars, c));
+ return (strchr (pathname_alphabetic_chars, c) != NULL);
else
return (0);
}
@@ -2668,11 +1451,11 @@ ding ()
{
if (readline_echoing_p)
{
-#ifndef __GO32__
- if (prefer_visible_bell && visible_bell)
- tputs (visible_bell, 1, output_character_function);
+#if !defined (_GO32_)
+ if (_rl_prefer_visible_bell && visible_bell)
+ tputs (visible_bell, 1, _rl_output_character_function);
else
-#endif /* !__GO32__ */
+#endif /* !_GO32_ */
{
fprintf (stderr, "\007");
fflush (stderr);
@@ -2699,12 +1482,8 @@ rl_abort ()
/* Return a copy of the string between FROM and TO.
FROM is inclusive, TO is not. */
-#if defined (sun) /* Yes, that's right, some crufty function in sunview is
- called rl_copy (). */
-static
-#endif
char *
-rl_copy (from, to)
+rl_copy_text (from, to)
int from, to;
{
register int length;
@@ -2752,7 +1531,6 @@ rl_extend_line_buffer (len)
rl_insert_text (string)
char *string;
{
- extern int doing_an_undo;
register int i, l = strlen (string);
if (rl_end + l >= rl_line_buffer_len)
@@ -2785,7 +1563,6 @@ rl_insert_text (string)
rl_delete_text (from, to)
int from, to;
{
- extern int doing_an_undo;
register char *text;
/* Fix it if the caller is confused. */
@@ -2795,7 +1572,7 @@ rl_delete_text (from, to)
from = to;
to = t;
}
- text = rl_copy (from, to);
+ text = rl_copy_text (from, to);
strncpy (the_line + from, the_line + to, rl_end - to);
/* Remember how to undo this delete. */
@@ -2853,18 +1630,19 @@ rl_forward (count)
while (count)
{
#if defined (VI_MODE)
- if (rl_point == (rl_end - (rl_editing_mode == vi_mode)))
+ if (rl_point >= (rl_end - (rl_editing_mode == vi_mode)))
#else
if (rl_point == rl_end)
#endif /* VI_MODE */
{
ding ();
- return;
+ return 0;
}
else
rl_point++;
--count;
}
+ return 0;
}
/* Move backward COUNT characters. */
@@ -2879,24 +1657,27 @@ rl_backward (count)
if (!rl_point)
{
ding ();
- return;
+ return 0;
}
else
--rl_point;
--count;
}
+ return 0;
}
/* Move to the beginning of the line. */
rl_beg_of_line ()
{
rl_point = 0;
+ return 0;
}
/* Move to the end of the line. */
rl_end_of_line ()
{
rl_point = rl_end;
+ return 0;
}
/* Move forward a word. We do what Emacs does. */
@@ -2908,13 +1689,13 @@ rl_forward_word (count)
if (count < 0)
{
rl_backward_word (-count);
- return;
+ return 0;
}
while (count)
{
if (rl_point == rl_end)
- return;
+ return 0;
/* If we are not in a word, move forward until we are in one.
Then, move forward until we hit a non-alphabetic character. */
@@ -2935,6 +1716,7 @@ rl_forward_word (count)
}
--count;
}
+ return 0;
}
/* Move backward a word. We do what Emacs does. */
@@ -2946,13 +1728,13 @@ rl_backward_word (count)
if (count < 0)
{
rl_forward_word (-count);
- return;
+ return 0;
}
while (count)
{
if (!rl_point)
- return;
+ return 0;
/* Like rl_forward_word (), except that we look at the characters
just before point. */
@@ -2976,31 +1758,35 @@ rl_backward_word (count)
}
--count;
}
+ return 0;
}
/* Clear the current line. Numeric argument to C-l does this. */
rl_refresh_line ()
{
- int curr_line = last_c_pos / screenwidth;
- extern char *term_clreol;
+ int curr_line = _rl_last_c_pos / screenwidth;
- move_vert(curr_line);
- move_cursor_relative (0, the_line); /* XXX is this right */
+ _rl_move_vert (curr_line);
+ _rl_move_cursor_relative (0, the_line); /* XXX is this right */
-#ifdef __GO32__
+#if defined (_GO32_)
{
- int r, c, w;
- ScreenGetCursor(&r, &c);
- w = ScreenCols();
- memset(ScreenPrimary+r*w+c, 0, (w-c)*2);
+ int row, col, width, row_start;
+
+ ScreenGetCursor (&row, &col);
+ width = ScreenCols ();
+ row_start = ScreenPrimary + (row * width);
+ memset (row_start + col, 0, (width - col) * 2);
}
-#else /* __GO32__ */
+#else /* !_GO32_ */
if (term_clreol)
- tputs (term_clreol, 1, output_character_function);
-#endif /* __GO32__/else */
+ tputs (term_clreol, 1, _rl_output_character_function);
+#endif /* !_GO32_ */
rl_forced_update_display ();
rl_display_fixed = 1;
+
+ return 0;
}
/* C-l typed to a line without quoting clears the screen, and then reprints
@@ -3008,23 +1794,23 @@ rl_refresh_line ()
the current line. */
rl_clear_screen ()
{
- extern char *term_clrpag;
-
if (rl_explicit_arg)
{
rl_refresh_line ();
- return;
+ return 0;
}
-#ifndef __GO32__
+#if !defined (_GO32_)
if (term_clrpag)
- tputs (term_clrpag, 1, output_character_function);
+ tputs (term_clrpag, 1, _rl_output_character_function);
else
-#endif /* !__GO32__ */
+#endif /* !_GO32_ */
crlf ();
rl_forced_update_display ();
rl_display_fixed = 1;
+
+ return 0;
}
rl_arrow_keys (count, c)
@@ -3055,6 +1841,7 @@ rl_arrow_keys (count, c)
default:
ding ();
}
+ return 0;
}
@@ -3072,7 +1859,7 @@ rl_insert (count, c)
char *string;
if (count <= 0)
- return;
+ return 0;
/* If we can optimize, then do it. But don't let people crash
readline because of extra large arguments. */
@@ -3085,7 +1872,7 @@ rl_insert (count, c)
string[i] = '\0';
rl_insert_text (string);
- return;
+ return 0;
}
if (count > 1024)
@@ -3104,7 +1891,7 @@ rl_insert (count, c)
rl_insert_text (string);
count -= decreaser;
}
- return;
+ return 0;
}
/* We are inserting a single character.
@@ -3120,8 +1907,8 @@ rl_insert (count, c)
string[i++] = c;
while ((t = rl_get_char (&key)) &&
- (keymap[key].type == ISFUNC &&
- keymap[key].function == rl_insert))
+ (_rl_keymap[key].type == ISFUNC &&
+ _rl_keymap[key].function == rl_insert))
string[i++] = key;
if (t)
@@ -3129,7 +1916,6 @@ rl_insert (count, c)
string[i] = '\0';
rl_insert_text (string);
- return;
}
else
{
@@ -3140,21 +1926,25 @@ rl_insert (count, c)
string[0] = c;
rl_insert_text (string);
}
+ return 0;
}
/* Insert the next typed character verbatim. */
rl_quoted_insert (count)
int count;
{
- int c = rl_read_key ();
- rl_insert (count, c);
+ int c;
+
+ c = rl_read_key ();
+ return (rl_insert (count, c));
+
}
/* Insert a tab character. */
rl_tab_insert (count)
int count;
{
- rl_insert (count, '\t');
+ return (rl_insert (count, '\t'));
}
/* What to do when a NEWLINE is pressed. We accept the whole line.
@@ -3163,39 +1953,42 @@ rl_tab_insert (count)
rl_newline (count, key)
int count, key;
{
-
rl_done = 1;
#if defined (VI_MODE)
{
- extern int vi_doing_insert;
- if (vi_doing_insert)
+ extern int _rl_vi_doing_insert;
+ if (_rl_vi_doing_insert)
{
rl_end_undo_group ();
- vi_doing_insert = 0;
+ _rl_vi_doing_insert = 0;
}
}
+ rl_vi_set_last ();
+
#endif /* VI_MODE */
if (readline_echoing_p)
{
- move_vert (vis_botlin);
- vis_botlin = 0;
+ _rl_move_vert (_rl_vis_botlin);
+ _rl_vis_botlin = 0;
crlf ();
fflush (out_stream);
rl_display_fixed++;
}
+ return 0;
}
rl_clean_up_for_exit ()
{
if (readline_echoing_p)
{
- move_vert (vis_botlin);
- vis_botlin = 0;
+ _rl_move_vert (_rl_vis_botlin);
+ _rl_vis_botlin = 0;
fflush (out_stream);
rl_restart_output ();
}
+ return 0;
}
/* What to do for some uppercase characters, like meta characters,
@@ -3205,6 +1998,7 @@ rl_clean_up_for_exit ()
rl_do_lowercase_version (ignore1, ignore2)
int ignore1, ignore2;
{
+ return 0;
}
/* Rubout the character behind point. */
@@ -3214,16 +2008,16 @@ rl_rubout (count)
if (count < 0)
{
rl_delete (-count);
- return;
+ return 0;
}
if (!rl_point)
{
ding ();
- return;
+ return -1;
}
- if (count > 1)
+ if (count > 1 || rl_explicit_arg)
{
int orig_point = rl_point;
rl_backward (count);
@@ -3234,16 +2028,14 @@ rl_rubout (count)
int c = the_line[--rl_point];
rl_delete_text (rl_point, rl_point + 1);
- if (rl_point == rl_end && alphabetic (c) && last_c_pos)
+ if (rl_point == rl_end && isprint (c) && _rl_last_c_pos)
{
- backspace (1);
- putc (' ', out_stream);
- backspace (1);
- last_c_pos--;
- visible_line[last_c_pos] = '\0';
- rl_display_fixed++;
+ int l;
+ l = rl_character_len (c, rl_point);
+ _rl_erase_at_end_of_line (l);
}
}
+ return 0;
}
/* Delete the character under the cursor. Given a numeric argument,
@@ -3253,25 +2045,48 @@ rl_delete (count, invoking_key)
{
if (count < 0)
{
- rl_rubout (-count);
- return;
+ return (rl_rubout (-count));
}
if (rl_point == rl_end)
{
ding ();
- return;
+ return -1;
}
- if (count > 1)
+ if (count > 1 || rl_explicit_arg)
{
int orig_point = rl_point;
rl_forward (count);
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
+ return 0;
}
else
- rl_delete_text (rl_point, rl_point + 1);
+ return (rl_delete_text (rl_point, rl_point + 1));
+
+}
+
+/* Delete all spaces and tabs around point. */
+rl_delete_horizontal_space (count, ignore)
+ int count, ignore;
+{
+ int start = rl_point;
+
+ while (rl_point && whitespace (the_line[rl_point - 1]))
+ rl_point--;
+
+ start = rl_point;
+
+ while (rl_point < rl_end && whitespace (the_line[rl_point]))
+ rl_point++;
+
+ if (start != rl_point)
+ {
+ rl_delete_text (start, rl_point);
+ rl_point = start;
+ }
+ return 0;
}
@@ -3289,15 +2104,21 @@ rl_delete (count, invoking_key)
using behaviour that they expect. */
rl_unix_word_rubout ()
{
- if (!rl_point) ding ();
- else {
- int orig_point = rl_point;
- while (rl_point && whitespace (the_line[rl_point - 1]))
- rl_point--;
- while (rl_point && !whitespace (the_line[rl_point - 1]))
- rl_point--;
- rl_kill_text (rl_point, orig_point);
- }
+ if (!rl_point)
+ ding ();
+ else
+ {
+ int orig_point = rl_point;
+
+ while (rl_point && whitespace (the_line[rl_point - 1]))
+ rl_point--;
+
+ while (rl_point && !whitespace (the_line[rl_point - 1]))
+ rl_point--;
+
+ rl_kill_text (rl_point, orig_point);
+ }
+ return 0;
}
/* Here is C-u doing what Unix does. You don't *have* to use these
@@ -3308,15 +2129,17 @@ rl_unix_word_rubout ()
doing. */
rl_unix_line_discard ()
{
- if (!rl_point) ding ();
- else {
- rl_kill_text (rl_point, 0);
- rl_point = 0;
- }
+ if (!rl_point)
+ ding ();
+ else
+ {
+ rl_kill_text (rl_point, 0);
+ rl_point = 0;
+ }
+ return 0;
}
-
/* **************************************************************** */
/* */
/* Commands For Typos */
@@ -3336,25 +2159,27 @@ rl_unix_line_discard ()
#define DownCase 2
#define CapCase 3
+static int rl_change_case ();
+
/* Uppercase the word at point. */
rl_upcase_word (count)
int count;
{
- rl_change_case (count, UpCase);
+ return (rl_change_case (count, UpCase));
}
/* Lowercase the word at point. */
rl_downcase_word (count)
int count;
{
- rl_change_case (count, DownCase);
+ return (rl_change_case (count, DownCase));
}
/* Upcase the first letter, downcase the rest. */
rl_capitalize_word (count)
int count;
{
- rl_change_case (count, CapCase);
+ return (rl_change_case (count, CapCase));
}
/* The meaty function.
@@ -3362,6 +2187,7 @@ rl_capitalize_word (count)
OP is one of UpCase, DownCase, or CapCase.
If a negative argument is given, leave point where it started,
otherwise, leave it where it moves to. */
+static int
rl_change_case (count, op)
int count, op;
{
@@ -3409,9 +2235,11 @@ rl_change_case (count, op)
default:
abort ();
+ return -1;
}
}
rl_point = end;
+ return 0;
}
/* **************************************************************** */
@@ -3428,7 +2256,8 @@ rl_transpose_words (count)
int w1_beg, w1_end, w2_beg, w2_end;
int orig_point = rl_point;
- if (!count) return;
+ if (!count)
+ return 0;
/* Find the two words. */
rl_forward_word (count);
@@ -3445,12 +2274,12 @@ rl_transpose_words (count)
{
ding ();
rl_point = orig_point;
- return;
+ return -1;
}
/* Get the text of the words. */
- word1 = rl_copy (w1_beg, w1_end);
- word2 = rl_copy (w2_beg, w2_end);
+ word1 = rl_copy_text (w1_beg, w1_end);
+ word2 = rl_copy_text (w2_beg, w2_end);
/* We are about to do many insertions and deletions. Remember them
as one operation. */
@@ -3472,7 +2301,10 @@ rl_transpose_words (count)
/* I think that does it. */
rl_end_undo_group ();
- free (word1); free (word2);
+ free (word1);
+ free (word2);
+
+ return 0;
}
/* Transpose the characters at point. If point is at the end of the line,
@@ -3480,793 +2312,40 @@ rl_transpose_words (count)
rl_transpose_chars (count)
int count;
{
- if (!count)
- return;
-
- if (!rl_point || rl_end < 2) {
- ding ();
- return;
- }
-
- while (count)
- {
- if (rl_point == rl_end)
- {
- int t = the_line[rl_point - 1];
-
- the_line[rl_point - 1] = the_line[rl_point - 2];
- the_line[rl_point - 2] = t;
- }
- else
- {
- int t = the_line[rl_point];
-
- the_line[rl_point] = the_line[rl_point - 1];
- the_line[rl_point - 1] = t;
-
- if (count < 0 && rl_point)
- rl_point--;
- else
- rl_point++;
- }
-
- if (count < 0)
- count++;
- else
- count--;
- }
-}
-
-
-/* **************************************************************** */
-/* */
-/* Bogus Flow Control */
-/* */
-/* **************************************************************** */
-
-rl_restart_output (count, key)
- int count, key;
-{
- int fildes = fileno (rl_outstream);
-#if defined (TIOCSTART)
-#if defined (apollo)
- ioctl (&fildes, TIOCSTART, 0);
-#else
- ioctl (fildes, TIOCSTART, 0);
-#endif /* apollo */
-
-#else
-# if defined (TERMIOS_TTY_DRIVER)
- tcflow (fildes, TCOON);
-# else
-# if defined (TCXONC)
- ioctl (fildes, TCXONC, TCOON);
-# endif /* TCXONC */
-# endif /* !TERMIOS_TTY_DRIVER */
-#endif /* TIOCSTART */
-}
-
-rl_stop_output (count, key)
- int count, key;
-{
- int fildes = fileno (rl_instream);
-
-#if defined (TIOCSTOP)
-# if defined (apollo)
- ioctl (&fildes, TIOCSTOP, 0);
-# else
- ioctl (fildes, TIOCSTOP, 0);
-# endif /* apollo */
-#else
-# if defined (TERMIOS_TTY_DRIVER)
- tcflow (fildes, TCOOFF);
-# else
-# if defined (TCXONC)
- ioctl (fildes, TCXONC, TCOON);
-# endif /* TCXONC */
-# endif /* !TERMIOS_TTY_DRIVER */
-#endif /* TIOCSTOP */
-}
-
-/* **************************************************************** */
-/* */
-/* Completion matching, from readline's point of view. */
-/* */
-/* **************************************************************** */
-
-/* Pointer to the generator function for completion_matches ().
- NULL means to use filename_entry_function (), the default filename
- completer. */
-Function *rl_completion_entry_function = (Function *)NULL;
-
-/* 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. */
-Function *rl_attempted_completion_function = (Function *)NULL;
-
-/* Local variable states what happened during the last completion attempt. */
-static int completion_changed_buffer = 0;
-
-/* Complete the word at or before point. You have supplied the function
- that does the initial simple matching selection algorithm (see
- completion_matches ()). The default is to do filename completion. */
-
-rl_complete (ignore, invoking_key)
- int ignore, invoking_key;
-{
- if (rl_last_func == rl_complete && !completion_changed_buffer)
- rl_complete_internal ('?');
- else
- rl_complete_internal (TAB);
-}
-
-/* List the possible completions. See description of rl_complete (). */
-rl_possible_completions ()
-{
- rl_complete_internal ('?');
-}
-
-/* The user must press "y" or "n". Non-zero return means "y" pressed. */
-get_y_or_n ()
-{
- int c;
- loop:
- c = rl_read_key ();
- if (c == 'y' || c == 'Y') return (1);
- if (c == 'n' || c == 'N') return (0);
- if (c == ABORT_CHAR) rl_abort ();
- ding (); goto loop;
-}
-
-/* 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. */
-int rl_completion_query_items = 100;
-
-/* The basic list of characters that signal a break between words for the
- completer routine. The contents of this variable is what breaks words
- in the shell, i.e. " \t\n\"\\'`@$><=" */
-char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
-
-/* 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. */
-char *rl_completer_word_break_characters = (char *)NULL;
-
-/* The list of characters which are used to quote a substring of the command
- line. Command 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. */
-char *rl_completer_quote_characters = (char *)NULL;
-
-/* 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. */
-char *rl_special_prefixes = (char *)NULL;
-
-/* If non-zero, then disallow duplicates in the matches. */
-int rl_ignore_completion_duplicates = 1;
-
-/* 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. */
-int rl_filename_completion_desired = 0;
-
-/* This function, if defined, is called by the completer when real
- filename completion is done, after all the matching names have been
- generated. It is passed a (char**) known as matches in the code below.
- It consists of a NULL-terminated array of pointers to potential
- matching strings. The 1st element (matches[0]) is the maximal
- substring that is common to all matches. This function can re-arrange
- the list of matches as required, but all elements of the array must be
- free()'d if they are deleted. The main intent of this function is
- to implement FIGNORE a la SunOS csh. */
-Function *rl_ignore_some_completions_function = (Function *)NULL;
-
-/* Complete the word at or before point.
- WHAT_TO_DO says what to do with the completion.
- `?' means list the possible completions.
- TAB means do standard completion.
- `*' means insert all of the possible completions. */
-rl_complete_internal (what_to_do)
- int what_to_do;
-{
- char *filename_completion_function ();
- char **completion_matches (), **matches;
- Function *our_func;
- int start, scan, end, delimiter = 0;
- char *text, *saved_line_buffer;
- char quote_char = '\0';
- char *replacement;
-
- if (the_line)
- saved_line_buffer = savestring (the_line);
- else
- saved_line_buffer = (char *)NULL;
-
- if (rl_completion_entry_function)
- our_func = rl_completion_entry_function;
- else
- our_func = (int (*)())filename_completion_function;
-
- /* Only the completion entry function can change this. */
- rl_filename_completion_desired = 0;
-
- /* We now look backwards for the start of a filename/variable word. */
- end = rl_point;
-
- if (rl_point)
- {
- if (rl_completer_quote_characters)
- {
- /* We have a list of characters which can be used in pairs to quote
- substrings for completion. Try to find the start of an unclosed
- quoted substring.
- FIXME: Doesn't yet handle '\' escapes to hid embedded quotes */
- for (scan = 0; scan < end; scan++)
- {
- if (quote_char != '\0')
- {
- /* Ignore everything until the matching close quote char */
- if (the_line[scan] == quote_char)
- {
- /* Found matching close quote. Abandon this substring. */
- quote_char = '\0';
- rl_point = end;
- }
- }
- else if (rindex (rl_completer_quote_characters, the_line[scan]))
- {
- /* Found start of a quoted substring. */
- quote_char = the_line[scan];
- rl_point = scan + 1;
- }
- }
- }
- if (rl_point == end)
- {
- /* We didn't find an unclosed quoted substring upon which to do
- completion, so use the word break characters to find the
- substring on which to do completion. */
- while (--rl_point &&
- !rindex (rl_completer_word_break_characters,
- the_line[rl_point])) {;}
- }
-
- /* If we are at a word break, then advance past it. */
- if (rindex (rl_completer_word_break_characters, the_line[rl_point]))
- {
- /* If the character that caused the word break was a quoting
- character, then remember it as the delimiter. */
- if (rindex ("\"'", the_line[rl_point]) && (end - rl_point) > 1)
- delimiter = the_line[rl_point];
-
- /* If the character isn't needed to determine something special
- about what kind of completion to perform, then advance past it. */
-
- if (!rl_special_prefixes ||
- !rindex (rl_special_prefixes, the_line[rl_point]))
- rl_point++;
- }
- }
-
- start = rl_point;
- rl_point = end;
- text = rl_copy (start, end);
-
- /* If the user wants to TRY to complete, but then wants to give
- up and use the default completion function, they set the
- variable rl_attempted_completion_function. */
- if (rl_attempted_completion_function)
- {
- matches =
- (char **)(*rl_attempted_completion_function) (text, start, end);
+ char dummy[2];
- if (matches)
- {
- our_func = (Function *)NULL;
- goto after_usual_completion;
- }
- }
-
- matches = completion_matches (text, our_func);
-
- after_usual_completion:
- free (text);
-
- if (!matches)
- ding ();
- else
- {
- register int i;
-
- some_matches:
-
- /* It seems to me that in all the cases we handle we would like
- to ignore duplicate possibilities. Scan for the text to
- insert being identical to the other completions. */
- if (rl_ignore_completion_duplicates)
- {
- char *lowest_common;
- int j, newlen = 0;
-
- /* Sort the items. */
- /* It is safe to sort this array, because the lowest common
- denominator found in matches[0] will remain in place. */
- for (i = 0; matches[i]; i++);
- qsort (matches, i, sizeof (char *), compare_strings);
-
- /* Remember the lowest common denominator for it may be unique. */
- lowest_common = savestring (matches[0]);
-
- for (i = 0; matches[i + 1]; i++)
- {
- if (strcmp (matches[i], matches[i + 1]) == 0)
- {
- free (matches[i]);
- matches[i] = (char *)-1;
- }
- else
- newlen++;
- }
-
- /* We have marked all the dead slots with (char *)-1.
- Copy all the non-dead entries into a new array. */
- {
- char **temp_array =
- (char **)malloc ((3 + newlen) * sizeof (char *));
-
- for (i = 1, j = 1; matches[i]; i++)
- {
- if (matches[i] != (char *)-1)
- temp_array[j++] = matches[i];
- }
-
- temp_array[j] = (char *)NULL;
-
- if (matches[0] != (char *)-1)
- free (matches[0]);
-
- free (matches);
-
- matches = temp_array;
- }
-
- /* Place the lowest common denominator back in [0]. */
- matches[0] = lowest_common;
-
- /* If there is one string left, and it is identical to the
- lowest common denominator, then the LCD is the string to
- insert. */
- if (j == 2 && strcmp (matches[0], matches[1]) == 0)
- {
- free (matches[1]);
- matches[1] = (char *)NULL;
- }
- }
-
- switch (what_to_do)
- {
- case TAB:
- /* If we are matching filenames, then here is our chance to
- do clever processing by re-examining the list. Call the
- ignore function with the array as a parameter. It can
- munge the array, deleting matches as it desires. */
- if (rl_ignore_some_completions_function &&
- our_func == (int (*)())filename_completion_function)
- (void)(*rl_ignore_some_completions_function)(matches);
-
- /* If we are doing completions on quoted substrings, and any matches
- contain any of the completer word break characters, then auto-
- matically prepend the substring with a quote character (just
- pick the first one from the list of such) if it does not already
- begin with a quote string. FIXME: Need to remove any such
- automatically inserted quote character when it no longer is
- necessary, such as if we change the string we are completing on
- and the new set of matches don't require a quoted substring? */
-
- replacement = matches[0];
- if (matches[0] != NULL
- && rl_completer_quote_characters != NULL
- && (quote_char == '\0'))
- {
- for (i = 1; matches[i] != NULL; i++)
- {
- if (strpbrk (matches[i], rl_completer_word_break_characters))
- {
- /* Found an embedded word break character in a potential
- match, so need to prepend a quote character if we are
- replacing the completion string. */
- replacement = (char *)alloca (strlen (matches[0]) + 2);
- quote_char = *rl_completer_quote_characters;
- *replacement = quote_char;
- strcpy (replacement + 1, matches[0]);
- break;
- }
- }
- }
- if (replacement)
- {
- rl_delete_text (start, rl_point);
- rl_point = start;
- rl_insert_text (replacement);
- }
-
- /* If there are more matches, ring the bell to indicate.
- If this was the only match, and we are hacking files,
- check the file to see if it was a directory. If so,
- add a '/' to the name. If not, and we are at the end
- of the line, then add a space. */
- if (matches[1])
- {
- ding (); /* There are other matches remaining. */
- }
- else
- {
- char temp_string[16];
- int temp_index = 0;
-
- if (quote_char)
- {
- temp_string[temp_index++] = quote_char;
- }
- temp_string[temp_index++] = delimiter ? delimiter : ' ';
- temp_string[temp_index++] = '\0';
-
- if (rl_filename_completion_desired)
- {
- struct stat finfo;
- char *filename = tilde_expand (matches[0]);
-
- if ((stat (filename, &finfo) == 0) &&
- S_ISDIR (finfo.st_mode))
- {
- if (the_line[rl_point] != '/')
- rl_insert_text ("/");
- }
- else
- {
- if (rl_point == rl_end)
- rl_insert_text (temp_string);
- }
- free (filename);
- }
- else
- {
- if (rl_point == rl_end)
- rl_insert_text (temp_string);
- }
- }
- break;
-
- case '*':
- {
- int i = 1;
-
- rl_delete_text (start, rl_point);
- rl_point = start;
- rl_begin_undo_group ();
- if (matches[1])
- {
- while (matches[i])
- {
- rl_insert_text (matches[i++]);
- rl_insert_text (" ");
- }
- }
- else
- {
- rl_insert_text (matches[0]);
- rl_insert_text (" ");
- }
- rl_end_undo_group ();
- }
- break;
-
- case '?':
- {
- int len, count, limit, max = 0;
- int j, k, l;
-
- /* Handle simple case first. What if there is only one answer? */
- if (!matches[1])
- {
- char *temp;
-
- if (rl_filename_completion_desired)
- temp = rindex (matches[0], '/');
- else
- temp = (char *)NULL;
-
- if (!temp)
- temp = matches[0];
- else
- temp++;
-
- crlf ();
- fprintf (out_stream, "%s", temp);
- crlf ();
- goto restart;
- }
-
- /* There is more than one answer. Find out how many there are,
- and find out what the maximum printed length of a single entry
- is. */
- for (i = 1; matches[i]; i++)
- {
- char *temp = (char *)NULL;
-
- /* If we are hacking filenames, then only count the characters
- after the last slash in the pathname. */
- if (rl_filename_completion_desired)
- temp = rindex (matches[i], '/');
- else
- temp = (char *)NULL;
-
- if (!temp)
- temp = matches[i];
- else
- temp++;
-
- if (strlen (temp) > max)
- max = strlen (temp);
- }
-
- len = i;
-
- /* If there are many items, then ask the user if she
- really wants to see them all. */
- if (len >= rl_completion_query_items)
- {
- crlf ();
- fprintf (out_stream,
- "There are %d possibilities. Do you really", len);
- crlf ();
- fprintf (out_stream, "wish to see them all? (y or n)");
- fflush (out_stream);
- if (!get_y_or_n ())
- {
- crlf ();
- goto restart;
- }
- }
- /* How many items of MAX length can we fit in the screen window? */
- max += 2;
- limit = screenwidth / max;
- if (limit != 1 && (limit * max == screenwidth))
- limit--;
-
- /* Avoid a possible floating exception. If max > screenwidth,
- limit will be 0 and a divide-by-zero fault will result. */
- if (limit == 0)
- limit = 1;
-
- /* How many iterations of the printing loop? */
- count = (len + (limit - 1)) / limit;
-
- /* Watch out for special case. If LEN is less than LIMIT, then
- just do the inner printing loop. */
- if (len < limit) count = 1;
-
- /* Sort the items if they are not already sorted. */
- if (!rl_ignore_completion_duplicates)
- qsort (matches, len, sizeof (char *), compare_strings);
-
- /* Print the sorted items, up-and-down alphabetically, like
- ls might. */
- crlf ();
-
- for (i = 1; i < count + 1; i++)
- {
- for (j = 0, l = i; j < limit; j++)
- {
- if (l > len || !matches[l])
- {
- break;
- }
- else
- {
- char *temp = (char *)NULL;
-
- if (rl_filename_completion_desired)
- temp = rindex (matches[l], '/');
- else
- temp = (char *)NULL;
-
- if (!temp)
- temp = matches[l];
- else
- temp++;
-
- fprintf (out_stream, "%s", temp);
- for (k = 0; k < max - strlen (temp); k++)
- putc (' ', out_stream);
- }
- l += count;
- }
- crlf ();
- }
- restart:
-
- rl_on_new_line ();
- }
- break;
-
- default:
- abort ();
- }
-
- for (i = 0; matches[i]; i++)
- free (matches[i]);
- free (matches);
- }
-
- /* Check to see if the line has changed through all of this manipulation. */
- if (saved_line_buffer)
- {
- if (strcmp (the_line, saved_line_buffer) != 0)
- completion_changed_buffer = 1;
- else
- completion_changed_buffer = 0;
-
- free (saved_line_buffer);
- }
-}
-
-/* Stupid comparison routine for qsort () ing strings. */
-static int
-compare_strings (s1, s2)
- char **s1, **s2;
-{
- return (strcmp (*s1, *s2));
-}
+ if (!count)
+ return 0;
-/* A completion function for usernames.
- TEXT contains a partial username preceded by a random
- character (usually `~'). */
-char *
-username_completion_function (text, state)
- int state;
- char *text;
-{
-#ifdef __GO32__
- return (char *)NULL;
-#else /* !__GO32__ */
- static char *username = (char *)NULL;
- static struct passwd *entry;
- static int namelen, first_char, first_char_loc;
-
- if (!state)
+ if (!rl_point || rl_end < 2)
{
- if (username)
- free (username);
-
- first_char = *text;
-
- if (first_char == '~')
- first_char_loc = 1;
- else
- first_char_loc = 0;
-
- username = savestring (&text[first_char_loc]);
- namelen = strlen (username);
- setpwent ();
+ ding ();
+ return -1;
}
- while (entry = getpwent ())
- {
- if (strncmp (username, entry->pw_name, namelen) == 0)
- break;
- }
+ rl_begin_undo_group ();
- if (!entry)
- {
- endpwent ();
- return ((char *)NULL);
- }
- else
+ if (rl_point == rl_end)
{
- char *value = (char *)xmalloc (2 + strlen (entry->pw_name));
-
- *value = *text;
-
- strcpy (value + first_char_loc, entry->pw_name);
-
- if (first_char == '~')
- rl_filename_completion_desired = 1;
-
- return (value);
+ --rl_point;
+ count = 1;
}
-#endif /* !__GO32__ */
-}
+ rl_point--;
-/* If non-null, this contains the address of a function to call if the
- standard meaning for expanding a tilde fails. The function is called
- with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
- which is the expansion, or a NULL pointer if there is no expansion. */
-Function *rl_tilde_expander = (Function *)NULL;
+ dummy[0] = the_line[rl_point];
+ dummy[1] = '\0';
-/* Expand FILENAME if it begins with a tilde. This always returns
- a new string. */
-char *
-tilde_expand (filename)
- char *filename;
-{
- char *dirname = filename ? savestring (filename) : (char *)NULL;
+ rl_delete_text (rl_point, rl_point + 1);
- if (dirname && *dirname == '~')
- {
- char *temp_name;
- if (!dirname[1] || dirname[1] == '/')
- {
- /* Prepend $HOME to the rest of the string. */
- char *temp_home = getenv ("HOME");
-
- temp_name = (char *)alloca (1 + strlen (&dirname[1])
- + (temp_home? strlen (temp_home) : 0));
- temp_name[0] = '\0';
- if (temp_home)
- strcpy (temp_name, temp_home);
- strcat (temp_name, &dirname[1]);
- free (dirname);
- dirname = savestring (temp_name);
- }
- else
- {
- struct passwd *getpwnam (), *user_entry;
- char *username = (char *)alloca (257);
- int i, c;
-
- for (i = 1; c = dirname[i]; i++)
- {
- if (c == '/') break;
- else username[i - 1] = c;
- }
- username[i - 1] = '\0';
+ rl_point += count;
+ if (rl_point > rl_end)
+ rl_point = rl_end;
+ else if (rl_point < 0)
+ rl_point = 0;
+ rl_insert_text (dummy);
- if (!(user_entry = getpwnam (username)))
- {
- /* If the calling program has a special syntax for
- expanding tildes, and we couldn't find a standard
- expansion, then let them try. */
- if (rl_tilde_expander)
- {
- char *expansion;
-
- expansion = (char *)(*rl_tilde_expander) (username);
-
- if (expansion)
- {
- temp_name = (char *)alloca (1 + strlen (expansion)
- + strlen (&dirname[i]));
- strcpy (temp_name, expansion);
- strcat (temp_name, &dirname[i]);
- free (expansion);
- goto return_name;
- }
- }
- /*
- * We shouldn't report errors.
- */
- }
- else
- {
- temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir)
- + strlen (&dirname[i]));
- strcpy (temp_name, user_entry->pw_dir);
- strcat (temp_name, &dirname[i]);
- return_name:
- free (dirname);
- dirname = savestring (temp_name);
- }
- endpwent ();
- }
- }
- return (dirname);
+ rl_end_undo_group ();
+ return 0;
}
/* **************************************************************** */
@@ -4275,15 +2354,12 @@ tilde_expand (filename)
/* */
/* **************************************************************** */
-/* Non-zero tells rl_delete_text and rl_insert_text to not add to
- the undo list. */
-int doing_an_undo = 0;
-
/* The current undo list for THE_LINE. */
UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
/* Remember how to undo something. Concatenate some undos if that
seems right. */
+void
rl_add_undo (what, start, end, text)
enum undo_code what;
int start, end;
@@ -4299,17 +2375,20 @@ rl_add_undo (what, start, end, text)
}
/* Free the existing undo list. */
+void
free_undo_list ()
{
- while (rl_undo_list) {
- UNDO_LIST *release = rl_undo_list;
- rl_undo_list = rl_undo_list->next;
+ while (rl_undo_list)
+ {
+ UNDO_LIST *release = rl_undo_list;
+ rl_undo_list = rl_undo_list->next;
- if (release->what == UNDO_DELETE)
- free (release->text);
+ if (release->what == UNDO_DELETE)
+ free (release->text);
- free (release);
- }
+ free (release);
+ }
+ rl_undo_list = (UNDO_LIST *)NULL;
}
/* Undo the next thing in the list. Return 0 if there
@@ -4352,7 +2431,11 @@ undo_thing:
if (waiting_for_begin)
waiting_for_begin--;
else
+#if 0
abort ();
+#else
+ ding ();
+#endif
break;
}
@@ -4372,12 +2455,14 @@ undo_thing:
rl_begin_undo_group ()
{
rl_add_undo (UNDO_BEGIN, 0, 0, 0);
+ return 0;
}
/* End an undo group started with rl_begin_undo_group (). */
rl_end_undo_group ()
{
rl_add_undo (UNDO_END, 0, 0, 0);
+ return 0;
}
/* Save an undo entry for the text from START to END. */
@@ -4393,41 +2478,46 @@ rl_modifying (start, end)
if (start != end)
{
- char *temp = rl_copy (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. */
rl_revert_line ()
{
- if (!rl_undo_list) ding ();
- else {
- while (rl_undo_list)
- rl_do_undo ();
- }
+ if (!rl_undo_list)
+ ding ();
+ else
+ {
+ while (rl_undo_list)
+ rl_do_undo ();
+ }
+ return 0;
}
/* Do some undoing of things that were done. */
rl_undo_command (count)
+ int count;
{
- if (count < 0) return; /* Nothing to do. */
+ if (count < 0)
+ return 0; /* Nothing to do. */
while (count)
{
if (rl_do_undo ())
- {
- count--;
- }
+ count--;
else
{
ding ();
break;
}
}
+ return 0;
}
/* **************************************************************** */
@@ -4452,13 +2542,16 @@ start_using_history ()
free_history_entry (saved_line_for_history);
saved_line_for_history = (HIST_ENTRY *)NULL;
+ return 0;
}
/* Free the contents (and containing structure) of a HIST_ENTRY. */
+void
free_history_entry (entry)
HIST_ENTRY *entry;
{
- if (!entry) return;
+ if (!entry)
+ return;
if (entry->line)
free (entry->line);
free (entry);
@@ -4476,6 +2569,7 @@ maybe_replace_line ()
free (temp->line);
free (temp);
}
+ return 0;
}
/* Put back the saved_line_for_history if there is one. */
@@ -4498,6 +2592,7 @@ maybe_unsave_line ()
}
else
ding ();
+ return 0;
}
/* Save the current line in saved_line_for_history. */
@@ -4509,6 +2604,7 @@ maybe_save_line ()
saved_line_for_history->line = savestring (the_line);
saved_line_for_history->data = (char *)rl_undo_list;
}
+ return 0;
}
/* **************************************************************** */
@@ -4520,7 +2616,7 @@ maybe_save_line ()
/* Meta-< goes to the start of the history. */
rl_beginning_of_history ()
{
- rl_get_previous_history (1 + where_history ());
+ return (rl_get_previous_history (1 + where_history ()));
}
/* Meta-> goes to the end of the history. (The current line). */
@@ -4529,6 +2625,7 @@ rl_end_of_history ()
maybe_replace_line ();
using_history ();
maybe_unsave_line ();
+ return 0;
}
/* Move down to the next history line. */
@@ -4538,13 +2635,10 @@ rl_get_next_history (count)
HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
if (count < 0)
- {
- rl_get_previous_history (-count);
- return;
- }
+ return (rl_get_previous_history (-count));
if (!count)
- return;
+ return 0;
maybe_replace_line ();
@@ -4575,6 +2669,7 @@ rl_get_next_history (count)
rl_point = 0;
#endif /* VI_MODE */
}
+ return 0;
}
/* Get the previous item out of our interactive history, making it the current
@@ -4586,13 +2681,10 @@ rl_get_previous_history (count)
HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
if (count < 0)
- {
- rl_get_next_history (-count);
- return;
- }
+ return (rl_get_next_history (-count));
if (!count)
- return;
+ return 0;
/* If we don't have a line saved, then save this one. */
maybe_save_line ();
@@ -4635,336 +2727,55 @@ rl_get_previous_history (count)
rl_point = 0;
#endif /* VI_MODE */
}
+ return 0;
+}
+
+/* Make C be the next command to be executed. */
+rl_execute_next (c)
+ int c;
+{
+ rl_pending_input = c;
+ return 0;
}
-
/* **************************************************************** */
/* */
-/* I-Search and Searching */
+/* The Mark and the Region. */
/* */
/* **************************************************************** */
-/* Search backwards through the history looking for a string which is typed
- interactively. Start with the current line. */
-rl_reverse_search_history (sign, key)
- int sign;
- int key;
+/* Set the mark at POSITION. */
+rl_set_mark (position)
+ int position;
{
- rl_search_history (-sign, key);
-}
-
-/* Search forwards through the history looking for a string which is typed
- interactively. Start with the current line. */
-rl_forward_search_history (sign, key)
- int sign;
- int key;
-{
- 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 1 for reverse,
- WHERE is the history list number of the current line. If it is
- -1, then this line is the starting one. */
-rl_display_search (search_string, reverse_p, where)
- char *search_string;
- int reverse_p, where;
-{
- char *message = (char *)NULL;
-
- message =
- (char *)alloca (1 + (search_string ? strlen (search_string) : 0) + 30);
-
- *message = '\0';
-
-#if defined (NOTDEF)
- if (where != -1)
- sprintf (message, "[%d]", where + history_base);
-#endif /* NOTDEF */
-
- strcat (message, "(");
-
- if (reverse_p)
- strcat (message, "reverse-");
-
- strcat (message, "i-search)`");
-
- if (search_string)
- strcat (message, search_string);
+ if (position > rl_end)
+ return -1;
- strcat (message, "': ");
- rl_message (message, 0, 0);
- rl_redisplay ();
+ rl_mark = position;
+ return 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. */
-rl_search_history (direction, invoking_key)
- int direction;
- int invoking_key;
+/* Exchange the position of mark and point. */
+rl_exchange_mark_and_point ()
{
- /* The string that the user types in to search for. */
- char *search_string = (char *)alloca (128);
-
- /* The current length of SEARCH_STRING. */
- int search_string_index;
-
- /* The list of lines to search through. */
- char **lines;
-
- /* The length of LINES. */
- int hlen;
-
- /* Where we get LINES from. */
- HIST_ENTRY **hlist = history_list ();
-
- register int i = 0;
- int orig_point = rl_point;
- int orig_line = where_history ();
- int last_found_line = orig_line;
- int c, done = 0;
-
- /* The line currently being searched. */
- char *sline;
-
- /* Offset in that line. */
- int index;
-
- /* Non-zero if we are doing a reverse search. */
- int reverse = (direction < 0);
-
- /* Create an arrary of pointers to the lines that we want to search. */
- maybe_replace_line ();
- if (hlist)
- for (i = 0; hlist[i]; i++);
+ if (rl_mark > rl_end)
+ rl_mark = -1;
- /* Allocate space for this many lines, +1 for the current input line,
- and remember those lines. */
- lines = (char **)alloca ((1 + (hlen = i)) * sizeof (char *));
- for (i = 0; i < hlen; i++)
- lines[i] = hlist[i]->line;
-
- if (saved_line_for_history)
- lines[i] = saved_line_for_history->line;
- else
- /* So I have to type it in this way instead. */
+ if (rl_mark == -1)
{
- char *alloced_line;
-
- /* Keep that mips alloca happy. */
- alloced_line = (char *)alloca (1 + strlen (the_line));
- lines[i] = alloced_line;
- strcpy (lines[i], &the_line[0]);
+ ding ();
+ return -1;
}
-
- hlen++;
-
- /* The line where we start the search. */
- i = orig_line;
-
- /* Initialize search parameters. */
- *search_string = '\0';
- search_string_index = 0;
-
- /* Normalize DIRECTION into 1 or -1. */
- if (direction >= 0)
- direction = 1;
else
- direction = -1;
-
- rl_display_search (search_string, reverse, -1);
-
- sline = the_line;
- index = rl_point;
-
- while (!done)
{
- c = rl_read_key ();
-
- /* Hack C to Do What I Mean. */
- {
- Function *f = (Function *)NULL;
-
- if (keymap[c].type == ISFUNC)
- {
- f = keymap[c].function;
-
- if (f == rl_reverse_search_history)
- c = reverse ? -1 : -2;
- else if (f == rl_forward_search_history)
- c = !reverse ? -1 : -2;
- }
- }
-
- switch (c)
- {
- case ESC:
- done = 1;
- continue;
-
- /* case invoking_key: */
- case -1:
- goto search_again;
-
- /* switch directions */
- case -2:
- direction = -direction;
- reverse = (direction < 0);
+ int temp = rl_point;
- goto do_search;
-
- case CTRL ('G'):
- strcpy (the_line, lines[orig_line]);
- rl_point = orig_point;
- rl_end = strlen (the_line);
- rl_clear_message ();
- return;
-
- default:
- if (c < 32 || c > 126)
- {
- rl_execute_next (c);
- done = 1;
- continue;
- }
- else
- {
- search_string[search_string_index++] = c;
- search_string[search_string_index] = '\0';
- goto do_search;
-
- search_again:
-
- if (!search_string_index)
- continue;
- else
- {
- if (reverse)
- --index;
- else
- if (index != strlen (sline))
- ++index;
- else
- ding ();
- }
- do_search:
-
- while (1)
- {
- if (reverse)
- {
- while (index >= 0)
- if (strncmp
- (search_string, sline + index, search_string_index)
- == 0)
- goto string_found;
- else
- index--;
- }
- else
- {
- register int limit =
- (strlen (sline) - search_string_index) + 1;
-
- while (index < limit)
- {
- if (strncmp (search_string,
- sline + index,
- search_string_index) == 0)
- goto string_found;
- index++;
- }
- }
-
- next_line:
- i += direction;
-
- /* At limit for direction? */
- if ((reverse && i < 0) ||
- (!reverse && i == hlen))
- goto search_failed;
-
- sline = lines[i];
- if (reverse)
- index = strlen (sline);
- else
- index = 0;
-
- /* If the search string is longer than the current
- line, no match. */
- if (search_string_index > strlen (sline))
- goto next_line;
-
- /* Start actually searching. */
- if (reverse)
- index -= search_string_index;
- }
-
- search_failed:
- /* We cannot find the search string. Ding the bell. */
- ding ();
- i = last_found_line;
- break;
-
- string_found:
- /* 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. */
- {
- int line_len;
-
- line_len = strlen (lines[i]);
-
- if (line_len >= rl_line_buffer_len)
- rl_extend_line_buffer (line_len);
-
- strcpy (the_line, lines[i]);
- rl_point = index;
- rl_end = line_len;
- last_found_line = i;
- rl_display_search
- (search_string, reverse, (i == orig_line) ? -1 : i);
- }
- }
- }
- continue;
+ rl_point = rl_mark;
+ rl_mark = temp;
}
-
- /* 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
- INDEX is -1, then that shows that the string searched for was not
- found. We use this to determine where to place rl_point. */
- {
- int now = last_found_line;
-
- /* First put back the original state. */
- strcpy (the_line, lines[orig_line]);
-
- if (now < orig_line)
- rl_get_previous_history (orig_line - now);
- else
- rl_get_next_history (now - orig_line);
-
- /* If the index of the "matched" string is less than zero, then the
- final search string was never matched, so put point somewhere
- reasonable. */
- if (index < 0)
- index = strlen (the_line);
-
- rl_point = index;
- rl_clear_message ();
- }
+ return 0;
}
-/* Make C be the next command to be executed. */
-rl_execute_next (c)
- int c;
-{
- rl_pending_input = c;
-}
/* **************************************************************** */
/* */
@@ -4991,7 +2802,9 @@ int rl_kill_ring_length = 0;
of kill material. */
rl_set_retained_kills (num)
int num;
-{}
+{
+ 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
@@ -5002,14 +2815,14 @@ rl_kill_text (from, to)
int from, to;
{
int slot;
- char *text = rl_copy (from, to);
+ char *text = rl_copy_text (from, to);
/* Is there anything to kill? */
if (from == to)
{
free (text);
last_command_was_kill++;
- return;
+ return 0;
}
/* Delete the copied text from the line. */
@@ -5080,6 +2893,7 @@ rl_kill_text (from, to)
}
rl_kill_index = slot;
last_command_was_kill++;
+ return 0;
}
/* Now REMEMBER! In order to do prepending or appending correctly, kill
@@ -5099,7 +2913,7 @@ rl_kill_word (count)
int orig_point = rl_point;
if (count < 0)
- rl_backward_kill_word (-count);
+ return (rl_backward_kill_word (-count));
else
{
rl_forward_word (count);
@@ -5109,6 +2923,7 @@ rl_kill_word (count)
rl_point = orig_point;
}
+ return 0;
}
/* Rubout the word before point, placing it on the kill ring. */
@@ -5118,7 +2933,7 @@ rl_backward_kill_word (count)
int orig_point = rl_point;
if (count < 0)
- rl_kill_word (-count);
+ return (rl_kill_word (-count));
else
{
rl_backward_word (count);
@@ -5136,7 +2951,7 @@ rl_kill_line (direction)
int orig_point = rl_point;
if (direction < 0)
- rl_backward_kill_line (1);
+ return (rl_backward_kill_line (1));
else
{
rl_end_of_line ();
@@ -5144,6 +2959,7 @@ rl_kill_line (direction)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
}
+ return 0;
}
/* Kill backwards to the start of the line. If DIRECTION is negative, kill
@@ -5154,7 +2970,7 @@ rl_backward_kill_line (direction)
int orig_point = rl_point;
if (direction < 0)
- rl_kill_line (1);
+ return (rl_kill_line (1));
else
{
if (!rl_point)
@@ -5165,13 +2981,21 @@ rl_backward_kill_line (direction)
rl_kill_text (orig_point, rl_point);
}
}
+ return 0;
}
/* Yank back the last killed text. This ignores arguments. */
rl_yank ()
{
- if (!rl_kill_ring) rl_abort ();
+ if (!rl_kill_ring)
+ {
+ rl_abort ();
+ return -1;
+ }
+
+ rl_set_mark (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
@@ -5186,6 +3010,7 @@ rl_yank_pop ()
!rl_kill_ring)
{
rl_abort ();
+ return -1;
}
l = strlen (rl_kill_ring[rl_kill_index]);
@@ -5199,10 +3024,13 @@ rl_yank_pop ()
if (rl_kill_index < 0)
rl_kill_index = rl_kill_ring_length - 1;
rl_yank ();
+ return 0;
}
else
- rl_abort ();
-
+ {
+ rl_abort ();
+ return -1;
+ }
}
/* Yank the COUNTth argument from the previous history line. */
@@ -5217,32 +3045,35 @@ rl_yank_nth_arg (count, ignore)
else
{
ding ();
- return;
+ return -1;
}
arg = history_arg_extract (count, count, entry->line);
if (!arg || !*arg)
{
ding ();
- return;
+ return -1;
}
rl_begin_undo_group ();
#if defined (VI_MODE)
- /* Vi mode always inserts a space befoe yanking the argument, and it
+ /* 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_point++;
#endif /* VI_MODE */
+#if 0
if (rl_point && the_line[rl_point - 1] != ' ')
rl_insert_text (" ");
+#endif
rl_insert_text (arg);
free (arg);
rl_end_undo_group ();
+ return 0;
}
/* How to toggle back and forth between editing modes. */
@@ -5251,1318 +3082,88 @@ rl_vi_editing_mode ()
#if defined (VI_MODE)
rl_editing_mode = vi_mode;
rl_vi_insertion_mode ();
+ return 0;
#endif /* VI_MODE */
}
rl_emacs_editing_mode ()
{
rl_editing_mode = emacs_mode;
- keymap = emacs_standard_keymap;
-}
-
-
-/* **************************************************************** */
-/* */
-/* Completion */
-/* */
-/* **************************************************************** */
-
-/* Non-zero means that case is not significant in completion. */
-int completion_case_fold = 0;
-
-/* Return an array of (char *) which is a list of completions for TEXT.
- If there are no completions, return a NULL pointer.
- The first entry in the returned array is the substitution for TEXT.
- The remaining entries are the possible completions.
- The array is terminated with a NULL pointer.
-
- ENTRY_FUNCTION is a function of two args, and returns a (char *).
- The first argument is TEXT.
- The second is a state argument; it should be zero on the first call, and
- non-zero on subsequent calls. It returns a NULL pointer to the caller
- when there are no more matches.
- */
-char **
-completion_matches (text, entry_function)
- char *text;
- char *(*entry_function) ();
-{
- /* Number of slots in match_list. */
- int match_list_size;
-
- /* The list of matches. */
- char **match_list =
- (char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
-
- /* Number of matches actually found. */
- int matches = 0;
-
- /* Temporary string binder. */
- char *string;
-
- match_list[1] = (char *)NULL;
-
- while (string = (*entry_function) (text, matches))
- {
- if (matches + 1 == match_list_size)
- match_list = (char **)xrealloc
- (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
-
- match_list[++matches] = string;
- match_list[matches + 1] = (char *)NULL;
- }
-
- /* If there were any matches, then look through them finding out the
- lowest common denominator. That then becomes match_list[0]. */
- if (matches)
- {
- register int i = 1;
- int low = 100000; /* Count of max-matched characters. */
-
- /* If only one match, just use that. */
- if (matches == 1)
- {
- match_list[0] = match_list[1];
- match_list[1] = (char *)NULL;
- }
- else
- {
- /* Otherwise, compare each member of the list with
- the next, finding out where they stop matching. */
-
- while (i < matches)
- {
- register int c1, c2, si;
-
- if (completion_case_fold)
- {
- for (si = 0;
- (c1 = to_lower(match_list[i][si])) &&
- (c2 = to_lower(match_list[i + 1][si]));
- si++)
- if (c1 != c2) break;
- }
- else
- {
- for (si = 0;
- (c1 = match_list[i][si]) &&
- (c2 = match_list[i + 1][si]);
- si++)
- if (c1 != c2) break;
- }
-
- if (low > si) low = si;
- i++;
- }
- match_list[0] = (char *)xmalloc (low + 1);
- strncpy (match_list[0], match_list[1], low);
- match_list[0][low] = '\0';
- }
- }
- else /* There were no matches. */
- {
- free (match_list);
- match_list = (char **)NULL;
- }
- return (match_list);
-}
-
-/* Okay, now we write the entry_function for filename completion. In the
- general case. Note that completion in the shell is a little different
- because of all the pathnames that must be followed when looking up the
- completion for a command. */
-char *
-filename_completion_function (text, state)
- int state;
- char *text;
-{
- static DIR *directory;
- static char *filename = (char *)NULL;
- static char *dirname = (char *)NULL;
- static char *users_dirname = (char *)NULL;
- static int filename_len;
-
- dirent *entry = (dirent *)NULL;
-
- /* If we don't have any state, then do some initialization. */
- if (!state)
- {
- char *temp;
-
- if (dirname) free (dirname);
- if (filename) free (filename);
- if (users_dirname) free (users_dirname);
-
- filename = savestring (text);
- if (!*text) text = ".";
- dirname = savestring (text);
-
- temp = rindex (dirname, '/');
-
- if (temp)
- {
- strcpy (filename, ++temp);
- *temp = '\0';
- }
- else
- strcpy (dirname, ".");
-
- /* We aren't done yet. We also support the "~user" syntax. */
-
- /* Save the version of the directory that the user typed. */
- users_dirname = savestring (dirname);
- {
- char *temp_dirname;
-
- temp_dirname = tilde_expand (dirname);
- free (dirname);
- dirname = temp_dirname;
-
- if (rl_symbolic_link_hook)
- (*rl_symbolic_link_hook) (&dirname);
- }
- directory = opendir (dirname);
- filename_len = strlen (filename);
-
- rl_filename_completion_desired = 1;
- }
-
- /* At this point we should entertain the possibility of hacking wildcarded
- filenames, like /usr/man/man<WILD>/te<TAB>. If the directory name
- contains globbing characters, then build an array of directories to
- glob on, and glob on the first one. */
-
- /* Now that we have some state, we can read the directory. */
-
- while (directory && (entry = readdir (directory)))
- {
- /* Special case for no filename.
- All entries except "." and ".." match. */
- if (!filename_len)
- {
- if ((strcmp (entry->d_name, ".") != 0) &&
- (strcmp (entry->d_name, "..") != 0))
- break;
- }
- else
- {
- /* Otherwise, if these match upto the length of filename, then
- it is a match. */
- if (entry->d_name[0] == filename[0] && /* Quick test */
- (strncmp (filename, entry->d_name, filename_len) == 0))
- {
- break;
- }
- }
- }
-
- if (!entry)
- {
- if (directory)
- {
- closedir (directory);
- directory = (DIR *)NULL;
- }
- return (char *)NULL;
- }
- else
- {
- char *temp;
-
- if (dirname && (strcmp (dirname, ".") != 0))
- {
- temp = (char *)
- xmalloc (1 + strlen (users_dirname) + strlen (entry->d_name));
- strcpy (temp, users_dirname);
- strcat (temp, entry->d_name);
- }
- else
- {
- temp = (savestring (entry->d_name));
- }
- return (temp);
- }
+ _rl_keymap = emacs_standard_keymap;
+ return 0;
}
/* **************************************************************** */
/* */
-/* Binding keys */
+/* USG (System V) Support */
/* */
/* **************************************************************** */
-/* rl_add_defun (char *name, Function *function, int key)
- Add NAME to the list of named functions. Make FUNCTION
- be the function that gets called.
- If KEY is not -1, then bind it. */
-rl_add_defun (name, function, key)
- char *name;
- Function *function;
- int key;
-{
- if (key != -1)
- rl_bind_key (key, function);
- rl_add_funmap_entry (name, function);
-}
-
-/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */
int
-rl_bind_key (key, function)
- int key;
- Function *function;
-{
- if (key < 0)
- return (key);
-
- if (key > 127 && key < 256)
- {
- if (keymap[ESC].type == ISKMAP)
- {
- Keymap escmap = (Keymap)keymap[ESC].function;
-
- key -= 128;
- escmap[key].type = ISFUNC;
- escmap[key].function = function;
- return (0);
- }
- return (key);
- }
-
- keymap[key].type = ISFUNC;
- keymap[key].function = function;
- return (0);
-}
-
-/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid
- KEY. */
-int
-rl_bind_key_in_map (key, function, map)
- int key;
- Function *function;
- Keymap map;
+rl_getc (stream)
+ FILE *stream;
{
int result;
- Keymap oldmap = keymap;
-
- keymap = map;
- result = rl_bind_key (key, function);
- keymap = oldmap;
- return (result);
-}
-
-/* Make KEY do nothing in the currently selected keymap.
- Returns non-zero in case of error. */
-int
-rl_unbind_key (key)
- int key;
-{
- return (rl_bind_key (key, (Function *)NULL));
-}
-
-/* Make KEY do nothing in MAP.
- Returns non-zero in case of error. */
-int
-rl_unbind_key_in_map (key, map)
- int key;
- Keymap map;
-{
- return (rl_bind_key_in_map (key, (Function *)NULL, map));
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
- FUNCTION. This makes new keymaps as necessary. The initial
- place to do bindings is in MAP. */
-rl_set_key (keyseq, function, map)
- char *keyseq;
- Function *function;
- Keymap map;
-{
- rl_generic_bind (ISFUNC, keyseq, function, map);
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
- the string of characters MACRO. This makes new keymaps as
- necessary. The initial place to do bindings is in MAP. */
-rl_macro_bind (keyseq, macro, map)
- char *keyseq, *macro;
- Keymap map;
-{
- char *macro_keys;
- int macro_keys_len;
-
- macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
-
- if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
- {
- free (macro_keys);
- return;
- }
- rl_generic_bind (ISMACR, keyseq, macro_keys, map);
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
- the arbitrary pointer DATA. TYPE says what kind of data is
- pointed to by DATA, right now this can be a function (ISFUNC),
- a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps
- as necessary. The initial place to do bindings is in MAP. */
-
-static void
-rl_generic_bind (type, keyseq, data, map)
- int type;
- char *keyseq, *data;
- Keymap map;
-{
- char *keys;
- int keys_len;
- register int i;
-
- /* If no keys to bind to, exit right away. */
- if (!keyseq || !*keyseq)
- {
- if (type == ISMACR)
- free (data);
- return;
- }
-
- keys = (char *)alloca (1 + (2 * strlen (keyseq)));
+ unsigned char c;
- /* Translate the ASCII representation of KEYSEQ into an array
- of characters. Stuff the characters into ARRAY, and the
- length of ARRAY into LENGTH. */
- if (rl_translate_keyseq (keyseq, keys, &keys_len))
- return;
+#if defined (_GO32_)
+ if (isatty (0))
+ return (getkey ());
+#endif /* _GO32_ */
- /* Bind keys, making new keymaps as necessary. */
- for (i = 0; i < keys_len; i++)
+ while (1)
{
- if (i + 1 < keys_len)
- {
- if (map[keys[i]].type != ISKMAP)
- {
- if (map[i].type == ISMACR)
- free ((char *)map[i].function);
+ result = read (fileno (stream), &c, sizeof (unsigned char));
- map[keys[i]].type = ISKMAP;
- map[keys[i]].function = (Function *)rl_make_bare_keymap ();
- }
- map = (Keymap)map[keys[i]].function;
- }
- else
- {
- if (map[keys[i]].type == ISMACR)
- free ((char *)map[keys[i]].function);
-
- map[keys[i]].function = (Function *)data;
- map[keys[i]].type = type;
- }
- }
-}
+ if (result == sizeof (unsigned char))
+ return (c);
-/* Translate the ASCII representation of SEQ, stuffing the
- values into ARRAY, an array of characters. LEN gets the
- final length of ARRAY. Return non-zero if there was an
- error parsing SEQ. */
-rl_translate_keyseq (seq, array, len)
- char *seq, *array;
- int *len;
-{
- register int i, c, l = 0;
+ /* If zero characters are returned, then the file that we are
+ reading from is empty! Return EOF in that case. */
+ if (result == 0)
+ return (EOF);
- for (i = 0; c = seq[i]; i++)
- {
- if (c == '\\')
+#if defined (EWOULDBLOCK)
+ if (errno == EWOULDBLOCK)
{
- c = seq[++i];
+ int flags;
- if (!c)
- break;
-
- if (((c == 'C' || c == 'M') && seq[i + 1] == '-') ||
- (c == 'e'))
+ if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
+ return (EOF);
+ if (flags & O_NDELAY)
{
- /* Handle special case of backwards define. */
- if (strncmp (&seq[i], "C-\\M-", 5) == 0)
- {
- array[l++] = ESC;
- i += 5;
- array[l++] = CTRL (to_upper (seq[i]));
- if (!seq[i])
- i--;
- continue;
- }
-
- switch (c)
- {
- case 'M':
- i++;
- array[l++] = ESC;
- break;
-
- case 'C':
- i += 2;
- /* Special hack for C-?... */
- if (seq[i] == '?')
- array[l++] = RUBOUT;
- else
- array[l++] = CTRL (to_upper (seq[i]));
- break;
-
- case 'e':
- array[l++] = ESC;
- }
-
+ flags &= ~O_NDELAY;
+ fcntl (fileno (stream), F_SETFL, flags);
continue;
}
+ continue;
}
- array[l++] = c;
- }
-
- *len = l;
- array[l] = '\0';
- return (0);
-}
-
-/* Return a pointer to the function that STRING represents.
- If STRING doesn't have a matching function, then a NULL pointer
- is returned. */
-Function *
-rl_named_function (string)
- char *string;
-{
- register int i;
-
- for (i = 0; funmap[i]; i++)
- if (stricmp (funmap[i]->name, string) == 0)
- return (funmap[i]->function);
- return ((Function *)NULL);
-}
-
-/* The last key bindings file read. */
-#ifdef __MSDOS__
-/* Don't know what to do, but this is a guess */
-static char *last_readline_init_file = "/INPUTRC";
-#else
-static char *last_readline_init_file = "~/.inputrc";
-#endif
-
-/* Re-read the current keybindings file. */
-rl_re_read_init_file (count, ignore)
- int count, ignore;
-{
- rl_read_init_file ((char *)NULL);
-}
-
-/* Do key bindings from a file. If FILENAME is NULL it defaults
- to `~/.inputrc'. If the file existed and could be opened and
- read, 0 is returned, otherwise errno is returned. */
-int
-rl_read_init_file (filename)
- char *filename;
-{
- register int i;
- char *buffer, *openname, *line, *end;
- struct stat finfo;
- int file;
-
- /* Default the filename. */
- if (!filename)
- filename = last_readline_init_file;
-
- openname = tilde_expand (filename);
-
- if (!openname || *openname == '\000')
- return ENOENT;
-
- if ((stat (openname, &finfo) < 0) ||
- (file = open (openname, O_RDONLY, 0666)) < 0)
- {
- free (openname);
- return (errno);
- }
- else
- free (openname);
-
- last_readline_init_file = filename;
-
- /* Read the file into BUFFER. */
- buffer = (char *)xmalloc (finfo.st_size + 1);
- i = read (file, buffer, finfo.st_size);
- close (file);
-
- if (i != finfo.st_size)
- return (errno);
-
- /* Loop over the lines in the file. Lines that start with `#' are
- comments; all other lines are commands for readline initialization. */
- line = buffer;
- end = buffer + finfo.st_size;
- while (line < end)
- {
- /* Find the end of this line. */
- for (i = 0; line + i != end && line[i] != '\n'; i++);
-
- /* Mark end of line. */
- line[i] = '\0';
-
- /* If the line is not a comment, then parse it. */
- if (*line != '#')
- rl_parse_and_bind (line);
-
- /* Move to the next line. */
- line += i + 1;
- }
- return (0);
-}
-
-/* **************************************************************** */
-/* */
-/* Parser Directives */
-/* */
-/* **************************************************************** */
-
-/* Conditionals. */
-
-/* Calling programs set this to have their argv[0]. */
-char *rl_readline_name = "other";
-
-/* Stack of previous values of parsing_conditionalized_out. */
-static unsigned char *if_stack = (unsigned char *)NULL;
-static int if_stack_depth = 0;
-static int if_stack_size = 0;
-
-/* Push parsing_conditionalized_out, and set parser state based on ARGS. */
-parser_if (args)
- char *args;
-{
- register int i;
-
- /* Push parser state. */
- if (if_stack_depth + 1 >= if_stack_size)
- {
- if (!if_stack)
- if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
- else
- if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
- }
- if_stack[if_stack_depth++] = parsing_conditionalized_out;
-
- /* If parsing is turned off, then nothing can turn it back on except
- for finding the matching endif. In that case, return right now. */
- if (parsing_conditionalized_out)
- return;
-
- /* Isolate first argument. */
- for (i = 0; args[i] && !whitespace (args[i]); i++);
-
- if (args[i])
- args[i++] = '\0';
-
- /* Handle "if term=foo" and "if mode=emacs" constructs. If this
- isn't term=foo, or mode=emacs, then check to see if the first
- word in ARGS is the same as the value stored in rl_readline_name. */
- if (rl_terminal_name && strnicmp (args, "term=", 5) == 0)
- {
- char *tem, *tname;
-
- /* Terminals like "aaa-60" are equivalent to "aaa". */
- tname = savestring (rl_terminal_name);
- tem = rindex (tname, '-');
- if (tem)
- *tem = '\0';
-
- if (stricmp (args + 5, tname) == 0)
- parsing_conditionalized_out = 0;
- else
- parsing_conditionalized_out = 1;
-
- free (tname);
- }
-#if defined (VI_MODE)
- else if (strnicmp (args, "mode=", 5) == 0)
- {
- int mode;
-
- if (stricmp (args + 5, "emacs") == 0)
- mode = emacs_mode;
- else if (stricmp (args + 5, "vi") == 0)
- mode = vi_mode;
- else
- mode = no_mode;
-
- if (mode == rl_editing_mode)
- parsing_conditionalized_out = 0;
- else
- parsing_conditionalized_out = 1;
- }
-#endif /* VI_MODE */
- /* Check to see if the first word in ARGS is the same as the
- value stored in rl_readline_name. */
- else if (stricmp (args, rl_readline_name) == 0)
- parsing_conditionalized_out = 0;
- else
- parsing_conditionalized_out = 1;
-}
-
-/* Invert the current parser state if there is anything on the stack. */
-parser_else (args)
- char *args;
-{
- register int i;
-
- if (!if_stack_depth)
- {
- /* Error message? */
- return;
- }
-
- /* Check the previous (n - 1) levels of the stack to make sure that
- we haven't previously turned off parsing. */
- for (i = 0; i < if_stack_depth - 1; i++)
- if (if_stack[i] == 1)
- return;
-
- /* Invert the state of parsing if at top level. */
- parsing_conditionalized_out = !parsing_conditionalized_out;
-}
-
-/* Terminate a conditional, popping the value of
- parsing_conditionalized_out from the stack. */
-parser_endif (args)
- char *args;
-{
- if (if_stack_depth)
- parsing_conditionalized_out = if_stack[--if_stack_depth];
- else
- {
- /* *** What, no error message? *** */
- }
-}
-
-/* Associate textual names with actual functions. */
-static struct {
- char *name;
- Function *function;
-} parser_directives [] = {
- { "if", parser_if },
- { "endif", parser_endif },
- { "else", parser_else },
- { (char *)0x0, (Function *)0x0 }
-};
-
-/* Handle a parser directive. STATEMENT is the line of the directive
- without any leading `$'. */
-static int
-handle_parser_directive (statement)
- char *statement;
-{
- register int i;
- char *directive, *args;
-
- /* Isolate the actual directive. */
-
- /* Skip whitespace. */
- for (i = 0; whitespace (statement[i]); i++);
-
- directive = &statement[i];
-
- for (; statement[i] && !whitespace (statement[i]); i++);
-
- if (statement[i])
- statement[i++] = '\0';
-
- for (; statement[i] && whitespace (statement[i]); i++);
-
- args = &statement[i];
-
- /* Lookup the command, and act on it. */
- for (i = 0; parser_directives[i].name; i++)
- if (stricmp (directive, parser_directives[i].name) == 0)
- {
- (*parser_directives[i].function) (args);
- return (0);
- }
-
- /* *** Should an error message be output? */
- return (1);
-}
-
-/* Ugly but working hack for binding prefix meta. */
-#define PREFIX_META_HACK
-
-static int substring_member_of_array ();
-
-/* Read the binding command from STRING and perform it.
- A key binding command looks like: Keyname: function-name\0,
- a variable binding command looks like: set variable value.
- A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
-rl_parse_and_bind (string)
- char *string;
-{
- extern char *possible_control_prefixes[], *possible_meta_prefixes[];
- char *funname, *kname;
- register int c;
- int key, i;
-
- while (string && whitespace (*string))
- string++;
-
- if (!string || !*string || *string == '#')
- return;
-
- /* If this is a parser directive, act on it. */
- if (*string == '$')
- {
- handle_parser_directive (&string[1]);
- return;
- }
-
- /* If we are supposed to be skipping parsing right now, then do it. */
- if (parsing_conditionalized_out)
- return;
-
- i = 0;
- /* If this keyname is a complex key expression surrounded by quotes,
- advance to after the matching close quote. */
- if (*string == '"')
- {
- for (i = 1; c = string[i]; i++)
- {
- if (c == '"' && string[i - 1] != '\\')
- break;
- }
- }
-
- /* Advance to the colon (:) or whitespace which separates the two objects. */
- for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
-
- /* Mark the end of the command (or keyname). */
- if (string[i])
- string[i++] = '\0';
-
- /* If this is a command to set a variable, then do that. */
- if (stricmp (string, "set") == 0)
- {
- char *var = string + i;
- char *value;
-
- /* Make VAR point to start of variable name. */
- while (*var && whitespace (*var)) var++;
-
- /* Make value point to start of value string. */
- value = var;
- while (*value && !whitespace (*value)) value++;
- if (*value)
- *value++ = '\0';
- while (*value && whitespace (*value)) value++;
-
- rl_variable_bind (var, value);
- return;
- }
-
- /* Skip any whitespace between keyname and funname. */
- for (; string[i] && whitespace (string[i]); i++);
- funname = &string[i];
-
- /* Now isolate funname.
- For straight function names just look for whitespace, since
- that will signify the end of the string. But this could be a
- macro definition. In that case, the string is quoted, so skip
- to the matching delimiter. */
- if (*funname == '\'' || *funname == '"')
- {
- int delimiter = string[i++];
-
- for (; c = string[i]; i++)
- {
- if (c == delimiter && string[i - 1] != '\\')
- break;
- }
- if (c)
- i++;
- }
-
- /* Advance to the end of the string. */
- for (; string[i] && !whitespace (string[i]); i++);
-
- /* No extra whitespace at the end of the string. */
- string[i] = '\0';
-
- /* If this is a new-style key-binding, then do the binding with
- rl_set_key (). Otherwise, let the older code deal with it. */
- if (*string == '"')
- {
- char *seq = (char *)alloca (1 + strlen (string));
- register int j, k = 0;
-
- for (j = 1; string[j]; j++)
- {
- if (string[j] == '"' && string[j - 1] != '\\')
- break;
-
- seq[k++] = string[j];
- }
- seq[k] = '\0';
-
- /* Binding macro? */
- if (*funname == '\'' || *funname == '"')
- {
- j = strlen (funname);
-
- if (j && funname[j - 1] == *funname)
- funname[j - 1] = '\0';
-
- rl_macro_bind (seq, &funname[1], keymap);
- }
- else
- rl_set_key (seq, rl_named_function (funname), keymap);
-
- return;
- }
-
- /* Get the actual character we want to deal with. */
- kname = rindex (string, '-');
- if (!kname)
- kname = string;
- else
- kname++;
-
- key = glean_key_from_name (kname);
-
- /* Add in control and meta bits. */
- if (substring_member_of_array (string, possible_control_prefixes))
- key = CTRL (to_upper (key));
-
- if (substring_member_of_array (string, possible_meta_prefixes))
- key = META (key);
-
- /* Temporary. Handle old-style keyname with macro-binding. */
- if (*funname == '\'' || *funname == '"')
- {
- char seq[2];
- int fl = strlen (funname);
-
- seq[0] = key; seq[1] = '\0';
- if (fl && funname[fl - 1] == *funname)
- funname[fl - 1] = '\0';
-
- rl_macro_bind (seq, &funname[1], keymap);
- }
-#if defined (PREFIX_META_HACK)
- /* Ugly, but working hack to keep prefix-meta around. */
- else if (stricmp (funname, "prefix-meta") == 0)
- {
- char seq[2];
-
- seq[0] = key;
- seq[1] = '\0';
- rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, keymap);
- }
-#endif /* PREFIX_META_HACK */
- else
- rl_bind_key (key, rl_named_function (funname));
-}
-
-rl_variable_bind (name, value)
- char *name, *value;
-{
- if (stricmp (name, "editing-mode") == 0)
- {
- if (strnicmp (value, "vi", 2) == 0)
- {
-#if defined (VI_MODE)
- keymap = vi_insertion_keymap;
- rl_editing_mode = vi_mode;
-#else
-#if defined (NOTDEF)
- /* What state is the terminal in? I'll tell you:
- non-determinate! That means we cannot do any output. */
- ding ();
-#endif /* NOTDEF */
-#endif /* VI_MODE */
- }
- else if (strnicmp (value, "emacs", 5) == 0)
- {
- keymap = emacs_standard_keymap;
- rl_editing_mode = emacs_mode;
- }
- }
- else if (stricmp (name, "horizontal-scroll-mode") == 0)
- {
- if (!*value || stricmp (value, "On") == 0)
- horizontal_scroll_mode = 1;
- else
- horizontal_scroll_mode = 0;
- }
- else if (stricmp (name, "mark-modified-lines") == 0)
- {
- if (!*value || stricmp (value, "On") == 0)
- mark_modified_lines = 1;
- else
- mark_modified_lines = 0;
- }
- else if (stricmp (name, "prefer-visible-bell") == 0)
- {
- if (!*value || stricmp (value, "On") == 0)
- prefer_visible_bell = 1;
- else
- prefer_visible_bell = 0;
- }
- else if (stricmp (name, "comment-begin") == 0)
- {
-#if defined (VI_MODE)
- extern char *rl_vi_comment_begin;
-
- if (*value)
- {
- if (rl_vi_comment_begin)
- free (rl_vi_comment_begin);
-
- rl_vi_comment_begin = savestring (value);
- }
-#endif /* VI_MODE */
- }
-}
-
-/* Return the character which matches NAME.
- For example, `Space' returns ' '. */
-
-typedef struct {
- char *name;
- int value;
-} assoc_list;
-
-assoc_list name_key_alist[] = {
- { "DEL", 0x7f },
- { "ESC", '\033' },
- { "Escape", '\033' },
- { "LFD", '\n' },
- { "Newline", '\n' },
- { "RET", '\r' },
- { "Return", '\r' },
- { "Rubout", 0x7f },
- { "SPC", ' ' },
- { "Space", ' ' },
- { "Tab", 0x09 },
- { (char *)0x0, 0 }
-};
-
-int
-glean_key_from_name (name)
- char *name;
-{
- register int i;
-
- for (i = 0; name_key_alist[i].name; i++)
- if (stricmp (name, name_key_alist[i].name) == 0)
- return (name_key_alist[i].value);
-
- return (*name);
-}
-
-
-/* **************************************************************** */
-/* */
-/* Key Binding and Function Information */
-/* */
-/* **************************************************************** */
-
-/* Each of the following functions produces information about the
- state of keybindings and functions known to Readline. The info
- is always printed to rl_outstream, and in such a way that it can
- be read back in (i.e., passed to rl_parse_and_bind (). */
-
-/* Print the names of functions known to Readline. */
-void
-rl_list_funmap_names (ignore)
- int ignore;
-{
- register int i;
- char **funmap_names;
- extern char **rl_funmap_names ();
-
- funmap_names = rl_funmap_names ();
-
- if (!funmap_names)
- return;
-
- for (i = 0; funmap_names[i]; i++)
- fprintf (rl_outstream, "%s\n", funmap_names[i]);
-
- free (funmap_names);
-}
-
-/* Return a NULL terminated array of strings which represent the key
- sequences that are used to invoke FUNCTION in MAP. */
-static char **
-invoking_keyseqs_in_map (function, map)
- Function *function;
- Keymap map;
-{
- register int key;
- char **result;
- int result_index, result_size;
-
- result = (char **)NULL;
- result_index = result_size = 0;
-
- for (key = 0; key < 128; key++)
- {
- switch (map[key].type)
- {
- case ISMACR:
- /* Macros match, if, and only if, the pointers are identical.
- Thus, they are treated exactly like functions in here. */
- case ISFUNC:
- /* If the function in the keymap is the one we are looking for,
- then add the current KEY to the list of invoking keys. */
- if (map[key].function == function)
- {
- char *keyname = (char *)xmalloc (5);
-
- if (CTRL_P (key))
- sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key)));
- else if (key == RUBOUT)
- sprintf (keyname, "\\C-?");
- else
- sprintf (keyname, "%c", key);
-
- if (result_index + 2 > result_size)
- {
- if (!result)
- result = (char **) xmalloc
- ((result_size = 10) * sizeof (char *));
- else
- result = (char **) xrealloc
- (result, (result_size += 10) * sizeof (char *));
- }
-
- result[result_index++] = keyname;
- result[result_index] = (char *)NULL;
- }
- break;
-
- case ISKMAP:
- {
- char **seqs = (char **)NULL;
-
- /* Find the list of keyseqs in this map which have FUNCTION as
- their target. Add the key sequences found to RESULT. */
- if (map[key].function)
- seqs =
- invoking_keyseqs_in_map (function, (Keymap)map[key].function);
-
- if (seqs)
- {
- register int i;
-
- for (i = 0; seqs[i]; i++)
- {
- char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
-
- if (key == ESC)
- sprintf (keyname, "\\e");
- else if (CTRL_P (key))
- sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key)));
- else if (key == RUBOUT)
- sprintf (keyname, "\\C-?");
- else
- sprintf (keyname, "%c", key);
-
- strcat (keyname, seqs[i]);
-
- if (result_index + 2 > result_size)
- {
- if (!result)
- result = (char **)
- xmalloc ((result_size = 10) * sizeof (char *));
- else
- result = (char **)
- xrealloc (result,
- (result_size += 10) * sizeof (char *));
- }
-
- result[result_index++] = keyname;
- result[result_index] = (char *)NULL;
- }
- }
- }
- break;
- }
- }
- return (result);
-}
-
-/* Return a NULL terminated array of strings which represent the key
- sequences that can be used to invoke FUNCTION using the current keymap. */
-char **
-rl_invoking_keyseqs (function)
- Function *function;
-{
- return (invoking_keyseqs_in_map (function, keymap));
-}
-
-/* Print all of the current functions and their bindings to
- rl_outstream. If an explicit argument is given, then print
- the output in such a way that it can be read back in. */
-int
-rl_dump_functions (count)
- int count;
-{
- void rl_function_dumper ();
-
- rl_function_dumper (rl_explicit_arg);
- rl_on_new_line ();
- return (0);
-}
-
-/* Print all of the functions and their bindings to rl_outstream. If
- PRINT_READABLY is non-zero, then print the output in such a way
- that it can be read back in. */
-void
-rl_function_dumper (print_readably)
- int print_readably;
-{
- register int i;
- char **rl_funmap_names (), **names;
- char *name;
-
- names = rl_funmap_names ();
-
- fprintf (rl_outstream, "\n");
-
- for (i = 0; name = names[i]; i++)
- {
- Function *function;
- char **invokers;
-
- function = rl_named_function (name);
- invokers = invoking_keyseqs_in_map (function, keymap);
+#endif /* EWOULDBLOCK */
- if (print_readably)
+#if defined (_POSIX_VERSION) && defined (EAGAIN) && defined (O_NONBLOCK)
+ if (errno == EAGAIN)
{
- if (!invokers)
- fprintf (rl_outstream, "# %s (not bound)\n", name);
- else
- {
- register int j;
+ int flags;
- for (j = 0; invokers[j]; j++)
- {
- fprintf (rl_outstream, "\"%s\": %s\n",
- invokers[j], name);
- free (invokers[j]);
- }
-
- free (invokers);
- }
- }
- else
- {
- if (!invokers)
- fprintf (rl_outstream, "%s is not bound to any keys\n",
- name);
- else
+ if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
+ return (EOF);
+ if (flags & O_NONBLOCK)
{
- register int j;
-
- fprintf (rl_outstream, "%s can be found on ", name);
-
- for (j = 0; invokers[j] && j < 5; j++)
- {
- fprintf (rl_outstream, "\"%s\"%s", invokers[j],
- invokers[j + 1] ? ", " : ".\n");
- }
-
- if (j == 5 && invokers[j])
- fprintf (rl_outstream, "...\n");
-
- for (j = 0; invokers[j]; j++)
- free (invokers[j]);
-
- free (invokers);
+ flags &= ~O_NONBLOCK;
+ fcntl (fileno (stream), F_SETFL, flags);
+ continue;
}
}
- }
-}
-
-
-/* **************************************************************** */
-/* */
-/* String Utility Functions */
-/* */
-/* **************************************************************** */
-
-static char *strindex ();
-
-/* Return non-zero if any members of ARRAY are a substring in STRING. */
-static int
-substring_member_of_array (string, array)
- char *string, **array;
-{
- while (*array)
- {
- if (strindex (string, *array))
- return (1);
- array++;
- }
- return (0);
-}
-
-/* Determine if s2 occurs in s1. If so, return a pointer to the
- match in s1. The compare is case insensitive. */
-static char *
-strindex (s1, s2)
- register char *s1, *s2;
-{
- register int i, l = strlen (s2);
- register int len = strlen (s1);
-
- for (i = 0; (len - i) >= l; i++)
- if (strnicmp (&s1[i], s2, l) == 0)
- return (s1 + i);
- return ((char *)NULL);
-}
-
-
-/* **************************************************************** */
-/* */
-/* USG (System V) Support */
-/* */
-/* **************************************************************** */
-
-/* When compiling and running in the `Posix' environment, Ultrix does
- not restart system calls, so this needs to do it. */
-int
-rl_getc (stream)
- FILE *stream;
-{
- int result;
- unsigned char c;
-
-#ifdef __GO32__
- if (isatty(0))
- return getkey();
-#endif /* __GO32__ */
-
- while (1)
- {
- result = read (fileno (stream), &c, sizeof (char));
-
- if (result == sizeof (char))
- return (c);
-
- /* If zero characters are returned, then the file that we are
- reading from is empty! Return EOF in that case. */
- if (result == 0)
- return (EOF);
+#endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */
-#ifndef __GO32__
+#if !defined (_GO32_)
/* If the error that we received was SIGINT, then try again,
this is simply an interrupted system call to read ().
Otherwise, some error ocurred, also signifying EOF. */
if (errno != EINTR)
return (EOF);
-#endif /* !__GO32__ */
+#endif /* !_GO32_ */
}
}
diff --git a/gnu/lib/libreadline/readline/chardefs.h b/gnu/lib/libreadline/readline/chardefs.h
index 9749ae4..c9dcff3 100644
--- a/gnu/lib/libreadline/readline/chardefs.h
+++ b/gnu/lib/libreadline/readline/chardefs.h
@@ -1,8 +1,24 @@
/* chardefs.h -- Character definitions for readline. */
#ifndef _CHARDEFS_
+#define _CHARDEFS_
+
+#include <ctype.h>
+
+#ifndef HAVE_STRING_H
+#define HAVE_STRING_H
+#endif
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* HAVE_STRING_H */
#ifndef savestring
-#define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
+#ifndef STATIC_MALLOC
+extern char *xmalloc ();
+#endif
+#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif
#ifndef whitespace
@@ -14,11 +30,13 @@
#endif
/* Some character stuff. */
-#define control_character_threshold 0x020 /* smaller than this is control */
-#define meta_character_threshold 0x07f /* larger than this is Meta. */
+#define control_character_threshold 0x020 /* Smaller than this is control. */
+#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 META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
#define CTRL(c) ((c) & (~control_character_bit))
#define META(c) ((c) | meta_character_bit)
@@ -38,13 +56,41 @@
#define CTRL_P(c) ((c) < control_character_threshold)
#define META_P(c) ((c) > meta_character_threshold)
+#ifndef NEWLINE
#define NEWLINE '\n'
+#endif
+
+#ifndef RETURN
#define RETURN CTRL('M')
+#endif
+
+#ifndef RUBOUT
#define RUBOUT 0x07f
+#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 0x020
+
+#ifdef ESC
+#undef ESC
+#endif
+
#define ESC CTRL('[')
#endif /* _CHARDEFS_ */
diff --git a/gnu/lib/libreadline/readline/history.h b/gnu/lib/libreadline/readline/history.h
index 0041171..72bdff9 100644
--- a/gnu/lib/libreadline/readline/history.h
+++ b/gnu/lib/libreadline/readline/history.h
@@ -6,6 +6,14 @@ typedef struct _hist_entry {
char *data;
} HIST_ENTRY;
+/* 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. */
+} HISTORY_STATE;
+
/* For convenience only. You set this when interpreting history commands.
It is the logical offset of the first history element. */
extern int history_base;
@@ -14,6 +22,12 @@ extern int history_base;
just initializes the interactive variables. */
extern void using_history ();
+/* Return the current HISTORY_STATE of the history. */
+extern HISTORY_STATE *history_get_history_state ();
+
+/* Set the state of the current history array to STATE. */
+extern void history_set_history_state ();
+
/* Place STRING at the end of the history list.
The associated data field (if any) is set to NULL. */
extern void add_history ();
diff --git a/gnu/lib/libreadline/readline/keymaps.h b/gnu/lib/libreadline/readline/keymaps.h
index a0b5aeb..2419f1a 100644
--- a/gnu/lib/libreadline/readline/keymaps.h
+++ b/gnu/lib/libreadline/readline/keymaps.h
@@ -1,13 +1,36 @@
/* keymaps.h -- Manipulation of readline keymaps. */
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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 1, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
#ifndef _KEYMAPS_H_
#define _KEYMAPS_H_
#include <readline/chardefs.h>
-#ifndef __FUNCTION_DEF
+#if !defined (__FUNCTION_DEF)
+# define __FUNCTION_DEF
typedef int Function ();
-#define __FUNCTION_DEF
+typedef void VFunction ();
+typedef char *CPFunction ();
+typedef char **CPPFunction ();
#endif
/* A keymap contains one entry for each key in the ASCII set.
@@ -20,12 +43,17 @@ typedef struct _keymap_entry {
Function *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). */
+#define KEYMAP_SIZE 256
+
/* I wanted to make the above structure contain a union of:
union { Function *function; struct _keymap_entry *keymap; } value;
but this made it impossible for me to create a static array.
Maybe I need C lessons. */
-typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[128];
+typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
typedef KEYMAP_ENTRY *Keymap;
/* The values that TYPE can have in a keymap entry. */
@@ -48,4 +76,14 @@ Keymap rl_copy_keymap ();
the Meta digits bound to produce numeric arguments. */
Keymap rl_make_keymap ();
+/* Return the keymap corresponding to a given name. Names look like
+ `emacs' or `emacs-meta' or `vi-insert'. */
+Keymap rl_get_keymap_by_name ();
+
+/* Return the current keymap. */
+Keymap rl_get_keymap ();
+
+/* Set the current keymap to MAP. */
+void rl_set_keymap ();
+
#endif /* _KEYMAPS_H_ */
diff --git a/gnu/lib/libreadline/readline/readline.h b/gnu/lib/libreadline/readline/readline.h
index 5b8b2a8..007bc87 100644
--- a/gnu/lib/libreadline/readline/readline.h
+++ b/gnu/lib/libreadline/readline/readline.h
@@ -1,18 +1,34 @@
/* Readline.h -- the names of functions callable from within readline. */
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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 1, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
#if !defined (_READLINE_H_)
#define _READLINE_H_
#include <readline/keymaps.h>
-#if !defined (__FUNCTION_DEF)
-typedef int Function ();
-#define __FUNCTION_DEF
-#endif /* __FUNCTION_DEF */
-
/* The functions for manipulating the text of the line within readline.
Most of these functions are bound to keys by default. */
extern int
+ rl_tilde_expand (),
rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (),
rl_forward (), ding (), rl_backward (), rl_newline (), rl_kill_line (),
rl_clear_screen (), rl_get_next_history (), rl_get_previous_history (),
@@ -21,19 +37,32 @@ extern int
rl_yank (), rl_rubout (), rl_backward_word (), rl_kill_word (),
rl_forward_word (), rl_tab_insert (), rl_yank_pop (), rl_yank_nth_arg (),
rl_backward_kill_word (), rl_backward_kill_line (), rl_transpose_words (),
- rl_complete (), rl_possible_completions (), rl_do_lowercase_version (),
+ rl_complete (), rl_possible_completions (), rl_insert_completions (),
+ rl_do_lowercase_version (),
rl_digit_argument (), rl_universal_argument (), rl_abort (),
rl_undo_command (), rl_revert_line (), rl_beginning_of_history (),
rl_end_of_history (), rl_forward_search_history (), rl_insert (),
rl_upcase_word (), rl_downcase_word (), rl_capitalize_word (),
- rl_restart_output (), rl_re_read_init_file (), rl_dump_functions ();
+ rl_restart_output (), rl_re_read_init_file (), rl_dump_functions (),
+ rl_delete_horizontal_space ();
+
+/* #define PAREN_MATCHING */
+#if defined (PAREN_MATCHING)
+extern int rl_insert_close ();
+#endif /* PAREN_MATCHING */
/* These are *both* defined even when VI_MODE is not. */
extern int rl_vi_editing_mode (), rl_emacs_editing_mode ();
+/* Non incremental history searching. */
+extern int
+ rl_noninc_forward_search (), rl_noninc_reverse_search (),
+ rl_noninc_forward_search_again (), rl_noninc_reverse_search_again ();
+
#if defined (VI_MODE)
/* Things for vi mode. */
extern int
+ rl_vi_redo (), rl_vi_tilde_expand (),
rl_vi_movement_mode (), rl_vi_insertion_mode (), rl_vi_arg_digit (),
rl_vi_prev_word (), rl_vi_next_word (), rl_vi_char_search (),
rl_vi_eof_maybe (), rl_vi_append_mode (), rl_vi_put (),
@@ -42,9 +71,9 @@ extern int
rl_vi_bWord (), rl_vi_eword (), rl_vi_eWord (), rl_vi_end_word (),
rl_vi_change_case (), rl_vi_match (), rl_vi_bracktype (),
rl_vi_change_char (), rl_vi_yank_arg (), rl_vi_search (),
- rl_vi_search_again (), rl_vi_dosearch (), rl_vi_subst (),
- rl_vi_overstrike (), rl_vi_overstrike_delete (), rl_vi_replace(),
- rl_vi_column (), rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (),
+ rl_vi_search_again (), rl_vi_subst (), rl_vi_overstrike (),
+ rl_vi_overstrike_delete (), rl_vi_replace(), rl_vi_column (),
+ rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (),
rl_vi_complete (), rl_vi_fetch_history ();
#endif /* VI_MODE */
@@ -144,13 +173,7 @@ extern Function *rl_ignore_some_completions_function;
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 Function *rl_attempted_completion_function;
-
-/* If non-null, this contains the address of a function to call if the
- standard meaning for expanding a tilde fails. The function is called
- with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
- which is the expansion, or a NULL pointer if there is no expansion. */
-extern Function *rl_tilde_expander;
+extern CPPFunction *rl_attempted_completion_function;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
@@ -161,8 +184,8 @@ extern Function *rl_startup_hook;
the address of a string (the current directory name) as an arg. */
extern Function *rl_symbolic_link_hook;
-/* If non-zero then this is the address of a function you want called
- while Readline is waiting for character input. */
+/* The address of a function to call periodically while Readline is
+ awaiting character input, or NULL, for no event handling. */
extern Function *rl_event_hook;
/* Non-zero means that modified history lines are preceded
diff --git a/gnu/lib/libreadline/rldefs.h b/gnu/lib/libreadline/rldefs.h
new file mode 100644
index 0000000..4d5eb8d
--- /dev/null
+++ b/gnu/lib/libreadline/rldefs.h
@@ -0,0 +1,176 @@
+/* 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,1989 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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 1, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (_RLDEFS_H)
+#define _RLDEFS_H
+
+#if defined (__GNUC__)
+# undef alloca
+# define alloca __builtin_alloca
+#else
+# if defined (sparc) || defined (HAVE_ALLOCA_H)
+# include <alloca.h>
+# endif
+#endif
+
+#define NEW_TTY_DRIVER
+#define HAVE_BSD_SIGNALS
+/* #define USE_XON_XOFF */
+
+#if defined (__linux__)
+# include <termcap.h>
+#endif /* __linux__ */
+
+/* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
+#if defined (USG) && !defined (hpux)
+# undef HAVE_BSD_SIGNALS
+#endif
+
+/* System V machines use termio. */
+#if !defined (_POSIX_VERSION)
+# if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX)
+# undef NEW_TTY_DRIVER
+# define TERMIO_TTY_DRIVER
+# include <termio.h>
+# if !defined (TCOON)
+# define TCOON 1
+# endif
+# endif /* USG || hpux || Xenix || sgi || DUGX */
+#endif /* !_POSIX_VERSION */
+
+/* Posix systems use termios and the Posix signal functions. */
+#if defined (_POSIX_VERSION)
+# if !defined (TERMIOS_MISSING)
+# undef NEW_TTY_DRIVER
+# define TERMIOS_TTY_DRIVER
+# include <termios.h>
+# endif /* !TERMIOS_MISSING */
+# define HAVE_POSIX_SIGNALS
+# if !defined (O_NDELAY)
+# define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */
+# endif /* O_NDELAY */
+#endif /* _POSIX_VERSION */
+
+/* System V.3 machines have the old 4.1 BSD `reliable' signal interface. */
+#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
+# if defined (USGr3)
+# if !defined (HAVE_USG_SIGHOLD)
+# define HAVE_USG_SIGHOLD
+# endif /* !HAVE_USG_SIGHOLD */
+# endif /* USGr3 */
+#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
+
+/* Other (BSD) machines use sgtty. */
+#if defined (NEW_TTY_DRIVER)
+# include <sgtty.h>
+#endif
+
+/* 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 (_POSIX_VERSION)
+# define _POSIX_VDISABLE 0
+# else /* !_POSIX_VERSION */
+# define _POSIX_VDISABLE -1
+# endif /* !_POSIX_VERSION */
+#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
+
+#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3))
+# if !defined (HAVE_DIRENT_H)
+# define HAVE_DIRENT_H
+# endif /* !HAVE_DIRENT_H */
+#endif /* !SHELL && (_POSIX_VERSION || USGr3) */
+
+#if defined (HAVE_DIRENT_H)
+# include <dirent.h>
+# if !defined (direct)
+# define direct dirent
+# endif /* !direct */
+# define D_NAMLEN(d) strlen ((d)->d_name)
+#else /* !HAVE_DIRENT_H */
+# define D_NAMLEN(d) ((d)->d_namlen)
+# if defined (USG)
+# if defined (Xenix)
+# include <sys/ndir.h>
+# else /* !Xenix (but USG...) */
+# include "ndir.h"
+# endif /* !Xenix */
+# else /* !USG */
+# include <sys/dir.h>
+# endif /* !USG */
+#endif /* !HAVE_DIRENT_H */
+
+#if defined (USG) && defined (TIOCGWINSZ) && !defined (Linux)
+# include <sys/stream.h>
+# if defined (HAVE_SYS_PTEM_H)
+# include <sys/ptem.h>
+# endif /* HAVE_SYS_PTEM_H */
+# if defined (HAVE_SYS_PTE_H)
+# include <sys/pte.h>
+# endif /* HAVE_SYS_PTE_H */
+#endif /* USG && TIOCGWINSZ && !Linux */
+
+/* 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 (USG) || defined (NeXT)
+# if !defined (HAVE_STRING_H)
+# define HAVE_STRING_H
+# endif /* !HAVE_STRING_H */
+#endif /* USG || NeXT */
+
+#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 (HAVE_VARARGS_H)
+# include <varargs.h>
+#endif /* HAVE_VARARGS_H */
+
+/* This definition is needed by readline.c, rltty.c, and signals.c. */
+/* If on, then readline handles signals in a way that doesn't screw. */
+#define HANDLE_SIGNALS
+
+#if !defined (emacs_mode)
+# define no_mode -1
+# define vi_mode 0
+# define emacs_mode 1
+#endif
+
+#endif /* !_RLDEFS_H */
diff --git a/gnu/lib/libreadline/rltty.c b/gnu/lib/libreadline/rltty.c
new file mode 100644
index 0000000..a73682b
--- /dev/null
+++ b/gnu/lib/libreadline/rltty.c
@@ -0,0 +1,668 @@
+/* rltty.c -- functions to prepare and restore the terminal for readline's
+ use. */
+
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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 1, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <sys/types.h>
+#include <sys/ioctl.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 "readline.h"
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+extern int readline_echoing_p;
+extern int _rl_eof_char;
+
+#if defined (_GO32_)
+# include <sys/pc.h>
+# undef HANDLE_SIGNALS
+#endif /* _GO32_ */
+
+/* **************************************************************** */
+/* */
+/* Signal Management */
+/* */
+/* **************************************************************** */
+
+#if defined (HAVE_POSIX_SIGNALS)
+static sigset_t sigint_set, sigint_oset;
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+static int sigint_oldmask;
+# endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+static int sigint_blocked = 0;
+
+/* Cause SIGINT to not be delivered until the corresponding call to
+ release_sigint(). */
+static void
+block_sigint ()
+{
+ if (sigint_blocked)
+ return;
+
+#if defined (HAVE_POSIX_SIGNALS)
+ sigemptyset (&sigint_set);
+ sigemptyset (&sigint_oset);
+ sigaddset (&sigint_set, SIGINT);
+ sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+ sigint_oldmask = sigblock (sigmask (SIGINT));
+# else /* !HAVE_BSD_SIGNALS */
+# if defined (HAVE_USG_SIGHOLD)
+ sighold (SIGINT);
+# endif /* HAVE_USG_SIGHOLD */
+# endif /* !HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+ sigint_blocked = 1;
+}
+
+/* Allow SIGINT to be delivered. */
+static void
+release_sigint ()
+{
+ if (!sigint_blocked)
+ return;
+
+#if defined (HAVE_POSIX_SIGNALS)
+ sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
+#else
+# if defined (HAVE_BSD_SIGNALS)
+ sigsetmask (sigint_oldmask);
+# else /* !HAVE_BSD_SIGNALS */
+# if defined (HAVE_USG_SIGHOLD)
+ sigrelse (SIGINT);
+# endif /* HAVE_USG_SIGHOLD */
+# endif /* !HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+ sigint_blocked = 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Controlling the Meta Key */
+/* */
+/* **************************************************************** */
+
+extern int term_has_meta;
+extern char *term_mm;
+extern char *term_mo;
+
+static void
+outchar (c)
+ int c;
+{
+ putc (c, rl_outstream);
+}
+
+/* Turn on/off the meta key depending on ON. */
+static void
+control_meta_key (on)
+ int on;
+{
+ if (term_has_meta)
+ {
+ if (on && term_mm)
+ tputs (term_mm, 1, outchar);
+ else if (!on && term_mo)
+ tputs (term_mo, 1, outchar);
+ }
+}
+
+/* **************************************************************** */
+/* */
+/* Saving and Restoring the TTY */
+/* */
+/* **************************************************************** */
+
+/* Non-zero means that the terminal is in a prepped state. */
+static int terminal_prepped = 0;
+
+/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
+ and output is suspended. */
+#if defined (__ksr1__)
+static int ksrflow = 0;
+#endif
+#if 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 int
+get_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+ tiop->flags = tiop->lflag = 0;
+
+ ioctl (tty, TIOCGETP, &(tiop->sgttyb));
+ tiop->flags |= SGTTY_SET;
+
+#if defined (TIOCLGET)
+ ioctl (tty, TIOCLGET, &(tiop->lflag));
+ tiop->flags |= LFLAG_SET;
+#endif
+
+#if defined (TIOCGETC)
+ ioctl (tty, TIOCGETC, &(tiop->tchars));
+ tiop->flags |= TCHARS_SET;
+#endif
+
+#if defined (TIOCGLTC)
+ ioctl (tty, TIOCGLTC, &(tiop->ltchars));
+ tiop->flags |= LTCHARS_SET;
+#endif
+
+ return 0;
+}
+
+set_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+ if (tiop->flags & SGTTY_SET)
+ {
+ ioctl (tty, TIOCSETN, &(tiop->sgttyb));
+ tiop->flags &= ~SGTTY_SET;
+ }
+ readline_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 (meta_flag, otio, tiop)
+ int meta_flag;
+ TIOTYPE otio, *tiop;
+{
+#if !defined (_GO32_)
+ readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
+
+ /* Copy the original settings to the structure we're going to use for
+ our settings. */
+ tiop->sgttyb = otio.sgttyb;
+ tiop->lflag = otio.lflag;
+#if defined (TIOCGETC)
+ tiop->tchars = otio.tchars;
+#endif
+#if defined (TIOCGLTC)
+ tiop->ltchars = otio.ltchars;
+#endif
+ tiop->flags = otio.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 (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
+ ((otio.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 (otio.tchars.t_startc != -1)
+ rl_bind_key (otio.tchars.t_startc, rl_restart_output);
+# endif /* USE_XON_XOFF */
+
+ /* If there is an EOF char, bind _rl_eof_char to it. */
+ if (otio.tchars.t_eofc != -1)
+ _rl_eof_char = otio.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 */
+#endif /* !_GO32_ */
+}
+
+#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))
+# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
+#else
+# define TIOTYPE struct termio
+# define DRAIN_OUTPUT(fd)
+# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
+# define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
+#endif /* !TERMIOS_TTY_DRIVER */
+
+static TIOTYPE otio;
+
+static int
+get_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+/* XXX this prevents to got editing mode from tcsh. Ache */
+ struct winsize w;
+
+ if (ioctl (tty, TIOCGWINSZ, &w) == 0)
+ (void) ioctl (tty, TIOCSWINSZ, &w);
+
+ while (GETATTR (tty, tiop) < 0)
+ {
+ if (errno != EINTR)
+ return -1;
+ errno = 0;
+ }
+ return 0;
+}
+
+static int
+set_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+ while (SETATTR (tty, tiop) < 0)
+ {
+ if (errno != EINTR)
+ return -1;
+ errno = 0;
+ }
+
+#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
+
+ return 0;
+}
+
+static void
+prepare_terminal_settings (meta_flag, otio, tiop)
+ int meta_flag;
+ TIOTYPE otio, *tiop;
+{
+ readline_echoing_p = (otio.c_lflag & ECHO);
+
+ tiop->c_lflag &= ~(ICANON | ECHO);
+
+ if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
+ _rl_eof_char = otio.c_cc[VEOF];
+
+#if defined (USE_XON_XOFF)
+#if defined (IXANY)
+ tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
+#else
+ /* `strict' Posix systems do not define IXANY. */
+ tiop->c_iflag &= ~(IXON | IXOFF);
+#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;
+
+ /* 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
+
+#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
+}
+#endif /* NEW_TTY_DRIVER */
+
+/* Put the terminal in CBREAK mode so that we can detect key presses. */
+void
+rl_prep_terminal (meta_flag)
+ int meta_flag;
+{
+#if !defined (_GO32_)
+ int tty = fileno (rl_instream);
+ TIOTYPE tio;
+
+ if (terminal_prepped)
+ return;
+
+ /* Try to keep this function from being INTerrupted. */
+ block_sigint ();
+
+ if (get_tty_settings (tty, &tio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ otio = tio;
+
+ prepare_terminal_settings (meta_flag, otio, &tio);
+
+ if (set_tty_settings (tty, &tio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ control_meta_key (1);
+ terminal_prepped = 1;
+
+ release_sigint ();
+#endif /* !_GO32_ */
+}
+
+/* Restore the terminal's normal settings and modes. */
+void
+rl_deprep_terminal ()
+{
+#if !defined (_GO32_)
+ int tty = fileno (rl_instream);
+
+ if (!terminal_prepped)
+ return;
+
+ /* Try to keep this function from being INTerrupted. */
+ block_sigint ();
+
+ if (set_tty_settings (tty, &otio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ control_meta_key (0);
+ terminal_prepped = 0;
+
+ release_sigint ();
+#endif /* !_GO32_ */
+}
+
+/* **************************************************************** */
+/* */
+/* Bogus Flow Control */
+/* */
+/* **************************************************************** */
+
+rl_restart_output (count, key)
+ int count, key;
+{
+ 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 */
+}
+
+rl_stop_output (count, key)
+ int count, key;
+{
+ 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 */
+}
+
+/* **************************************************************** */
+/* */
+/* Default Key Bindings */
+/* */
+/* **************************************************************** */
+void
+rltty_set_default_bindings (kmap)
+ Keymap kmap;
+{
+ TIOTYPE ttybuff;
+ int tty = fileno (rl_instream);
+
+#if defined (NEW_TTY_DRIVER)
+
+ if (get_tty_settings (tty, &ttybuff) == 0)
+ {
+ if (ttybuff.flags & SGTTY_SET)
+ {
+ int erase, kill;
+
+ erase = ttybuff.sgttyb.sg_erase;
+ kill = ttybuff.sgttyb.sg_kill;
+
+ if (erase != -1 && kmap[erase].type == ISFUNC)
+ kmap[erase].function = rl_rubout;
+
+ if (kill != -1 && kmap[kill].type == ISFUNC)
+ kmap[kill].function = rl_unix_line_discard;
+ }
+
+# if defined (TIOCGLTC)
+
+ if (ttybuff.flags & LTCHARS_SET)
+ {
+ int werase, nextc;
+
+ werase = ttybuff.ltchars.t_werasc;
+ nextc = ttybuff.ltchars.t_lnextc;
+
+ if (werase != -1 && kmap[werase].type == ISFUNC)
+ kmap[werase].function = rl_unix_word_rubout;
+
+ if (nextc != -1 && kmap[nextc].type == ISFUNC)
+ kmap[nextc].function = rl_quoted_insert;
+ }
+ }
+# endif /* TIOCGLTC */
+
+#else /* !NEW_TTY_DRIVER */
+
+ if (get_tty_settings (tty, &ttybuff) == 0)
+ {
+ unsigned char erase, kill;
+
+ erase = ttybuff.c_cc[VERASE];
+ kill = ttybuff.c_cc[VKILL];
+
+ if (erase != (unsigned char)_POSIX_VDISABLE &&
+ kmap[erase].type == ISFUNC)
+ kmap[erase].function = rl_rubout;
+
+ if (kill != (unsigned char)_POSIX_VDISABLE &&
+ kmap[kill].type == ISFUNC)
+ kmap[kill].function = rl_unix_line_discard;
+
+# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
+ {
+ unsigned char nextc;
+
+ nextc = ttybuff.c_cc[VLNEXT];
+
+ if (nextc != (unsigned char)_POSIX_VDISABLE &&
+ kmap[nextc].type == ISFUNC)
+ kmap[nextc].function = rl_quoted_insert;
+ }
+# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
+
+# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
+ {
+ unsigned char werase;
+
+ werase = ttybuff.c_cc[VWERASE];
+
+ if (werase != (unsigned char)_POSIX_VDISABLE &&
+ kmap[werase].type == ISFUNC)
+ kmap[werase].function = rl_unix_word_rubout;
+ }
+# endif /* VWERASE && TERMIOS_TTY_DRIVER */
+ }
+#endif /* !NEW_TTY_DRIVER */
+}
diff --git a/gnu/lib/libreadline/search.c b/gnu/lib/libreadline/search.c
new file mode 100644
index 0000000..3bf6c1e
--- /dev/null
+++ b/gnu/lib/libreadline/search.c
@@ -0,0 +1,275 @@
+/* search.c - code for non-incremental searching in emacs and vi modes. */
+
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+
+ This file is part of the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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 1, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+
+#if defined (__GNUC__)
+# define alloca __builtin_alloca
+#else
+# if defined (sparc) || defined (HAVE_ALLOCA_H)
+# include <alloca.h>
+# endif
+#endif
+
+#include "readline.h"
+#include "history.h"
+
+extern char *xmalloc (), *xrealloc ();
+
+/* Variables imported from readline.c */
+extern int rl_point, rl_end, rl_line_buffer_len;
+extern Keymap _rl_keymap;
+extern char *rl_prompt;
+extern char *rl_line_buffer;
+extern HIST_ENTRY *saved_line_for_history;
+
+static char *noninc_search_string = (char *) NULL;
+static int noninc_history_pos = 0;
+
+/* 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 (string, pos, dir)
+ char *string;
+ int pos, dir;
+{
+ int ret, old;
+
+ old = where_history ();
+ history_set_pos (pos);
+
+ if (*string == '^')
+ ret = history_search_prefix (string + 1, dir);
+ else
+ ret = history_search (string, dir);
+
+ 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. */
+static void
+noninc_dosearch (string, dir)
+ char *string;
+ int dir;
+{
+ int oldpos, pos;
+ HIST_ENTRY *entry;
+
+ if (string == 0 || *string == 0 || noninc_history_pos < 0)
+ {
+ ding ();
+ return;
+ }
+
+ pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
+ if (pos == -1)
+ {
+ /* Search failed, current history position unchanged. */
+ maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = 0;
+ ding ();
+ return;
+ }
+
+ noninc_history_pos = pos;
+
+ oldpos = where_history ();
+ history_set_pos (noninc_history_pos);
+ entry = current_history ();
+ history_set_pos (oldpos);
+
+ {
+ int line_len;
+
+ line_len = strlen (entry->line);
+ if (line_len >= rl_line_buffer_len)
+ rl_extend_line_buffer (line_len);
+ strcpy (rl_line_buffer, entry->line);
+ }
+
+ rl_undo_list = (UNDO_LIST *)entry->data;
+ rl_end = strlen (rl_line_buffer);
+ rl_point = 0;
+ rl_clear_message ();
+
+ if (saved_line_for_history)
+ free_history_entry (saved_line_for_history);
+ saved_line_for_history = (HIST_ENTRY *)NULL;
+}
+
+/* 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 void
+noninc_search (dir, pchar)
+ int dir;
+ int pchar;
+{
+ int saved_point, c, pmtlen;
+ char *p;
+
+ maybe_save_line ();
+ saved_point = rl_point;
+
+ /* Use the line buffer to read the search string. */
+ rl_line_buffer[0] = 0;
+ rl_end = rl_point = 0;
+
+ pmtlen = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
+ p = (char *)alloca (2 + pmtlen);
+ if (pmtlen)
+ strcpy (p, rl_prompt);
+ p[pmtlen] = pchar ? pchar : ':';
+ p[pmtlen + 1] = '\0';
+
+ rl_message (p, 0, 0);
+
+ /* Read the search string. */
+ while (c = rl_read_key ())
+ {
+ switch (c)
+ {
+ case CTRL('H'):
+ case RUBOUT:
+ if (rl_point == 0)
+ {
+ maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = saved_point;
+ return;
+ }
+ /* FALLTHROUGH */
+
+ case CTRL('W'):
+ case CTRL('U'):
+ rl_dispatch (c, _rl_keymap);
+ break;
+
+ case RETURN:
+ case NEWLINE:
+ goto dosearch;
+ /* NOTREACHED */
+ break;
+
+ case CTRL('C'):
+ case CTRL('G'):
+ maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = saved_point;
+ ding ();
+ return;
+
+ default:
+ rl_insert (1, c);
+ break;
+ }
+ rl_redisplay ();
+ }
+
+ dosearch:
+ /* 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)
+ {
+ ding ();
+ return;
+ }
+ }
+ else
+ {
+ /* We want to start the search from the current history position. */
+ noninc_history_pos = where_history ();
+ if (noninc_search_string)
+ free (noninc_search_string);
+ noninc_search_string = savestring (rl_line_buffer);
+ }
+
+ noninc_dosearch (noninc_search_string, dir);
+}
+
+/* Search forward through the history list for a string. If the vi-mode
+ code calls this, KEY will be `?'. */
+rl_noninc_forward_search (count, key)
+ int count, key;
+{
+ if (key == '?')
+ noninc_search (1, '?');
+ else
+ noninc_search (1, 0);
+ return 0;
+}
+
+/* Reverse search the history list for a string. If the vi-mode code
+ calls this, KEY will be `/'. */
+rl_noninc_reverse_search (count, key)
+ int count, key;
+{
+ if (key == '/')
+ noninc_search (-1, '/');
+ else
+ noninc_search (-1, 0);
+ return 0;
+}
+
+/* Search forward through the history list for the last string searched
+ for. If there is no saved search string, abort. */
+rl_noninc_forward_search_again (count, key)
+ int count, key;
+{
+ if (!noninc_search_string)
+ {
+ ding ();
+ return (-1);
+ }
+ noninc_dosearch (noninc_search_string, 1);
+ return 0;
+}
+
+/* Reverse search in the history list for the last string searched
+ for. If there is no saved search string, abort. */
+rl_noninc_reverse_search_again (count, key)
+ int count, key;
+{
+ if (!noninc_search_string)
+ {
+ ding ();
+ return (-1);
+ }
+ noninc_dosearch (noninc_search_string, -1);
+ return 0;
+}
diff --git a/gnu/lib/libreadline/signals.c b/gnu/lib/libreadline/signals.c
new file mode 100644
index 0000000..8c0624d
--- /dev/null
+++ b/gnu/lib/libreadline/signals.c
@@ -0,0 +1,298 @@
+/* signals.c -- signal handling support for readline. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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 1, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if !defined (NO_SYS_FILE)
+# include <sys/file.h>
+#endif /* !NO_SYS_FILE */
+#include <signal.h>
+
+/* This is needed to include support for TIOCGWINSZ and window resizing. */
+#if defined (OSF1) || defined (BSD386) || defined (_386BSD) || defined (__BSD_4_4__) || defined (AIX)
+# include <sys/ioctl.h>
+#endif /* OSF1 || BSD386 || _386BSD || __BSD_4_4__ || AIX */
+
+#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 */
+
+#include <errno.h>
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+static void cr ();
+
+extern int readline_echoing_p;
+extern int rl_pending_input;
+
+extern int _rl_meta_flag;
+
+extern void _rl_output_character_function ();
+
+extern void free_undo_list ();
+
+#if defined (VOID_SIGHANDLER)
+# define sighandler void
+#else
+# define sighandler int
+#endif /* VOID_SIGHANDLER */
+
+/* This typedef is equivalant to the one for Function; it allows us
+ to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
+typedef sighandler SigHandler ();
+
+#if defined (_GO32_)
+# undef HANDLE_SIGNALS
+#endif /* _GO32_ */
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+
+/* **************************************************************** */
+/* */
+/* Signal Handling */
+/* */
+/* **************************************************************** */
+
+#if defined (SIGWINCH)
+static SigHandler *old_sigwinch = (SigHandler *)NULL;
+
+static sighandler
+rl_handle_sigwinch (sig)
+ int sig;
+{
+ if (readline_echoing_p)
+ {
+ _rl_set_screen_size (fileno (rl_instream), 1);
+
+ cr (); /* was crlf () */
+ rl_forced_update_display ();
+ }
+
+ if (old_sigwinch &&
+ old_sigwinch != (SigHandler *)SIG_IGN &&
+ old_sigwinch != (SigHandler *)SIG_DFL)
+ (*old_sigwinch) (sig);
+#if !defined (VOID_SIGHANDLER)
+ return (0);
+#endif /* VOID_SIGHANDLER */
+}
+#endif /* SIGWINCH */
+
+#if defined (HANDLE_SIGNALS)
+/* Interrupt handling. */
+static SigHandler
+ *old_int = (SigHandler *)NULL,
+ *old_tstp = (SigHandler *)NULL,
+ *old_ttou = (SigHandler *)NULL,
+ *old_ttin = (SigHandler *)NULL,
+ *old_cont = (SigHandler *)NULL,
+ *old_alrm = (SigHandler *)NULL;
+
+/* Handle an interrupt character. */
+static sighandler
+rl_signal_handler (sig)
+ int sig;
+{
+#if defined (HAVE_POSIX_SIGNALS)
+ sigset_t set;
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+ long omask;
+# endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+#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 (sig == SIGINT)
+ signal (sig, SIG_IGN);
+#endif /* !HAVE_BSD_SIGNALS */
+
+ switch (sig)
+ {
+ case SIGINT:
+ {
+ register HIST_ENTRY *entry;
+
+ free_undo_list ();
+
+ entry = current_history ();
+ if (entry)
+ entry->data = (char *)NULL;
+ }
+ _rl_kill_kbd_macro ();
+ rl_clear_message ();
+ rl_init_argument ();
+
+#if defined (SIGTSTP)
+ case SIGTSTP:
+ case SIGTTOU:
+ case SIGTTIN:
+#endif /* SIGTSTP */
+ case SIGALRM:
+ rl_clean_up_for_exit ();
+ rl_deprep_terminal ();
+ rl_clear_signals ();
+ rl_pending_input = 0;
+
+#if defined (HAVE_POSIX_SIGNALS)
+ sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
+ sigdelset (&set, sig);
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+ omask = sigblock (0);
+# endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+ kill (getpid (), sig);
+
+ /* Let the signal that we just sent through. */
+#if defined (HAVE_POSIX_SIGNALS)
+ sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+ sigsetmask (omask & ~(sigmask (sig)));
+# endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+ rl_prep_terminal (_rl_meta_flag);
+ rl_set_signals ();
+ }
+
+#if !defined (VOID_SIGHANDLER)
+ return (0);
+#endif /* !VOID_SIGHANDLER */
+}
+
+#if defined (HAVE_POSIX_SIGNALS)
+static SigHandler *
+rl_set_sighandler (sig, handler)
+ int sig;
+ SigHandler *handler;
+{
+ struct sigaction act, oact;
+
+ act.sa_handler = handler;
+ act.sa_flags = 0;
+ sigemptyset (&act.sa_mask);
+ sigemptyset (&oact.sa_mask);
+ sigaction (sig, &act, &oact);
+ return (oact.sa_handler);
+}
+
+#else /* !HAVE_POSIX_SIGNALS */
+# define rl_set_sighandler(sig, handler) (SigHandler *)signal (sig, handler)
+#endif /* !HAVE_POSIX_SIGNALS */
+
+rl_set_signals ()
+{
+ old_int = (SigHandler *)rl_set_sighandler (SIGINT, rl_signal_handler);
+ if (old_int == (SigHandler *)SIG_IGN)
+ signal (SIGINT, SIG_IGN);
+
+ old_alrm = (SigHandler *)rl_set_sighandler (SIGALRM, rl_signal_handler);
+ if (old_alrm == (SigHandler *)SIG_IGN)
+ signal (SIGALRM, SIG_IGN);
+
+#if !defined (SHELL)
+
+#if defined (SIGTSTP)
+ old_tstp = (SigHandler *)rl_set_sighandler (SIGTSTP, rl_signal_handler);
+ if (old_tstp == (SigHandler *)SIG_IGN)
+ signal (SIGTSTP, SIG_IGN);
+#endif /* SIGTSTP */
+#if defined (SIGTTOU)
+ old_ttou = (SigHandler *)rl_set_sighandler (SIGTTOU, rl_signal_handler);
+ old_ttin = (SigHandler *)rl_set_sighandler (SIGTTIN, rl_signal_handler);
+
+ if (old_tstp == (SigHandler *)SIG_IGN)
+ {
+ signal (SIGTTOU, SIG_IGN);
+ signal (SIGTTIN, SIG_IGN);
+ }
+#endif /* SIGTTOU */
+
+#endif /* !SHELL */
+
+#if defined (SIGWINCH)
+ old_sigwinch =
+ (SigHandler *) rl_set_sighandler (SIGWINCH, rl_handle_sigwinch);
+#endif /* SIGWINCH */
+}
+
+rl_clear_signals ()
+{
+ rl_set_sighandler (SIGINT, old_int);
+ rl_set_sighandler (SIGALRM, old_alrm);
+
+#if !defined (SHELL)
+
+#if defined (SIGTSTP)
+ signal (SIGTSTP, old_tstp);
+#endif
+
+#if defined (SIGTTOU)
+ signal (SIGTTOU, old_ttou);
+ signal (SIGTTIN, old_ttin);
+#endif /* SIGTTOU */
+
+#endif /* !SHELL */
+
+#if defined (SIGWINCH)
+ signal (SIGWINCH, old_sigwinch);
+#endif
+}
+
+/* Move to the start of the current line. */
+static void
+cr ()
+{
+ extern char *term_cr;
+
+ if (term_cr)
+ tputs (term_cr, 1, _rl_output_character_function);
+}
+#endif /* HANDLE_SIGNALS */
diff --git a/gnu/lib/libreadline/tcsh_hack.readme b/gnu/lib/libreadline/tcsh_hack.readme
index 2777512..ed05869 100644
--- a/gnu/lib/libreadline/tcsh_hack.readme
+++ b/gnu/lib/libreadline/tcsh_hack.readme
@@ -1,50 +1,27 @@
-*** readline.c.orig Thu May 5 04:02:17 1994
---- readline.c Mon May 9 00:33:44 1994
+*** rltty.c.orig Tue May 10 02:18:03 1994
+--- rltty.c Tue May 10 03:12:55 1994
***************
-*** 32,37 ****
---- 32,38 ----
-
- #include <stdio.h>
+*** 21,26 ****
+--- 21,27 ----
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/types.h>
+ #include <sys/ioctl.h>
- #include <fcntl.h>
- #include <sys/file.h>
#include <signal.h>
+ #include <errno.h>
+ #include <stdio.h>
***************
-*** 280,285 ****
---- 281,295 ----
- /* Non-zero means to save keys that we dispatch on in a kbd macro. */
- static int defining_kbd_macro = 0;
-
-+ /* XXX this prevents to got editing mode from tcsh */
-+ static void wait_foreground(void)
-+ {
-+ struct winsize w;
-+ int tty = fileno (rl_instream);
+*** 347,352 ****
+--- 348,359 ----
+ int tty;
+ TIOTYPE *tiop;
+ {
++ /* XXX this prevents to got editing mode from tcsh. Ache */
++ struct winsize w;
+
-+ if (ioctl (tty, TIOCGWINSZ, &w) == 0)
-+ (void) ioctl (tty, TIOCSWINSZ, &w);
-+ }
-
- /* **************************************************************** */
- /* */
-***************
-*** 1153,1158 ****
---- 1163,1169 ----
- #endif /* POSIX */
- int tty = fileno (rl_instream);
-
-+ wait_foreground (); /* XXX this prevents to got editing mode from tcsh */
- #if defined (_POSIX_VERSION)
- if (tcgetattr (tty, &ttybuff) != -1)
- #else
-***************
-*** 2307,2312 ****
---- 2318,2324 ----
- # endif /* HAVE_BSD_SIGNALS */
- #endif /* POSIX */
-
-+ wait_foreground (); /* XXX this prevents to got editing mode from tcsh */
- #if defined (_POSIX_VERSION)
- tcgetattr (tty, &tio);
- #else
++ if (ioctl (tty, TIOCGWINSZ, &w) == 0)
++ (void) ioctl (tty, TIOCSWINSZ, &w);
++
+ while (GETATTR (tty, tiop) < 0)
+ {
+ if (errno != EINTR)
diff --git a/gnu/lib/libreadline/tilde.c b/gnu/lib/libreadline/tilde.c
new file mode 100644
index 0000000..c0cb023
--- /dev/null
+++ b/gnu/lib/libreadline/tilde.c
@@ -0,0 +1,398 @@
+/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
+
+/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
+
+ This file is part of GNU 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 1, 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; see the file COPYING. If not, write to the Free
+ Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if defined (__GNUC__)
+# undef alloca
+# define alloca __builtin_alloca
+#else /* !__GNUC__ */
+# if defined (_AIX)
+ #pragma alloca
+# else /* !_AIX */
+# if defined (HAVE_ALLOCA_H)
+# include <alloca.h>
+# endif /* HAVE_ALLOCA_H */
+# endif /* !AIX */
+#endif /* !__GNUC__ */
+
+#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 <tilde.h>
+#include <pwd.h>
+
+#if defined (USG) && !defined (isc386) && !defined (sgi)
+extern struct passwd *getpwuid (), *getpwent ();
+#endif
+#if defined (isc386) && !defined (__STDC__) && defined (_POSIX_SOURCE)
+extern struct passwd *getpwent ();
+#endif
+
+#if !defined (savestring)
+extern char *xmalloc ();
+# ifndef strcpy
+extern char *strcpy ();
+# endif
+#define savestring(x) strcpy (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 defined (TEST) || defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* TEST || STATIC_MALLOC */
+
+/* The default value of tilde_additional_prefixes. This is set to
+ whitespace preceding a tilde so that simple programs which do not
+ perform any word separation get desired behaviour. */
+static char *default_prefixes[] =
+ { " ~", "\t~", (char *)NULL };
+
+/* The default value of tilde_additional_suffixes. This is set to
+ whitespace or newline so that simple programs which do not
+ perform any word separation get desired behaviour. */
+static char *default_suffixes[] =
+ { " ", "\n", (char *)NULL };
+
+/* If non-null, this contains the address of a function to call if the
+ standard meaning for expanding a tilde fails. The function is called
+ with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
+ which is the expansion, or a NULL pointer if there is no expansion. */
+CPFunction *tilde_expansion_failure_hook = (CPFunction *)NULL;
+
+/* When non-null, this is a NULL terminated array of strings which
+ are duplicates for a tilde prefix. Bash uses this to expand
+ `=~' and `:~'. */
+char **tilde_additional_prefixes = default_prefixes;
+
+/* When non-null, this is a NULL terminated array of strings which match
+ the end of a username, instead of just "/". Bash sets this to
+ `:' and `=~'. */
+char **tilde_additional_suffixes = default_suffixes;
+
+/* Find the start of a tilde expansion in STRING, and return the index of
+ the tilde which starts the expansion. Place the length of the text
+ which identified this tilde starter in LEN, excluding the tilde itself. */
+static int
+tilde_find_prefix (string, len)
+ char *string;
+ int *len;
+{
+ register int i, j, string_len;
+ register char **prefixes = tilde_additional_prefixes;
+
+ string_len = strlen (string);
+ *len = 0;
+
+ if (!*string || *string == '~')
+ return (0);
+
+ if (prefixes)
+ {
+ for (i = 0; i < string_len; i++)
+ {
+ for (j = 0; prefixes[j]; j++)
+ {
+ if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
+ {
+ *len = strlen (prefixes[j]) - 1;
+ return (i + *len);
+ }
+ }
+ }
+ }
+ return (string_len);
+}
+
+/* Find the end of a tilde expansion in STRING, and return the index of
+ the character which ends the tilde definition. */
+static int
+tilde_find_suffix (string)
+ char *string;
+{
+ register int i, j, string_len;
+ register char **suffixes = tilde_additional_suffixes;
+
+ string_len = strlen (string);
+
+ for (i = 0; i < string_len; i++)
+ {
+ if (string[i] == '/' || !string[i])
+ break;
+
+ for (j = 0; suffixes && suffixes[j]; j++)
+ {
+ if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
+ return (i);
+ }
+ }
+ return (i);
+}
+
+/* Return a new string which is the result of tilde expanding STRING. */
+char *
+tilde_expand (string)
+ char *string;
+{
+ char *result, *tilde_expand_word ();
+ int result_size, result_index;
+
+ result_size = result_index = 0;
+ result = (char *)NULL;
+
+ /* Scan through STRING expanding tildes as we come to them. */
+ while (1)
+ {
+ register int start, end;
+ char *tilde_word, *expansion;
+ int len;
+
+ /* Make START point to the tilde which starts the expansion. */
+ start = tilde_find_prefix (string, &len);
+
+ /* Copy the skipped text into the result. */
+ if ((result_index + start + 1) > result_size)
+ result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
+
+ strncpy (result + result_index, string, start);
+ result_index += start;
+
+ /* Advance STRING to the starting tilde. */
+ string += start;
+
+ /* Make END be the index of one after the last character of the
+ username. */
+ end = tilde_find_suffix (string);
+
+ /* If both START and END are zero, we are all done. */
+ if (!start && !end)
+ break;
+
+ /* Expand the entire tilde word, and copy it into RESULT. */
+ tilde_word = (char *)xmalloc (1 + end);
+ strncpy (tilde_word, string, end);
+ tilde_word[end] = '\0';
+ string += end;
+
+ expansion = tilde_expand_word (tilde_word);
+ free (tilde_word);
+
+ len = strlen (expansion);
+ if ((result_index + len + 1) > result_size)
+ result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
+
+ strcpy (result + result_index, expansion);
+ result_index += len;
+ free (expansion);
+ }
+
+ result[result_index] = '\0';
+
+ return (result);
+}
+
+/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
+ tilde. If there is no expansion, call tilde_expansion_failure_hook. */
+char *
+tilde_expand_word (filename)
+ char *filename;
+{
+ char *dirname;
+
+ dirname = filename ? savestring (filename) : (char *)NULL;
+
+ if (dirname && *dirname == '~')
+ {
+ char *temp_name;
+ if (!dirname[1] || dirname[1] == '/')
+ {
+ /* Prepend $HOME to the rest of the string. */
+ char *temp_home = (char *)getenv ("HOME");
+
+ /* If there is no HOME variable, look up the directory in
+ the password database. */
+ if (!temp_home)
+ {
+ struct passwd *entry;
+
+ entry = getpwuid (getuid ());
+ if (entry)
+ temp_home = entry->pw_dir;
+ }
+
+ temp_name = (char *)alloca (1 + strlen (&dirname[1])
+ + (temp_home ? strlen (temp_home) : 0));
+ temp_name[0] = '\0';
+ if (temp_home)
+ strcpy (temp_name, temp_home);
+ strcat (temp_name, &dirname[1]);
+ free (dirname);
+ dirname = savestring (temp_name);
+ }
+ else
+ {
+ struct passwd *user_entry;
+ char *username = (char *)alloca (257);
+ int i, c;
+
+ for (i = 1; c = dirname[i]; i++)
+ {
+ if (c == '/')
+ break;
+ else
+ username[i - 1] = c;
+ }
+ username[i - 1] = '\0';
+
+ if (!(user_entry = getpwnam (username)))
+ {
+ /* If the calling program has a special syntax for
+ expanding tildes, and we couldn't find a standard
+ expansion, then let them try. */
+ if (tilde_expansion_failure_hook)
+ {
+ char *expansion;
+
+ expansion = (*tilde_expansion_failure_hook) (username);
+
+ if (expansion)
+ {
+ temp_name = (char *)alloca (1 + strlen (expansion)
+ + strlen (&dirname[i]));
+ strcpy (temp_name, expansion);
+ strcat (temp_name, &dirname[i]);
+ free (expansion);
+ goto return_name;
+ }
+ }
+ /* We shouldn't report errors. */
+ }
+ else
+ {
+ temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir)
+ + strlen (&dirname[i]));
+ strcpy (temp_name, user_entry->pw_dir);
+ strcat (temp_name, &dirname[i]);
+ return_name:
+ free (dirname);
+ dirname = savestring (temp_name);
+ }
+ endpwent ();
+ }
+ }
+ return (dirname);
+}
+
+
+#if defined (TEST)
+#undef NULL
+#include <stdio.h>
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *result, line[512];
+ int done = 0;
+
+ while (!done)
+ {
+ printf ("~expand: ");
+ fflush (stdout);
+
+ if (!gets (line))
+ strcpy (line, "done");
+
+ if ((strcmp (line, "done") == 0) ||
+ (strcmp (line, "quit") == 0) ||
+ (strcmp (line, "exit") == 0))
+ {
+ done = 1;
+ break;
+ }
+
+ result = tilde_expand (line);
+ printf (" --> %s\n", result);
+ free (result);
+ }
+ exit (0);
+}
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+
+ return (temp);
+}
+
+static void
+memory_error_and_abort ()
+{
+ fprintf (stderr, "readline: Out of virtual memory!\n");
+ abort ();
+}
+
+/*
+ * Local variables:
+ * compile-command: "gcc -g -DTEST -o tilde tilde.c"
+ * end:
+ */
+#endif /* TEST */
diff --git a/gnu/lib/libreadline/vi_keymap.c b/gnu/lib/libreadline/vi_keymap.c
index 3863e83..24fbc3e 100644
--- a/gnu/lib/libreadline/vi_keymap.c
+++ b/gnu/lib/libreadline/vi_keymap.c
@@ -1,29 +1,35 @@
/* vi_keymap.c -- the keymap for vi_mode in readline (). */
-/* Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
- This file is part of GNU Readline, a library for reading lines
- of text with interactive input and history editing.
+ This file is part of the GNU Readline Library, 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 2 of the License, or
+ The GNU Readline Library 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 1, 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
+ The GNU Readline Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (BUFSIZ)
+#include <stdio.h>
+#endif /* !BUFSIZ */
+
+#include "readline.h"
extern KEYMAP_ENTRY_ARRAY vi_escape_keymap;
/* The keymap arrays for handling vi mode. */
KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
-
/* The regular control keys come first. */
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
{ ISFUNC, (Function *)0x0 }, /* Control-a */
@@ -33,7 +39,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_emacs_editing_mode }, /* Control-e */
{ ISFUNC, (Function *)0x0 }, /* Control-f */
{ ISFUNC, rl_abort }, /* Control-g */
- { ISFUNC, rl_rubout }, /* Control-h */
+ { ISFUNC, rl_backward }, /* Control-h */
{ ISFUNC, (Function *)0x0 }, /* Control-i */
{ ISFUNC, rl_newline }, /* Control-j */
{ ISFUNC, rl_kill_line }, /* Control-k */
@@ -53,7 +59,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, (Function *)0x0 }, /* Control-z */
- { ISKMAP, (Function *)vi_escape_keymap }, /* Control-[ */
+ { ISFUNC, rl_abort }, /* Control-[ */
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Control-] */
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
@@ -66,7 +72,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_vi_comment }, /* # */
{ ISFUNC, rl_end_of_line }, /* $ */
{ ISFUNC, rl_vi_match }, /* % */
- { ISFUNC, (Function *)0x0 }, /* & */
+ { ISFUNC, rl_vi_tilde_expand }, /* & */
{ ISFUNC, (Function *)0x0 }, /* ' */
{ ISFUNC, (Function *)0x0 }, /* ( */
{ ISFUNC, (Function *)0x0 }, /* ) */
@@ -74,7 +80,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_get_next_history}, /* + */
{ ISFUNC, rl_vi_char_search }, /* , */
{ ISFUNC, rl_get_previous_history }, /* - */
- { ISFUNC, (Function *)0x0 }, /* . */
+ { ISFUNC, rl_vi_redo }, /* . */
{ ISFUNC, rl_vi_search }, /* / */
/* Regular digits. */
@@ -167,12 +173,143 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_vi_column }, /* | */
{ ISFUNC, (Function *)0x0 }, /* } */
{ ISFUNC, rl_vi_change_case }, /* ~ */
- { ISFUNC, rl_backward } /* RUBOUT */
+ { ISFUNC, (Function *)0x0 }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
};
KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
-
/* The regular control keys come first. */
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
{ ISFUNC, rl_insert }, /* Control-a */
@@ -316,7 +453,143 @@ KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
{ ISFUNC, rl_insert }, /* | */
{ ISFUNC, rl_insert }, /* } */
{ ISFUNC, rl_insert }, /* ~ */
- { ISFUNC, rl_rubout } /* RUBOUT */
+ { 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 vi_escape_keymap = {
@@ -424,7 +697,7 @@ KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
{ ISFUNC, rl_do_lowercase_version }, /* Z */
/* Some more punctuation. */
- { ISFUNC, (Function *)0x0 }, /* [ */
+ { ISFUNC, rl_arrow_keys }, /* [ */
{ ISFUNC, (Function *)0x0 }, /* \ */
{ ISFUNC, (Function *)0x0 }, /* ] */
{ ISFUNC, (Function *)0x0 }, /* ^ */
@@ -446,7 +719,7 @@ KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
{ ISFUNC, (Function *)0x0 }, /* l */
{ ISFUNC, (Function *)0x0 }, /* m */
{ ISFUNC, (Function *)0x0 }, /* n */
- { ISFUNC, (Function *)0x0 }, /* o */
+ { ISFUNC, rl_arrow_keys }, /* o */
{ ISFUNC, (Function *)0x0 }, /* p */
{ ISFUNC, (Function *)0x0 }, /* q */
{ ISFUNC, (Function *)0x0 }, /* r */
@@ -464,5 +737,137 @@ KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
{ ISFUNC, (Function *)0x0 }, /* | */
{ ISFUNC, (Function *)0x0 }, /* } */
{ ISFUNC, (Function *)0x0 }, /* ~ */
- { ISFUNC, rl_backward_kill_word } /* RUBOUT */
+ { ISFUNC, rl_backward_kill_word }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
};
diff --git a/gnu/lib/libreadline/vi_mode.c b/gnu/lib/libreadline/vi_mode.c
index a399791..971c377 100644
--- a/gnu/lib/libreadline/vi_mode.c
+++ b/gnu/lib/libreadline/vi_mode.c
@@ -1,26 +1,25 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
-/* Copyright (C) 1988, 1991 Free Software Foundation, Inc.
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
- This file is part of the GNU Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
- The Library is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ The GNU Readline Library 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 1, or
(at your option) any later version.
- The Library 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
+ The GNU Readline Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
/* **************************************************************** */
/* */
@@ -29,9 +28,24 @@
/* **************************************************************** */
#if defined (VI_MODE)
-/* Some standard library routines. */
-#include "sysdep.h"
+#include <sys/types.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
#include <stdio.h>
+
+/* Some standard library routines. */
+#include "rldefs.h"
#include "readline.h"
#include "history.h"
@@ -48,7 +62,7 @@
#endif
#ifndef member
-#define member(c, s) ((c) ? index ((s), (c)) : 0)
+#define member(c, s) ((c) ? (char *)strchr ((s), (c)) : 0)
#endif
#ifndef isident
@@ -59,24 +73,24 @@
#define exchange(x, y) {int temp = x; x = y; y = temp;}
#endif
+#ifndef VI_COMMENT_BEGIN_DEFAULT
+#define VI_COMMENT_BEGIN_DEFAULT "#"
+#endif
+
/* Variables imported from readline.c */
extern int rl_point, rl_end, rl_mark, rl_done;
extern FILE *rl_instream;
extern int rl_line_buffer_len, rl_explicit_arg, rl_numeric_arg;
-extern Keymap keymap;
+extern Keymap _rl_keymap;
extern char *rl_prompt;
extern char *rl_line_buffer;
extern int rl_arg_sign;
-extern char *xmalloc (), *xrealloc ();
extern void rl_extend_line_buffer ();
-
-/* Last string searched for from `/' or `?'. */
-static char *vi_last_search = (char *)NULL;
-static int vi_histpos;
+extern int rl_vi_check (), rl_digit_loop1 ();
/* Non-zero means enter insertion mode. */
-int vi_doing_insert = 0;
+int _rl_vi_doing_insert = 0;
/* String inserted into the line by rl_vi_comment (). */
char *rl_vi_comment_begin = (char *)NULL;
@@ -92,16 +106,70 @@ static Keymap vi_replace_map = (Keymap)NULL;
/* The number of characters inserted in the last replace operation. */
static int vi_replace_count = 0;
+int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
+int _rl_vi_last_repeat = 1;
+int _rl_vi_last_arg_sign = 1;
+static int _rl_vi_last_motion = 0;
+static int _rl_vi_last_search_char = 0;
+static int _rl_vi_last_replacement = 0;
+
+static int vi_redoing = 0;
+
+/* Text modification commands. These are the `redoable' commands. */
+static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
+
+void
+rl_vi_set_last ()
+{
+ _rl_vi_last_command = 'i';
+ _rl_vi_last_repeat = 1;
+ _rl_vi_last_arg_sign = 1;
+ _rl_vi_last_motion = 0;
+}
+
+/* Is the command C a VI mode text modification command? */
+int
+rl_vi_textmod_command (c)
+ int c;
+{
+ return (member (c, vi_textmod) != (char *)NULL);
+}
+
+/* Bound to `.'. Called from command mode, so we know that we have to
+ redo a text modification command. The default for _rl_vi_last_command
+ puts you back into insert mode. */
+rl_vi_redo (count, c)
+ int count, c;
+{
+ if (!rl_explicit_arg)
+ {
+ rl_numeric_arg = _rl_vi_last_repeat;
+ rl_arg_sign = _rl_vi_last_arg_sign;
+ }
+
+ vi_redoing = 1;
+ rl_dispatch (_rl_vi_last_command, _rl_keymap);
+ vi_redoing = 0;
+
+ return (0);
+}
+
/* Yank the nth arg from the previous line into this line at point. */
rl_vi_yank_arg (count)
int count;
{
+ /* vi mode is defined to insert a space before the last argument. */
+ rl_insert (1, ' ');
+
/* Readline thinks that the first word on a line is the 0th, while vi
thinks the first word on a line is the 1st. Compensate. */
if (rl_explicit_arg)
rl_yank_nth_arg (count - 1, 0);
else
rl_yank_nth_arg ('$', 0);
+
+ rl_vi_insertion_mode ();
+ return (0);
}
/* With an argument, move back that many history lines, else move to the
@@ -109,7 +177,6 @@ rl_vi_yank_arg (count)
rl_vi_fetch_history (count, c)
int count, c;
{
- extern int rl_explicit_arg;
int current = where_history ();
/* Giving an argument of n means we want the nth command in the history
@@ -127,176 +194,45 @@ rl_vi_fetch_history (count, c)
}
else
rl_beginning_of_history (count, 0);
+ return (0);
}
/* Search again for the last thing searched for. */
-rl_vi_search_again (ignore, key)
- int ignore, key;
+rl_vi_search_again (count, key)
+ int count, key;
{
switch (key)
{
case 'n':
- rl_vi_dosearch (vi_last_search, -1);
+ rl_noninc_reverse_search_again (count, key);
break;
case 'N':
- rl_vi_dosearch (vi_last_search, 1);
+ rl_noninc_forward_search_again (count, key);
break;
}
+ return (0);
}
/* Do a vi style search. */
rl_vi_search (count, key)
int count, key;
{
- int dir, c, save_pos;
- char *p;
-
switch (key)
{
case '?':
- dir = 1;
+ rl_noninc_forward_search (count, key);
break;
case '/':
- dir = -1;
+ rl_noninc_reverse_search (count, key);
break;
default:
ding ();
- return;
- }
-
- vi_histpos = where_history ();
- maybe_save_line ();
- save_pos = rl_point;
-
- /* Reuse the line input buffer to read the search string. */
- rl_line_buffer[0] = 0;
- rl_end = rl_point = 0;
- p = (char *)alloca (2 + (rl_prompt ? strlen (rl_prompt) : 0));
-
- sprintf (p, "%s%c", rl_prompt ? rl_prompt : "", key);
-
- rl_message (p, 0, 0);
-
- while (c = rl_read_key ())
- {
- switch (c)
- {
- case CTRL('H'):
- case RUBOUT:
- if (rl_point == 0)
- {
- maybe_unsave_line ();
- rl_clear_message ();
- rl_point = save_pos;
- return;
- }
-
- case CTRL('W'):
- case CTRL('U'):
- rl_dispatch (c, keymap);
- break;
-
- case ESC:
- case RETURN:
- case NEWLINE:
- goto dosearch;
- break;
-
- case CTRL('C'):
- maybe_unsave_line ();
- rl_clear_message ();
- rl_point = 0;
- ding ();
- return;
-
- default:
- rl_insert (1, c);
- break;
- }
- rl_redisplay ();
- }
- dosearch:
- if (vi_last_search)
- free (vi_last_search);
-
- vi_last_search = savestring (rl_line_buffer);
- rl_vi_dosearch (rl_line_buffer, dir);
-}
-
-/* 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. If the first character of STRING
- is `^', the string must match a prefix of a history line, otherwise
- a full substring match is performed. */
-static int
-vi_history_search_pos (string, dir, pos)
- char *string;
- int dir, pos;
-{
- int ret, old = where_history ();
-
- history_set_pos (pos);
-
- if (*string == '^')
- ret = history_search_prefix (string + 1, dir);
- else
- ret = history_search (string, dir);
-
- if (ret == -1)
- {
- history_set_pos (old);
- return (-1);
- }
-
- ret = where_history ();
- history_set_pos (old);
- return ret;
-}
-
-rl_vi_dosearch (string, dir)
- char *string;
- int dir;
-{
- int old, save = vi_histpos;
- HIST_ENTRY *h;
-
- if (string == 0 || *string == 0 || vi_histpos < 0)
- {
- ding ();
- return;
- }
-
- if ((save = vi_history_search_pos (string, dir, vi_histpos + dir)) == -1)
- {
- maybe_unsave_line ();
- rl_clear_message ();
- rl_point = 0;
- ding ();
- return;
+ break;
}
-
- vi_histpos = save;
-
- old = where_history ();
- history_set_pos (vi_histpos);
- h = current_history ();
- history_set_pos (old);
-
- {
- int line_len = strlen (h->line);
-
- if (line_len >= rl_line_buffer_len)
- rl_extend_line_buffer (line_len);
- strcpy (rl_line_buffer, h->line);
- }
-
- rl_undo_list = (UNDO_LIST *)h->data;
- rl_end = strlen (rl_line_buffer);
- rl_point = 0;
- rl_clear_message ();
+ return (0);
}
/* Completion, from vi's point of view. */
@@ -318,6 +254,19 @@ rl_vi_complete (ignore, key)
rl_complete_internal (TAB); /* Standard Readline completion. */
else
rl_complete (0, key);
+
+ if (key == '*' || key == '\\')
+ rl_vi_insertion_mode ();
+ return (0);
+}
+
+/* Tilde expansion for vi mode. */
+rl_vi_tilde_expand (ignore, key)
+ int ignore, key;
+{
+ rl_tilde_expand (0, key);
+ rl_vi_insertion_mode ();
+ return (0);
}
/* Previous word in vi mode. */
@@ -325,21 +274,20 @@ rl_vi_prev_word (count, key)
int count, key;
{
if (count < 0)
- {
- rl_vi_next_word (-count, key);
- return;
- }
+ return (rl_vi_next_word (-count, key));
if (rl_point == 0)
{
ding ();
- return;
+ return (0);
}
if (uppercase_p (key))
rl_vi_bWord (count);
else
rl_vi_bword (count);
+
+ return (0);
}
/* Next word in vi mode. */
@@ -347,21 +295,19 @@ rl_vi_next_word (count, key)
int count;
{
if (count < 0)
- {
- rl_vi_prev_word (-count, key);
- return;
- }
+ return (rl_vi_prev_word (-count, key));
if (rl_point >= (rl_end - 1))
{
ding ();
- return;
+ return (0);
}
if (uppercase_p (key))
rl_vi_fWord (count);
else
rl_vi_fword (count);
+ return (0);
}
/* Move to the end of the ?next? word. */
@@ -371,13 +317,14 @@ rl_vi_end_word (count, key)
if (count < 0)
{
ding ();
- return;
+ return -1;
}
if (uppercase_p (key))
rl_vi_eWord (count);
else
rl_vi_eword (count);
+ return (0);
}
/* Move forward a word the way that 'W' does. */
@@ -394,6 +341,7 @@ rl_vi_fWord (count)
while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++;
}
+ return (0);
}
rl_vi_bWord (count)
@@ -416,6 +364,7 @@ rl_vi_bWord (count)
rl_point++;
}
}
+ return (0);
}
rl_vi_eWord (count)
@@ -444,6 +393,7 @@ rl_vi_eWord (count)
rl_point--;
}
}
+ return (0);
}
rl_vi_fword (count)
@@ -468,6 +418,7 @@ rl_vi_fword (count)
while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++;
}
+ return (0);
}
rl_vi_bword (count)
@@ -505,6 +456,7 @@ rl_vi_bword (count)
rl_point++;
}
}
+ return (0);
}
rl_vi_eword (count)
@@ -528,13 +480,14 @@ rl_vi_eword (count)
}
rl_point--;
}
+ return (0);
}
rl_vi_insert_beg ()
{
rl_beg_of_line ();
rl_vi_insertion_mode ();
- return 0;
+ return (0);
}
rl_vi_append_mode ()
@@ -542,21 +495,21 @@ rl_vi_append_mode ()
if (rl_point < rl_end)
rl_point += 1;
rl_vi_insertion_mode ();
- return 0;
+ return (0);
}
rl_vi_append_eol ()
{
rl_end_of_line ();
rl_vi_append_mode ();
- return 0;
+ return (0);
}
/* What to do in the case of C-d. */
rl_vi_eof_maybe (count, c)
int count, c;
{
- rl_newline (1, '\n');
+ return (rl_newline (1, '\n'));
}
/* Insertion mode stuff. */
@@ -565,7 +518,8 @@ rl_vi_eof_maybe (count, c)
switching keymaps. */
rl_vi_insertion_mode ()
{
- keymap = vi_insertion_keymap;
+ _rl_keymap = vi_insertion_keymap;
+ return (0);
}
rl_vi_movement_mode ()
@@ -573,26 +527,30 @@ rl_vi_movement_mode ()
if (rl_point > 0)
rl_backward (1);
- keymap = vi_movement_keymap;
+ rl_vi_set_last ();
+
+ _rl_keymap = vi_movement_keymap;
vi_done_inserting ();
+ return (0);
}
vi_done_inserting ()
{
- if (vi_doing_insert)
+ if (_rl_vi_doing_insert)
{
rl_end_undo_group ();
- vi_doing_insert = 0;
+ _rl_vi_doing_insert = 0;
}
+ return (0);
}
rl_vi_arg_digit (count, c)
int count, c;
{
if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
- rl_beg_of_line ();
+ return (rl_beg_of_line ());
else
- rl_digit_argument (count, c);
+ return (rl_digit_argument (count, c));
}
rl_vi_change_case (count, ignore)
@@ -602,7 +560,7 @@ rl_vi_change_case (count, ignore)
/* Don't try this on an empty line. */
if (rl_point >= rl_end)
- return;
+ return (0);
while (count-- && rl_point < rl_end)
{
@@ -610,6 +568,12 @@ rl_vi_change_case (count, ignore)
c = to_lower (rl_line_buffer[rl_point]);
else if (lowercase_p (rl_line_buffer[rl_point]))
c = to_upper (rl_line_buffer[rl_point]);
+ else
+ {
+ /* Just skip over characters neither upper nor lower case. */
+ rl_forward (1);
+ continue;
+ }
/* Vi is kind of strange here. */
if (c)
@@ -623,6 +587,7 @@ rl_vi_change_case (count, ignore)
else
rl_forward (1);
}
+ return (0);
}
rl_vi_put (count, key)
@@ -633,12 +598,14 @@ rl_vi_put (count, key)
rl_yank ();
rl_backward (1);
+ return (0);
}
rl_vi_check ()
{
if (rl_point && rl_point == rl_end)
rl_point--;
+ return (0);
}
rl_vi_column (count)
@@ -647,6 +614,7 @@ rl_vi_column (count)
rl_end_of_line ();
else
rl_point = count - 1;
+ return (0);
}
int
@@ -654,9 +622,7 @@ rl_vi_domove (key, nextkey)
int key, *nextkey;
{
int c, save;
- int old_end, added_blank;
-
- added_blank = 0;
+ int old_end;
rl_mark = rl_point;
c = rl_read_key ();
@@ -679,26 +645,28 @@ rl_vi_domove (key, nextkey)
{
rl_mark = rl_end;
rl_beg_of_line ();
+ _rl_vi_last_motion = c;
return (0);
}
else
return (-1);
}
+ _rl_vi_last_motion = c;
+
/* Append a blank character temporarily so that the motion routines
work right at the end of the line. */
old_end = rl_end;
- rl_line_buffer[rl_end++] = ' '; /* This looks pretty bogus to me??? */
+ rl_line_buffer[rl_end++] = ' ';
rl_line_buffer[rl_end] = '\0';
- added_blank++;
- rl_dispatch (c, keymap);
+ rl_dispatch (c, _rl_keymap);
/* Remove the blank that we added. */
rl_end = old_end;
rl_line_buffer[rl_end] = '\0';
if (rl_point > rl_end)
- rl_point = rl_end - 1;
+ rl_point = rl_end;
/* No change in position means the command failed. */
if (rl_mark == rl_point)
@@ -712,12 +680,18 @@ rl_vi_domove (key, nextkey)
rl_point--;
/* If cw or cW, back up to the end of a word, so the behaviour of ce
- or cE is the actual result. Brute-force, no subtlety. Do the same
- thing for dw or dW. */
+ or cE is the actual result. Brute-force, no subtlety. */
if (key == 'c' && (to_upper (c) == 'W'))
{
while (rl_point && whitespace (rl_line_buffer[rl_point]))
rl_point--;
+
+ /* Move past the end of the word so that the kill doesn't remove the
+ last letter of the previous word. Only do this if we are not at
+ the end of the line. */
+ if ((rl_point >= 0) && (rl_point < (rl_end - 1)) &&
+ !whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
}
if (rl_mark < rl_point)
@@ -737,8 +711,8 @@ rl_digit_loop1 ()
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
key = c = rl_read_key ();
- if (keymap[c].type == ISFUNC &&
- keymap[c].function == rl_universal_argument)
+ if (_rl_keymap[c].type == ISFUNC &&
+ _rl_keymap[c].function == rl_universal_argument)
{
rl_numeric_arg *= 4;
continue;
@@ -760,6 +734,7 @@ rl_digit_loop1 ()
break;
}
}
+ return (0);
}
rl_vi_delete_to (count, key)
@@ -769,40 +744,58 @@ rl_vi_delete_to (count, key)
if (uppercase_p (key))
rl_stuff_char ('$');
+ else if (vi_redoing)
+ rl_stuff_char (_rl_vi_last_motion);
if (rl_vi_domove (key, &c))
{
ding ();
- return;
+ return -1;
}
- if ((c != 'l') && (c != '|') && (c != 'h') && rl_mark < rl_end)
+ /* These are the motion commands that do not require adjusting the
+ mark. */
+ if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
rl_mark++;
rl_kill_text (rl_point, rl_mark);
+ return (0);
}
rl_vi_change_to (count, key)
int count, key;
{
- int c;
+ int c, start_pos;
if (uppercase_p (key))
rl_stuff_char ('$');
+ else if (vi_redoing)
+ rl_stuff_char (_rl_vi_last_motion);
+
+ start_pos = rl_point;
if (rl_vi_domove (key, &c))
{
ding ();
- return;
+ return -1;
}
- if ((c != 'l') && (c != '|') && (c != 'h') && rl_mark < rl_end)
+ /* These are the motion commands that do not require adjusting the
+ mark. c[wW] are handled by special-case code in rl_vi_domove(),
+ and already leave the mark at the correct location. */
+ if ((strchr (" l|hwW^0%bB", c) == 0) && (rl_mark < rl_end))
rl_mark++;
+ /* The cursor never moves with c[wW]. */
+ if ((to_upper (c) == 'W') && rl_point < start_pos)
+ rl_point = start_pos;
+
rl_begin_undo_group ();
- vi_doing_insert = 1;
+ _rl_vi_doing_insert = 1;
rl_kill_text (rl_point, rl_mark);
rl_vi_insertion_mode ();
+
+ return (0);
}
rl_vi_yank_to (count, key)
@@ -816,10 +809,12 @@ rl_vi_yank_to (count, key)
if (rl_vi_domove (key, &c))
{
ding ();
- return;
+ return -1;
}
- if ((c != 'l') && (c != '|') && (c != 'h') && rl_mark < rl_end)
+ /* These are the motion commands that do not require adjusting the
+ mark. */
+ if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
rl_mark++;
rl_begin_undo_group ();
@@ -827,16 +822,19 @@ rl_vi_yank_to (count, key)
rl_end_undo_group ();
rl_do_undo ();
rl_point = save;
+
+ return (0);
}
rl_vi_delete (count)
+ int count;
{
int end;
if (rl_end == 0)
{
ding ();
- return;
+ return -1;
}
end = rl_point + count;
@@ -848,6 +846,7 @@ rl_vi_delete (count)
if (rl_point > 0 && rl_point == rl_end)
rl_backward (1);
+ return (0);
}
/* Turn the current line into a comment in shell history.
@@ -859,15 +858,16 @@ rl_vi_comment ()
if (rl_vi_comment_begin != (char *)NULL)
rl_insert_text (rl_vi_comment_begin);
else
- rl_insert_text (": "); /* Default. */
+ rl_insert_text (VI_COMMENT_BEGIN_DEFAULT); /* Default. */
rl_redisplay ();
rl_newline (1, '\010');
+ return (0);
}
rl_vi_first_print ()
{
- rl_back_to_indent (0, 0);
+ return (rl_back_to_indent ());
}
rl_back_to_indent (ignore1, ignore2)
@@ -876,6 +876,7 @@ rl_back_to_indent (ignore1, ignore2)
rl_beg_of_line ();
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
rl_point++;
+ return (0);
}
/* NOTE: it is necessary that opposite directions are inverses */
@@ -895,7 +896,10 @@ rl_vi_char_search (count, key)
dir = (key == ';' ? orig_dir : -orig_dir);
else
{
- target = rl_getc (rl_instream);
+ if (vi_redoing)
+ target = _rl_vi_last_search_char;
+ else
+ _rl_vi_last_search_char = target = rl_getc (rl_instream);
switch (key)
{
@@ -946,7 +950,7 @@ rl_vi_char_search (count, key)
if (pos < 0)
{
ding ();
- return;
+ return -1;
}
}
else
@@ -954,7 +958,7 @@ rl_vi_char_search (count, key)
if (pos >= rl_end)
{
ding ();
- return;
+ return -1;
}
pos++;
@@ -974,10 +978,11 @@ rl_vi_char_search (count, key)
if (pos >= (rl_end - 1))
{
ding ();
- return;
+ return -1;
}
}
}
+ return (0);
}
/* Match brackets */
@@ -996,7 +1001,7 @@ rl_vi_match ()
{
rl_point = pos;
ding ();
- return;
+ return -1;
}
}
@@ -1017,7 +1022,7 @@ rl_vi_match ()
else
{
ding ();
- return;
+ return -1;
}
}
}
@@ -1036,11 +1041,12 @@ rl_vi_match ()
else
{
ding ();
- return;
+ return -1;
}
}
}
rl_point = pos;
+ return (0);
}
int
@@ -1064,10 +1070,13 @@ rl_vi_change_char (count, key)
{
int c;
- c = rl_getc (rl_instream);
+ if (vi_redoing)
+ c = _rl_vi_last_replacement;
+ else
+ _rl_vi_last_replacement = c = rl_getc (rl_instream);
if (c == '\033' || c == CTRL ('C'))
- return;
+ return -1;
while (count-- && rl_point < rl_end)
{
@@ -1080,13 +1089,14 @@ rl_vi_change_char (count, key)
rl_end_undo_group ();
}
+ return (0);
}
rl_vi_subst (count, key)
int count, key;
{
rl_begin_undo_group ();
- vi_doing_insert = 1;
+ _rl_vi_doing_insert = 1;
if (uppercase_p (key))
{
@@ -1097,7 +1107,9 @@ rl_vi_subst (count, key)
rl_delete (count, key);
rl_end_undo_group ();
+
rl_vi_insertion_mode ();
+ return (0);
}
rl_vi_overstrike (count, key)
@@ -1105,9 +1117,9 @@ rl_vi_overstrike (count, key)
{
int i;
- if (vi_doing_insert == 0)
+ if (_rl_vi_doing_insert == 0)
{
- vi_doing_insert = 1;
+ _rl_vi_doing_insert = 1;
rl_begin_undo_group ();
}
@@ -1126,6 +1138,7 @@ rl_vi_overstrike (count, key)
rl_end_undo_group ();
}
+ return (0);
}
rl_vi_overstrike_delete (count)
@@ -1149,12 +1162,13 @@ rl_vi_overstrike_delete (count)
rl_backward (1);
}
- if (vi_replace_count == 0 && vi_doing_insert)
+ if (vi_replace_count == 0 && _rl_vi_doing_insert)
{
rl_end_undo_group ();
rl_do_undo ();
- vi_doing_insert = 0;
+ _rl_vi_doing_insert = 0;
}
+ return (0);
}
rl_vi_replace (count, key)
@@ -1184,24 +1198,24 @@ rl_vi_replace (count, key)
vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
}
- keymap = vi_replace_map;
+ _rl_keymap = vi_replace_map;
+ return (0);
}
-/*
- * Try to complete the word we are standing on or the word that ends with
- * the previous character. A space matches everything.
- * Word delimiters are space and ;.
- */
+/* Try to complete the word we are standing on or the word that ends with
+ the previous character. A space matches everything. Word delimiters are
+ space and ;. */
rl_vi_possible_completions()
{
int save_pos = rl_point;
- if (!index (" ;", rl_line_buffer[rl_point]))
+ if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
{
- while (!index(" ;", rl_line_buffer[++rl_point]))
+ while (rl_line_buffer[rl_point] != ' ' &&
+ rl_line_buffer[rl_point] != ';')
;
}
- else if (rl_line_buffer[rl_point-1] == ';')
+ else if (rl_line_buffer[rl_point - 1] == ';')
{
ding ();
return (0);
@@ -1213,4 +1227,51 @@ rl_vi_possible_completions()
return (0);
}
+#if defined (STATIC_MALLOC)
+
+/* **************************************************************** */
+/* */
+/* xmalloc and xrealloc () */
+/* */
+/* **************************************************************** */
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)xmalloc (bytes);
+ else
+ temp = (char *)realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+
+ return (temp);
+}
+
+static void
+memory_error_and_abort ()
+{
+ fprintf (stderr, "readline: Out of virtual memory!\n");
+ abort ();
+}
+#endif /* STATIC_MALLOC */
+
#endif /* VI_MODE */
diff --git a/gnu/lib/libreadline/xmalloc.c b/gnu/lib/libreadline/xmalloc.c
new file mode 100644
index 0000000..4f6dc76
--- /dev/null
+++ b/gnu/lib/libreadline/xmalloc.c
@@ -0,0 +1,78 @@
+/* xmalloc.c -- safe versions of malloc and realloc */
+
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+
+ This file is part of GNU 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 1, 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; see the file COPYING. If not, write to the Free
+ Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if defined (ALREADY_HAVE_XMALLOC)
+#else
+#include <stdio.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+static void memory_error_and_abort ();
+
+/* **************************************************************** */
+/* */
+/* Memory Allocation and Deallocation. */
+/* */
+/* **************************************************************** */
+
+/* Return a pointer to free()able block of memory large enough
+ to hold BYTES number of bytes. If the memory cannot be allocated,
+ print an error message and abort. */
+char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ("xmalloc");
+ return (temp);
+}
+
+char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ("xrealloc");
+ return (temp);
+}
+
+static void
+memory_error_and_abort (fname)
+ char *fname;
+{
+ fprintf (stderr, "%s: Out of virtual memory!\n", fname);
+ abort ();
+}
+#endif /* !ALREADY_HAVE_XMALLOC */
OpenPOWER on IntegriCloud