implement ksh93 feature ${ foo;}
This commit is contained in:
parent
8e51bb7a23
commit
9b7b7f742e
42
check.t
42
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.552 2012/07/30 19:58:03 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.553 2012/07/30 21:37:08 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 $
|
||||
@ -29,7 +29,7 @@
|
||||
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R40 2012/07/21
|
||||
@(#)MIRBSD KSH R40 2012/07/30
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
@ -38,7 +38,7 @@ name: KSH_VERSION
|
||||
category: shell:legacy-no
|
||||
---
|
||||
expected-stdout:
|
||||
@(#)LEGACY KSH R40 2012/07/21
|
||||
@(#)LEGACY KSH R40 2012/07/30
|
||||
description:
|
||||
Check version of legacy shell.
|
||||
stdin:
|
||||
@ -6194,21 +6194,6 @@ expected-stdout:
|
||||
expected-stderr-pattern:
|
||||
/(Unrecognized character .... ignored at \..t4 line 1)*/
|
||||
---
|
||||
name: utf8bom-3
|
||||
description:
|
||||
Reading the UTF-8 BOM should enable the utf8-mode flag
|
||||
(temporarily for COMSUBs)
|
||||
stdin:
|
||||
"$__progname" -c ':; if [[ $- = *U* ]]; then echo 1 on; else echo 1 off; fi'
|
||||
"$__progname" -c ':; if [[ $- = *U* ]]; then echo 2 on; else echo 2 off; fi'
|
||||
"$__progname" -c 'if [[ $- = *U* ]]; then echo 3 on; else echo 3 off; fi; x=$(:; if [[ $- = *U* ]]; then echo 4 on; else echo 4 off; fi); echo $x; if [[ $- = *U* ]]; then echo 5 on; else echo 5 off; fi'
|
||||
expected-stdout:
|
||||
1 off
|
||||
2 on
|
||||
3 off
|
||||
4 on
|
||||
5 off
|
||||
---
|
||||
name: utf8opt-1a
|
||||
description:
|
||||
Check that the utf8-mode flag is not set at non-interactive startup
|
||||
@ -9520,6 +9505,26 @@ expected-stdout:
|
||||
x=$(( echo $(true >&3 ) $((1+ 2)) ) | tr u x )
|
||||
}
|
||||
---
|
||||
name: funsub-1
|
||||
description:
|
||||
Check that non-subenvironment command substitution works
|
||||
stdin:
|
||||
set -e
|
||||
foo=bar
|
||||
echo "ob $foo ."
|
||||
echo "${
|
||||
echo "ib $foo :"
|
||||
foo=baz
|
||||
echo "ia $foo :"
|
||||
false
|
||||
}" .
|
||||
echo "oa $foo ."
|
||||
expected-stdout:
|
||||
ob bar .
|
||||
ib bar :
|
||||
ia baz : .
|
||||
oa baz .
|
||||
---
|
||||
name: test-stnze-1
|
||||
description:
|
||||
Check that the short form [ $x ] works
|
||||
@ -9613,7 +9618,6 @@ expected-stdout:
|
||||
name: event-subst-3
|
||||
description:
|
||||
Check that '!' substitution in noninteractive mode is ignored
|
||||
category: !smksh
|
||||
file-setup: file 755 "falsetto"
|
||||
#! /bin/sh
|
||||
echo molto bene
|
||||
|
@ -1,7 +1,8 @@
|
||||
# $Id$
|
||||
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.69 2011/12/31 01:07:19 tg Exp $
|
||||
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.70 2012/07/30 21:37:10 tg Exp $
|
||||
#-
|
||||
# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012
|
||||
# Thorsten Glaser <tg@mirbsd.org>
|
||||
#
|
||||
# Provided that these terms and disclaimer and all copyright notices
|
||||
@ -29,7 +30,7 @@ function precmd {
|
||||
|
||||
(( e )) && print -n "$e|"
|
||||
}
|
||||
PS1=$'\001\r''$(precmd)${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \?
|
||||
PS1=$'\001\r''${ precmd;}${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \?
|
||||
)}@${HOSTNAME%%.*}:$(local d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || \
|
||||
d=${d/#$p/~}; local m=${%d} n p=...; (( m > 0 )) || m=${#d}
|
||||
(( m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && d=${d:(-n)} || \
|
||||
|
49
eval.c
49
eval.c
@ -23,7 +23,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.122 2012/07/30 17:28:21 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.123 2012/07/30 21:37:11 tg Exp $");
|
||||
|
||||
/*
|
||||
* string expansion
|
||||
@ -58,7 +58,7 @@ typedef struct Expand {
|
||||
#define IFS_NWS 2 /* have seen IFS non-white-space */
|
||||
|
||||
static int varsub(Expand *, const char *, const char *, int *, int *);
|
||||
static int comsub(Expand *, const char *);
|
||||
static int comsub(Expand *, const char *, int);
|
||||
static char *trimsub(char *, char *, int);
|
||||
static void glob(char *, XPtrV *, int);
|
||||
static void globit(XString *, char **, char *, XPtrV *, int);
|
||||
@ -278,17 +278,27 @@ expand(const char *cp, /* input word */
|
||||
quote = st->quotew;
|
||||
continue;
|
||||
case COMSUB:
|
||||
case FUNSUB:
|
||||
tilde_ok = 0;
|
||||
if (f & DONTRUNCOMMAND) {
|
||||
word = IFS_WORD;
|
||||
*dp++ = '$'; *dp++ = '(';
|
||||
*dp++ = '$';
|
||||
if (c == FUNSUB) {
|
||||
*dp++ = '{';
|
||||
*dp++ = ' ';
|
||||
} else
|
||||
*dp++ = '(';
|
||||
while (*sp != '\0') {
|
||||
Xcheck(ds, dp);
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
*dp++ = ')';
|
||||
if (c == FUNSUB) {
|
||||
*dp++ = ';';
|
||||
*dp++ = '}';
|
||||
} else
|
||||
*dp++ = ')';
|
||||
} else {
|
||||
type = comsub(&x, sp);
|
||||
type = comsub(&x, sp, c);
|
||||
if (type == XCOM && (f&DOBLANK))
|
||||
doblank++;
|
||||
sp = strnul(sp) + 1;
|
||||
@ -611,8 +621,8 @@ expand(const char *cp, /* input word */
|
||||
case '#':
|
||||
case '%':
|
||||
/* ! DOBLANK,DOBRACE,DOTILDE */
|
||||
f = DOPAT | (f&DONTRUNCOMMAND) |
|
||||
DOTEMP;
|
||||
f = (f & DONTRUNCOMMAND) |
|
||||
DOPAT | DOTEMP;
|
||||
st->quotew = quote = 0;
|
||||
/*
|
||||
* Prepend open pattern (so |
|
||||
@ -1272,7 +1282,7 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||
* Run the command in $(...) and read its output.
|
||||
*/
|
||||
static int
|
||||
comsub(Expand *xp, const char *cp)
|
||||
comsub(Expand *xp, const char *cp, int fn)
|
||||
{
|
||||
Source *s, *sold;
|
||||
struct op *t;
|
||||
@ -1286,10 +1296,15 @@ comsub(Expand *xp, const char *cp)
|
||||
afree(s, ATEMP);
|
||||
source = sold;
|
||||
|
||||
UTFMODE = old_utfmode;
|
||||
|
||||
if (t == NULL)
|
||||
return (XBASE);
|
||||
|
||||
if (t != NULL && t->type == TCOM &&
|
||||
/* no waitlast() unless specifically enabled later */
|
||||
xp->split = false;
|
||||
|
||||
if (t->type == TCOM &&
|
||||
*t->args == NULL && *t->vars == NULL && t->ioact != NULL) {
|
||||
/* $(<file) */
|
||||
struct ioword *io = *t->ioact;
|
||||
@ -1302,10 +1317,9 @@ comsub(Expand *xp, const char *cp)
|
||||
SHF_MAPHI|SHF_CLEXEC);
|
||||
if (shf == NULL)
|
||||
errorf("%s: %s %s", name, "can't open", "$() input");
|
||||
/* no waitlast() */
|
||||
xp->split = false;
|
||||
} else {
|
||||
int ofd1, pv[2];
|
||||
|
||||
openpipe(pv);
|
||||
shf = shf_fdopen(pv[0], SHF_RD, NULL);
|
||||
ofd1 = savefd(1);
|
||||
@ -1313,14 +1327,16 @@ comsub(Expand *xp, const char *cp)
|
||||
ksh_dup2(pv[1], 1, false);
|
||||
close(pv[1]);
|
||||
}
|
||||
execute(t, XFORK|XXCOM|XPIPEO, NULL);
|
||||
execute(t, XXCOM | XPIPEO |
|
||||
(fn == FUNSUB ? XERROK : XFORK), NULL);
|
||||
restfd(1, ofd1);
|
||||
startlast();
|
||||
/* waitlast() */
|
||||
xp->split = true;
|
||||
if (fn != FUNSUB) {
|
||||
startlast();
|
||||
/* waitlast() */
|
||||
xp->split = true;
|
||||
}
|
||||
}
|
||||
|
||||
UTFMODE = old_utfmode;
|
||||
xp->u.shf = shf;
|
||||
return (XCOM);
|
||||
}
|
||||
@ -1328,7 +1344,6 @@ comsub(Expand *xp, const char *cp)
|
||||
/*
|
||||
* perform #pattern and %pattern substitution in ${}
|
||||
*/
|
||||
|
||||
static char *
|
||||
trimsub(char *str, char *pat, int how)
|
||||
{
|
||||
|
28
lex.c
28
lex.c
@ -23,7 +23,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.165 2012/07/01 15:54:55 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.166 2012/07/30 21:37:12 tg Exp $");
|
||||
|
||||
/*
|
||||
* states while lexing word
|
||||
@ -109,7 +109,7 @@ void yyskiputf8bom(void);
|
||||
static int backslash_skip;
|
||||
static int ignore_backslash_newline;
|
||||
static struct sretrace_info *retrace_info;
|
||||
short subshell_nesting_level = 0;
|
||||
int subshell_nesting_type = 0;
|
||||
|
||||
/* optimised getsc_bn() */
|
||||
#define o_getsc() (*source->str != '\0' && *source->str != '\\' && \
|
||||
@ -262,6 +262,11 @@ yylex(int cf)
|
||||
while (!((c = getsc()) == 0 ||
|
||||
((state == SBASE || state == SHEREDELIM || state == SHERESTRING) &&
|
||||
ctype(c, C_LEX1)))) {
|
||||
if (state == SBASE &&
|
||||
subshell_nesting_type == /*{*/ '}' &&
|
||||
c == /*{*/ '}')
|
||||
/* possibly end ${ :;} */
|
||||
break;
|
||||
accept_nonword:
|
||||
Xcheck(ws, wp);
|
||||
switch (state) {
|
||||
@ -395,14 +400,27 @@ yylex(int cf)
|
||||
} else {
|
||||
ungetsc(c);
|
||||
subst_command:
|
||||
sp = yyrecursive();
|
||||
c = COMSUB;
|
||||
subst_command2:
|
||||
sp = yyrecursive(c);
|
||||
cz = strlen(sp) + 1;
|
||||
XcheckN(ws, wp, cz);
|
||||
*wp++ = COMSUB;
|
||||
*wp++ = c;
|
||||
memcpy(wp, sp, cz);
|
||||
wp += cz;
|
||||
}
|
||||
} else if (c == '{') /*}*/ {
|
||||
c = getsc();
|
||||
if (ctype(c, C_IFSWS)) {
|
||||
/*
|
||||
* non-subenvironment
|
||||
* "command" substitution
|
||||
*/
|
||||
c = FUNSUB;
|
||||
goto subst_command2;
|
||||
}
|
||||
ungetsc(c);
|
||||
|
||||
*wp++ = OSUBST;
|
||||
*wp++ = '{'; /*}*/
|
||||
wp = get_brace_var(&ws, wp);
|
||||
@ -1171,7 +1189,7 @@ readhere(struct ioword *iop)
|
||||
/* end of here document marker, what to do? */
|
||||
switch (c) {
|
||||
case /*(*/ ')':
|
||||
if (!subshell_nesting_level)
|
||||
if (!subshell_nesting_type)
|
||||
/*-
|
||||
* not allowed outside $(...) or (...)
|
||||
* => mismatch
|
||||
|
6
misc.c
6
misc.c
@ -30,7 +30,7 @@
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.196 2012/07/20 21:18:45 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.197 2012/07/30 21:37:13 tg Exp $");
|
||||
|
||||
#define KSH_CHVT_FLAG
|
||||
#ifdef MKSH_SMALL
|
||||
@ -101,9 +101,9 @@ initctypes(void)
|
||||
chtypes['_'] |= C_ALPHA;
|
||||
setctypes("0123456789", C_DIGIT);
|
||||
/* \0 added automatically */
|
||||
setctypes(" \t\n|&;<>()", C_LEX1);
|
||||
setctypes(TC_LEX1, C_LEX1);
|
||||
setctypes("*@#!$-?", C_VAR1);
|
||||
setctypes(" \t\n", C_IFSWS);
|
||||
setctypes(TC_IFSWS, C_IFSWS);
|
||||
setctypes("=-+?", C_SUBOP1);
|
||||
setctypes("\t\n \"#$&'()*;<=>?[\\]`|", C_QUOTE);
|
||||
}
|
||||
|
16
mksh.1
16
mksh.1
@ -1,4 +1,4 @@
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.290 2012/07/25 19:40:40 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.291 2012/07/30 21:37:13 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.144 2012/07/08 08:13:20 guenther Exp $
|
||||
.\"-
|
||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
@ -74,7 +74,7 @@
|
||||
.\" with -mandoc, it might implement .Mx itself, but we want to
|
||||
.\" use our own definition. And .Dd must come *first*, always.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 25 2012 $
|
||||
.Dd $Mdocdate: July 30 2012 $
|
||||
.\"
|
||||
.\" Check which macro package we use, and do other -mdoc setup.
|
||||
.\"
|
||||
@ -1145,9 +1145,15 @@ or
|
||||
command substitutions take the form
|
||||
.Pf $( Ns Ar command Ns \&)
|
||||
or (deprecated)
|
||||
.Pf \` Ns Ar command Ns \` ;
|
||||
.Pf \` Ns Ar command Ns \`
|
||||
or (executed in the current environment)
|
||||
.Pf ${\ \& Ar command Ns \&;}
|
||||
and strip trailing newlines;
|
||||
and arithmetic substitutions take the form
|
||||
.Pf $(( Ns Ar expression Ns )) .
|
||||
Parsing the current-environment command substitution requires a space,
|
||||
tab or newline after the opening brace and that the closing brace be
|
||||
recognised as a keyword (i.e. is preceded by a newline or semicolon).
|
||||
.Pp
|
||||
If a substitution appears outside of double quotes, the results of the
|
||||
substitution are generally subject to word or field splitting according to
|
||||
@ -1225,6 +1231,8 @@ A command substitution is replaced by the output generated by the specified
|
||||
command which is run in a subshell.
|
||||
For
|
||||
.Pf $( Ns Ar command Ns \&)
|
||||
and
|
||||
.Pf ${\ \& Ar command Ns \&;}
|
||||
substitutions, normal quoting rules are used when
|
||||
.Ar command
|
||||
is parsed; however, for the deprecated
|
||||
@ -1963,7 +1971,7 @@ x=$(print \e\e001)
|
||||
PS1="$x$(print \e\er)$x$(tput smso)$x\e$PWD$x$(tput rmso)$x\*(Gt "
|
||||
.Ed
|
||||
.Pp
|
||||
Due to pressure from David G. Korn,
|
||||
Due to a strong suggestion from David G. Korn,
|
||||
.Nm
|
||||
now also supports the following form:
|
||||
.Bd -literal -offset indent
|
||||
|
9
sh.h
9
sh.h
@ -157,9 +157,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.575 2012/07/30 17:04:30 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.576 2012/07/30 21:37:15 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R40 2012/07/21"
|
||||
#define MKSH_VERSION "R40 2012/07/30"
|
||||
|
||||
/* arithmetic types: C implementation */
|
||||
#if !HAVE_CAN_INTTYPES
|
||||
@ -765,6 +765,8 @@ EXTERN const char Tgbuiltin[] E_INIT("=builtin");
|
||||
#define Tbuiltin (Tgbuiltin + 1) /* "builtin" */
|
||||
EXTERN const char T_function[] E_INIT(" function");
|
||||
#define Tfunction (T_function + 1) /* "function" */
|
||||
EXTERN const char TC_LEX1[] E_INIT("|&;<>() \t\n");
|
||||
#define TC_IFSWS (TC_LEX1 + 7) /* space tab newline */
|
||||
|
||||
typedef uint8_t Temp_type;
|
||||
/* expanded heredoc */
|
||||
@ -1281,6 +1283,7 @@ struct op {
|
||||
#define SPAT 10 /* separate pattern: | */
|
||||
#define CPAT 11 /* close pattern: ) */
|
||||
#define ADELIM 12 /* arbitrary delimiter: ${foo:2:3} ${foo/bar/baz} */
|
||||
#define FUNSUB 14 /* ${ foo;} substitution (NUL terminated) */
|
||||
|
||||
/*
|
||||
* IO redirection
|
||||
@ -1903,7 +1906,7 @@ ssize_t shf_vfprintf(struct shf *, const char *, va_list)
|
||||
void initkeywords(void);
|
||||
struct op *compile(Source *, bool);
|
||||
bool parse_usec(const char *, struct timeval *);
|
||||
char *yyrecursive(void);
|
||||
char *yyrecursive(int);
|
||||
/* tree.c */
|
||||
void fptreef(struct shf *, int, const char *, ...);
|
||||
char *snptreef(char *, ssize_t, const char *, ...);
|
||||
|
36
syn.c
36
syn.c
@ -23,9 +23,9 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.78 2012/07/30 17:04:31 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.79 2012/07/30 21:37:16 tg Exp $");
|
||||
|
||||
extern short subshell_nesting_level;
|
||||
extern int subshell_nesting_type;
|
||||
extern void yyskiputf8bom(void);
|
||||
|
||||
struct nesting_state {
|
||||
@ -363,12 +363,15 @@ get_command(int cf)
|
||||
Leave:
|
||||
break;
|
||||
|
||||
case '(':
|
||||
case '(': /*)*/ {
|
||||
int subshell_nesting_type_saved;
|
||||
Subshell:
|
||||
++subshell_nesting_level;
|
||||
subshell_nesting_type_saved = subshell_nesting_type;
|
||||
subshell_nesting_type = ')';
|
||||
t = nested(TPAREN, '(', ')');
|
||||
--subshell_nesting_level;
|
||||
subshell_nesting_type = subshell_nesting_type_saved;
|
||||
break;
|
||||
}
|
||||
|
||||
case '{': /*}*/
|
||||
t = nested(TBRACE, '{', '}');
|
||||
@ -1115,16 +1118,29 @@ parse_usec(const char *s, struct timeval *tv)
|
||||
* a COMSUB recursively using the main shell parser and lexer
|
||||
*/
|
||||
char *
|
||||
yyrecursive(void)
|
||||
yyrecursive(int subtype)
|
||||
{
|
||||
struct op *t;
|
||||
char *cp;
|
||||
bool old_reject;
|
||||
int old_symbol, old_salias;
|
||||
int old_symbol, old_salias, old_nesting_type;
|
||||
struct ioword **old_herep;
|
||||
int stok, etok;
|
||||
|
||||
switch (subtype) {
|
||||
case FUNSUB:
|
||||
stok = '{';
|
||||
etok = '}';
|
||||
break;
|
||||
case COMSUB:
|
||||
default:
|
||||
stok = '(';
|
||||
etok = ')';
|
||||
}
|
||||
|
||||
/* tell the lexer to accept a closing parenthesis as EOD */
|
||||
++subshell_nesting_level;
|
||||
old_nesting_type = subshell_nesting_type;
|
||||
subshell_nesting_type = etok;
|
||||
|
||||
/* push reject state, parse recursively, pop reject state */
|
||||
old_reject = reject;
|
||||
@ -1134,7 +1150,7 @@ yyrecursive(void)
|
||||
old_salias = sALIAS;
|
||||
sALIAS = 0;
|
||||
/* we use TPAREN as a helper container here */
|
||||
t = nested(TPAREN, '(', ')');
|
||||
t = nested(TPAREN, stok, etok);
|
||||
sALIAS = old_salias;
|
||||
herep = old_herep;
|
||||
reject = old_reject;
|
||||
@ -1144,6 +1160,6 @@ yyrecursive(void)
|
||||
cp = snptreef(NULL, 0, "%T", t->left);
|
||||
tfree(t, ATEMP);
|
||||
|
||||
--subshell_nesting_level;
|
||||
subshell_nesting_type = old_nesting_type;
|
||||
return (cp);
|
||||
}
|
||||
|
21
tree.c
21
tree.c
@ -23,7 +23,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.62 2012/07/30 19:58:05 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.63 2012/07/30 21:37:17 tg Exp $");
|
||||
|
||||
#define INDENT 8
|
||||
|
||||
@ -292,6 +292,7 @@ static const char *
|
||||
wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
|
||||
{
|
||||
int c;
|
||||
const char *cs;
|
||||
|
||||
/*-
|
||||
* problems:
|
||||
@ -335,16 +336,20 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
|
||||
}
|
||||
case COMSUB:
|
||||
shf_puts("$(", shf);
|
||||
cs = ")";
|
||||
pSUB:
|
||||
while ((c = *wp++) != 0)
|
||||
shf_putc(c, shf);
|
||||
shf_putc(')', shf);
|
||||
shf_puts(cs, shf);
|
||||
break;
|
||||
case FUNSUB:
|
||||
shf_puts("${ ", shf);
|
||||
cs = ";}";
|
||||
goto pSUB;
|
||||
case EXPRSUB:
|
||||
shf_puts("$((", shf);
|
||||
while ((c = *wp++) != 0)
|
||||
shf_putc(c, shf);
|
||||
shf_puts("))", shf);
|
||||
break;
|
||||
cs = "))";
|
||||
goto pSUB;
|
||||
case OQUOTE:
|
||||
if (opmode & WDS_TPUTS) {
|
||||
quotelevel++;
|
||||
@ -580,6 +585,7 @@ wdscan(const char *wp, int c)
|
||||
wp++;
|
||||
break;
|
||||
case COMSUB:
|
||||
case FUNSUB:
|
||||
case EXPRSUB:
|
||||
while (*wp++ != 0)
|
||||
;
|
||||
@ -819,6 +825,9 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
|
||||
closeandout:
|
||||
shf_putc('>', shf);
|
||||
break;
|
||||
case FUNSUB:
|
||||
shf_puts("FUNSUB<", shf);
|
||||
goto dumpsub;
|
||||
case EXPRSUB:
|
||||
shf_puts("EXPRSUB<", shf);
|
||||
goto dumpsub;
|
||||
|
4
var.c
4
var.c
@ -27,7 +27,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.152 2012/07/01 15:38:09 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.153 2012/07/30 21:37:17 tg Exp $");
|
||||
|
||||
/*-
|
||||
* Variables
|
||||
@ -1254,7 +1254,7 @@ unsetspec(struct tbl *vp)
|
||||
flushcom(true);
|
||||
break;
|
||||
case V_IFS:
|
||||
setctypes(" \t\n", C_IFS);
|
||||
setctypes(TC_IFSWS, C_IFS);
|
||||
ifs0 = ' ';
|
||||
break;
|
||||
case V_TMPDIR:
|
||||
|
Loading…
x
Reference in New Issue
Block a user