of `last', since they're equal at call time and rl_vi_domove can
change rl_numeric_arg (which vi apparently updates). Fixes redo bug
of `c2....' reported by Marion Berryman <mwberryman@copper.net>
+
+ 5/4
+ ---
+parse.y
+ - fix decode_prompt_string to properly deal with strftime() returning 0
+
+ 5/6
+ ---
+variables.c
+ - in make_local_array_variable, return an already-existing local array
+ variable immediately rather than creating a new array (causing a
+ memory leak)
+
+ 5/8
+ ---
+lib/readline/vi_mode.c
+ - change rl_vi_domove to set rl_explicit_arg before calling
+ rl_digit_loop1 so that multi-digit numeric arguments work right
+ - _rl_vi_last_command is no longer static
+
+lib/readline/rlprivate.h
+ - new extern declaration for _rl_vi_last_command
+
+lib/readline/text.c
+ - change rl_newline to only call _rl_vi_reset_last if the last command
+ (_rl_vi_last_command) is not a text modification command. This lets
+ the last-command and last-argument work across command lines
+
+
- if get_working_directory fails and returns null (causing resetpwd
to return NULL), use set_working_directory to set $PWD to the
absolute pathname for which chdir just succeeded
+
+ 5/1
+ ---
+lib/readline/vi_mode.c
+ - in rl_vi_change_to, call _rl_vi_set_last with rl_numeric_arg instead
+ of `last', since they're equal at call time and rl_vi_domove can
+ change rl_numeric_arg (which vi apparently updates). Fixes redo bug
+ of `c2....' reported by Marion Berryman <mwberryman@copper.net>
+
+ 5/4
+ ---
+parse.y
+ - fix decode_prompt_string to properly deal with strftime() returning 0
+
+ 5/6
+ ---
+variables.c
+ - in make_local_array_variable, return an already-existing local array
+ variable immediately rather than creating a new array (causing a
+ memory leak)
+
+ 5/8
+ ---
+lib/readline/vi_mode.c
+ - change rl_vi_domove to set rl_explicit_arg before calling
+ rl_digit_loop1 so that multi-digit numeric arguments work right
+ - _rl_vi_last_command is no longer static
+
+lib/readline/rlprivate.h
+ - new extern declaration for _rl_vi_last_command
+
+lib/readline/text.c
+ - change rl_newline to only call _rl_vi_reset_last if the last command
+ (_rl_vi_last_command) is not a text modification command
+
tests/jobs1.sub f
tests/jobs2.sub f
tests/jobs3.sub f
+tests/jobs4.sub f
tests/jobs.right f
tests/more-exp.tests f
tests/more-exp.right f
* chet@ins.cwru.edu
*/
-/* Copyright (C) 1997-2002 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
This file is trap.def, from which is created trap.c.
It implements the builtin "trap" in Bash.
-Copyright (C) 1987-2002 Free Software Foundation, Inc.
+Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
operation = SET;
first_arg = list->word->word;
- /* When not in posix mode, the historical behavior of looking for a
+ /* When in posix mode, the historical behavior of looking for a
missing first argument is disabled. To revert to the original
signal handling disposition, use `-' as the first argument. */
if (posixly_correct == 0 && first_arg && *first_arg &&
--- /dev/null
+This file is trap.def, from which is created trap.c.
+It implements the builtin "trap" in Bash.
+
+Copyright (C) 1987-2002 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 2, 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, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+
+$PRODUCES trap.c
+
+$BUILTIN trap
+$FUNCTION trap_builtin
+$SHORT_DOC trap [arg] [signal_spec ...] or trap -l
+The command ARG is to be read and executed when the shell receives
+signal(s) SIGNAL_SPEC. If ARG is absent all specified signals are
+reset to their original values. If ARG is the null string each
+SIGNAL_SPEC is ignored by the shell and by the commands it invokes.
+If a SIGNAL_SPEC is EXIT (0) the command ARG is executed on exit from
+the shell. If a SIGNAL_SPEC is DEBUG, ARG is executed after every
+command. If ARG is `-p' then the trap commands associated with
+each SIGNAL_SPEC are displayed. If no arguments are supplied or if
+only `-p' is given, trap prints the list of commands associated with
+each signal number. Each SIGNAL_SPEC is either a signal name in <signal.h>
+or a signal number. `trap -l' prints a list of signal names and their
+corresponding numbers. Note that a signal can be sent to the shell
+with "kill -signal $$".
+$END
+
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+# ifdef _MINIX
+# include <sys/types.h>
+# endif
+# include <unistd.h>
+#endif
+
+#include "../bashtypes.h"
+#include <signal.h>
+#include <stdio.h>
+#include "../bashansi.h"
+
+#include "../shell.h"
+#include "../trap.h"
+#include "common.h"
+#include "bashgetopt.h"
+
+static void showtrap __P((int));
+static int display_traps __P((WORD_LIST *));
+
+/* The trap command:
+
+ trap <arg> <signal ...>
+ trap <signal ...>
+ trap -l
+ trap -p [sigspec ...]
+ trap [--]
+
+ Set things up so that ARG is executed when SIGNAL(s) N is recieved.
+ If ARG is the empty string, then ignore the SIGNAL(s). If there is
+ no ARG, then set the trap for SIGNAL(s) to its original value. Just
+ plain "trap" means to print out the list of commands associated with
+ each signal number. Single arg of "-l" means list the signal names. */
+
+/* Possible operations to perform on the list of signals.*/
+#define SET 0 /* Set this signal to first_arg. */
+#define REVERT 1 /* Revert to this signals original value. */
+#define IGNORE 2 /* Ignore this signal. */
+
+extern int posixly_correct;
+
+int
+trap_builtin (list)
+ WORD_LIST *list;
+{
+ int list_signal_names, display, result, opt;
+
+ list_signal_names = display = 0;
+ result = EXECUTION_SUCCESS;
+ reset_internal_getopt ();
+ while ((opt = internal_getopt (list, "lp")) != -1)
+ {
+ switch (opt)
+ {
+ case 'l':
+ list_signal_names++;
+ break;
+ case 'p':
+ display++;
+ break;
+ default:
+ builtin_usage ();
+ return (EX_USAGE);
+ }
+ }
+ list = loptend;
+
+ opt = DSIG_NOCASE|DSIG_SIGPREFIX; /* flags for decode_signal */
+
+ if (list_signal_names)
+ return (display_signal_list ((WORD_LIST *)NULL, 1));
+ else if (display || list == 0)
+ return (display_traps (list));
+ else
+ {
+ char *first_arg;
+ int operation, sig;
+
+ operation = SET;
+ first_arg = list->word->word;
+ /* When not in posix mode, the historical behavior of looking for a
+ missing first argument is disabled. To revert to the original
+ signal handling disposition, use `-' as the first argument. */
+ if (posixly_correct == 0 && first_arg && *first_arg &&
+ (*first_arg != '-' || first_arg[1]) &&
+ signal_object_p (first_arg, opt))
+ operation = REVERT;
+ else
+ {
+ list = list->next;
+ if (*first_arg == '\0')
+ operation = IGNORE;
+ else if (first_arg[0] == '-' && !first_arg[1])
+ operation = REVERT;
+ }
+
+ while (list)
+ {
+ sig = decode_signal (list->word->word, opt);
+
+ if (sig == NO_SIG)
+ {
+ sh_invalidsig (list->word->word);
+ result = EXECUTION_FAILURE;
+ }
+ else
+ {
+ switch (operation)
+ {
+ case SET:
+ set_signal (sig, first_arg);
+ break;
+
+ case REVERT:
+ restore_default_signal (sig);
+
+ /* Signals that the shell treats specially need special
+ handling. */
+ switch (sig)
+ {
+ case SIGINT:
+ if (interactive)
+ set_signal_handler (SIGINT, sigint_sighandler);
+ else
+ set_signal_handler (SIGINT, termination_unwind_protect);
+ break;
+
+ case SIGQUIT:
+ /* Always ignore SIGQUIT. */
+ set_signal_handler (SIGQUIT, SIG_IGN);
+ break;
+ case SIGTERM:
+#if defined (JOB_CONTROL)
+ case SIGTTIN:
+ case SIGTTOU:
+ case SIGTSTP:
+#endif /* JOB_CONTROL */
+ if (interactive)
+ set_signal_handler (sig, SIG_IGN);
+ break;
+ }
+ break;
+
+ case IGNORE:
+ ignore_signal (sig);
+ break;
+ }
+ }
+ list = list->next;
+ }
+ }
+
+ return (result);
+}
+
+static void
+showtrap (i)
+ int i;
+{
+ char *t, *p, *sn;
+
+ p = trap_list[i];
+
+ if (p == (char *)DEFAULT_SIG)
+ return;
+
+ t = (p == (char *)IGNORE_SIG) ? (char *)NULL : sh_single_quote (p);
+ sn = signal_name (i);
+ /* Make sure that signals whose names are unknown (for whatever reason)
+ are printed as signal numbers. */
+ if (STREQN (sn, "SIGJUNK", 7) || STREQN (sn, "unknown", 7))
+ printf ("trap -- %s %d\n", t ? t : "''", i);
+ else if (posixly_correct)
+ {
+ if (STREQN (sn, "SIG", 3))
+ printf ("trap -- %s %s\n", t ? t : "''", sn+3);
+ else
+ printf ("trap -- %s %s\n", t ? t : "''", sn);
+ }
+ else
+ printf ("trap -- %s %s\n", t ? t : "''", sn);
+
+ FREE (t);
+}
+
+static int
+display_traps (list)
+ WORD_LIST *list;
+{
+ int result, i;
+
+ if (list == 0)
+ {
+ for (i = 0; i < BASH_NSIG; i++)
+ showtrap (i);
+ return (EXECUTION_SUCCESS);
+ }
+
+ for (result = EXECUTION_SUCCESS; list; list = list->next)
+ {
+ i = decode_signal (list->word->word, DSIG_NOCASE|DSIG_SIGPREFIX);
+ if (i == NO_SIG)
+ {
+ sh_invalidsig (list->word->word);
+ result = EXECUTION_FAILURE;
+ }
+ else
+ showtrap (i);
+ }
+
+ return (result);
+}
<HTML>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<!-- Created on April, 20 2004 by texi2html 1.64 -->
+<!-- Created on May, 4 2004 by texi2html 1.64 -->
<!--
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
Karl Berry <karl@freefriends.org>
Many of the builtins have been extended by POSIX or Bash.
</P><P>
+Unless otherwise noted, each builtin command documented as accepting
+options preceded by <SAMP>`-'</SAMP> accepts <SAMP>`--'</SAMP>
+to signify the end of the options.
+</P><P>
+
<A NAME="Bourne Shell Builtins"></A>
<HR SIZE="6">
<A NAME="SEC57"></A>
Invoke an editor on the current command line, and execute the result as shell
commands.
Bash attempts to invoke
-<CODE>$FCEDIT</CODE>, <CODE>$EDITOR</CODE>, and <CODE>emacs</CODE>
+<CODE>$VISUAL</CODE>, <CODE>$EDITOR</CODE>, and <CODE>emacs</CODE>
as the editor, in that order.
<P>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="bashref.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<H1>About this document</H1>
-This document was generated by <I>Chet Ramey</I> on <I>April, 20 2004</I>
+This document was generated by <I>Chet Ramey</I> on <I>May, 4 2004</I>
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
"><I>texi2html</I></A>
<P></P>
<BR>
<FONT SIZE="-1">
This document was generated
-by <I>Chet Ramey</I> on <I>April, 20 2004</I>
+by <I>Chet Ramey</I> on <I>May, 4 2004</I>
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
"><I>texi2html</I></A>
Many of the builtins have been extended by POSIX or Bash.
+ Unless otherwise noted, each builtin command documented as accepting
+options preceded by `-' accepts `--' to signify the end of the options.
+
\1f
File: bashref.info, Node: Bourne Shell Builtins, Next: Bash Builtins, Up: Shell Builtin Commands
`edit-and-execute-command (C-xC-e)'
Invoke an editor on the current command line, and execute the
- result as shell commands. Bash attempts to invoke `$FCEDIT',
+ result as shell commands. Bash attempts to invoke `$VISUAL',
`$EDITOR', and `emacs' as the editor, in that order.
Node: Signals\7f86969
Node: Shell Scripts\7f88924
Node: Shell Builtin Commands\7f91435
-Node: Bourne Shell Builtins\7f92865
-Node: Bash Builtins\7f109748
-Node: The Set Builtin\7f137870
-Node: Special Builtins\7f146088
-Node: Shell Variables\7f147060
-Node: Bourne Shell Variables\7f147496
-Node: Bash Variables\7f149473
-Node: Bash Features\7f168978
-Node: Invoking Bash\7f169860
-Node: Bash Startup Files\7f175671
-Node: Interactive Shells\7f180541
-Node: What is an Interactive Shell?\7f180943
-Node: Is this Shell Interactive?\7f181578
-Node: Interactive Shell Behavior\7f182384
-Node: Bash Conditional Expressions\7f185651
-Node: Shell Arithmetic\7f189071
-Node: Aliases\7f191811
-Node: Arrays\7f194374
-Node: The Directory Stack\7f197394
-Node: Directory Stack Builtins\7f198100
-Node: Printing a Prompt\7f200979
-Node: The Restricted Shell\7f203688
-Node: Bash POSIX Mode\7f205513
-Node: Job Control\7f212159
-Node: Job Control Basics\7f212625
-Node: Job Control Builtins\7f216910
-Node: Job Control Variables\7f221206
-Node: Command Line Editing\7f222356
-Node: Introduction and Notation\7f223354
-Node: Readline Interaction\7f224971
-Node: Readline Bare Essentials\7f226157
-Node: Readline Movement Commands\7f227937
-Node: Readline Killing Commands\7f228893
-Node: Readline Arguments\7f230802
-Node: Searching\7f231837
-Node: Readline Init File\7f234014
-Node: Readline Init File Syntax\7f235068
-Node: Conditional Init Constructs\7f246712
-Node: Sample Init File\7f249236
-Node: Bindable Readline Commands\7f252419
-Node: Commands For Moving\7f253618
-Node: Commands For History\7f254467
-Node: Commands For Text\7f257356
-Node: Commands For Killing\7f260017
-Node: Numeric Arguments\7f262147
-Node: Commands For Completion\7f263274
-Node: Keyboard Macros\7f266855
-Node: Miscellaneous Commands\7f267414
-Node: Readline vi Mode\7f272713
-Node: Programmable Completion\7f273622
-Node: Programmable Completion Builtins\7f279429
-Node: Using History Interactively\7f286791
-Node: Bash History Facilities\7f287470
-Node: Bash History Builtins\7f290160
-Node: History Interaction\7f294012
-Node: Event Designators\7f296563
-Node: Word Designators\7f297567
-Node: Modifiers\7f299197
-Node: Installing Bash\7f300594
-Node: Basic Installation\7f301728
-Node: Compilers and Options\7f304413
-Node: Compiling For Multiple Architectures\7f305147
-Node: Installation Names\7f306804
-Node: Specifying the System Type\7f307615
-Node: Sharing Defaults\7f308324
-Node: Operation Controls\7f308989
-Node: Optional Features\7f309940
-Node: Reporting Bugs\7f318212
-Node: Major Differences From The Bourne Shell\7f319387
-Node: Copying This Manual\7f335135
-Node: GNU Free Documentation License\7f335389
-Node: Builtin Index\7f357782
-Node: Reserved Word Index\7f361409
-Node: Variable Index\7f362885
-Node: Function Index\7f369878
-Node: Concept Index\7f374491
+Node: Bourne Shell Builtins\7f93010
+Node: Bash Builtins\7f109893
+Node: The Set Builtin\7f138015
+Node: Special Builtins\7f146233
+Node: Shell Variables\7f147205
+Node: Bourne Shell Variables\7f147641
+Node: Bash Variables\7f149618
+Node: Bash Features\7f169123
+Node: Invoking Bash\7f170005
+Node: Bash Startup Files\7f175816
+Node: Interactive Shells\7f180686
+Node: What is an Interactive Shell?\7f181088
+Node: Is this Shell Interactive?\7f181723
+Node: Interactive Shell Behavior\7f182529
+Node: Bash Conditional Expressions\7f185796
+Node: Shell Arithmetic\7f189216
+Node: Aliases\7f191956
+Node: Arrays\7f194519
+Node: The Directory Stack\7f197539
+Node: Directory Stack Builtins\7f198245
+Node: Printing a Prompt\7f201124
+Node: The Restricted Shell\7f203833
+Node: Bash POSIX Mode\7f205658
+Node: Job Control\7f212304
+Node: Job Control Basics\7f212770
+Node: Job Control Builtins\7f217055
+Node: Job Control Variables\7f221351
+Node: Command Line Editing\7f222501
+Node: Introduction and Notation\7f223499
+Node: Readline Interaction\7f225116
+Node: Readline Bare Essentials\7f226302
+Node: Readline Movement Commands\7f228082
+Node: Readline Killing Commands\7f229038
+Node: Readline Arguments\7f230947
+Node: Searching\7f231982
+Node: Readline Init File\7f234159
+Node: Readline Init File Syntax\7f235213
+Node: Conditional Init Constructs\7f246857
+Node: Sample Init File\7f249381
+Node: Bindable Readline Commands\7f252564
+Node: Commands For Moving\7f253763
+Node: Commands For History\7f254612
+Node: Commands For Text\7f257501
+Node: Commands For Killing\7f260162
+Node: Numeric Arguments\7f262292
+Node: Commands For Completion\7f263419
+Node: Keyboard Macros\7f267000
+Node: Miscellaneous Commands\7f267559
+Node: Readline vi Mode\7f272858
+Node: Programmable Completion\7f273767
+Node: Programmable Completion Builtins\7f279574
+Node: Using History Interactively\7f286936
+Node: Bash History Facilities\7f287615
+Node: Bash History Builtins\7f290305
+Node: History Interaction\7f294157
+Node: Event Designators\7f296708
+Node: Word Designators\7f297712
+Node: Modifiers\7f299342
+Node: Installing Bash\7f300739
+Node: Basic Installation\7f301873
+Node: Compilers and Options\7f304558
+Node: Compiling For Multiple Architectures\7f305292
+Node: Installation Names\7f306949
+Node: Specifying the System Type\7f307760
+Node: Sharing Defaults\7f308469
+Node: Operation Controls\7f309134
+Node: Optional Features\7f310085
+Node: Reporting Bugs\7f318357
+Node: Major Differences From The Bourne Shell\7f319532
+Node: Copying This Manual\7f335280
+Node: GNU Free Documentation License\7f335534
+Node: Builtin Index\7f357927
+Node: Reserved Word Index\7f361554
+Node: Variable Index\7f363030
+Node: Function Index\7f370023
+Node: Concept Index\7f374636
\1f
End Tag Table
-This is TeX, Version 3.14159 (Web2C 7.3.1) (format=tex 2001.2.12) 20 APR 2004 15:26
+This is TeX, Version 3.14159 (Web2C 7.3.1) (format=tex 2001.2.12) 4 MAY 2004 10:27
**/usr/homes/chet/src/bash/src/doc/bashref.texi
(/usr/homes/chet/src/bash/src/doc/bashref.texi (texinfo.tex
Loading texinfo [version 2003-02-03.16]: Basics,
[11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25]
[26] [27] [28] [29] [30] [31] Chapter 4 [32] [33] [34] [35] [36] [37] [38]
-Underfull \hbox (badness 5231) in paragraph at lines 3098--3111
+Underfull \hbox (badness 5231) in paragraph at lines 3102--3115
@texttt emacs-meta[]@textrm , @texttt emacs-ctlx[]@textrm , @texttt vi[]@textr
m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
.etc.
[39] [40] [41] [42] [43]
-Overfull \hbox (43.33536pt too wide) in paragraph at lines 3435--3435
+Overfull \hbox (43.33536pt too wide) in paragraph at lines 3439--3439
[]@texttt read [-ers] [-a @textttsl aname@texttt ] [-d @textttsl de-lim@texttt
] [-n @textttsl nchars@texttt ] [-p @textttsl prompt@texttt ] [-t @textttsl ti
me-
.etc.
[44] [45] [46] [47] [48] [49] [50] [51]
-Underfull \hbox (badness 4036) in paragraph at lines 4044--4051
+Underfull \hbox (badness 4036) in paragraph at lines 4048--4055
@texttt -x[]@textrm Print a trace of sim-ple com-mands, @texttt \@textrm fB-fo
r@texttt \@textrm fP com-mands,
.etc.
[52] [53] Chapter 5 [54] [55] [56] [57] [58] [59] [60] [61] Chapter 6 [62]
-Overfull \hbox (51.96864pt too wide) in paragraph at lines 4756--4756
+Overfull \hbox (51.96864pt too wide) in paragraph at lines 4760--4760
[]@texttt bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@t
exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
.etc.
-Overfull \hbox (76.23077pt too wide) in paragraph at lines 4757--4757
+Overfull \hbox (76.23077pt too wide) in paragraph at lines 4761--4761
[]@texttt bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@texttt
] [-O @textttsl shopt_option@texttt ] -c @textttsl string @texttt [@textttsl ar
-
.etc.
-Overfull \hbox (34.72258pt too wide) in paragraph at lines 4758--4758
+Overfull \hbox (34.72258pt too wide) in paragraph at lines 4762--4762
[]@texttt bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@text
tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
.etc.
[63] [64]
-Underfull \hbox (badness 2245) in paragraph at lines 4932--4934
+Underfull \hbox (badness 2245) in paragraph at lines 4936--4938
[]@textrm When a lo-gin shell ex-its, Bash reads and ex-e-cutes com-mands from
the file
[107]) (/usr/homes/chet/src/bash/src/lib/readline/doc/hsuser.texi Chapter 9
[108] [109] [110] [111] [112]) Chapter 10 [113] [114] [115] [116] [117]
-Underfull \hbox (badness 2772) in paragraph at lines 6600--6604
+Underfull \hbox (badness 2772) in paragraph at lines 6604--6608
[]@textrm Enable sup-port for large files (@texttt http://www.sas.com/standard
s/large_
19 hyphenation exceptions out of 1000
15i,8n,11p,273b,465s stack positions out of 300i,100n,500p,50000b,4000s
-Output written on bashref.dvi (154 pages, 579284 bytes).
+Output written on bashref.dvi (154 pages, 579456 bytes).
%DVIPSWebPage: (www.radicaleye.com)
%DVIPSCommandLine: dvips -D 600 -t letter -o bashref.ps bashref.dvi
%DVIPSParameters: dpi=600, compressed
-%DVIPSSource: TeX output 2004.04.20:1526
+%DVIPSSource: TeX output 2004.05.04:1027
%%BeginProcSet: texc.pro
%!
/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
%%Page: 33 39
33 38 bop 150 -116 a Ft(Chapter)30 b(4:)41 b(Shell)28
b(Builtin)g(Commands)2069 b(33)150 299 y Fo(4)80 b(Shell)55
-b(Builtin)g(Commands)275 572 y Ft(Builtin)22 b(commands)i(are)h(con)m
+b(Builtin)g(Commands)275 525 y Ft(Builtin)22 b(commands)i(are)h(con)m
(tained)g(within)d(the)j(shell)e(itself.)38 b(When)24
-b(the)h(name)g(of)g(a)g(builtin)c(com-)150 681 y(mand)26
+b(the)h(name)g(of)g(a)g(builtin)c(com-)150 635 y(mand)26
b(is)h(used)f(as)i(the)g(\014rst)e(w)m(ord)h(of)h(a)f(simple)f(command)
h(\(see)h(Section)f(3.2.1)i([Simple)d(Commands],)150
-791 y(page)21 b(8\),)j(the)d(shell)e(executes)j(the)f(command)f
+745 y(page)21 b(8\),)j(the)d(shell)e(executes)j(the)f(command)f
(directly)-8 b(,)22 b(without)e(in)m(v)m(oking)g(another)h(program.)37
-b(Builtin)150 900 y(commands)f(are)h(necessary)g(to)g(implemen)m(t)e
+b(Builtin)150 854 y(commands)f(are)h(necessary)g(to)g(implemen)m(t)e
(functionalit)m(y)g(imp)s(ossible)e(or)k(incon)m(v)m(enien)m(t)f(to)h
-(obtain)150 1010 y(with)29 b(separate)i(utilities.)275
-1157 y(This)i(section)i(brie\015y)f(the)h(builtins)d(whic)m(h)i(Bash)h
+(obtain)150 964 y(with)29 b(separate)i(utilities.)275
+1097 y(This)i(section)i(brie\015y)f(the)h(builtins)d(whic)m(h)i(Bash)h
(inherits)e(from)i(the)g(Bourne)g(Shell,)g(as)g(w)m(ell)g(as)150
-1267 y(the)c(builtin)26 b(commands)k(whic)m(h)g(are)g(unique)f(to)i(or)
-f(ha)m(v)m(e)i(b)s(een)e(extended)g(in)f(Bash.)275 1414
+1206 y(the)c(builtin)26 b(commands)k(whic)m(h)g(are)g(unique)f(to)i(or)
+f(ha)m(v)m(e)i(b)s(een)e(extended)g(in)f(Bash.)275 1339
y(Sev)m(eral)44 b(builtin)c(commands)k(are)h(describ)s(ed)d(in)h(other)
h(c)m(hapters:)69 b(builtin)40 b(commands)k(whic)m(h)150
-1524 y(pro)m(vide)22 b(the)i(Bash)f(in)m(terface)h(to)g(the)g(job)f
+1449 y(pro)m(vide)22 b(the)i(Bash)f(in)m(terface)h(to)g(the)g(job)f
(con)m(trol)h(facilities)d(\(see)j(Section)g(7.2)g([Job)f(Con)m(trol)g
-(Builtins],)150 1633 y(page)40 b(80\),)j(the)c(directory)g(stac)m(k)h
+(Builtins],)150 1558 y(page)40 b(80\),)j(the)c(directory)g(stac)m(k)h
(\(see)g(Section)f(6.8.1)i([Directory)f(Stac)m(k)g(Builtins],)f(page)h
-(73\),)j(the)150 1743 y(command)23 b(history)g(\(see)h(Section)f(9.2)i
+(73\),)j(the)150 1668 y(command)23 b(history)g(\(see)h(Section)f(9.2)i
([Bash)f(History)f(Builtins],)f(page)j(109\),)h(and)d(the)h
-(programmable)150 1853 y(completion)30 b(facilities)e(\(see)k(Section)e
+(programmable)150 1778 y(completion)30 b(facilities)e(\(see)k(Section)e
(8.7)h([Programmable)f(Completion)f(Builtins],)f(page)k(105\).)275
-2000 y(Man)m(y)f(of)f(the)h(builtins)26 b(ha)m(v)m(e)32
-b(b)s(een)e(extended)g(b)m(y)g Fl(posix)g Ft(or)g(Bash.)150
-2290 y Fr(4.1)68 b(Bourne)45 b(Shell)g(Builtins)275 2546
+1911 y(Man)m(y)f(of)f(the)h(builtins)26 b(ha)m(v)m(e)32
+b(b)s(een)e(extended)g(b)m(y)g Fl(posix)g Ft(or)g(Bash.)275
+2044 y(Unless)19 b(otherwise)h(noted,)i(eac)m(h)g(builtin)17
+b(command)j(do)s(cumen)m(ted)g(as)h(accepting)g(options)e(preceded)150
+2153 y(b)m(y)30 b(`)p Fs(-)p Ft(')h(accepts)g(`)p Fs(--)p
+Ft(')g(to)g(signify)d(the)j(end)f(of)g(the)h(options.)150
+2406 y Fr(4.1)68 b(Bourne)45 b(Shell)g(Builtins)275 2648
y Ft(The)31 b(follo)m(wing)f(shell)f(builtin)g(commands)i(are)h
(inherited)d(from)i(the)h(Bourne)f(Shell.)43 b(These)31
-b(com-)150 2656 y(mands)e(are)i(implemen)m(ted)e(as)i(sp)s(eci\014ed)d
-(b)m(y)j(the)f Fl(posix)g Ft(1003.2)j(standard.)150 2835
-y Fs(:)d Ft(\(a)h(colon\))870 2944 y Fs(:)47 b([)p Fj(arguments)11
-b Fs(])630 3085 y Ft(Do)43 b(nothing)e(b)s(ey)m(ond)h(expanding)e
+b(com-)150 2758 y(mands)e(are)i(implemen)m(ted)e(as)i(sp)s(eci\014ed)d
+(b)m(y)j(the)f Fl(posix)g Ft(1003.2)j(standard.)150 2914
+y Fs(:)d Ft(\(a)h(colon\))870 3024 y Fs(:)47 b([)p Fj(arguments)11
+b Fs(])630 3157 y Ft(Do)43 b(nothing)e(b)s(ey)m(ond)h(expanding)e
Fq(argumen)m(ts)46 b Ft(and)c(p)s(erforming)e(redirections.)74
-b(The)630 3195 y(return)29 b(status)i(is)e(zero.)150
-3367 y Fs(.)h Ft(\(a)h(p)s(erio)s(d\))870 3477 y Fs(.)47
+b(The)630 3267 y(return)29 b(status)i(is)e(zero.)150
+3423 y Fs(.)h Ft(\(a)h(p)s(erio)s(d\))870 3532 y Fs(.)47
b Fj(filename)57 b Fs([)p Fj(arguments)11 b Fs(])630
-3618 y Ft(Read)34 b(and)f(execute)i(commands)e(from)g(the)h
+3665 y Ft(Read)34 b(and)f(execute)i(commands)e(from)g(the)h
Fq(\014lename)k Ft(argumen)m(t)c(in)e(the)i(curren)m(t)g(shell)630
-3727 y(con)m(text.)45 b(If)31 b Fq(\014lename)36 b Ft(do)s(es)31
+3775 y(con)m(text.)45 b(If)31 b Fq(\014lename)36 b Ft(do)s(es)31
b(not)g(con)m(tain)h(a)f(slash,)g(the)h Fs(PATH)e Ft(v)-5
-b(ariable)30 b(is)g(used)g(to)i(\014nd)630 3837 y Fq(\014lename)p
+b(ariable)30 b(is)g(used)g(to)i(\014nd)630 3885 y Fq(\014lename)p
Ft(.)51 b(When)34 b(Bash)g(is)g(not)g(in)f Fl(posix)g
Ft(mo)s(de,)i(the)g(curren)m(t)f(directory)f(is)g(searc)m(hed)630
-3946 y(if)d Fq(\014lename)35 b Ft(is)30 b(not)i(found)d(in)h
+3994 y(if)d Fq(\014lename)35 b Ft(is)30 b(not)i(found)d(in)h
Fs($PATH)p Ft(.)41 b(If)31 b(an)m(y)g Fq(argumen)m(ts)k
-Ft(are)c(supplied,)d(they)k(b)s(ecome)630 4056 y(the)e(p)s(ositional)e
+Ft(are)c(supplied,)d(they)k(b)s(ecome)630 4104 y(the)e(p)s(ositional)e
(parameters)j(when)e Fq(\014lename)34 b Ft(is)29 b(executed.)42
-b(Otherwise)29 b(the)h(p)s(ositional)630 4166 y(parameters)43
+b(Otherwise)29 b(the)h(p)s(ositional)630 4213 y(parameters)43
b(are)h(unc)m(hanged.)79 b(The)42 b(return)g(status)i(is)e(the)h(exit)g
-(status)h(of)f(the)g(last)630 4275 y(command)37 b(executed,)k(or)c
+(status)h(of)f(the)g(last)630 4323 y(command)37 b(executed,)k(or)c
(zero)h(if)f(no)g(commands)g(are)h(executed.)63 b(If)36
-b Fq(\014lename)42 b Ft(is)37 b(not)630 4385 y(found,)22
+b Fq(\014lename)42 b Ft(is)37 b(not)630 4433 y(found,)22
b(or)f(cannot)g(b)s(e)f(read,)j(the)e(return)f(status)h(is)f(non-zero.)
38 b(This)19 b(builtin)f(is)h(equiv)-5 b(alen)m(t)630
-4494 y(to)31 b Fs(source)p Ft(.)150 4667 y Fs(break)870
-4808 y(break)46 b([)p Fj(n)11 b Fs(])630 4949 y Ft(Exit)44
+4542 y(to)31 b Fs(source)p Ft(.)150 4699 y Fs(break)870
+4831 y(break)46 b([)p Fj(n)11 b Fs(])630 4964 y Ft(Exit)44
b(from)g(a)g Fs(for)p Ft(,)k Fs(while)p Ft(,)e Fs(until)p
Ft(,)h(or)d Fs(select)f Ft(lo)s(op.)82 b(If)44 b Fq(n)g
-Ft(is)f(supplied,)i(the)g Fq(n)p Ft(th)630 5058 y(enclosing)39
+Ft(is)f(supplied,)i(the)g Fq(n)p Ft(th)630 5074 y(enclosing)39
b(lo)s(op)g(is)h(exited.)69 b Fq(n)40 b Ft(m)m(ust)g(b)s(e)f(greater)j
(than)d(or)i(equal)e(to)i(1.)70 b(The)40 b(return)630
-5168 y(status)31 b(is)e(zero)i(unless)e Fq(n)h Ft(is)f(not)i(greater)g
+5184 y(status)31 b(is)e(zero)i(unless)e Fq(n)h Ft(is)f(not)i(greater)g
(than)g(or)f(equal)g(to)h(1.)150 5340 y Fs(cd)p eop
%%Page: 34 40
34 39 bop 150 -116 a Ft(34)2572 b(Bash)31 b(Reference)g(Man)m(ual)870
y Ft(In)m(v)m(ok)m(e)34 b(an)f(editor)f(on)h(the)g(curren)m(t)f
(command)h(line,)f(and)g(execute)i(the)f(result)f(as)h(shell)630
2016 y(commands.)81 b(Bash)44 b(attempts)h(to)g(in)m(v)m(ok)m(e)g
-Fs($FCEDIT)p Ft(,)g Fs($EDITOR)p Ft(,)h(and)d Fs(emacs)g
+Fs($VISUAL)p Ft(,)g Fs($EDITOR)p Ft(,)h(and)d Fs(emacs)g
Ft(as)h(the)630 2125 y(editor,)30 b(in)f(that)i(order.)150
2363 y Fr(8.5)68 b(Readline)47 b(vi)e(Mo)t(de)275 2600
y Ft(While)22 b(the)i(Readline)e(library)f(do)s(es)j(not)g(ha)m(v)m(e)g
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2004 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.
extern int _rl_doing_an_undo;
extern int _rl_undo_group_level;
+/* vi_mode.c */
+extern int _rl_vi_last_command;
+
#endif /* _RL_PRIVATE_H_ */
--- /dev/null
+/* rlprivate.h -- functions and variables global to the readline library,
+ but not intended for use by applications. */
+
+/* Copyright (C) 1999-2004 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 2, 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,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RL_PRIVATE_H_)
+#define _RL_PRIVATE_H_
+
+#include "rlconf.h" /* for VISIBLE_STATS */
+#include "rlstdc.h"
+#include "posixjmp.h" /* defines procenv_t */
+
+/*************************************************************************
+ * *
+ * Global functions undocumented in texinfo manual and not in readline.h *
+ * *
+ *************************************************************************/
+
+/*************************************************************************
+ * *
+ * Global variables undocumented in texinfo manual and not in readline.h *
+ * *
+ *************************************************************************/
+
+/* complete.c */
+extern int rl_complete_with_tilde_expansion;
+#if defined (VISIBLE_STATS)
+extern int rl_visible_stats;
+#endif /* VISIBLE_STATS */
+
+/* readline.c */
+extern int rl_line_buffer_len;
+extern int rl_arg_sign;
+extern int rl_visible_prompt_length;
+extern int readline_echoing_p;
+extern int rl_key_sequence_length;
+extern int rl_byte_oriented;
+
+/* display.c */
+extern int rl_display_fixed;
+
+/* parens.c */
+extern int rl_blink_matching_paren;
+
+/*************************************************************************
+ * *
+ * Global functions and variables unsed and undocumented *
+ * *
+ *************************************************************************/
+
+/* kill.c */
+extern int rl_set_retained_kills PARAMS((int));
+
+/* terminal.c */
+extern void _rl_set_screen_size PARAMS((int, int));
+
+/* undo.c */
+extern int _rl_fix_last_undo_of_type PARAMS((int, int, int));
+
+/* util.c */
+extern char *_rl_savestring PARAMS((const char *));
+
+/*************************************************************************
+ * *
+ * Functions and variables private to the readline library *
+ * *
+ *************************************************************************/
+
+/* NOTE: Functions and variables prefixed with `_rl_' are
+ pseudo-global: they are global so they can be shared
+ between files in the readline library, but are not intended
+ to be visible to readline callers. */
+
+/*************************************************************************
+ * Undocumented private functions *
+ *************************************************************************/
+
+#if defined(READLINE_CALLBACKS)
+
+/* readline.c */
+extern void readline_internal_setup PARAMS((void));
+extern char *readline_internal_teardown PARAMS((int));
+extern int readline_internal_char PARAMS((void));
+
+#endif /* READLINE_CALLBACKS */
+
+/* bind.c */
+
+/* complete.c */
+extern char _rl_find_completion_word PARAMS((int *, int *));
+extern void _rl_free_match_list PARAMS((char **));
+
+/* display.c */
+extern char *_rl_strip_prompt PARAMS((char *));
+extern void _rl_move_cursor_relative PARAMS((int, const char *));
+extern void _rl_move_vert PARAMS((int));
+extern void _rl_save_prompt PARAMS((void));
+extern void _rl_restore_prompt PARAMS((void));
+extern char *_rl_make_prompt_for_search PARAMS((int));
+extern void _rl_erase_at_end_of_line PARAMS((int));
+extern void _rl_clear_to_eol PARAMS((int));
+extern void _rl_clear_screen PARAMS((void));
+extern void _rl_update_final PARAMS((void));
+extern void _rl_redisplay_after_sigwinch PARAMS((void));
+extern void _rl_clean_up_for_exit PARAMS((void));
+extern void _rl_erase_entire_line PARAMS((void));
+extern int _rl_current_display_line PARAMS((void));
+
+/* input.c */
+extern int _rl_any_typein PARAMS((void));
+extern int _rl_input_available PARAMS((void));
+extern int _rl_input_queued PARAMS((int));
+extern void _rl_insert_typein PARAMS((int));
+extern int _rl_unget_char PARAMS((int));
+extern int _rl_pushed_input_available PARAMS((void));
+
+/* macro.c */
+extern void _rl_with_macro_input PARAMS((char *));
+extern int _rl_next_macro_key PARAMS((void));
+extern void _rl_push_executing_macro PARAMS((void));
+extern void _rl_pop_executing_macro PARAMS((void));
+extern void _rl_add_macro_char PARAMS((int));
+extern void _rl_kill_kbd_macro PARAMS((void));
+
+/* misc.c */
+extern int _rl_init_argument PARAMS((void));
+extern void _rl_start_using_history PARAMS((void));
+extern int _rl_free_saved_history_line PARAMS((void));
+extern void _rl_set_insert_mode PARAMS((int, int));
+
+/* nls.c */
+extern int _rl_init_eightbit PARAMS((void));
+
+/* parens.c */
+extern void _rl_enable_paren_matching PARAMS((int));
+
+/* readline.c */
+extern void _rl_init_line_state PARAMS((void));
+extern void _rl_set_the_line PARAMS((void));
+extern int _rl_dispatch PARAMS((int, Keymap));
+extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
+
+/* rltty.c */
+extern int _rl_disable_tty_signals PARAMS((void));
+extern int _rl_restore_tty_signals PARAMS((void));
+
+/* terminal.c */
+extern void _rl_get_screen_size PARAMS((int, int));
+extern int _rl_init_terminal_io PARAMS((const char *));
+#ifdef _MINIX
+extern void _rl_output_character_function PARAMS((int));
+#else
+extern int _rl_output_character_function PARAMS((int));
+#endif
+extern void _rl_output_some_chars PARAMS((const char *, int));
+extern int _rl_backspace PARAMS((int));
+extern void _rl_enable_meta_key PARAMS((void));
+extern void _rl_control_keypad PARAMS((int));
+extern void _rl_set_cursor PARAMS((int, int));
+
+/* text.c */
+extern void _rl_fix_point PARAMS((int));
+extern int _rl_replace_text PARAMS((const char *, int, int));
+extern int _rl_insert_char PARAMS((int, int));
+extern int _rl_overwrite_char PARAMS((int, int));
+extern int _rl_overwrite_rubout PARAMS((int, int));
+extern int _rl_rubout_char PARAMS((int, int));
+#if defined (HANDLE_MULTIBYTE)
+extern int _rl_char_search_internal PARAMS((int, int, char *, int));
+#else
+extern int _rl_char_search_internal PARAMS((int, int, int));
+#endif
+extern int _rl_set_mark_at_pos PARAMS((int));
+
+/* util.c */
+extern int _rl_abort_internal PARAMS((void));
+extern char *_rl_strindex PARAMS((const char *, const char *));
+extern int _rl_qsort_string_compare PARAMS((char **, char **));
+extern int (_rl_uppercase_p) PARAMS((int));
+extern int (_rl_lowercase_p) PARAMS((int));
+extern int (_rl_pure_alphabetic) PARAMS((int));
+extern int (_rl_digit_p) PARAMS((int));
+extern int (_rl_to_lower) PARAMS((int));
+extern int (_rl_to_upper) PARAMS((int));
+extern int (_rl_digit_value) PARAMS((int));
+
+/* vi_mode.c */
+extern void _rl_vi_initialize_line PARAMS((void));
+extern void _rl_vi_reset_last PARAMS((int));
+extern void _rl_vi_set_last PARAMS((int, int, int));
+extern int _rl_vi_textmod_command PARAMS((int));
+extern void _rl_vi_done_inserting PARAMS((void));
+
+/*************************************************************************
+ * Undocumented private variables *
+ *************************************************************************/
+
+/* bind.c */
+extern const char *_rl_possible_control_prefixes[];
+extern const char *_rl_possible_meta_prefixes[];
+
+/* complete.c */
+extern int _rl_complete_show_all;
+extern int _rl_complete_show_unmodified;
+extern int _rl_complete_mark_directories;
+extern int _rl_complete_mark_symlink_dirs;
+extern int _rl_print_completions_horizontally;
+extern int _rl_completion_case_fold;
+extern int _rl_match_hidden_files;
+extern int _rl_page_completions;
+
+/* display.c */
+extern int _rl_vis_botlin;
+extern int _rl_last_c_pos;
+extern int _rl_suppress_redisplay;
+extern char *rl_display_prompt;
+
+/* isearch.c */
+extern char *_rl_isearch_terminators;
+
+/* macro.c */
+extern char *_rl_executing_macro;
+
+/* misc.c */
+extern int _rl_history_preserve_point;
+extern int _rl_history_saved_point;
+
+/* readline.c */
+extern int _rl_horizontal_scroll_mode;
+extern int _rl_mark_modified_lines;
+extern int _rl_bell_preference;
+extern int _rl_meta_flag;
+extern int _rl_convert_meta_chars_to_ascii;
+extern int _rl_output_meta_chars;
+extern char *_rl_comment_begin;
+extern unsigned char _rl_parsing_conditionalized_out;
+extern Keymap _rl_keymap;
+extern FILE *_rl_in_stream;
+extern FILE *_rl_out_stream;
+extern int _rl_last_command_was_kill;
+extern int _rl_eof_char;
+extern procenv_t readline_top_level;
+
+/* terminal.c */
+extern int _rl_enable_keypad;
+extern int _rl_enable_meta;
+extern char *_rl_term_clreol;
+extern char *_rl_term_clrpag;
+extern char *_rl_term_im;
+extern char *_rl_term_ic;
+extern char *_rl_term_ei;
+extern char *_rl_term_DC;
+extern char *_rl_term_up;
+extern char *_rl_term_dc;
+extern char *_rl_term_cr;
+extern char *_rl_term_IC;
+extern int _rl_screenheight;
+extern int _rl_screenwidth;
+extern int _rl_screenchars;
+extern int _rl_terminal_can_insert;
+extern int _rl_term_autowrap;
+
+/* undo.c */
+extern int _rl_doing_an_undo;
+extern int _rl_undo_group_level;
+
+/* vi_mode.c */
+extern int _rl_vi_last_command;
+
+#endif /* _RL_PRIVATE_H_ */
/* text.c -- text handling commands for readline. */
-/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2004 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.
if (rl_editing_mode == vi_mode)
{
_rl_vi_done_inserting ();
- _rl_vi_reset_last ();
+ if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
+ _rl_vi_reset_last ();
}
#endif /* VI_MODE */
--- /dev/null
+/* text.c -- text handling commands for readline. */
+
+/* Copyright (C) 1987-2002 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 2, 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,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+# include <config.h>
+#endif
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_LOCALE_H)
+# include <locale.h>
+#endif
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+#if defined (__EMX__)
+# define INCL_DOSPROCESS
+# include <os2.h>
+#endif /* __EMX__ */
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
+/* Forward declarations. */
+static int rl_change_case PARAMS((int, int));
+static int _rl_char_search PARAMS((int, int, int));
+
+/* **************************************************************** */
+/* */
+/* Insert and Delete */
+/* */
+/* **************************************************************** */
+
+/* Insert a string of text into the line at point. This is the only
+ way that you should do insertion. _rl_insert_char () calls this
+ function. Returns the number of characters inserted. */
+int
+rl_insert_text (string)
+ const char *string;
+{
+ register int i, l;
+
+ l = (string && *string) ? strlen (string) : 0;
+ if (l == 0)
+ return 0;
+
+ if (rl_end + l >= rl_line_buffer_len)
+ rl_extend_line_buffer (rl_end + l);
+
+ for (i = rl_end; i >= rl_point; i--)
+ rl_line_buffer[i + l] = rl_line_buffer[i];
+ strncpy (rl_line_buffer + rl_point, string, l);
+
+ /* Remember how to undo this if we aren't undoing something. */
+ if (_rl_doing_an_undo == 0)
+ {
+ /* If possible and desirable, concatenate the undos. */
+ if ((l == 1) &&
+ rl_undo_list &&
+ (rl_undo_list->what == UNDO_INSERT) &&
+ (rl_undo_list->end == rl_point) &&
+ (rl_undo_list->end - rl_undo_list->start < 20))
+ rl_undo_list->end++;
+ else
+ rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
+ }
+ rl_point += l;
+ rl_end += l;
+ rl_line_buffer[rl_end] = '\0';
+ return l;
+}
+
+/* Delete the string between FROM and TO. FROM is inclusive, TO is not.
+ Returns the number of characters deleted. */
+int
+rl_delete_text (from, to)
+ int from, to;
+{
+ register char *text;
+ register int diff, i;
+
+ /* Fix it if the caller is confused. */
+ if (from > to)
+ SWAP (from, to);
+
+ /* fix boundaries */
+ if (to > rl_end)
+ {
+ to = rl_end;
+ if (from > to)
+ from = to;
+ }
+ if (from < 0)
+ from = 0;
+
+ text = rl_copy_text (from, to);
+
+ /* Some versions of strncpy() can't handle overlapping arguments. */
+ diff = to - from;
+ for (i = from; i < rl_end - diff; i++)
+ rl_line_buffer[i] = rl_line_buffer[i + diff];
+
+ /* Remember how to undo this delete. */
+ if (_rl_doing_an_undo == 0)
+ rl_add_undo (UNDO_DELETE, from, to, text);
+ else
+ free (text);
+
+ rl_end -= diff;
+ rl_line_buffer[rl_end] = '\0';
+ return (diff);
+}
+
+/* Fix up point so that it is within the line boundaries after killing
+ text. If FIX_MARK_TOO is non-zero, the mark is forced within line
+ boundaries also. */
+
+#define _RL_FIX_POINT(x) \
+ do { \
+ if (x > rl_end) \
+ x = rl_end; \
+ else if (x < 0) \
+ x = 0; \
+ } while (0)
+
+void
+_rl_fix_point (fix_mark_too)
+ int fix_mark_too;
+{
+ _RL_FIX_POINT (rl_point);
+ if (fix_mark_too)
+ _RL_FIX_POINT (rl_mark);
+}
+#undef _RL_FIX_POINT
+
+/* Replace the contents of the line buffer between START and END with
+ TEXT. The operation is undoable. To replace the entire line in an
+ undoable mode, use _rl_replace_text(text, 0, rl_end); */
+int
+_rl_replace_text (text, start, end)
+ const char *text;
+ int start, end;
+{
+ int n;
+
+ rl_begin_undo_group ();
+ rl_delete_text (start, end + 1);
+ rl_point = start;
+ n = rl_insert_text (text);
+ rl_end_undo_group ();
+
+ return n;
+}
+
+/* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
+ non-zero, we free the current undo list. */
+void
+rl_replace_line (text, clear_undo)
+ const char *text;
+ int clear_undo;
+{
+ int len;
+
+ len = strlen (text);
+ if (len >= rl_line_buffer_len)
+ rl_extend_line_buffer (len);
+ strcpy (rl_line_buffer, text);
+ rl_end = len;
+
+ if (clear_undo)
+ rl_free_undo_list ();
+
+ _rl_fix_point (1);
+}
+
+/* **************************************************************** */
+/* */
+/* Readline character functions */
+/* */
+/* **************************************************************** */
+
+/* This is not a gap editor, just a stupid line input routine. No hair
+ is involved in writing any of the functions, and none should be. */
+
+/* Note that:
+
+ rl_end is the place in the string that we would place '\0';
+ i.e., it is always safe to place '\0' there.
+
+ rl_point is the place in the string where the cursor is. Sometimes
+ this is the same as rl_end.
+
+ Any command that is called interactively receives two arguments.
+ The first is a count: the numeric arg pased to this command.
+ The second is the key which invoked this command.
+*/
+
+/* **************************************************************** */
+/* */
+/* Movement Commands */
+/* */
+/* **************************************************************** */
+
+/* Note that if you `optimize' the display for these functions, you cannot
+ use said functions in other functions which do not do optimizing display.
+ I.e., you will have to update the data base for rl_redisplay, and you
+ might as well let rl_redisplay do that job. */
+
+/* Move forward COUNT bytes. */
+int
+rl_forward_byte (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_backward_byte (-count, key));
+
+ if (count > 0)
+ {
+ int end = rl_point + count;
+#if defined (VI_MODE)
+ int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;
+#else
+ int lend = rl_end;
+#endif
+
+ if (end > lend)
+ {
+ rl_point = lend;
+ rl_ding ();
+ }
+ else
+ rl_point = end;
+ }
+
+ if (rl_end < 0)
+ rl_end = 0;
+
+ return 0;
+}
+
+#if defined (HANDLE_MULTIBYTE)
+/* Move forward COUNT characters. */
+int
+rl_forward_char (count, key)
+ int count, key;
+{
+ int point;
+
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ return (rl_forward_byte (count, key));
+
+ if (count < 0)
+ return (rl_backward_char (-count, key));
+
+ if (count > 0)
+ {
+ point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
+
+#if defined (VI_MODE)
+ if (rl_end <= point && rl_editing_mode == vi_mode)
+ point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
+#endif
+
+ if (rl_point == point)
+ rl_ding ();
+
+ rl_point = point;
+
+ if (rl_end < 0)
+ rl_end = 0;
+ }
+
+ return 0;
+}
+#else /* !HANDLE_MULTIBYTE */
+int
+rl_forward_char (count, key)
+ int count, key;
+{
+ return (rl_forward_byte (count, key));
+}
+#endif /* !HANDLE_MULTIBYTE */
+
+/* Backwards compatibility. */
+int
+rl_forward (count, key)
+ int count, key;
+{
+ return (rl_forward_char (count, key));
+}
+
+/* Move backward COUNT bytes. */
+int
+rl_backward_byte (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_forward_byte (-count, key));
+
+ if (count > 0)
+ {
+ if (rl_point < count)
+ {
+ rl_point = 0;
+ rl_ding ();
+ }
+ else
+ rl_point -= count;
+ }
+
+ if (rl_point < 0)
+ rl_point = 0;
+
+ return 0;
+}
+
+#if defined (HANDLE_MULTIBYTE)
+/* Move backward COUNT characters. */
+int
+rl_backward_char (count, key)
+ int count, key;
+{
+ int point;
+
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ return (rl_backward_byte (count, key));
+
+ if (count < 0)
+ return (rl_forward_char (-count, key));
+
+ if (count > 0)
+ {
+ point = rl_point;
+
+ while (count > 0 && point > 0)
+ {
+ point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
+ count--;
+ }
+ if (count > 0)
+ {
+ rl_point = 0;
+ rl_ding ();
+ }
+ else
+ rl_point = point;
+ }
+
+ return 0;
+}
+#else
+int
+rl_backward_char (count, key)
+ int count, key;
+{
+ return (rl_backward_byte (count, key));
+}
+#endif
+
+/* Backwards compatibility. */
+int
+rl_backward (count, key)
+ int count, key;
+{
+ return (rl_backward_char (count, key));
+}
+
+/* Move to the beginning of the line. */
+int
+rl_beg_of_line (count, key)
+ int count, key;
+{
+ rl_point = 0;
+ return 0;
+}
+
+/* Move to the end of the line. */
+int
+rl_end_of_line (count, key)
+ int count, key;
+{
+ rl_point = rl_end;
+ return 0;
+}
+
+/* XXX - these might need changes for multibyte characters */
+/* Move forward a word. We do what Emacs does. */
+int
+rl_forward_word (count, key)
+ int count, key;
+{
+ int c;
+
+ if (count < 0)
+ return (rl_backward_word (-count, key));
+
+ while (count)
+ {
+ if (rl_point == rl_end)
+ 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. */
+ c = rl_line_buffer[rl_point];
+ if (rl_alphabetic (c) == 0)
+ {
+ while (++rl_point < rl_end)
+ {
+ c = rl_line_buffer[rl_point];
+ if (rl_alphabetic (c))
+ break;
+ }
+ }
+
+ if (rl_point == rl_end)
+ return 0;
+
+ while (++rl_point < rl_end)
+ {
+ c = rl_line_buffer[rl_point];
+ if (rl_alphabetic (c) == 0)
+ break;
+ }
+ --count;
+ }
+
+ return 0;
+}
+
+/* Move backward a word. We do what Emacs does. */
+int
+rl_backward_word (count, key)
+ int count, key;
+{
+ int c;
+
+ if (count < 0)
+ return (rl_forward_word (-count, key));
+
+ while (count)
+ {
+ if (!rl_point)
+ return 0;
+
+ /* Like rl_forward_word (), except that we look at the characters
+ just before point. */
+
+ c = rl_line_buffer[rl_point - 1];
+ if (rl_alphabetic (c) == 0)
+ {
+ while (--rl_point)
+ {
+ c = rl_line_buffer[rl_point - 1];
+ if (rl_alphabetic (c))
+ break;
+ }
+ }
+
+ while (rl_point)
+ {
+ c = rl_line_buffer[rl_point - 1];
+ if (rl_alphabetic (c) == 0)
+ break;
+ else
+ --rl_point;
+ }
+
+ --count;
+ }
+
+ return 0;
+}
+
+/* Clear the current line. Numeric argument to C-l does this. */
+int
+rl_refresh_line (ignore1, ignore2)
+ int ignore1, ignore2;
+{
+ int curr_line;
+
+ curr_line = _rl_current_display_line ();
+
+ _rl_move_vert (curr_line);
+ _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
+
+ _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
+
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+
+ return 0;
+}
+
+/* C-l typed to a line without quoting clears the screen, and then reprints
+ the prompt and the current input line. Given a numeric arg, redraw only
+ the current line. */
+int
+rl_clear_screen (count, key)
+ int count, key;
+{
+ if (rl_explicit_arg)
+ {
+ rl_refresh_line (count, key);
+ return 0;
+ }
+
+ _rl_clear_screen (); /* calls termcap function to clear screen */
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+
+ return 0;
+}
+
+int
+rl_arrow_keys (count, c)
+ int count, c;
+{
+ int ch;
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ ch = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ switch (_rl_to_upper (ch))
+ {
+ case 'A':
+ rl_get_previous_history (count, ch);
+ break;
+
+ case 'B':
+ rl_get_next_history (count, ch);
+ break;
+
+ case 'C':
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_forward_char (count, ch);
+ else
+ rl_forward_byte (count, ch);
+ break;
+
+ case 'D':
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_backward_char (count, ch);
+ else
+ rl_backward_byte (count, ch);
+ break;
+
+ default:
+ rl_ding ();
+ }
+
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Text commands */
+/* */
+/* **************************************************************** */
+
+#ifdef HANDLE_MULTIBYTE
+static char pending_bytes[MB_LEN_MAX];
+static int pending_bytes_length = 0;
+static mbstate_t ps = {0};
+#endif
+
+/* Insert the character C at the current location, moving point forward.
+ If C introduces a multibyte sequence, we read the whole sequence and
+ then insert the multibyte char into the line buffer. */
+int
+_rl_insert_char (count, c)
+ int count, c;
+{
+ register int i;
+ char *string;
+#ifdef HANDLE_MULTIBYTE
+ int string_size;
+ char incoming[MB_LEN_MAX + 1];
+ int incoming_length = 0;
+ mbstate_t ps_back;
+ static int stored_count = 0;
+#endif
+
+ if (count <= 0)
+ return 0;
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ {
+ incoming[0] = c;
+ incoming[1] = '\0';
+ incoming_length = 1;
+ }
+ else
+ {
+ wchar_t wc;
+ size_t ret;
+
+ if (stored_count <= 0)
+ stored_count = count;
+ else
+ count = stored_count;
+
+ ps_back = ps;
+ pending_bytes[pending_bytes_length++] = c;
+ ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
+
+ if (ret == (size_t)-2)
+ {
+ /* Bytes too short to compose character, try to wait for next byte.
+ Restore the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ ps = ps_back;
+ return 1;
+ }
+ else if (ret == (size_t)-1)
+ {
+ /* Invalid byte sequence for the current locale. Treat first byte
+ as a single character. */
+ incoming[0] = pending_bytes[0];
+ incoming[1] = '\0';
+ incoming_length = 1;
+ pending_bytes_length--;
+ memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
+ /* Clear the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (ret == (size_t)0)
+ {
+ incoming[0] = '\0';
+ incoming_length = 0;
+ pending_bytes_length--;
+ /* Clear the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else
+ {
+ /* We successfully read a single multibyte character. */
+ memcpy (incoming, pending_bytes, pending_bytes_length);
+ incoming[pending_bytes_length] = '\0';
+ incoming_length = pending_bytes_length;
+ pending_bytes_length = 0;
+ }
+ }
+#endif /* HANDLE_MULTIBYTE */
+
+ /* If we can optimize, then do it. But don't let people crash
+ readline because of extra large arguments. */
+ if (count > 1 && count <= 1024)
+ {
+#if defined (HANDLE_MULTIBYTE)
+ string_size = count * incoming_length;
+ string = (char *)xmalloc (1 + string_size);
+
+ i = 0;
+ while (i < string_size)
+ {
+ strncpy (string + i, incoming, incoming_length);
+ i += incoming_length;
+ }
+ incoming_length = 0;
+ stored_count = 0;
+#else /* !HANDLE_MULTIBYTE */
+ string = (char *)xmalloc (1 + count);
+
+ for (i = 0; i < count; i++)
+ string[i] = c;
+#endif /* !HANDLE_MULTIBYTE */
+
+ string[i] = '\0';
+ rl_insert_text (string);
+ free (string);
+
+ return 0;
+ }
+
+ if (count > 1024)
+ {
+ int decreaser;
+#if defined (HANDLE_MULTIBYTE)
+ string_size = incoming_length * 1024;
+ string = (char *)xmalloc (1 + string_size);
+
+ i = 0;
+ while (i < string_size)
+ {
+ strncpy (string + i, incoming, incoming_length);
+ i += incoming_length;
+ }
+
+ while (count)
+ {
+ decreaser = (count > 1024) ? 1024 : count;
+ string[decreaser*incoming_length] = '\0';
+ rl_insert_text (string);
+ count -= decreaser;
+ }
+
+ free (string);
+ incoming_length = 0;
+ stored_count = 0;
+#else /* !HANDLE_MULTIBYTE */
+ char str[1024+1];
+
+ for (i = 0; i < 1024; i++)
+ str[i] = c;
+
+ while (count)
+ {
+ decreaser = (count > 1024 ? 1024 : count);
+ str[decreaser] = '\0';
+ rl_insert_text (str);
+ count -= decreaser;
+ }
+#endif /* !HANDLE_MULTIBYTE */
+
+ return 0;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ {
+#endif
+ /* We are inserting a single character.
+ If there is pending input, then make a string of all of the
+ pending characters that are bound to rl_insert, and insert
+ them all. */
+ if (_rl_any_typein ())
+ _rl_insert_typein (c);
+ else
+ {
+ /* Inserting a single character. */
+ char str[2];
+
+ str[1] = '\0';
+ str[0] = c;
+ rl_insert_text (str);
+ }
+#if defined (HANDLE_MULTIBYTE)
+ }
+ else
+ {
+ rl_insert_text (incoming);
+ stored_count = 0;
+ }
+#endif
+
+ return 0;
+}
+
+/* Overwrite the character at point (or next COUNT characters) with C.
+ If C introduces a multibyte character sequence, read the entire sequence
+ before starting the overwrite loop. */
+int
+_rl_overwrite_char (count, c)
+ int count, c;
+{
+ int i;
+#if defined (HANDLE_MULTIBYTE)
+ char mbkey[MB_LEN_MAX];
+ int k;
+
+ /* Read an entire multibyte character sequence to insert COUNT times. */
+ if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
+#endif
+
+ rl_begin_undo_group ();
+
+ for (i = 0; i < count; i++)
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_insert_text (mbkey);
+ else
+#endif
+ _rl_insert_char (1, c);
+
+ if (rl_point < rl_end)
+ rl_delete (1, c);
+ }
+
+ rl_end_undo_group ();
+
+ return 0;
+}
+
+int
+rl_insert (count, c)
+ int count, c;
+{
+ return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
+ : _rl_overwrite_char (count, c));
+}
+
+/* Insert the next typed character verbatim. */
+int
+rl_quoted_insert (count, key)
+ int count, key;
+{
+ int c;
+
+#if defined (HANDLE_SIGNALS)
+ _rl_disable_tty_signals ();
+#endif
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+#if defined (HANDLE_SIGNALS)
+ _rl_restore_tty_signals ();
+#endif
+
+ return (_rl_insert_char (count, c));
+}
+
+/* Insert a tab character. */
+int
+rl_tab_insert (count, key)
+ int count, key;
+{
+ return (_rl_insert_char (count, '\t'));
+}
+
+/* What to do when a NEWLINE is pressed. We accept the whole line.
+ KEY is the key that invoked this command. I guess it could have
+ meaning in the future. */
+int
+rl_newline (count, key)
+ int count, key;
+{
+ rl_done = 1;
+
+ if (_rl_history_preserve_point)
+ _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
+
+ RL_SETSTATE(RL_STATE_DONE);
+
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ {
+ _rl_vi_done_inserting ();
+ if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
+ _rl_vi_reset_last ();
+ }
+#endif /* VI_MODE */
+
+ /* If we've been asked to erase empty lines, suppress the final update,
+ since _rl_update_final calls rl_crlf(). */
+ if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
+ return 0;
+
+ if (readline_echoing_p)
+ _rl_update_final ();
+ return 0;
+}
+
+/* What to do for some uppercase characters, like meta characters,
+ and some characters appearing in emacs_ctlx_keymap. This function
+ is just a stub, you bind keys to it and the code in _rl_dispatch ()
+ is special cased. */
+int
+rl_do_lowercase_version (ignore1, ignore2)
+ int ignore1, ignore2;
+{
+ return 0;
+}
+
+/* This is different from what vi does, so the code's not shared. Emacs
+ rubout in overwrite mode has one oddity: it replaces a control
+ character that's displayed as two characters (^X) with two spaces. */
+int
+_rl_overwrite_rubout (count, key)
+ int count, key;
+{
+ int opoint;
+ int i, l;
+
+ if (rl_point == 0)
+ {
+ rl_ding ();
+ return 1;
+ }
+
+ opoint = rl_point;
+
+ /* L == number of spaces to insert */
+ for (i = l = 0; i < count; i++)
+ {
+ rl_backward_char (1, key);
+ l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
+ }
+
+ rl_begin_undo_group ();
+
+ if (count > 1 || rl_explicit_arg)
+ rl_kill_text (opoint, rl_point);
+ else
+ rl_delete_text (opoint, rl_point);
+
+ /* Emacs puts point at the beginning of the sequence of spaces. */
+ if (rl_point < rl_end)
+ {
+ opoint = rl_point;
+ _rl_insert_char (l, ' ');
+ rl_point = opoint;
+ }
+
+ rl_end_undo_group ();
+
+ return 0;
+}
+
+/* Rubout the character behind point. */
+int
+rl_rubout (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_delete (-count, key));
+
+ if (!rl_point)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ if (rl_insert_mode == RL_IM_OVERWRITE)
+ return (_rl_overwrite_rubout (count, key));
+
+ return (_rl_rubout_char (count, key));
+}
+
+int
+_rl_rubout_char (count, key)
+ int count, key;
+{
+ int orig_point;
+ unsigned char c;
+
+ /* Duplicated code because this is called from other parts of the library. */
+ if (count < 0)
+ return (rl_delete (-count, key));
+
+ if (rl_point == 0)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ if (count > 1 || rl_explicit_arg)
+ {
+ orig_point = rl_point;
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_backward_char (count, key);
+ else
+#endif
+ rl_backward_byte (count, key);
+ rl_kill_text (orig_point, rl_point);
+ }
+ else
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ {
+#endif
+ c = rl_line_buffer[--rl_point];
+ rl_delete_text (rl_point, rl_point + 1);
+#if defined (HANDLE_MULTIBYTE)
+ }
+ else
+ {
+ int orig_point;
+
+ orig_point = rl_point;
+ rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
+ c = rl_line_buffer[rl_point];
+ rl_delete_text (rl_point, orig_point);
+ }
+#endif /* HANDLE_MULTIBYTE */
+
+ /* I don't think that the hack for end of line is needed for
+ multibyte chars. */
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+#endif
+ if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
+ {
+ 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,
+ kill that many characters instead. */
+int
+rl_delete (count, key)
+ int count, key;
+{
+ int r;
+
+ if (count < 0)
+ return (_rl_rubout_char (-count, key));
+
+ if (rl_point == rl_end)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ if (count > 1 || rl_explicit_arg)
+ {
+ int orig_point = rl_point;
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_forward_char (count, key);
+ else
+#endif
+ rl_forward_byte (count, key);
+
+ r = rl_kill_text (orig_point, rl_point);
+ rl_point = orig_point;
+ return r;
+ }
+ else
+ {
+ int new_point;
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ new_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
+ else
+ new_point = rl_point + 1;
+
+ return (rl_delete_text (rl_point, new_point));
+ }
+}
+
+/* Delete the character under the cursor, unless the insertion
+ point is at the end of the line, in which case the character
+ behind the cursor is deleted. COUNT is obeyed and may be used
+ to delete forward or backward that many characters. */
+int
+rl_rubout_or_delete (count, key)
+ int count, key;
+{
+ if (rl_end != 0 && rl_point == rl_end)
+ return (_rl_rubout_char (count, key));
+ else
+ return (rl_delete (count, key));
+}
+
+/* Delete all spaces and tabs around point. */
+int
+rl_delete_horizontal_space (count, ignore)
+ int count, ignore;
+{
+ int start = rl_point;
+
+ while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
+ rl_point--;
+
+ start = rl_point;
+
+ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+
+ if (start != rl_point)
+ {
+ rl_delete_text (start, rl_point);
+ rl_point = start;
+ }
+ return 0;
+}
+
+/* Like the tcsh editing function delete-char-or-list. The eof character
+ is caught before this is invoked, so this really does the same thing as
+ delete-char-or-list-or-eof, as long as it's bound to the eof character. */
+int
+rl_delete_or_show_completions (count, key)
+ int count, key;
+{
+ if (rl_end != 0 && rl_point == rl_end)
+ return (rl_possible_completions (count, key));
+ else
+ return (rl_delete (count, key));
+}
+
+#ifndef RL_COMMENT_BEGIN_DEFAULT
+#define RL_COMMENT_BEGIN_DEFAULT "#"
+#endif
+
+/* Turn the current line into a comment in shell history.
+ A K*rn shell style function. */
+int
+rl_insert_comment (count, key)
+ int count, key;
+{
+ char *rl_comment_text;
+ int rl_comment_len;
+
+ rl_beg_of_line (1, key);
+ rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
+
+ if (rl_explicit_arg == 0)
+ rl_insert_text (rl_comment_text);
+ else
+ {
+ rl_comment_len = strlen (rl_comment_text);
+ if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
+ rl_delete_text (rl_point, rl_point + rl_comment_len);
+ else
+ rl_insert_text (rl_comment_text);
+ }
+
+ (*rl_redisplay_function) ();
+ rl_newline (1, '\n');
+
+ return (0);
+}
+
+/* **************************************************************** */
+/* */
+/* Changing Case */
+/* */
+/* **************************************************************** */
+
+/* The three kinds of things that we know how to do. */
+#define UpCase 1
+#define DownCase 2
+#define CapCase 3
+
+/* Uppercase the word at point. */
+int
+rl_upcase_word (count, key)
+ int count, key;
+{
+ return (rl_change_case (count, UpCase));
+}
+
+/* Lowercase the word at point. */
+int
+rl_downcase_word (count, key)
+ int count, key;
+{
+ return (rl_change_case (count, DownCase));
+}
+
+/* Upcase the first letter, downcase the rest. */
+int
+rl_capitalize_word (count, key)
+ int count, key;
+{
+ return (rl_change_case (count, CapCase));
+}
+
+/* The meaty function.
+ Change the case of COUNT words, performing OP on them.
+ 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;
+{
+ register int start, end;
+ int inword, c;
+
+ start = rl_point;
+ rl_forward_word (count, 0);
+ end = rl_point;
+
+ if (count < 0)
+ SWAP (start, end);
+
+ /* We are going to modify some text, so let's prepare to undo it. */
+ rl_modifying (start, end);
+
+ for (inword = 0; start < end; start++)
+ {
+ c = rl_line_buffer[start];
+ switch (op)
+ {
+ case UpCase:
+ rl_line_buffer[start] = _rl_to_upper (c);
+ break;
+
+ case DownCase:
+ rl_line_buffer[start] = _rl_to_lower (c);
+ break;
+
+ case CapCase:
+ rl_line_buffer[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c);
+ inword = rl_alphabetic (rl_line_buffer[start]);
+ break;
+
+ default:
+ rl_ding ();
+ return -1;
+ }
+ }
+ rl_point = end;
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Transposition */
+/* */
+/* **************************************************************** */
+
+/* Transpose the words at point. If point is at the end of the line,
+ transpose the two words before point. */
+int
+rl_transpose_words (count, key)
+ int count, key;
+{
+ char *word1, *word2;
+ int w1_beg, w1_end, w2_beg, w2_end;
+ int orig_point = rl_point;
+
+ if (!count)
+ return 0;
+
+ /* Find the two words. */
+ rl_forward_word (count, key);
+ w2_end = rl_point;
+ rl_backward_word (1, key);
+ w2_beg = rl_point;
+ rl_backward_word (count, key);
+ w1_beg = rl_point;
+ rl_forward_word (1, key);
+ w1_end = rl_point;
+
+ /* Do some check to make sure that there really are two words. */
+ if ((w1_beg == w2_beg) || (w2_beg < w1_end))
+ {
+ rl_ding ();
+ rl_point = orig_point;
+ return -1;
+ }
+
+ /* Get the text of the words. */
+ 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. */
+ rl_begin_undo_group ();
+
+ /* Do the stuff at word2 first, so that we don't have to worry
+ about word1 moving. */
+ rl_point = w2_beg;
+ rl_delete_text (w2_beg, w2_end);
+ rl_insert_text (word1);
+
+ rl_point = w1_beg;
+ rl_delete_text (w1_beg, w1_end);
+ rl_insert_text (word2);
+
+ /* This is exactly correct since the text before this point has not
+ changed in length. */
+ rl_point = w2_end;
+
+ /* I think that does it. */
+ rl_end_undo_group ();
+ free (word1);
+ free (word2);
+
+ return 0;
+}
+
+/* Transpose the characters at point. If point is at the end of the line,
+ then transpose the characters before point. */
+int
+rl_transpose_chars (count, key)
+ int count, key;
+{
+#if defined (HANDLE_MULTIBYTE)
+ char *dummy;
+ int i, prev_point;
+#else
+ char dummy[2];
+#endif
+ int char_length;
+
+ if (count == 0)
+ return 0;
+
+ if (!rl_point || rl_end < 2)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ rl_begin_undo_group ();
+
+ if (rl_point == rl_end)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
+ else
+ --rl_point;
+ count = 1;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ prev_point = rl_point;
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
+ else
+#endif
+ rl_point--;
+
+#if defined (HANDLE_MULTIBYTE)
+ char_length = prev_point - rl_point;
+ dummy = (char *)xmalloc (char_length + 1);
+ for (i = 0; i < char_length; i++)
+ dummy[i] = rl_line_buffer[rl_point + i];
+ dummy[i] = '\0';
+#else
+ dummy[0] = rl_line_buffer[rl_point];
+ dummy[char_length = 1] = '\0';
+#endif
+
+ rl_delete_text (rl_point, rl_point + char_length);
+
+ rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
+
+ _rl_fix_point (0);
+ rl_insert_text (dummy);
+ rl_end_undo_group ();
+
+#if defined (HANDLE_MULTIBYTE)
+ free (dummy);
+#endif
+
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Character Searching */
+/* */
+/* **************************************************************** */
+
+int
+#if defined (HANDLE_MULTIBYTE)
+_rl_char_search_internal (count, dir, smbchar, len)
+ int count, dir;
+ char *smbchar;
+ int len;
+#else
+_rl_char_search_internal (count, dir, schar)
+ int count, dir, schar;
+#endif
+{
+ int pos, inc;
+#if defined (HANDLE_MULTIBYTE)
+ int prepos;
+#endif
+
+ pos = rl_point;
+ inc = (dir < 0) ? -1 : 1;
+ while (count)
+ {
+ if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
+ {
+ rl_ding ();
+ return -1;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
+ : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
+#else
+ pos += inc;
+#endif
+ do
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
+#else
+ if (rl_line_buffer[pos] == schar)
+#endif
+ {
+ count--;
+ if (dir < 0)
+ rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
+ : pos;
+ else
+ rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
+ : pos;
+ break;
+ }
+#if defined (HANDLE_MULTIBYTE)
+ prepos = pos;
+#endif
+ }
+#if defined (HANDLE_MULTIBYTE)
+ while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
+ : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
+#else
+ while ((dir < 0) ? pos-- : ++pos < rl_end);
+#endif
+ }
+ return (0);
+}
+
+/* Search COUNT times for a character read from the current input stream.
+ FDIR is the direction to search if COUNT is non-negative; otherwise
+ the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
+ that there are two separate versions of this function. */
+#if defined (HANDLE_MULTIBYTE)
+static int
+_rl_char_search (count, fdir, bdir)
+ int count, fdir, bdir;
+{
+ char mbchar[MB_LEN_MAX];
+ int mb_len;
+
+ mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
+
+ if (count < 0)
+ return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
+ else
+ return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
+}
+#else /* !HANDLE_MULTIBYTE */
+static int
+_rl_char_search (count, fdir, bdir)
+ int count, fdir, bdir;
+{
+ int c;
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (count < 0)
+ return (_rl_char_search_internal (-count, bdir, c));
+ else
+ return (_rl_char_search_internal (count, fdir, c));
+}
+#endif /* !HANDLE_MULTIBYTE */
+
+int
+rl_char_search (count, key)
+ int count, key;
+{
+ return (_rl_char_search (count, FFIND, BFIND));
+}
+
+int
+rl_backward_char_search (count, key)
+ int count, key;
+{
+ return (_rl_char_search (count, BFIND, FFIND));
+}
+
+/* **************************************************************** */
+/* */
+/* The Mark and the Region. */
+/* */
+/* **************************************************************** */
+
+/* Set the mark at POSITION. */
+int
+_rl_set_mark_at_pos (position)
+ int position;
+{
+ if (position > rl_end)
+ return -1;
+
+ rl_mark = position;
+ return 0;
+}
+
+/* A bindable command to set the mark. */
+int
+rl_set_mark (count, key)
+ int count, key;
+{
+ return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
+}
+
+/* Exchange the position of mark and point. */
+int
+rl_exchange_point_and_mark (count, key)
+ int count, key;
+{
+ if (rl_mark > rl_end)
+ rl_mark = -1;
+
+ if (rl_mark == -1)
+ {
+ rl_ding ();
+ return -1;
+ }
+ else
+ SWAP (rl_point, rl_mark);
+
+ return 0;
+}
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2004 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.
#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
#endif
+int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
+
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
static char *vi_insert_buffer;
static int vi_insert_buffer_size;
-static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
static int _rl_vi_last_repeat = 1;
static int _rl_vi_last_arg_sign = 1;
static int _rl_vi_last_motion;
{
save = rl_numeric_arg;
rl_numeric_arg = _rl_digit_value (c);
+ rl_explicit_arg = 1;
rl_digit_loop1 ();
rl_numeric_arg *= save;
RL_SETSTATE(RL_STATE_MOREINPUT);
#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
#endif
+int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
+
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
static char *vi_insert_buffer;
static int vi_insert_buffer_size;
-static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
static int _rl_vi_last_repeat = 1;
static int _rl_vi_last_arg_sign = 1;
static int _rl_vi_last_motion;
{
save = rl_numeric_arg;
rl_numeric_arg = _rl_digit_value (c);
+ rl_explicit_arg = 1;
rl_digit_loop1 ();
rl_numeric_arg *= save;
RL_SETSTATE(RL_STATE_MOREINPUT);
/* `C' does not save the text inserted for undoing or redoing. */
if (_rl_uppercase_p (key) == 0)
_rl_vi_doing_insert = 1;
- _rl_vi_set_last (key, count, rl_arg_sign);
+ _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
rl_vi_insertion_mode (1, key);
}
else if (c == 'A')
n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
- timebuf[sizeof(timebuf) - 1] = '\0';
+ if (n == 0)
+ timebuf[0] = '\0';
+ else
+ timebuf[sizeof(timebuf) - 1] = '\0';
+
temp = savestring (timebuf);
goto add_string;
n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
free (timefmt);
- timebuf[sizeof(timebuf) - 1] = '\0';
+ if (n == 0)
+ timebuf[0] = '\0';
+ else
+ timebuf[sizeof(timebuf) - 1] = '\0';
+
if (promptvars || posixly_correct)
/* Make sure that expand_prompt_string is called with a
second argument of Q_DOUBLE_QUOTES if we use this
msgid "OLDPWD not set"
msgstr "OLDPWD not set"
-#: builtins/cd.def:350
+#: builtins/cd.def:357
#, c-format
msgid "write error: %s"
msgstr "write error: %s"
msgid "%s: not a shell builtin"
msgstr "%s: not a shell builtin"
-#: builtins/common.c:481
-#, c-format
-msgid "%s: could not get current directory: %s: %s\n"
+#: builtins/common.c:486
+#, fuzzy, c-format
+msgid "%s: error retrieving current directory: %s: %s\n"
msgstr "%s: could not get current directory: %s: %s\n"
-#: builtins/common.c:548 builtins/common.c:550
+#: builtins/common.c:553 builtins/common.c:555
#, c-format
msgid "%s: ambiguous job spec"
msgstr "%s: ambiguous job spec"
msgid "%s: history expansion failed"
msgstr "%s: history expansion failed"
-#: builtins/jobs.def:102
+#: builtins/jobs.def:99
msgid "no other options allowed with `-x'"
msgstr "no other options allowed with ‘\e[1m-x\e[0m’"
msgid "OLDPWD not set"
msgstr "OLDPWD not set"
-#: builtins/cd.def:350
+#: builtins/cd.def:357
#, c-format
msgid "write error: %s"
msgstr "write error: %s"
msgid "%s: not a shell builtin"
msgstr "%s: not a shell builtin"
-#: builtins/common.c:481
-#, c-format
-msgid "%s: could not get current directory: %s: %s\n"
+#: builtins/common.c:486
+#, fuzzy, c-format
+msgid "%s: error retrieving current directory: %s: %s\n"
msgstr "%s: could not get current directory: %s: %s\n"
-#: builtins/common.c:548 builtins/common.c:550
+#: builtins/common.c:553 builtins/common.c:555
#, c-format
msgid "%s: ambiguous job spec"
msgstr "%s: ambiguous job spec"
msgid "%s: history expansion failed"
msgstr "%s: history expansion failed"
-#: builtins/jobs.def:102
+#: builtins/jobs.def:99
msgid "no other options allowed with `-x'"
msgstr "no other options allowed with ‘-x’"
job 6 returns 0
Waiting for job 7
job 7 returns 0
+[1] Running sleep 5 &
+[2] Running sleep 5 &
+[3] Running sleep 5 &
+[4]- Running sleep 5 &
+[5]+ Running ( sleep 5; exit 4 ) &
+4
0
-./jobs.tests: line 15: wait: %1: no such job
-./jobs.tests: line 20: fg: no job control
+i killed it
+0
+./jobs.tests: line 19: wait: %1: no such job
+./jobs.tests: line 24: fg: no job control
wait-for-pid
wait-errors
-./jobs.tests: line 33: wait: `1-1': not a pid or valid job spec
-./jobs.tests: line 34: wait: `-4': not a pid or valid job spec
+./jobs.tests: line 37: wait: `1-1': not a pid or valid job spec
+./jobs.tests: line 38: wait: `-4': not a pid or valid job spec
wait-for-background-pids
async list wait-for-background-pids
async list wait for child
forked
wait-when-no-children
wait-for-job
-./jobs.tests: line 56: wait: %2: no such job
+./jobs.tests: line 60: wait: %2: no such job
127
async list wait-for-job
forked
fg-bg 4
sleep 5
fg-bg 5
-./jobs.tests: line 83: fg: %2: no such job
-./jobs.tests: line 84: bg: job 1 already in background
+./jobs.tests: line 87: fg: %2: no such job
+./jobs.tests: line 88: bg: job 1 already in background
fg-bg 6
-./jobs.tests: line 91: fg: -s: invalid option
+./jobs.tests: line 95: fg: -s: invalid option
fg: usage: fg [job_spec]
-./jobs.tests: line 92: bg: -s: invalid option
+./jobs.tests: line 96: bg: -s: invalid option
bg: usage: bg [job_spec]
-./jobs.tests: line 97: disown: -s: invalid option
+./jobs.tests: line 101: disown: -s: invalid option
disown: usage: disown [-h] [-ar] [jobspec ...]
-./jobs.tests: line 101: disown: %1: no such job
-./jobs.tests: line 104: disown: %2: no such job
+./jobs.tests: line 105: disown: %1: no such job
+./jobs.tests: line 108: disown: %2: no such job
wait-for-non-child
-./jobs.tests: line 107: wait: pid 1 is not a child of this shell
+./jobs.tests: line 111: wait: pid 1 is not a child of this shell
127
3 -- 1 2 3 -- 1 - 2 - 3
[1] Running sleep 300 &
[1] Running sleep 300 &
[2]- Running sleep 350 &
[3]+ Running sleep 400 &
-./jobs.tests: line 123: kill: %4: no such job
-./jobs.tests: line 125: jobs: %4: no such job
+./jobs.tests: line 127: kill: %4: no such job
+./jobs.tests: line 129: jobs: %4: no such job
current job:
[3]+ Running sleep 400 &
previous job:
# before 2.03
${THIS_SH} ./jobs3.sub
+# test out behavior of using job control notation when job control is not
+# active
+${THIS_SH} ./jobs4.sub
+
jobs
echo $?
--- /dev/null
+# test being able to use job control notation in jobs/kill/wait without
+# job control active, as the SUS requires
+
+sleep 5 &
+
+sleep 5 &
+sleep 5 &
+sleep 5 &
+(sleep 5 ; exit 4) &
+
+jobs
+
+wait %%
+echo $?
+
+wait %1
+echo $?
+
+wait
+
+cat &
+kill -1 %% && echo i killed it || echo could not kill it
ARRAY *array;
var = make_local_variable (name);
- if (var == 0)
+ if (var == 0 || array_p (var))
return var;
+
array = array_create ();
FREE (value_cell(var));