implement completely new multiline code by delaying history store
this commit is valgrind-tested
This commit is contained in:
parent
be8c2fa8c2
commit
e0196f47d5
6
check.t
6
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.697 2015/07/05 17:04:24 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.698 2015/07/05 19:37:11 tg Exp $
|
||||||
# -*- mode: sh -*-
|
# -*- mode: sh -*-
|
||||||
#-
|
#-
|
||||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
@ -30,7 +30,7 @@
|
|||||||
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
||||||
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)MIRBSD KSH R51 2015/06/28
|
@(#)MIRBSD KSH R51 2015/07/05
|
||||||
description:
|
description:
|
||||||
Check version of shell.
|
Check version of shell.
|
||||||
stdin:
|
stdin:
|
||||||
@ -39,7 +39,7 @@ name: KSH_VERSION
|
|||||||
category: shell:legacy-no
|
category: shell:legacy-no
|
||||||
---
|
---
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)LEGACY KSH R51 2015/06/28
|
@(#)LEGACY KSH R51 2015/07/05
|
||||||
description:
|
description:
|
||||||
Check version of legacy shell.
|
Check version of legacy shell.
|
||||||
stdin:
|
stdin:
|
||||||
|
8
edit.c
8
edit.c
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.286 2015/05/03 11:28:53 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.287 2015/07/05 19:37:13 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in later versions we might use libtermcap for this, but since external
|
* in later versions we might use libtermcap for this, but since external
|
||||||
@ -3054,7 +3054,7 @@ x_edit_line(int c MKSH_A_UNUSED)
|
|||||||
}
|
}
|
||||||
if (modified) {
|
if (modified) {
|
||||||
*xep = '\0';
|
*xep = '\0';
|
||||||
histsave(&source->line, xbuf, true, true);
|
histsave(&source->line, xbuf, HIST_STORE, true);
|
||||||
x_arg = 0;
|
x_arg = 0;
|
||||||
} else
|
} else
|
||||||
x_arg = source->line - (histptr - x_histp);
|
x_arg = source->line - (histptr - x_histp);
|
||||||
@ -4311,8 +4311,8 @@ vi_cmd(int argcnt, const char *cmd)
|
|||||||
return (-1);
|
return (-1);
|
||||||
if (modified) {
|
if (modified) {
|
||||||
es->cbuf[es->linelen] = '\0';
|
es->cbuf[es->linelen] = '\0';
|
||||||
histsave(&source->line, es->cbuf, true,
|
histsave(&source->line, es->cbuf,
|
||||||
true);
|
HIST_STORE, true);
|
||||||
} else
|
} else
|
||||||
argcnt = source->line + 1 -
|
argcnt = source->line + 1 -
|
||||||
(hlast - hnum);
|
(hlast - hnum);
|
||||||
|
6
funcs.c
6
funcs.c
@ -38,7 +38,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.275 2015/07/05 17:50:39 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.276 2015/07/05 19:37:14 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
@ -442,7 +442,7 @@ c_print(const char **wp)
|
|||||||
|
|
||||||
if (flags & PO_HIST) {
|
if (flags & PO_HIST) {
|
||||||
Xput(xs, xp, '\0');
|
Xput(xs, xp, '\0');
|
||||||
histsave(&source->line, Xstring(xs, xp), true, false);
|
histsave(&source->line, Xstring(xs, xp), HIST_STORE, false);
|
||||||
Xfree(xs, xp);
|
Xfree(xs, xp);
|
||||||
} else {
|
} else {
|
||||||
int len = Xlength(xs, xp);
|
int len = Xlength(xs, xp);
|
||||||
@ -2076,7 +2076,7 @@ c_read(const char **wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (savehist)
|
if (savehist)
|
||||||
histsave(&source->line, Xstring(xs, xp), true, false);
|
histsave(&source->line, Xstring(xs, xp), HIST_STORE, false);
|
||||||
|
|
||||||
ccp = cp = Xclose(xs, xp);
|
ccp = cp = Xclose(xs, xp);
|
||||||
expanding = false;
|
expanding = false;
|
||||||
|
66
histrap.c
66
histrap.c
@ -27,7 +27,7 @@
|
|||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.146 2015/07/05 17:04:26 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.147 2015/07/05 19:37:15 tg Exp $");
|
||||||
|
|
||||||
Trap sigtraps[ksh_NSIG + 1];
|
Trap sigtraps[ksh_NSIG + 1];
|
||||||
static struct sigaction Sigact_ign;
|
static struct sigaction Sigact_ign;
|
||||||
@ -380,7 +380,7 @@ hist_execute(char *cmd, Area *areap)
|
|||||||
last_line = hist_source->line;
|
last_line = hist_source->line;
|
||||||
}
|
}
|
||||||
|
|
||||||
histsave(&hist_source->line, cmd, true, true);
|
histsave(&hist_source->line, cmd, HIST_STORE, true);
|
||||||
/* now *histptr == cmd without all trailing newlines */
|
/* now *histptr == cmd without all trailing newlines */
|
||||||
afree(cmd, areap);
|
afree(cmd, areap);
|
||||||
cmd = *histptr;
|
cmd = *histptr;
|
||||||
@ -620,31 +620,67 @@ histsync(void)
|
|||||||
* save command in history
|
* save command in history
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
histsave(int *lnp, const char *cmd, bool dowrite MKSH_A_UNUSED, bool ignoredups)
|
histsave(int *lnp, const char *cmd, int svmode, bool ignoredups)
|
||||||
{
|
{
|
||||||
char **hp;
|
static char *enqueued = NULL;
|
||||||
char *c;
|
char **hp, *c;
|
||||||
const char *ccp;
|
const char *ccp;
|
||||||
|
|
||||||
|
if (svmode == HIST_APPEND) {
|
||||||
|
if (!enqueued)
|
||||||
|
svmode = HIST_STORE;
|
||||||
|
} else if (enqueued) {
|
||||||
|
c = enqueued;
|
||||||
|
enqueued = NULL;
|
||||||
|
--*lnp;
|
||||||
|
histsave(lnp, c, HIST_STORE, true);
|
||||||
|
afree(c, APERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (svmode == HIST_FLUSH)
|
||||||
|
return;
|
||||||
|
|
||||||
ccp = cmd + strlen(cmd);
|
ccp = cmd + strlen(cmd);
|
||||||
while (ccp > cmd && ccp[-1] == '\n')
|
while (ccp > cmd && ccp[-1] == '\n')
|
||||||
--ccp;
|
--ccp;
|
||||||
strndupx(c, cmd, ccp - cmd, APERM);
|
strndupx(c, cmd, ccp - cmd, APERM);
|
||||||
|
|
||||||
if (ignoredups && !strcmp(c, *histptr)
|
if (svmode != HIST_APPEND) {
|
||||||
|
if (ignoredups && !strcmp(c, *histptr)
|
||||||
#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY
|
#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY
|
||||||
&& !histsync()
|
&& !histsync()
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
|
afree(c, APERM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++*lnp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_PERSISTENT_HISTORY
|
||||||
|
if (svmode == HIST_STORE && histfd != -1)
|
||||||
|
writehistfile(*lnp, c);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (svmode == HIST_QUEUE || svmode == HIST_APPEND) {
|
||||||
|
size_t nenq, ncmd;
|
||||||
|
|
||||||
|
if (!enqueued) {
|
||||||
|
if (*c)
|
||||||
|
enqueued = c;
|
||||||
|
else
|
||||||
|
afree(c, APERM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nenq = strlen(enqueued);
|
||||||
|
ncmd = strlen(c);
|
||||||
|
enqueued = aresize(enqueued, nenq + 1 + ncmd + 1, APERM);
|
||||||
|
enqueued[nenq] = '\n';
|
||||||
|
memcpy(enqueued + nenq + 1, c, ncmd + 1);
|
||||||
afree(c, APERM);
|
afree(c, APERM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
++*lnp;
|
|
||||||
|
|
||||||
#if HAVE_PERSISTENT_HISTORY
|
|
||||||
if (dowrite && histfd != -1)
|
|
||||||
writehistfile(*lnp, c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hp = histptr;
|
hp = histptr;
|
||||||
|
|
||||||
@ -855,7 +891,7 @@ histload(Source *s, unsigned char *base, size_t bytes)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s->line = lno--;
|
s->line = lno--;
|
||||||
histsave(&lno, (char *)(base + 4), false, false);
|
histsave(&lno, (char *)(base + 4), HIST_NOTE, false);
|
||||||
}
|
}
|
||||||
/* advance base pointer past NUL */
|
/* advance base pointer past NUL */
|
||||||
bytes -= ++cp - base;
|
bytes -= ++cp - base;
|
||||||
|
13
lex.c
13
lex.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.202 2015/07/05 13:49:42 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.203 2015/07/05 19:37:16 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* states while lexing word
|
* states while lexing word
|
||||||
@ -1461,11 +1461,16 @@ getsc_line(Source *s)
|
|||||||
if (s->type == SFILE)
|
if (s->type == SFILE)
|
||||||
shf_fdclose(s->u.shf);
|
shf_fdclose(s->u.shf);
|
||||||
s->str = NULL;
|
s->str = NULL;
|
||||||
} else if (interactive && *s->str &&
|
} else if (interactive && *s->str) {
|
||||||
(cur_prompt != PS1 || !ctype(*s->str, C_IFS | C_IFSWS))) {
|
if (cur_prompt != PS1)
|
||||||
histsave(&s->line, s->str, true, true);
|
histsave(&s->line, s->str, HIST_APPEND, true);
|
||||||
|
else if (!ctype(*s->str, C_IFS | C_IFSWS))
|
||||||
|
histsave(&s->line, s->str, HIST_QUEUE, true);
|
||||||
#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY
|
#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY
|
||||||
|
else
|
||||||
|
goto check_for_sole_return;
|
||||||
} else if (interactive && cur_prompt == PS1) {
|
} else if (interactive && cur_prompt == PS1) {
|
||||||
|
check_for_sole_return:
|
||||||
cp = Xstring(s->xs, xp);
|
cp = Xstring(s->xs, xp);
|
||||||
while (*cp && ctype(*cp, C_IFSWS))
|
while (*cp && ctype(*cp, C_IFSWS))
|
||||||
++cp;
|
++cp;
|
||||||
|
4
main.c
4
main.c
@ -34,7 +34,7 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.293 2015/04/29 20:07:33 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.294 2015/07/05 19:37:16 tg Exp $");
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
@ -803,6 +803,8 @@ shell(Source * volatile s, volatile bool toplevel)
|
|||||||
set_prompt(PS1, s);
|
set_prompt(PS1, s);
|
||||||
}
|
}
|
||||||
t = compile(s, sfirst);
|
t = compile(s, sfirst);
|
||||||
|
if (interactive)
|
||||||
|
histsave(&s->line, NULL, HIST_FLUSH, true);
|
||||||
sfirst = false;
|
sfirst = false;
|
||||||
if (!t)
|
if (!t)
|
||||||
goto source_no_tree;
|
goto source_no_tree;
|
||||||
|
5
mksh.1
5
mksh.1
@ -1,4 +1,4 @@
|
|||||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.371 2015/07/05 17:50:40 tg Exp $
|
.\" $MirOS: src/bin/mksh/mksh.1,v 1.372 2015/07/05 19:37:17 tg Exp $
|
||||||
.\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $
|
.\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $
|
||||||
.\"-
|
.\"-
|
||||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
@ -1859,7 +1859,8 @@ below for more information.
|
|||||||
.It Ev HISTFILE
|
.It Ev HISTFILE
|
||||||
The name of the file used to store command history.
|
The name of the file used to store command history.
|
||||||
When assigned to or unset, the file is opened, history is truncated
|
When assigned to or unset, the file is opened, history is truncated
|
||||||
then loaded from the file; subsequent new lines are appended.
|
then loaded from the file; subsequent new commands (possibly consisting
|
||||||
|
of several lines) are appended once they successfully compiled.
|
||||||
Also, several invocations of the shell will share history if their
|
Also, several invocations of the shell will share history if their
|
||||||
.Ev HISTFILE
|
.Ev HISTFILE
|
||||||
parameters all point to the same file.
|
parameters all point to the same file.
|
||||||
|
13
sh.h
13
sh.h
@ -169,9 +169,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.732 2015/07/05 14:43:08 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.733 2015/07/05 19:37:18 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R51 2015/06/28"
|
#define MKSH_VERSION "R51 2015/07/05"
|
||||||
|
|
||||||
/* arithmetic types: C implementation */
|
/* arithmetic types: C implementation */
|
||||||
#if !HAVE_CAN_INTTYPES
|
#if !HAVE_CAN_INTTYPES
|
||||||
@ -1625,6 +1625,13 @@ EXTERN char **history; /* saved commands */
|
|||||||
EXTERN char **histptr; /* last history item */
|
EXTERN char **histptr; /* last history item */
|
||||||
EXTERN mksh_ari_t histsize; /* history size */
|
EXTERN mksh_ari_t histsize; /* history size */
|
||||||
|
|
||||||
|
/* flags to histsave */
|
||||||
|
#define HIST_FLUSH 0
|
||||||
|
#define HIST_QUEUE 1
|
||||||
|
#define HIST_APPEND 2
|
||||||
|
#define HIST_STORE 3
|
||||||
|
#define HIST_NOTE 4
|
||||||
|
|
||||||
/* user and system time of last j_waitjed job */
|
/* user and system time of last j_waitjed job */
|
||||||
EXTERN struct timeval j_usrtime, j_systime;
|
EXTERN struct timeval j_usrtime, j_systime;
|
||||||
|
|
||||||
@ -1751,7 +1758,7 @@ void hist_init(Source *);
|
|||||||
#if HAVE_PERSISTENT_HISTORY
|
#if HAVE_PERSISTENT_HISTORY
|
||||||
void hist_finish(void);
|
void hist_finish(void);
|
||||||
#endif
|
#endif
|
||||||
void histsave(int *, const char *, bool, bool);
|
void histsave(int *, const char *, int, bool);
|
||||||
#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY
|
#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY
|
||||||
bool histsync(void);
|
bool histsync(void);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user