slightly optimised and, more importantly, much more consistent (use only

one set of CTRL, UNCTRL, and new ISCTRL macros) C0 and DEL handling; the
optimisation only works for 7-bit ASCII, so those places 8-bit must pass
intact have an added check

also, while here, remove an editor oops (‘;’), oksh rcsid sync (they did
accept I was right wrt. set -e), int → bool, and code merge/cleanup
This commit is contained in:
tg 2013-09-24 20:19:45 +00:00
parent 2e7509548a
commit 7f16464902
6 changed files with 68 additions and 76 deletions

11
check.t
View File

@ -1,8 +1,8 @@
# $MirOS: src/bin/mksh/check.t,v 1.632 2013/09/10 17:32:58 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.633 2013/09/24 20:19:40 tg Exp $
# $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 $
# $OpenBSD: regress.t,v 1.15 2013/07/01 17:25:27 jca Exp $
# $OpenBSD: regress.t,v 1.16 2013/09/14 20:09:30 millert Exp $
# $OpenBSD: obsd-regress.t,v 1.5 2013/07/01 17:25:27 jca Exp $
#-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -31,7 +31,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout:
@(#)MIRBSD KSH R48 2013/09/10
@(#)MIRBSD KSH R48 2013/09/24
description:
Check version of shell.
stdin:
@ -40,7 +40,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
@(#)LEGACY KSH R48 2013/09/10
@(#)LEGACY KSH R48 2013/09/24
description:
Check version of legacy shell.
stdin:
@ -4806,11 +4806,12 @@ description:
them exit 0. The POSIX behaviour is needed by BSD make.
stdin:
set -e
echo `false; echo hi`
echo `false; echo hi` $(<this-file-does-not-exist)
echo $?
expected-stdout:
0
expected-stderr-pattern: /this-file-does-not-exist/
---
name: regression-40
description:

105
edit.c
View File

@ -1,4 +1,4 @@
;/* $OpenBSD: edit.c,v 1.38 2013/06/03 15:41:59 tedu Exp $ */
/* $OpenBSD: edit.c,v 1.38 2013/06/03 15:41:59 tedu Exp $ */
/* $OpenBSD: edit.h,v 1.9 2011/05/30 17:14:35 martynas Exp $ */
/* $OpenBSD: emacs.c,v 1.44 2011/09/05 04:50:33 marco Exp $ */
/* $OpenBSD: vi.c,v 1.26 2009/06/29 22:50:19 martynas Exp $ */
@ -28,7 +28,7 @@
#ifndef MKSH_NO_CMDLINE_EDITING
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.271 2013/08/16 10:59:01 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.272 2013/09/24 20:19:42 tg Exp $");
/*
* in later versions we might use libtermcap for this, but since external
@ -966,7 +966,6 @@ static void x_bs3(char **);
static int x_size_str(char *);
static int x_size2(char *, char **);
static void x_zots(char *);
static void x_zotc2(int);
static void x_zotc3(char **);
static void x_load_hist(char **);
static int x_search(char *, int, int);
@ -1608,7 +1607,7 @@ x_size_str(char *cp)
static int
x_size2(char *cp, char **dcp)
{
int c = *(unsigned char *)cp;
uint8_t c = *(unsigned char *)cp;
if (UTFMODE && (c > 0x7F))
return (utf_widthadj(cp, (const char **)dcp));
@ -1617,7 +1616,7 @@ x_size2(char *cp, char **dcp)
if (c == '\t')
/* Kludge, tabs are always four spaces. */
return (4);
if (c < ' ' || c == 0x7f)
if (ISCTRL(c) && /* but not C1 */ c < 0x80)
/* control unsigned char */
return (2);
return (1);
@ -1633,19 +1632,6 @@ x_zots(char *str)
x_zotc3(&str);
}
static void
x_zotc2(int c)
{
if (c == '\t') {
/* Kludge, tabs are always four spaces. */
x_e_puts(" ");
} else if (c < ' ' || c == 0x7f) {
x_e_putc2('^');
x_e_putc2(UNCTRL(c));
} else
x_e_putc2(c);
}
static void
x_zotc3(char **cp)
{
@ -1655,7 +1641,7 @@ x_zotc3(char **cp)
/* Kludge, tabs are always four spaces. */
x_e_puts(" ");
(*cp)++;
} else if (c < ' ' || c == 0x7f) {
} else if (ISCTRL(c) && /* but not C1 */ c < 0x80) {
x_e_putc2('^');
x_e_putc2(UNCTRL(c));
(*cp)++;
@ -1767,7 +1753,10 @@ x_newline(int c MKSH_A_UNUSED)
static int
x_end_of_text(int c MKSH_A_UNUSED)
{
x_zotc2(edchars.eof);
char tmp = edchars.eof;
char *cp = &tmp;
x_zotc3(&cp);
x_putc('\r');
x_putc('\n');
x_flush();
@ -2379,6 +2368,7 @@ x_mapin(const char *cp, Area *ap)
/* XXX -- should handle \^ escape? */
if (*cp == '^') {
cp++;
/*XXX or ^^ escape? this is ugly. */
if (*cp >= '?')
/* includes '?'; ASCII */
*op++ = CTRL(*cp);
@ -2400,7 +2390,7 @@ x_mapout2(int c, char **buf)
{
char *p = *buf;
if (c < ' ' || c == 0x7f) {
if (ISCTRL(c)) {
*p++ = '^';
*p++ = UNCTRL(c);
} else
@ -3343,8 +3333,6 @@ x_mode(bool onoff)
#if !MKSH_S_NOVI
/* +++ vi editing mode +++ */
#define Ctrl(c) (c&0x1f)
struct edstate {
char *cbuf;
ssize_t winleft;
@ -3378,13 +3366,14 @@ static void redraw_line(bool);
static void refresh(int);
static int outofwin(void);
static void rewindow(void);
static int newcol(int, int);
static int newcol(unsigned char, int);
static void display(char *, char *, int);
static void ed_mov_opt(int, char *);
static int expand_word(int);
static int complete_word(int, int);
static int print_expansions(struct edstate *, int);
#define char_len(c) ((c) < ' ' || (c) == 0x7F ? 2 : 1)
#define char_len(c) ((ISCTRL((unsigned char)c) && \
/* but not C1 */ (unsigned char)c < 0x80) ? 2 : 1)
static void x_vi_zotc(int);
static void vi_error(void);
static void vi_macro_reset(void);
@ -3620,7 +3609,7 @@ vi_hook(int ch)
case VNORMAL:
if (insert != 0) {
if (ch == Ctrl('v')) {
if (ch == CTRL('v')) {
state = VLIT;
ch = '^';
}
@ -3732,7 +3721,7 @@ vi_hook(int ch)
break;
case VXCH:
if (ch == Ctrl('['))
if (ch == CTRL('['))
state = VNORMAL;
else {
curcmd[cmdlen++] = ch;
@ -3741,7 +3730,7 @@ vi_hook(int ch)
break;
case VSEARCH:
if (ch == '\r' || ch == '\n' /*|| ch == Ctrl('[')*/ ) {
if (ch == '\r' || ch == '\n' /*|| ch == CTRL('[')*/ ) {
restore_cbuf();
/* Repeat last search? */
if (srchlen == 0) {
@ -3756,10 +3745,10 @@ vi_hook(int ch)
memcpy(srchpat, locpat, srchlen + 1);
}
state = VCMD;
} else if (ch == edchars.erase || ch == Ctrl('h')) {
} else if (ch == edchars.erase || ch == CTRL('h')) {
if (srchlen != 0) {
srchlen--;
es->linelen -= char_len((unsigned char)locpat[srchlen]);
es->linelen -= char_len(locpat[srchlen]);
es->cursor = es->linelen;
refresh(0);
return (0);
@ -3786,7 +3775,7 @@ vi_hook(int ch)
es = save_es;
for (i = srchlen; --i >= n; )
es->linelen -= char_len((unsigned char)locpat[i]);
es->linelen -= char_len(locpat[i]);
srchlen = n;
es->cursor = es->linelen;
refresh(0);
@ -3796,12 +3785,12 @@ vi_hook(int ch)
vi_error();
else {
locpat[srchlen++] = ch;
if (ch < ' ' || ch == 0x7f) {
if (ISCTRL(ch) && /* but not C1 */ ch < 0x80) {
if ((size_t)es->linelen + 2 >
(size_t)es->cbufsize)
vi_error();
es->cbuf[es->linelen++] = '^';
es->cbuf[es->linelen++] = ch ^ '@';
es->cbuf[es->linelen++] = UNCTRL(ch);
} else {
if (es->linelen >= es->cbufsize)
vi_error();
@ -3912,7 +3901,7 @@ nextstate(int ch)
return (VXCH);
else if (ch == '.')
return (VREDO);
else if (ch == Ctrl('v'))
else if (ch == CTRL('v'))
return (VVERSION);
else if (is_cmd(ch))
return (VCMD);
@ -3925,7 +3914,7 @@ vi_insert(int ch)
{
int tcursor;
if (ch == edchars.erase || ch == Ctrl('h')) {
if (ch == edchars.erase || ch == CTRL('h')) {
if (insert == REPLACE) {
if (es->cursor == undo->cursor) {
vi_error();
@ -3982,7 +3971,7 @@ vi_insert(int ch)
* buffer (if user inserts & deletes char, ibuf gets trashed and
* we don't want to use it)
*/
if (first_insert && ch != Ctrl('['))
if (first_insert && ch != CTRL('['))
saved_inslen = 0;
switch (ch) {
case '\0':
@ -3992,7 +3981,7 @@ vi_insert(int ch)
case '\n':
return (1);
case Ctrl('['):
case CTRL('['):
expanded = NONE;
if (first_insert) {
first_insert = false;
@ -4010,19 +3999,19 @@ vi_insert(int ch)
return (redo_insert(lastac - 1));
/* { Begin nonstandard vi commands */
case Ctrl('x'):
case CTRL('x'):
expand_word(0);
break;
case Ctrl('f'):
case CTRL('f'):
complete_word(0, 0);
break;
case Ctrl('e'):
case CTRL('e'):
print_expansions(es, 0);
break;
case Ctrl('i'):
case CTRL('i'):
if (Flag(FVITABCOMPLETE)) {
complete_word(0, 0);
break;
@ -4077,8 +4066,8 @@ vi_cmd(int argcnt, const char *cmd)
}
switch (*cmd) {
case Ctrl('l'):
case Ctrl('r'):
case CTRL('l'):
case CTRL('r'):
redraw_line(true);
break;
@ -4265,7 +4254,7 @@ vi_cmd(int argcnt, const char *cmd)
case 'j':
case '+':
case Ctrl('n'):
case CTRL('n'):
if (grabhist(modified, hnum + argcnt) < 0)
return (-1);
else {
@ -4276,7 +4265,7 @@ vi_cmd(int argcnt, const char *cmd)
case 'k':
case '-':
case Ctrl('p'):
case CTRL('p'):
if (grabhist(modified, hnum - argcnt) < 0)
return (-1);
else {
@ -4508,26 +4497,26 @@ vi_cmd(int argcnt, const char *cmd)
/* AT&T ksh */
case '=':
/* Nonstandard vi/ksh */
case Ctrl('e'):
case CTRL('e'):
print_expansions(es, 1);
break;
/* Nonstandard vi/ksh */
case Ctrl('i'):
case CTRL('i'):
if (!Flag(FVITABCOMPLETE))
return (-1);
complete_word(1, argcnt);
break;
/* some annoying AT&T kshs */
case Ctrl('['):
case CTRL('['):
if (!Flag(FVIESCCOMPLETE))
return (-1);
/* AT&T ksh */
case '\\':
/* Nonstandard vi/ksh */
case Ctrl('f'):
case CTRL('f'):
complete_word(1, argcnt);
break;
@ -4535,7 +4524,7 @@ vi_cmd(int argcnt, const char *cmd)
/* AT&T ksh */
case '*':
/* Nonstandard vi/ksh */
case Ctrl('x'):
case CTRL('x'):
expand_word(1);
break;
@ -4614,7 +4603,7 @@ domove(int argcnt, const char *cmd, int sub)
break;
case 'h':
case Ctrl('h'):
case CTRL('h'):
if (!sub && es->cursor == 0)
return (-1);
ncursor = es->cursor - argcnt;
@ -5030,7 +5019,7 @@ grabsearch(int save, int start, int fwd, const char *pat)
{
char *hptr;
int hist;
int anchored;
bool anchored;
if ((start == 0 && fwd == 0) || (start >= hlast - 1 && fwd == 1))
return (-1);
@ -5038,7 +5027,7 @@ grabsearch(int save, int start, int fwd, const char *pat)
start++;
else
start--;
anchored = *pat == '^' ? (++pat, 1) : 0;
anchored = *pat == '^' ? (++pat, true) : false;
if ((hist = findhist(start, fwd, pat, anchored)) < 0) {
/* (start != 0 && fwd && match(holdbufp, pat) >= 0) */
if (start != 0 && fwd && strcmp(holdbufp, pat) >= 0) {
@ -5127,7 +5116,7 @@ rewindow(void)
}
static int
newcol(int ch, int col)
newcol(unsigned char ch, int col)
{
if (ch == '\t')
return ((col | 7) + 1);
@ -5155,10 +5144,10 @@ display(char *wb1, char *wb2, int leftside)
*twb1++ = ' ';
} while (++col < winwidth && (col & 7) != 0);
else if (col < winwidth) {
if (ch < ' ' || ch == 0x7f) {
if (ISCTRL(ch) && /* but not C1 */ ch < 0x80) {
*twb1++ = '^';
if (++col < winwidth) {
*twb1++ = ch ^ '@';
*twb1++ = UNCTRL(ch);
col++;
}
} else {
@ -5435,9 +5424,9 @@ print_expansions(struct edstate *est, int cmd MKSH_A_UNUSED)
static void
x_vi_zotc(int c)
{
if (c < ' ' || c == 0x7f) {
if (ISCTRL(c)) {
x_putc('^');
c ^= '@';
c = UNCTRL(c);
}
x_putc(c);
}

4
eval.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: eval.c,v 1.39 2013/07/01 17:25:27 jca Exp $ */
/* $OpenBSD: eval.c,v 1.40 2013/09/14 20:09:30 millert Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.142 2013/07/24 18:03:57 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.143 2013/09/24 20:19:44 tg Exp $");
/*
* string expansion

View File

@ -27,7 +27,7 @@
#include <sys/file.h>
#endif
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.131 2012/12/28 02:28:35 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.132 2013/09/24 20:19:44 tg Exp $");
Trap sigtraps[NSIG + 1];
static struct sigaction Sigact_ign;
@ -442,7 +442,7 @@ hist_get(const char *str, bool approx, bool allow_cur)
hp = NULL;
}
} else {
int anchored = *str == '?' ? (++str, 0) : 1;
bool anchored = *str == '?' ? (++str, false) : true;
/* the -1 is to avoid the current fc command */
if ((n = findhist(histptr - history - 1, 0, str, anchored)) < 0)
@ -509,7 +509,7 @@ histnum(int n)
* direction.
*/
int
findhist(int start, int fwd, const char *str, int anchored)
findhist(int start, int fwd, const char *str, bool anchored)
{
char **hp;
int maxhist = histptr - history;

7
sh.h
View File

@ -164,9 +164,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.670 2013/09/10 17:33:04 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.671 2013/09/24 20:19:44 tg Exp $");
#endif
#define MKSH_VERSION "R48 2013/09/10"
#define MKSH_VERSION "R48 2013/09/24"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -1587,6 +1587,7 @@ typedef union {
#undef CTRL
#define CTRL(x) ((x) == '?' ? 0x7F : (x) & 0x1F) /* ASCII */
#define UNCTRL(x) ((x) ^ 0x40) /* ASCII */
#define ISCTRL(x) (((signed char)((uint8_t)(x) + 1)) < 33)
#define IDENT 64
@ -1782,7 +1783,7 @@ void sethistfile(const char *);
char **histpos(void);
int histnum(int);
#endif
int findhist(int, int, const char *, int);
int findhist(int, int, const char *, bool);
char **hist_get_newest(bool);
void inittraps(void);
void alarm_init(void);

11
tree.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.71 2013/07/26 20:33:24 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.72 2013/09/24 20:19:45 tg Exp $");
#define INDENT 8
@ -778,15 +778,16 @@ vistree(char *dst, size_t sz, struct op *t)
if (--sz == 0 || (c = (unsigned char)(*cp++)) == 0)
/* NUL or not enough free space */
goto vist_out;
if ((c & 0x60) == 0 || (c & 0x7F) == 0x7F) {
if (ISCTRL(c & 0x7F)) {
/* C0 or C1 control character or DEL */
if (--sz == 0)
/* not enough free space for two chars */
goto vist_out;
*dst++ = (c & 0x80) ? '$' : '^';
c = (c & 0x7F) ^ 0x40;
c = UNCTRL(c & 0x7F);
} else if (UTFMODE && c > 0x7F) {
/* better not try to display broken multibyte chars */
/* also go easy on the Unicode: no U+FFFD here */
c = '?';
}
*dst++ = c;
@ -801,10 +802,10 @@ vistree(char *dst, size_t sz, struct op *t)
void
dumpchar(struct shf *shf, int c)
{
if (((c & 0x60) == 0) || ((c & 0x7F) == 0x7F)) {
if (ISCTRL(c & 0x7F)) {
/* C0 or C1 control character or DEL */
shf_putc((c & 0x80) ? '$' : '^', shf);
c = (c & 0x7F) ^ 0x40;
c = UNCTRL(c & 0x7F);
}
shf_putc(c, shf);
}