promote x=(a b); x+=(c) to standard mksh functionality at cost of 932 MKSH_SMALL .text bytes on MirBSD/i386
This commit is contained in:
parent
7e719a4cc1
commit
e20b1295b7
97
check.t
97
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.489 2011/11/09 22:17:23 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.490 2011/11/11 22:14:15 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 $
|
||||
@ -25,7 +25,7 @@
|
||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R40 2011/11/09
|
||||
@(#)MIRBSD KSH R40 2011/11/11
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
@ -6177,7 +6177,6 @@ expected-stdout:
|
||||
name: arrays-2a
|
||||
description:
|
||||
Check if bash-style arrays work as expected
|
||||
category: !smksh
|
||||
stdin:
|
||||
v="c d"
|
||||
foo=(a \$v "$v" '$v' b)
|
||||
@ -6188,7 +6187,6 @@ expected-stdout:
|
||||
name: arrays-2b
|
||||
description:
|
||||
Check if bash-style arrays work as expected, with newlines
|
||||
category: !smksh
|
||||
stdin:
|
||||
test -n "$ZSH_VERSION" && setopt KSH_ARRAYS
|
||||
v="e f"
|
||||
@ -6229,7 +6227,6 @@ expected-stdout:
|
||||
name: arrays-4
|
||||
description:
|
||||
Check if Korn Shell arrays with specified indices work as expected
|
||||
category: !smksh
|
||||
stdin:
|
||||
v="c d"
|
||||
set -A foo -- [1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b
|
||||
@ -6240,7 +6237,6 @@ expected-stdout:
|
||||
name: arrays-5
|
||||
description:
|
||||
Check if bash-style arrays with specified indices work as expected
|
||||
category: !smksh
|
||||
stdin:
|
||||
v="c d"
|
||||
foo=([1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b)
|
||||
@ -6409,7 +6405,6 @@ expected-stdout:
|
||||
name: arrays-9a
|
||||
description:
|
||||
Check that we can concatenate arrays
|
||||
category: !smksh
|
||||
stdin:
|
||||
unset foo; foo=(bar); foo+=(baz); echo 1 ${!foo[*]} : ${foo[*]} .
|
||||
unset foo; foo=(foo bar); foo+=(baz); echo 2 ${!foo[*]} : ${foo[*]} .
|
||||
@ -7651,46 +7646,39 @@ description:
|
||||
Fails on: pdksh bash2 bash3 zsh
|
||||
Passes on: bash4 ksh93 mksh(20110313+)
|
||||
stdin:
|
||||
echo $(case 1 in (1) echo yes;; (2) echo no;; esac)
|
||||
echo $(case 1 in 1) echo yes;; 2) echo no;; esac)
|
||||
TEST=1234; echo ${TEST: $(case 1 in (1) echo 1;; (*) echo 2;; esac)}
|
||||
TEST=5678; echo ${TEST: $(case 1 in 1) echo 1;; *) echo 2;; esac)}
|
||||
echo 1 $(case 1 in (1) echo yes;; (2) echo no;; esac) .
|
||||
echo 2 $(case 1 in 1) echo yes;; 2) echo no;; esac) .
|
||||
TEST=1234; echo 3 ${TEST: $(case 1 in (1) echo 1;; (*) echo 2;; esac)} .
|
||||
TEST=5678; echo 4 ${TEST: $(case 1 in 1) echo 1;; *) echo 2;; esac)} .
|
||||
a=($(case 1 in (1) echo 1;; (*) echo 2;; esac)); echo 5 ${a[0]} .
|
||||
a=($(case 1 in 1) echo 1;; *) echo 2;; esac)); echo 6 ${a[0]} .
|
||||
expected-stdout:
|
||||
yes
|
||||
yes
|
||||
234
|
||||
678
|
||||
1 yes .
|
||||
2 yes .
|
||||
3 234 .
|
||||
4 678 .
|
||||
5 1 .
|
||||
6 1 .
|
||||
---
|
||||
name: comsub-1b
|
||||
description:
|
||||
COMSUB are now parsed recursively, so this works
|
||||
Fails on GNU bash even, ksh93 passes
|
||||
Fails on: pdksh bash2 bash3 bash4 zsh
|
||||
Passes on: ksh93 mksh(20110313+)
|
||||
stdin:
|
||||
echo $(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10))
|
||||
echo $(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20))
|
||||
(( a = $(case 1 in (1) echo 1;; (*) echo 2;; esac) )); echo $a.
|
||||
(( a = $(case 1 in 1) echo 1;; *) echo 2;; esac) )); echo $a.
|
||||
echo 1 $(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10)) .
|
||||
echo 2 $(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20)) .
|
||||
(( a = $(case 1 in (1) echo 1;; (*) echo 2;; esac) )); echo 3 $a .
|
||||
(( a = $(case 1 in 1) echo 1;; *) echo 2;; esac) )); echo 4 $a .
|
||||
a=($(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10))); echo 5 ${a[0]} .
|
||||
a=($(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20))); echo 6 ${a[0]} .
|
||||
expected-stdout:
|
||||
11
|
||||
21
|
||||
1.
|
||||
1.
|
||||
---
|
||||
name: comsub-1c
|
||||
description:
|
||||
COMSUB are now parsed recursively, so this works (ksh93, mksh)
|
||||
First test passes on bash4, second fails there
|
||||
category: !smksh
|
||||
stdin:
|
||||
a=($(case 1 in (1) echo 1;; (*) echo 2;; esac)); echo ${a[0]}.
|
||||
a=($(case 1 in 1) echo 1;; *) echo 2;; esac)); echo ${a[0]}.
|
||||
a=($(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10))); echo ${a[0]}.
|
||||
a=($(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20))); echo ${a[0]}.
|
||||
expected-stdout:
|
||||
1.
|
||||
1.
|
||||
11.
|
||||
21.
|
||||
1 11 .
|
||||
2 21 .
|
||||
3 1 .
|
||||
4 1 .
|
||||
5 11 .
|
||||
6 21 .
|
||||
---
|
||||
name: comsub-2
|
||||
description:
|
||||
@ -7732,16 +7720,16 @@ description:
|
||||
Check the tree dump functions for !MKSH_SMALL functionality
|
||||
category: !smksh
|
||||
stdin:
|
||||
x() { case $1 in a) a+=b ;;& *) c+=(d e) ;; esac; }
|
||||
x() { case $1 in u) echo x ;;& *) echo $1 ;; esac; }
|
||||
typeset -f x
|
||||
expected-stdout:
|
||||
x() {
|
||||
case $1 in
|
||||
(a)
|
||||
a+=b
|
||||
(u)
|
||||
echo x
|
||||
;|
|
||||
(*)
|
||||
set -A c+ -- d e
|
||||
echo $1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@ -7844,6 +7832,8 @@ stdin:
|
||||
install -c -o root -g wheel -m 664 /dev/null /etc/motd
|
||||
print -- "$x\n" >/etc/motd
|
||||
fi
|
||||
#wdarrassign
|
||||
a+=b; c+=(d e)
|
||||
#0
|
||||
EOD
|
||||
expected-stdout:
|
||||
@ -8409,6 +8399,25 @@ expected-stdout:
|
||||
EOF
|
||||
)" = @(?) ]] && rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then install -c -o root -g wheel -m 664 /dev/null /etc/motd ; print -- "$x\n" >/etc/motd ; fi ) | tr u x )
|
||||
}
|
||||
inline_wdarrassign() {
|
||||
a+=b; c+=(d e)
|
||||
}
|
||||
inline_wdarrassign() {
|
||||
a+=b
|
||||
set -A c+ -- d e
|
||||
}
|
||||
function comsub_wdarrassign { x=$(
|
||||
a+=b; c+=(d e)
|
||||
); }
|
||||
function comsub_wdarrassign {
|
||||
x=$(a+=b ; set -A c+ -- d e )
|
||||
}
|
||||
function reread_wdarrassign { x=$((
|
||||
a+=b; c+=(d e)
|
||||
)|tr u x); }
|
||||
function reread_wdarrassign {
|
||||
x=$(( a+=b ; set -A c+ -- d e ) | tr u x )
|
||||
}
|
||||
---
|
||||
name: test-stnze-1
|
||||
description:
|
||||
|
4
sh.h
4
sh.h
@ -151,9 +151,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.501 2011/11/09 22:17:26 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.502 2011/11/11 22:14:17 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R40 2011/11/09"
|
||||
#define MKSH_VERSION "R40 2011/11/11"
|
||||
|
||||
#ifndef MKSH_INCLUDES_ONLY
|
||||
|
||||
|
126
syn.c
126
syn.c
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.69 2011/09/07 15:24:21 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.70 2011/11/11 22:14:19 tg Exp $");
|
||||
|
||||
extern short subshell_nesting_level;
|
||||
extern void yyskiputf8bom(void);
|
||||
@ -232,13 +232,27 @@ nested(int type, int smark, int emark)
|
||||
return (block(type, t, NOBLOCK, NOWORDS));
|
||||
}
|
||||
|
||||
static const char let_cmd[] = {
|
||||
CHAR, 'l', CHAR, 'e', CHAR, 't', EOS
|
||||
};
|
||||
static const char setA_cmd0[] = {
|
||||
CHAR, 's', CHAR, 'e', CHAR, 't', EOS
|
||||
};
|
||||
static const char setA_cmd1[] = {
|
||||
CHAR, '-', CHAR, 'A', EOS
|
||||
};
|
||||
static const char setA_cmd2[] = {
|
||||
CHAR, '-', CHAR, '-', EOS
|
||||
};
|
||||
|
||||
static struct op *
|
||||
get_command(int cf)
|
||||
{
|
||||
struct op *t;
|
||||
int c, iopn = 0, syniocf;
|
||||
int c, iopn = 0, syniocf, lno;
|
||||
struct ioword *iop, **iops;
|
||||
XPtrV args, vars;
|
||||
char *tcp;
|
||||
struct nesting_state old_nesting;
|
||||
|
||||
/* NUFILE is small enough to leave this addition unchecked */
|
||||
@ -292,67 +306,50 @@ get_command(int cf)
|
||||
XPput(args, yylval.cp);
|
||||
break;
|
||||
|
||||
case '(':
|
||||
#ifndef MKSH_SMALL
|
||||
if ((XPsize(args) == 0 || Flag(FKEYWORD)) &&
|
||||
XPsize(vars) == 1 && is_wdvarassign(yylval.cp))
|
||||
goto is_wdarrassign;
|
||||
#endif
|
||||
/*
|
||||
* Check for "> foo (echo hi)" which AT&T ksh
|
||||
* allows (not POSIX, but not disallowed)
|
||||
*/
|
||||
afree(t, ATEMP);
|
||||
if (XPsize(args) == 0 && XPsize(vars) == 0) {
|
||||
case '(' /*)*/:
|
||||
if (XPsize(args) == 0 && XPsize(vars) == 1 &&
|
||||
is_wdvarassign(yylval.cp)) {
|
||||
/* wdarrassign: foo=(bar) */
|
||||
ACCEPT;
|
||||
goto Subshell;
|
||||
|
||||
/* manipulate the vars string */
|
||||
tcp = *(--vars.cur);
|
||||
/* 'varname=' -> 'varname' */
|
||||
tcp[wdscan(tcp, EOS) - tcp - 3] = EOS;
|
||||
|
||||
/* construct new args strings */
|
||||
XPput(args, wdcopy(setA_cmd0, ATEMP));
|
||||
XPput(args, wdcopy(setA_cmd1, ATEMP));
|
||||
XPput(args, tcp);
|
||||
XPput(args, wdcopy(setA_cmd2, ATEMP));
|
||||
|
||||
/* slurp in words till closing paren */
|
||||
while (token(CONTIN) == LWORD)
|
||||
XPput(args, yylval.cp);
|
||||
if (symbol != /*(*/ ')')
|
||||
syntaxerr(NULL);
|
||||
} else {
|
||||
/*
|
||||
* Check for "> foo (echo hi)"
|
||||
* which AT&T ksh allows (not
|
||||
* POSIX, but not disallowed)
|
||||
*/
|
||||
afree(t, ATEMP);
|
||||
if (XPsize(args) == 0 &&
|
||||
XPsize(vars) == 0) {
|
||||
ACCEPT;
|
||||
goto Subshell;
|
||||
}
|
||||
|
||||
/* must be a function */
|
||||
if (iopn != 0 || XPsize(args) != 1 ||
|
||||
XPsize(vars) != 0)
|
||||
syntaxerr(NULL);
|
||||
ACCEPT;
|
||||
musthave(/*(*/')', 0);
|
||||
t = function_body(XPptrv(args)[0], false);
|
||||
}
|
||||
|
||||
/* must be a function */
|
||||
if (iopn != 0 || XPsize(args) != 1 ||
|
||||
XPsize(vars) != 0)
|
||||
syntaxerr(NULL);
|
||||
ACCEPT;
|
||||
musthave(/*(*/')', 0);
|
||||
t = function_body(XPptrv(args)[0], false);
|
||||
goto Leave;
|
||||
#ifndef MKSH_SMALL
|
||||
is_wdarrassign:
|
||||
{
|
||||
static const char set_cmd0[] = {
|
||||
CHAR, 's', CHAR, 'e',
|
||||
CHAR, 't', EOS
|
||||
};
|
||||
static const char set_cmd1[] = {
|
||||
CHAR, '-', CHAR, 'A', EOS
|
||||
};
|
||||
static const char set_cmd2[] = {
|
||||
CHAR, '-', CHAR, '-', EOS
|
||||
};
|
||||
char *tcp;
|
||||
|
||||
ACCEPT;
|
||||
|
||||
/* manipulate the vars string */
|
||||
tcp = *(--vars.cur);
|
||||
/* 'varname=' -> 'varname' */
|
||||
tcp[wdscan(tcp, EOS) - tcp - 3] = EOS;
|
||||
|
||||
/* construct new args strings */
|
||||
XPput(args, wdcopy(set_cmd0, ATEMP));
|
||||
XPput(args, wdcopy(set_cmd1, ATEMP));
|
||||
XPput(args, tcp);
|
||||
XPput(args, wdcopy(set_cmd2, ATEMP));
|
||||
|
||||
/* slurp in words till closing paren */
|
||||
while (token(CONTIN) == LWORD)
|
||||
XPput(args, yylval.cp);
|
||||
if (symbol != /*(*/ ')')
|
||||
syntaxerr(NULL);
|
||||
|
||||
goto Leave;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
goto Leave;
|
||||
@ -372,13 +369,7 @@ get_command(int cf)
|
||||
t = nested(TBRACE, '{', '}');
|
||||
break;
|
||||
|
||||
case MDPAREN: {
|
||||
int lno;
|
||||
static const char let_cmd[] = {
|
||||
CHAR, 'l', CHAR, 'e',
|
||||
CHAR, 't', EOS
|
||||
};
|
||||
|
||||
case MDPAREN:
|
||||
/* leave KEYWORD in syniocf (allow if (( 1 )) then ...) */
|
||||
lno = source->line;
|
||||
ACCEPT;
|
||||
@ -395,7 +386,6 @@ get_command(int cf)
|
||||
XPput(args, wdcopy(let_cmd, ATEMP));
|
||||
XPput(args, yylval.cp);
|
||||
break;
|
||||
}
|
||||
|
||||
case DBRACKET: /* [[ .. ]] */
|
||||
/* leave KEYWORD in syniocf (allow if [[ -n 1 ]] then ...) */
|
||||
|
20
var.c
20
var.c
@ -26,7 +26,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.134 2011/11/08 22:07:15 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.135 2011/11/11 22:14:19 tg Exp $");
|
||||
|
||||
/*-
|
||||
* Variables
|
||||
@ -1379,29 +1379,23 @@ set_array(const char *var, bool reset, const char **vals)
|
||||
{
|
||||
struct tbl *vp, *vq;
|
||||
mksh_uari_t i = 0, j = 0;
|
||||
const char *ccp;
|
||||
#ifndef MKSH_SMALL
|
||||
const char *ccp = var;
|
||||
char *cp = NULL;
|
||||
size_t n;
|
||||
#endif
|
||||
|
||||
/* to get local array, use "typeset foo; set -A foo" */
|
||||
#ifndef MKSH_SMALL
|
||||
n = strlen(var);
|
||||
if (n > 0 && var[n - 1] == '+') {
|
||||
/* append mode */
|
||||
reset = false;
|
||||
strndupx(cp, var, n - 1, ATEMP);
|
||||
ccp = cp;
|
||||
}
|
||||
#define CPORVAR (cp ? cp : var)
|
||||
#else
|
||||
#define CPORVAR var
|
||||
#endif
|
||||
vp = global(CPORVAR);
|
||||
vp = global(ccp);
|
||||
|
||||
/* Note: AT&T ksh allows set -A but not set +A of a read-only var */
|
||||
if ((vp->flag&RDONLY))
|
||||
errorfx(2, "%s: %s", CPORVAR, "is read only");
|
||||
errorfx(2, "%s: %s", ccp, "is read only");
|
||||
/* This code is quite non-optimal */
|
||||
if (reset)
|
||||
/* trash existing values and attributes */
|
||||
@ -1411,7 +1405,6 @@ set_array(const char *var, bool reset, const char **vals)
|
||||
* completely fail. Only really effects integer arrays:
|
||||
* evaluation of some of vals[] may fail...
|
||||
*/
|
||||
#ifndef MKSH_SMALL
|
||||
if (cp != NULL) {
|
||||
/* find out where to set when appending */
|
||||
for (vq = vp; vq; vq = vq->u.array) {
|
||||
@ -1422,9 +1415,7 @@ set_array(const char *var, bool reset, const char **vals)
|
||||
}
|
||||
afree(cp, ATEMP);
|
||||
}
|
||||
#endif
|
||||
while ((ccp = vals[i])) {
|
||||
#ifndef MKSH_SMALL
|
||||
if (*ccp == '[') {
|
||||
int level = 0;
|
||||
|
||||
@ -1445,7 +1436,6 @@ set_array(const char *var, bool reset, const char **vals)
|
||||
} else
|
||||
ccp = vals[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
vq = arraysearch(vp, j);
|
||||
/* would be nice to deal with errors here... (see above) */
|
||||
|
Loading…
Reference in New Issue
Block a user