Merge remote-tracking branch 'mksh/master'

This commit is contained in:
KO Myung-Hun 2016-05-06 17:12:52 +09:00
commit e8966076c8
11 changed files with 256 additions and 137 deletions

102
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.728 2016/03/05 15:39:36 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.731 2016/05/05 22:58:19 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 R52 2016/03/04 @(#)MIRBSD KSH R52 2016/05/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 R52 2016/03/04 @(#)LEGACY KSH R52 2016/05/05
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:
@ -1687,6 +1687,50 @@ stdin:
expected-stdout: expected-stdout:
<~/x> </x> <~> <\~> <~><~> <~/x> <~//etc> <~/~> <~/x> </x> <~> <\~> <~><~> <~/x> <~//etc> <~/~>
--- ---
name: expand-bang-1
description:
Check corner case of ${!?} with ! being var vs. op
stdin:
echo ${!?}
expected-exit: 1
expected-stderr-pattern: /not set/
---
name: expand-bang-2
description:
Check corner case of ${!var} vs. ${var op} with var=!
stdin:
echo 1 $! .
echo 2 ${!#} .
echo 3 ${!#[0-9]} .
echo 4 ${!-foo} .
# get an at least three-digit bg pid
while :; do
:&
x=$!
if [[ $x != +([0-9]) ]]; then
echo >&2 "cannot test, pid '$x' not numeric"
echo >&2 report this with as many details as possible
exit 1
fi
[[ $x = [0-9][0-9][0-9]* ]] && break
done
y=${x#?}
t=$!; [[ $t = $x ]]; echo 5 $? .
t=${!#}; [[ $t = $x ]]; echo 6 $? .
t=${!#[0-9]}; [[ $t = $y ]]; echo 7 $? .
t=${!-foo}; [[ $t = $x ]]; echo 8 $? .
t=${!?bar}; [[ $t = $x ]]; echo 9 $? .
expected-stdout:
1 .
2 .
3 .
4 foo .
5 0 .
6 0 .
7 0 .
8 0 .
9 0 .
---
name: expand-number-1 name: expand-number-1
description: description:
Check that positional arguments do not overflow Check that positional arguments do not overflow
@ -3173,6 +3217,37 @@ expected-stdout:
expected-stderr-pattern: expected-stderr-pattern:
/(.*can't unlink HISTFILE.*\n)?X*$/ /(.*can't unlink HISTFILE.*\n)?X*$/
--- ---
name: history-multiline
description:
Check correct multiline history, Debian #783978
need-ctty: yes
arguments: !-i!
env-setup: !ENV=./Env!
file-setup: file 644 "Env"
PS1=X
PS2=Y
stdin:
for i in A B C
do
print $i
print $i
done
fc -l
expected-stdout:
A
A
B
B
C
C
1 for i in A B C
do
print $i
print $i
done
expected-stderr-pattern:
/^XYYYYXX$/
---
name: history-e-minus-1 name: history-e-minus-1
description: description:
Check if more recent command is executed Check if more recent command is executed
@ -7775,6 +7850,27 @@ expected-stdout:
2 off 2 off
3 done 3 done
--- ---
name: utf8bug-1
description:
Ensure trailing combining characters are not lost
stdin:
set -U
a=a
b=$'\u0301'
x=$a$b
print -r -- "<e$x>"
x=$a
x+=$b
print -r -- "<e$x>"
b=$'\u0301'b
x=$a
x+=$b
print -r -- "<e$x>"
expected-stdout:
<eá>
<eá>
<eáb>
---
name: aliases-1 name: aliases-1
description: description:
Check if built-in shell aliases are okay Check if built-in shell aliases are okay

View File

@ -1,8 +1,8 @@
# $Id$ # $Id$
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.104 2015/12/31 21:00:12 tg Exp $ # $MirOS: src/bin/mksh/dot.mkshrc,v 1.105 2016/04/09 16:33:23 tg Exp $
#- #-
# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015, 2016
# mirabilos <m@mirbsd.org> # mirabilos <m@mirbsd.org>
# #
# Provided that these terms and disclaimer and all copyright notices # Provided that these terms and disclaimer and all copyright notices
@ -250,25 +250,23 @@ function pushd {
} }
# pager (not control character safe) # pager (not control character safe)
function smores { smores() (
( \set +m
\set +m \cat "$@" |&
\cat "$@" |& \trap "rv=\$?; 'kill' $! >/dev/null 2>&1; 'exit' \$rv" EXIT
\trap "rv=\$?; 'kill' $! >/dev/null 2>&1; 'exit' \$rv" EXIT while IFS= \read -pr line; do
while IFS= \read -pr line; do llen=${%line}
llen=${%line} (( llen == -1 )) && llen=${#line}
(( llen == -1 )) && llen=${#line} (( llen = llen ? (llen + COLUMNS - 1) / COLUMNS : 1 ))
(( llen = llen ? (llen + COLUMNS - 1) / COLUMNS : 1 )) if (( (curlin += llen) >= LINES )); then
if (( (curlin += llen) >= LINES )); then \builtin print -n -- '\e[7m--more--\e[0m'
\builtin print -n -- '\e[7m--more--\e[0m' \read -u1 || \exit $?
\read -u1 || \exit $? [[ $REPLY = [Qq]* ]] && \exit 0
[[ $REPLY = [Qq]* ]] && \exit 0 curlin=$llen
curlin=$llen fi
fi \builtin print -r -- "$line"
\builtin print -r -- "$line" done
done )
)
}
# base64 encoder and decoder, RFC compliant, NUL safe, not EBCDIC safe # base64 encoder and decoder, RFC compliant, NUL safe, not EBCDIC safe
function Lb64decode { function Lb64decode {

26
edit.c
View File

@ -28,7 +28,7 @@
#ifndef MKSH_NO_CMDLINE_EDITING #ifndef MKSH_NO_CMDLINE_EDITING
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.294 2016/03/04 14:26:12 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/edit.c,v 1.296 2016/05/05 22:56:12 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
@ -1580,7 +1580,7 @@ static void
x_goto(char *cp) x_goto(char *cp)
{ {
cp = cp >= xep ? xep : x_bs0(cp, xbuf); cp = cp >= xep ? xep : x_bs0(cp, xbuf);
if (cp < xbp || cp >= utf_skipcols(xbp, x_displen)) { if (cp < xbp || cp >= utf_skipcols(xbp, x_displen, NULL)) {
/* we are heading off screen */ /* we are heading off screen */
xcp = cp; xcp = cp;
x_adjust(); x_adjust();
@ -4922,16 +4922,16 @@ forwword(int argcnt)
ncursor = es->cursor; ncursor = es->cursor;
while (ncursor < es->linelen && argcnt--) { while (ncursor < es->linelen && argcnt--) {
if (ksh_isalnux(es->cbuf[ncursor])) if (ksh_isalnux(es->cbuf[ncursor]))
while (ksh_isalnux(es->cbuf[ncursor]) && while (ncursor < es->linelen &&
ncursor < es->linelen) ksh_isalnux(es->cbuf[ncursor]))
ncursor++; ncursor++;
else if (!ksh_isspace(es->cbuf[ncursor])) else if (!ksh_isspace(es->cbuf[ncursor]))
while (!ksh_isalnux(es->cbuf[ncursor]) && while (ncursor < es->linelen &&
!ksh_isspace(es->cbuf[ncursor]) && !ksh_isalnux(es->cbuf[ncursor]) &&
ncursor < es->linelen) !ksh_isspace(es->cbuf[ncursor]))
ncursor++; ncursor++;
while (ksh_isspace(es->cbuf[ncursor]) && while (ncursor < es->linelen &&
ncursor < es->linelen) ksh_isspace(es->cbuf[ncursor]))
ncursor++; ncursor++;
} }
return (ncursor); return (ncursor);
@ -4995,11 +4995,11 @@ Forwword(int argcnt)
ncursor = es->cursor; ncursor = es->cursor;
while (ncursor < es->linelen && argcnt--) { while (ncursor < es->linelen && argcnt--) {
while (!ksh_isspace(es->cbuf[ncursor]) && while (ncursor < es->linelen &&
ncursor < es->linelen) !ksh_isspace(es->cbuf[ncursor]))
ncursor++; ncursor++;
while (ksh_isspace(es->cbuf[ncursor]) && while (ncursor < es->linelen &&
ncursor < es->linelen) ksh_isspace(es->cbuf[ncursor]))
ncursor++; ncursor++;
} }
return (ncursor); return (ncursor);

118
eval.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.185 2016/02/26 19:05:21 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.187 2016/05/05 22:45:57 tg Exp $");
/* /*
* string expansion * string expansion
@ -1213,67 +1213,65 @@ varsub(Expand *xp, const char *sp, const char *word,
} }
/* POSIX 2009? */ /* POSIX 2009? */
zero_ok = true; zero_ok = true;
} else { } else if ((p = cstrchr(sp, '[')) && (p[1] == '*' || p[1] == '@') &&
if ((p = cstrchr(sp, '[')) && (p[1] == '*' || p[1] == '@') && p[2] == ']') {
p[2] == ']') { XPtrV wv;
XPtrV wv;
switch (stype & 0x17F) { switch (stype & 0x17F) {
/* can't assign to a vector */ /* can't assign to a vector */
case '=': case '=':
/* can't trim a vector (yet) */ /* can't trim a vector (yet) */
case '%': case '%':
case '#': case '#':
case '?': case '?':
case '0': case '0':
case '/': case '/':
case 0x100 | '#': case 0x100 | '#':
case 0x100 | 'Q': case 0x100 | 'Q':
return (-1); return (-1);
}
XPinit(wv, 32);
if ((c = sp[0]) == '!')
++sp;
vp = global(arrayname(sp));
for (; vp; vp = vp->u.array) {
if (!(vp->flag&ISSET))
continue;
XPput(wv, c == '!' ? shf_smprintf("%lu",
arrayindex(vp)) :
str_val(vp));
}
if (XPsize(wv) == 0) {
xp->str = null;
state = p[1] == '@' ? XNULLSUB : XSUB;
XPfree(wv);
} else {
XPput(wv, 0);
xp->u.strv = (const char **)XPptrv(wv);
xp->str = *xp->u.strv++;
/* ${foo[@]} */
xp->split = tobool(p[1] == '@');
state = XARG;
}
} else {
/* Can't assign things like $! or $1 */
if ((stype & 0x17F) == '=' &&
ctype(*sp, C_VAR1 | C_DIGIT))
return (-1);
if (*sp == '!' && sp[1]) {
++sp;
xp->var = global(sp);
if (vstrchr(sp, '['))
xp->str = shf_smprintf("%s[%lu]",
xp->var->name,
arrayindex(xp->var));
else
xp->str = xp->var->name;
} else {
xp->var = global(sp);
xp->str = str_val(xp->var);
}
state = XSUB;
} }
XPinit(wv, 32);
if ((c = sp[0]) == '!')
++sp;
vp = global(arrayname(sp));
for (; vp; vp = vp->u.array) {
if (!(vp->flag&ISSET))
continue;
XPput(wv, c == '!' ? shf_smprintf("%lu",
arrayindex(vp)) :
str_val(vp));
}
if (XPsize(wv) == 0) {
xp->str = null;
state = p[1] == '@' ? XNULLSUB : XSUB;
XPfree(wv);
} else {
XPput(wv, 0);
xp->u.strv = (const char **)XPptrv(wv);
xp->str = *xp->u.strv++;
/* ${foo[@]} */
xp->split = tobool(p[1] == '@');
state = XARG;
}
} else {
/* Can't assign things like $! or $1 */
if ((stype & 0x17F) == '=' &&
ctype(*sp, C_VAR1 | C_DIGIT))
return (-1);
if (*sp == '!' && sp[1] && !ctype(sp[1], C_VAR1)) {
++sp;
xp->var = global(sp);
if (vstrchr(sp, '['))
xp->str = shf_smprintf("%s[%lu]",
xp->var->name,
arrayindex(xp->var));
else
xp->str = xp->var->name;
} else {
xp->var = global(sp);
xp->str = str_val(xp->var);
}
state = XSUB;
} }
c = stype & 0x7F; c = stype & 0x7F;

4
exec.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.172 2016/03/01 18:30:04 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.173 2016/04/09 16:41:07 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL #ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
@ -1111,7 +1111,7 @@ define(const char *name, struct op *t)
} }
if (tp->flag & ALLOC) { if (tp->flag & ALLOC) {
tp->flag &= ~(ISSET|ALLOC); tp->flag &= ~(ISSET|ALLOC|FKSH);
tfree(tp->val.t, tp->areap); tfree(tp->val.t, tp->areap);
} }

19
expr.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.83 2016/03/01 18:29:38 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/expr.c,v 1.85 2016/05/05 22:56:13 tg Exp $");
/* the order of these enums is constrained by the order of opinfo[] */ /* the order of these enums is constrained by the order of opinfo[] */
enum token { enum token {
@ -809,15 +809,26 @@ utf_mbswidth(const char *s)
} }
const char * const char *
utf_skipcols(const char *p, int cols) utf_skipcols(const char *p, int cols, int *colp)
{ {
int c = 0; int c = 0;
const char *q;
while (c < cols) { while (c < cols) {
if (!*p) if (!*p) {
return (p + cols - c); /* end of input; special handling for edit.c */
if (!colp)
return (p + cols - c);
*colp = c;
return (p);
}
c += utf_widthadj(p, &p); c += utf_widthadj(p, &p);
} }
if (UTFMODE)
while (utf_widthadj(p, &q) == 0)
p = q;
if (colp)
*colp = c;
return (p); return (p);
} }

28
lex.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.222 2016/03/01 19:22:31 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.224 2016/05/05 22:45:58 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -1350,7 +1350,8 @@ getsc_line(Source *s)
alarm(ksh_tmout); alarm(ksh_tmout);
} }
if (interactive) { if (interactive) {
histsave(&s->line, NULL, HIST_FLUSH, true); if (cur_prompt == PS1)
histsave(&s->line, NULL, HIST_FLUSH, true);
change_winsz(); change_winsz();
} }
#ifndef MKSH_NO_CMDLINE_EDITING #ifndef MKSH_NO_CMDLINE_EDITING
@ -1565,20 +1566,34 @@ get_brace_var(XString *wsp, char *wp)
{ {
char c; char c;
enum parse_state { enum parse_state {
PS_INITIAL, PS_SAW_HASH, PS_IDENT, PS_INITIAL, PS_SAW_PERCENT, PS_SAW_HASH, PS_SAW_BANG,
PS_NUMBER, PS_VAR1 PS_IDENT, PS_NUMBER, PS_VAR1
} state = PS_INITIAL; } state = PS_INITIAL;
while (/* CONSTCOND */ 1) { while (/* CONSTCOND */ 1) {
c = getsc(); c = getsc();
/* State machine to figure out where the variable part ends. */ /* State machine to figure out where the variable part ends. */
switch (state) { switch (state) {
case PS_SAW_BANG:
if (ctype(c, C_VAR1))
goto out;
if (0)
/* FALLTHROUGH */
case PS_INITIAL: case PS_INITIAL:
if (c == '#' || c == '!' || c == '%') { switch (c) {
case '%':
state = PS_SAW_PERCENT;
goto next;
case '#':
state = PS_SAW_HASH; state = PS_SAW_HASH;
break; goto next;
case '!':
state = PS_SAW_BANG;
goto next;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
case PS_SAW_PERCENT:
case PS_SAW_HASH: case PS_SAW_HASH:
if (ksh_isalphx(c)) if (ksh_isalphx(c))
state = PS_IDENT; state = PS_IDENT;
@ -1619,6 +1634,7 @@ get_brace_var(XString *wsp, char *wp)
} }
goto out; goto out;
} }
next:
break; break;
case PS_NUMBER: case PS_NUMBER:
if (!ksh_isdigit(c)) if (!ksh_isdigit(c))

26
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.393 2016/03/06 21:01:28 tg Exp $ .\" $MirOS: src/bin/mksh/mksh.1,v 1.395 2016/05/05 22:45:58 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,
@ -76,7 +76,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" use our own definition. And .Dd must come *first*, always.
.\" .\"
.Dd $Mdocdate: March 6 2016 $ .Dd $Mdocdate: May 5 2016 $
.\" .\"
.\" Check which macro package we use, and do other -mdoc setup. .\" Check which macro package we use, and do other -mdoc setup.
.\" .\"
@ -1001,9 +1001,9 @@ Third, a double quote
.Pq Sq \&" .Pq Sq \&"
quotes all characters, except quotes all characters, except
.Ql $ , .Ql $ ,
.Ql \`
and
.Ql \e , .Ql \e ,
and
.Ql \` ,
up to the next unescaped double quote. up to the next unescaped double quote.
.Ql $ .Ql $
and and
@ -1015,13 +1015,15 @@ substitution has backslash-quoting for double quotes enabled.
If a If a
.Ql \e .Ql \e
inside a double-quoted string is followed by inside a double-quoted string is followed by
.Ql \e ,
.Ql $ ,
.Ql \` ,
or
.Ql \&" , .Ql \&" ,
it is replaced by the second character; if it is followed by a newline, both .Ql $ ,
the .Ql \e ,
or
.Ql \` ,
only the
.Ql \e
is removed, i.e. the combination is replaced by the second character;
if it is followed by a newline, both the
.Ql \e .Ql \e
and the newline are stripped; otherwise, both the and the newline are stripped; otherwise, both the
.Ql \e .Ql \e
@ -1591,6 +1593,8 @@ is a name reference (bound variable), created by the
.Ic nameref .Ic nameref
command (which is an alias for command (which is an alias for
.Ic typeset Fl n ) . .Ic typeset Fl n ) .
.Ar name
cannot be one of most special parameters (see below).
.Pp .Pp
.It Pf ${! Ns Ar name Ns \&[*]} .It Pf ${! Ns Ar name Ns \&[*]}
.It Pf ${! Ns Ar name Ns \&[@]} .It Pf ${! Ns Ar name Ns \&[@]}
@ -6585,7 +6589,7 @@ for the in-memory portion of the history is slow, should use
.Xr memmove 3 . .Xr memmove 3 .
.Pp .Pp
This document attempts to describe This document attempts to describe
.Nm mksh\ R52c .Nm mksh\ R52c+CVS
and up, and up,
.\" with vendor patches from insert-your-name-here, .\" with vendor patches from insert-your-name-here,
compiled without any options impacting functionality, such as compiled without any options impacting functionality, such as

6
sh.h
View File

@ -175,9 +175,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.768 2016/03/04 18:28:42 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.771 2016/05/05 22:56:14 tg Exp $");
#endif #endif
#define MKSH_VERSION "R52 2016/03/04" #define MKSH_VERSION "R52 2016/05/05"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -1756,7 +1756,7 @@ size_t utf_mbtowc(unsigned int *, const char *);
size_t utf_wctomb(char *, unsigned int); size_t utf_wctomb(char *, unsigned int);
int utf_widthadj(const char *, const char **); int utf_widthadj(const char *, const char **);
size_t utf_mbswidth(const char *) MKSH_A_PURE; size_t utf_mbswidth(const char *) MKSH_A_PURE;
const char *utf_skipcols(const char *, int) MKSH_A_PURE; const char *utf_skipcols(const char *, int, int *);
size_t utf_ptradj(const char *) MKSH_A_PURE; size_t utf_ptradj(const char *) MKSH_A_PURE;
#ifdef MIRBSD_BOOTFLOPPY #ifdef MIRBSD_BOOTFLOPPY
#define utf_wcwidth(i) wcwidth((wchar_t)(i)) #define utf_wcwidth(i) wcwidth((wchar_t)(i))

14
shf.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.70 2016/03/04 14:26:16 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/shf.c,v 1.73 2016/05/05 22:56:15 tg Exp $");
/* flags to shf_emptybuf() */ /* flags to shf_emptybuf() */
#define EB_READSW 0x01 /* about to switch to reading */ #define EB_READSW 0x01 /* about to switch to reading */
@ -1040,15 +1040,11 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
} else } else
field = 0; field = 0;
if (precision) { nwritten += precision;
const char *q; precision = utf_skipcols(s, precision, &tmp) - s;
while (precision--)
shf_putc(*s++, shf);
nwritten += precision;
q = utf_skipcols(s, precision);
do {
shf_putc(*s, shf);
} while (++s < q);
}
nwritten += field; nwritten += field;
while (field--) while (field--)
shf_putc(c, shf); shf_putc(c, shf);

10
var.c
View File

@ -28,7 +28,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.201 2016/03/01 20:28:33 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.202 2016/05/05 22:56:15 tg Exp $");
/*- /*-
* Variables * Variables
@ -649,14 +649,14 @@ formatstr(struct tbl *vp, const char *s)
p = alloc((psiz = nlen * /* MB_LEN_MAX */ 3 + 1), ATEMP); p = alloc((psiz = nlen * /* MB_LEN_MAX */ 3 + 1), ATEMP);
if (vp->flag & (RJUST|LJUST)) { if (vp->flag & (RJUST|LJUST)) {
int slen = olen, i = 0; int slen = olen;
if (vp->flag & RJUST) { if (vp->flag & RJUST) {
const char *qq = s; const char *qq;
int n = 0; int n = 0;
while (i < slen) qq = utf_skipcols(s, slen, &slen);
i += utf_widthadj(qq, &qq);
/* strip trailing spaces (AT&T uses qq[-1] == ' ') */ /* strip trailing spaces (AT&T uses qq[-1] == ' ') */
while (qq > s && ksh_isspace(qq[-1])) { while (qq > s && ksh_isspace(qq[-1])) {
--qq; --qq;