implement an extension that an interactive mode input line, when
starting with an ‘!’ exclamation mark at the beginning of a com- mand (PS1 not PS2), shall have the same effect as the predefined “r” alias, to be compatible with csh and GNU bash’s “!string” to «Execute last used command starting with string» – documentation and feature request provided by wbx@ (Waldemar Brodkorb)
This commit is contained in:
parent
b90007d784
commit
da5dc48cd0
109
check.t
109
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.280 2009/05/27 09:58:21 tg Stab $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.281 2009/05/27 19:52:35 tg Stab $
|
||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||
@ -5722,3 +5722,110 @@ expected-stdout:
|
||||
11 0
|
||||
12 0
|
||||
---
|
||||
name: event-subst-1a
|
||||
description:
|
||||
Check that '!' substitution in interactive mode works
|
||||
file-setup: file 755 "falsetto"
|
||||
echo molto bene
|
||||
exit 42
|
||||
file-setup: file 755 "!false"
|
||||
echo si
|
||||
arguments: !-i!
|
||||
stdin:
|
||||
export PATH=.:$PATH
|
||||
falsetto
|
||||
echo yeap
|
||||
!false
|
||||
expected-exit: 42
|
||||
expected-stdout:
|
||||
molto bene
|
||||
yeap
|
||||
molto bene
|
||||
expected-stderr-pattern:
|
||||
/.*/
|
||||
---
|
||||
name: event-subst-1b
|
||||
description:
|
||||
Check that '!' substitution in interactive mode works
|
||||
even when a space separates it from the search command,
|
||||
which is not what GNU bash provides but required for the
|
||||
other regression tests below to check
|
||||
file-setup: file 755 "falsetto"
|
||||
echo molto bene
|
||||
exit 42
|
||||
file-setup: file 755 "!"
|
||||
echo si
|
||||
arguments: !-i!
|
||||
stdin:
|
||||
export PATH=.:$PATH
|
||||
falsetto
|
||||
echo yeap
|
||||
! false
|
||||
expected-exit: 42
|
||||
expected-stdout:
|
||||
molto bene
|
||||
yeap
|
||||
molto bene
|
||||
expected-stderr-pattern:
|
||||
/.*/
|
||||
---
|
||||
name: event-subst-2
|
||||
description:
|
||||
Check that '!' substitution in interactive mode
|
||||
does not break things
|
||||
file-setup: file 755 "falsetto"
|
||||
echo molto bene
|
||||
exit 42
|
||||
file-setup: file 755 "!"
|
||||
echo si
|
||||
arguments: !-i!
|
||||
env-setup: !ENV=./Env!
|
||||
file-setup: file 644 "Env"
|
||||
PS1=X
|
||||
stdin:
|
||||
export PATH=.:$PATH
|
||||
falsetto
|
||||
echo yeap
|
||||
!false
|
||||
echo meow
|
||||
! false
|
||||
echo = $?
|
||||
if
|
||||
! false; then echo foo; else echo bar; fi
|
||||
expected-stdout:
|
||||
molto bene
|
||||
yeap
|
||||
molto bene
|
||||
meow
|
||||
molto bene
|
||||
= 42
|
||||
foo
|
||||
expected-stderr-pattern:
|
||||
/.*/
|
||||
---
|
||||
name: event-subst-3
|
||||
description:
|
||||
Check that '!' substitution in noninteractive mode is ignored
|
||||
file-setup: file 755 "falsetto"
|
||||
echo molto bene
|
||||
exit 42
|
||||
file-setup: file 755 "!false"
|
||||
echo si
|
||||
stdin:
|
||||
export PATH=.:$PATH
|
||||
falsetto
|
||||
echo yeap
|
||||
!false
|
||||
echo meow
|
||||
! false
|
||||
echo = $?
|
||||
if
|
||||
! false; then echo foo; else echo bar; fi
|
||||
expected-stdout:
|
||||
molto bene
|
||||
yeap
|
||||
si
|
||||
meow
|
||||
= 0
|
||||
foo
|
||||
---
|
||||
|
24
lex.c
24
lex.c
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.84 2009/05/27 09:58:22 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.85 2009/05/27 19:52:36 tg Exp $");
|
||||
|
||||
/*
|
||||
* states while lexing word
|
||||
@ -1189,7 +1189,7 @@ getsc__(void)
|
||||
static void
|
||||
getsc_line(Source *s)
|
||||
{
|
||||
char *xp = Xstring(s->xs, xp);
|
||||
char *xp = Xstring(s->xs, xp), *cp;
|
||||
int interactive = Flag(FTALKING) && s->type == SSTDIN;
|
||||
int have_tty = interactive && (s->flags & SF_TTY);
|
||||
|
||||
@ -1254,7 +1254,25 @@ getsc_line(Source *s)
|
||||
ksh_tmout_state = TMOUT_EXECUTING;
|
||||
alarm(0);
|
||||
}
|
||||
s->start = s->str = Xstring(s->xs, xp);
|
||||
cp = Xstring(s->xs, xp);
|
||||
if (interactive && *cp == '!' && cur_prompt == PS1) {
|
||||
int linelen;
|
||||
|
||||
linelen = Xlength(s->xs, xp);
|
||||
XcheckN(s->xs, xp, fc_e_n + /* NUL */ 1);
|
||||
/* reload after potential realloc */
|
||||
cp = Xstring(s->xs, xp);
|
||||
/* change initial '!' into space */
|
||||
*cp = ' ';
|
||||
/* NUL terminate the current string */
|
||||
*xp = '\0';
|
||||
/* move the actual string forward */
|
||||
memmove(cp + fc_e_n, cp, linelen + /* NUL */ 1);
|
||||
xp += fc_e_n;
|
||||
/* prepend it with "fc -e -" */
|
||||
memcpy(cp, fc_e_, fc_e_n);
|
||||
}
|
||||
s->start = s->str = cp;
|
||||
strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp));
|
||||
/* Note: if input is all nulls, this is not eof */
|
||||
if (Xlength(s->xs, xp) == 0) { /* EOF */
|
||||
|
4
main.c
4
main.c
@ -33,7 +33,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.128 2009/05/16 21:00:51 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.129 2009/05/27 19:52:37 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@ -69,7 +69,7 @@ static const char *initcoms[] = {
|
||||
"functions=typeset -f",
|
||||
"history=fc -l",
|
||||
"nohup=nohup ",
|
||||
"r=fc -e -",
|
||||
r_fc_e_,
|
||||
"source=PATH=$PATH:. command .",
|
||||
"login=exec login",
|
||||
NULL,
|
||||
|
9
mksh.1
9
mksh.1
@ -1,4 +1,4 @@
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.167 2009/05/21 14:28:34 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.168 2009/05/27 19:52:37 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.128 2009/03/06 12:28:36 jmc Exp $
|
||||
.\"-
|
||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
@ -48,7 +48,7 @@
|
||||
.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
|
||||
..
|
||||
.\"-
|
||||
.Dd $Mdocdate: May 21 2009 $
|
||||
.Dd $Mdocdate: May 27 2009 $
|
||||
.Dt MKSH 1
|
||||
.Os MirBSD
|
||||
.Sh NAME
|
||||
@ -2982,7 +2982,10 @@ and
|
||||
.Fl s
|
||||
is identical: re-execute the selected command without invoking an editor.
|
||||
This command is usually accessed with the predefined
|
||||
.Ic alias r=\*(aqfc \-e \-\*(aq .
|
||||
.Ic alias r=\*(aqfc \-e \-\*(aq
|
||||
or by prefixing an interactive mode input line with
|
||||
.Sq \&!
|
||||
.Pq wbx extension .
|
||||
.Pp
|
||||
.It Ic fg Op Ar job ...
|
||||
Resume the specified job(s) in the foreground.
|
||||
|
5
sh.h
5
sh.h
@ -122,7 +122,7 @@
|
||||
#define __SCCSID(x) __IDSTRING(sccsid,x)
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.303 2009/05/27 09:58:23 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.304 2009/05/27 19:52:38 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R38 2009/05/27"
|
||||
|
||||
@ -576,6 +576,9 @@ EXTERN char shell_flags[FNFLAGS];
|
||||
EXTERN char null[] I__("");
|
||||
/* helpers for string pooling */
|
||||
#define T_synerr "syntax error"
|
||||
EXTERN const char r_fc_e_[] I__("r=fc -e -");
|
||||
#define fc_e_ (r_fc_e_ + 2) /* "fc -e -" */
|
||||
#define fc_e_n 7 /* strlen(fc_e_) */
|
||||
|
||||
enum temp_type {
|
||||
TT_HEREDOC_EXP, /* expanded heredoc */
|
||||
|
Loading…
x
Reference in New Issue
Block a user