implement completely new multiline code by delaying history store

this commit is valgrind-tested
This commit is contained in:
tg 2015-07-05 19:37:18 +00:00
parent be8c2fa8c2
commit e0196f47d5
8 changed files with 86 additions and 35 deletions

View File

@ -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 -*-
#-
# 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
expected-stdout:
@(#)MIRBSD KSH R51 2015/06/28
@(#)MIRBSD KSH R51 2015/07/05
description:
Check version of shell.
stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
@(#)LEGACY KSH R51 2015/06/28
@(#)LEGACY KSH R51 2015/07/05
description:
Check version of legacy shell.
stdin:

8
edit.c
View File

@ -28,7 +28,7 @@
#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
@ -3054,7 +3054,7 @@ x_edit_line(int c MKSH_A_UNUSED)
}
if (modified) {
*xep = '\0';
histsave(&source->line, xbuf, true, true);
histsave(&source->line, xbuf, HIST_STORE, true);
x_arg = 0;
} else
x_arg = source->line - (histptr - x_histp);
@ -4311,8 +4311,8 @@ vi_cmd(int argcnt, const char *cmd)
return (-1);
if (modified) {
es->cbuf[es->linelen] = '\0';
histsave(&source->line, es->cbuf, true,
true);
histsave(&source->line, es->cbuf,
HIST_STORE, true);
} else
argcnt = source->line + 1 -
(hlast - hnum);

View File

@ -38,7 +38,7 @@
#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
/*
@ -442,7 +442,7 @@ c_print(const char **wp)
if (flags & PO_HIST) {
Xput(xs, xp, '\0');
histsave(&source->line, Xstring(xs, xp), true, false);
histsave(&source->line, Xstring(xs, xp), HIST_STORE, false);
Xfree(xs, xp);
} else {
int len = Xlength(xs, xp);
@ -2076,7 +2076,7 @@ c_read(const char **wp)
}
if (savehist)
histsave(&source->line, Xstring(xs, xp), true, false);
histsave(&source->line, Xstring(xs, xp), HIST_STORE, false);
ccp = cp = Xclose(xs, xp);
expanding = false;

View File

@ -27,7 +27,7 @@
#include <sys/file.h>
#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];
static struct sigaction Sigact_ign;
@ -380,7 +380,7 @@ hist_execute(char *cmd, Area *areap)
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 */
afree(cmd, areap);
cmd = *histptr;
@ -620,31 +620,67 @@ histsync(void)
* save command in history
*/
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;
char *c;
static char *enqueued = NULL;
char **hp, *c;
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);
while (ccp > cmd && ccp[-1] == '\n')
--ccp;
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
&& !histsync()
&& !histsync()
#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);
return;
}
++*lnp;
#if HAVE_PERSISTENT_HISTORY
if (dowrite && histfd != -1)
writehistfile(*lnp, c);
#endif
hp = histptr;
@ -855,7 +891,7 @@ histload(Source *s, unsigned char *base, size_t bytes)
}
} else {
s->line = lno--;
histsave(&lno, (char *)(base + 4), false, false);
histsave(&lno, (char *)(base + 4), HIST_NOTE, false);
}
/* advance base pointer past NUL */
bytes -= ++cp - base;

13
lex.c
View File

@ -23,7 +23,7 @@
#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
@ -1461,11 +1461,16 @@ getsc_line(Source *s)
if (s->type == SFILE)
shf_fdclose(s->u.shf);
s->str = NULL;
} else if (interactive && *s->str &&
(cur_prompt != PS1 || !ctype(*s->str, C_IFS | C_IFSWS))) {
histsave(&s->line, s->str, true, true);
} else if (interactive && *s->str) {
if (cur_prompt != PS1)
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
else
goto check_for_sole_return;
} else if (interactive && cur_prompt == PS1) {
check_for_sole_return:
cp = Xstring(s->xs, xp);
while (*cp && ctype(*cp, C_IFSWS))
++cp;

4
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h>
#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;
@ -803,6 +803,8 @@ shell(Source * volatile s, volatile bool toplevel)
set_prompt(PS1, s);
}
t = compile(s, sfirst);
if (interactive)
histsave(&s->line, NULL, HIST_FLUSH, true);
sfirst = false;
if (!t)
goto source_no_tree;

5
mksh.1
View File

@ -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 $
.\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
@ -1859,7 +1859,8 @@ below for more information.
.It Ev HISTFILE
The name of the file used to store command history.
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
.Ev HISTFILE
parameters all point to the same file.

13
sh.h
View File

@ -169,9 +169,9 @@
#endif
#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
#define MKSH_VERSION "R51 2015/06/28"
#define MKSH_VERSION "R51 2015/07/05"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -1625,6 +1625,13 @@ EXTERN char **history; /* saved commands */
EXTERN char **histptr; /* last history item */
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 */
EXTERN struct timeval j_usrtime, j_systime;
@ -1751,7 +1758,7 @@ void hist_init(Source *);
#if HAVE_PERSISTENT_HISTORY
void hist_finish(void);
#endif
void histsave(int *, const char *, bool, bool);
void histsave(int *, const char *, int, bool);
#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY
bool histsync(void);
#endif