revert most of commitid 3ec342c92b3a8874 and fixup the rest;
this should bring us closer to POSIX again
This commit is contained in:
13
check.t
13
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.708 2015/10/05 17:58:57 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.709 2015/10/09 17:48:46 tg Exp $
|
||||||
# -*- mode: sh -*-
|
# -*- mode: sh -*-
|
||||||
#-
|
#-
|
||||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
@ -6505,18 +6505,13 @@ name: xxx-param-subst-qmark-1
|
|||||||
description:
|
description:
|
||||||
Check suppresion of error message with null string. According to
|
Check suppresion of error message with null string. According to
|
||||||
POSIX, it shouldn't print the error as 'word' isn't ommitted.
|
POSIX, it shouldn't print the error as 'word' isn't ommitted.
|
||||||
ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error,
|
ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error.
|
||||||
that's why the condition is reversed.
|
|
||||||
stdin:
|
stdin:
|
||||||
unset foo
|
unset foo
|
||||||
x=
|
x=
|
||||||
echo x${foo?$x}
|
echo x${foo?$x}
|
||||||
expected-exit: 1
|
expected-exit: 1
|
||||||
# POSIX
|
expected-stderr-pattern: !/not set/
|
||||||
#expected-fail: yes
|
|
||||||
#expected-stderr-pattern: !/not set/
|
|
||||||
# common use
|
|
||||||
expected-stderr-pattern: /parameter null or not set/
|
|
||||||
---
|
---
|
||||||
name: xxx-param-_-1
|
name: xxx-param-_-1
|
||||||
# fails due to weirdness of execv stuff
|
# fails due to weirdness of execv stuff
|
||||||
@ -6532,7 +6527,7 @@ description:
|
|||||||
env-setup: !HOME=/sweet!
|
env-setup: !HOME=/sweet!
|
||||||
stdin:
|
stdin:
|
||||||
echo ${A=a=}~ b=~ c=d~ ~
|
echo ${A=a=}~ b=~ c=d~ ~
|
||||||
set +o braceexpand
|
set -o posix
|
||||||
unset A
|
unset A
|
||||||
echo ${A=a=}~ b=~ c=d~ ~
|
echo ${A=a=}~ b=~ c=d~ ~
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
|
24
eval.c
24
eval.c
@ -3,7 +3,7 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2015
|
* 2011, 2012, 2013, 2014, 2015
|
||||||
* mirabilos <tg@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
|
||||||
* are retained or reproduced in an accompanying document, permission
|
* are retained or reproduced in an accompanying document, permission
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.172 2015/09/06 19:46:59 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.173 2015/10/09 17:48:48 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string expansion
|
* string expansion
|
||||||
@ -648,6 +648,9 @@ expand(
|
|||||||
tilde_ok = 1;
|
tilde_ok = 1;
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
|
if (*sp == CSUBST)
|
||||||
|
errorf("%s: parameter null or not set",
|
||||||
|
st->var->name);
|
||||||
f &= ~DOBLANK;
|
f &= ~DOBLANK;
|
||||||
f |= DOTEMP;
|
f |= DOTEMP;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
@ -743,14 +746,12 @@ expand(
|
|||||||
st = st->prev;
|
st = st->prev;
|
||||||
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
|
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
|
||||||
continue;
|
continue;
|
||||||
case '?': {
|
case '?':
|
||||||
char *s = Xrestpos(ds, dp, st->base);
|
dp = Xrestpos(ds, dp, st->base);
|
||||||
|
|
||||||
errorf("%s: %s", st->var->name,
|
errorf("%s: %s", st->var->name,
|
||||||
dp == s ?
|
debunk(dp, dp, strlen(dp) + 1));
|
||||||
"parameter null or not set" :
|
break;
|
||||||
(debunk(s, s, strlen(s) + 1), s));
|
|
||||||
}
|
|
||||||
case '0':
|
case '0':
|
||||||
case '/':
|
case '/':
|
||||||
case 0x100 | '#':
|
case 0x100 | '#':
|
||||||
@ -1001,9 +1002,8 @@ expand(
|
|||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
/* Note first unquoted = for ~ */
|
/* Note first unquoted = for ~ */
|
||||||
if (!(f & DOTEMP) && !saw_eq &&
|
if (!(f & DOTEMP) && (!Flag(FPOSIX) ||
|
||||||
(Flag(FBRACEEXPAND) ||
|
(f & DOASNTILDE)) && !saw_eq) {
|
||||||
(f & DOASNTILDE))) {
|
|
||||||
saw_eq = true;
|
saw_eq = true;
|
||||||
tilde_ok = 1;
|
tilde_ok = 1;
|
||||||
}
|
}
|
||||||
@ -1287,7 +1287,7 @@ varsub(Expand *xp, const char *sp, const char *word,
|
|||||||
c = stype & 0x7F;
|
c = stype & 0x7F;
|
||||||
/* test the compiler's code generator */
|
/* test the compiler's code generator */
|
||||||
if (((stype < 0x100) && (ctype(c, C_SUBOP2) || c == '/' ||
|
if (((stype < 0x100) && (ctype(c, C_SUBOP2) || c == '/' ||
|
||||||
(((stype&0x80) ? *xp->str=='\0' : xp->str==null) ? /* undef? */
|
(((stype & 0x80) ? *xp->str == '\0' : xp->str == null) ?
|
||||||
c == '=' || c == '-' || c == '?' : c == '+'))) ||
|
c == '=' || c == '-' || c == '?' : c == '+'))) ||
|
||||||
stype == (0x80 | '0') || stype == (0x100 | '#') ||
|
stype == (0x80 | '0') || stype == (0x100 | '#') ||
|
||||||
stype == (0x100 | 'Q'))
|
stype == (0x100 | 'Q'))
|
||||||
|
6
exec.c
6
exec.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.165 2015/10/09 16:11:14 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.166 2015/10/09 17:48:49 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"
|
||||||
@ -1348,7 +1348,9 @@ call_builtin(struct tbl *tp, const char **wp, const char *where, bool resetspec)
|
|||||||
if (!tp)
|
if (!tp)
|
||||||
internal_errorf("%s: %s", where, wp[0]);
|
internal_errorf("%s: %s", where, wp[0]);
|
||||||
builtin_argv0 = wp[0];
|
builtin_argv0 = wp[0];
|
||||||
builtin_spec = tobool(!resetspec && (tp->flag & SPEC_BI));
|
builtin_spec = tobool(!resetspec &&
|
||||||
|
/*XXX odd use of KEEPASN */
|
||||||
|
((tp->flag & SPEC_BI) || (Flag(FPOSIX) && (tp->flag & KEEPASN))));
|
||||||
shf_reopen(1, SHF_WR, shl_stdout);
|
shf_reopen(1, SHF_WR, shl_stdout);
|
||||||
shl_stdout_ok = true;
|
shl_stdout_ok = true;
|
||||||
ksh_getopt_reset(&builtin_opt, GF_ERROR);
|
ksh_getopt_reset(&builtin_opt, GF_ERROR);
|
||||||
|
15
funcs.c
15
funcs.c
@ -38,7 +38,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.284 2015/10/09 16:11:14 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.285 2015/10/09 17:48:50 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
@ -1305,7 +1305,8 @@ c_fgbg(const char **wp)
|
|||||||
rv = j_resume(*wp, bg);
|
rv = j_resume(*wp, bg);
|
||||||
else
|
else
|
||||||
rv = j_resume("%%", bg);
|
rv = j_resume("%%", bg);
|
||||||
return (bg ? 0 : rv);
|
/* fg returns $? of the job unless POSIX */
|
||||||
|
return ((bg | Flag(FPOSIX)) ? 0 : rv);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1383,6 +1384,13 @@ c_kill(const char **wp)
|
|||||||
else
|
else
|
||||||
shprintf("%d\n", n);
|
shprintf("%d\n", n);
|
||||||
}
|
}
|
||||||
|
} else if (Flag(FPOSIX)) {
|
||||||
|
n = 1;
|
||||||
|
while (n < ksh_NSIG) {
|
||||||
|
shf_puts(sigtraps[n].name, shl_stdout);
|
||||||
|
shf_putc(++n == ksh_NSIG ? '\n' : ' ',
|
||||||
|
shl_stdout);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ssize_t w, mess_cols = 0, mess_octs = 0;
|
ssize_t w, mess_cols = 0, mess_octs = 0;
|
||||||
int j = ksh_NSIG - 1;
|
int j = ksh_NSIG - 1;
|
||||||
@ -1436,7 +1444,8 @@ void
|
|||||||
getopts_reset(int val)
|
getopts_reset(int val)
|
||||||
{
|
{
|
||||||
if (val >= 1) {
|
if (val >= 1) {
|
||||||
ksh_getopt_reset(&user_opt, GF_NONAME | GF_PLUSOPT);
|
ksh_getopt_reset(&user_opt, GF_NONAME |
|
||||||
|
(Flag(FPOSIX) ? 0 : GF_PLUSOPT));
|
||||||
user_opt.optind = user_opt.uoptind = val;
|
user_opt.optind = user_opt.uoptind = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
lex.c
50
lex.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.210 2015/10/09 16:11:16 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.211 2015/10/09 17:48:51 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* states while lexing word
|
* states while lexing word
|
||||||
@ -234,6 +234,8 @@ yylex(int cf)
|
|||||||
if (source->flags & SF_ALIAS) {
|
if (source->flags & SF_ALIAS) {
|
||||||
/* trailing ' ' in alias definition */
|
/* trailing ' ' in alias definition */
|
||||||
source->flags &= ~SF_ALIAS;
|
source->flags &= ~SF_ALIAS;
|
||||||
|
/* POSIX: trailing space only counts if parsing simple cmd */
|
||||||
|
if (!Flag(FPOSIX) || (cf & CMDWORD))
|
||||||
cf |= ALIAS;
|
cf |= ALIAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,27 +526,32 @@ yylex(int cf)
|
|||||||
PUSH_STATE(SBQUOTE);
|
PUSH_STATE(SBQUOTE);
|
||||||
*wp++ = COMSUB;
|
*wp++ = COMSUB;
|
||||||
/*
|
/*
|
||||||
* Need to know if we are inside double quotes
|
* We need to know whether we are within double
|
||||||
* since sh/AT&T-ksh translate the \" to " in
|
* quotes, since most shells translate \" to "
|
||||||
* "`...\"...`".
|
* within "…`…\"…`…". This is not done in POSIX
|
||||||
* This is not done in POSIX mode (section
|
* mode (§2.2.3 Double-Quotes: “The backquote
|
||||||
* 3.2.3, Double Quotes: "The backquote shall
|
* shall retain its special meaning introducing
|
||||||
* retain its special meaning introducing the
|
* the other form of command substitution (see
|
||||||
* other form of command substitution (see
|
* Command Substitution). The portion of the
|
||||||
* 3.6.3). The portion of the quoted string
|
* quoted string from the initial backquote and
|
||||||
* from the initial backquote and the
|
* the characters up to the next backquote that
|
||||||
* characters up to the next backquote that
|
* is not preceded by a <backslash>, having
|
||||||
* is not preceded by a backslash (having
|
* escape characters removed, defines that
|
||||||
* escape characters removed) defines that
|
* command whose output replaces "`...`" when
|
||||||
* command whose output replaces `...` when
|
* the word is expanded.”; §2.6.3 Command
|
||||||
* the word is expanded."
|
* Substitution: “Within the backquoted style
|
||||||
* Section 3.6.3, Command Substitution:
|
* of command substitution, <backslash> shall
|
||||||
* "Within the backquoted style of command
|
* retain its literal meaning, except when
|
||||||
* substitution, backslash shall retain its
|
* followed by: '$', '`', or <backslash>. The
|
||||||
* literal meaning, except when followed by
|
* search for the matching backquote shall be
|
||||||
* $ ` \.").
|
* satisfied by the first unquoted non-escaped
|
||||||
|
* backquote; during this search, if a
|
||||||
|
* non-escaped backquote is encountered[…],
|
||||||
|
* undefined results occur.”).
|
||||||
*/
|
*/
|
||||||
statep->ls_bool = false;
|
statep->ls_bool = false;
|
||||||
|
if (Flag(FPOSIX))
|
||||||
|
break;
|
||||||
s2 = statep;
|
s2 = statep;
|
||||||
base = state_info.base;
|
base = state_info.base;
|
||||||
while (/* CONSTCOND */ 1) {
|
while (/* CONSTCOND */ 1) {
|
||||||
@ -732,8 +739,9 @@ yylex(int cf)
|
|||||||
case 0:
|
case 0:
|
||||||
/* trailing \ is lost */
|
/* trailing \ is lost */
|
||||||
break;
|
break;
|
||||||
|
case '$':
|
||||||
|
case '`':
|
||||||
case '\\':
|
case '\\':
|
||||||
case '$': case '`':
|
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
|
5
main.c
5
main.c
@ -34,7 +34,7 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.304 2015/10/09 16:11:16 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.305 2015/10/09 17:48:51 tg Exp $");
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
@ -1265,8 +1265,7 @@ bi_errorf(const char *fmt, ...)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* POSIX special builtins and ksh special builtins cause
|
* POSIX special builtins and ksh special builtins cause
|
||||||
* non-interactive shells to exit.
|
* non-interactive shells to exit. XXX may not want LERROR here
|
||||||
* XXX odd use of KEEPASN; also may not want LERROR here
|
|
||||||
*/
|
*/
|
||||||
if (builtin_spec) {
|
if (builtin_spec) {
|
||||||
builtin_argv0 = NULL;
|
builtin_argv0 = NULL;
|
||||||
|
9
sh.h
9
sh.h
@ -172,7 +172,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.746 2015/10/09 16:11:18 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.747 2015/10/09 17:48:52 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R51 2015/10/05"
|
#define MKSH_VERSION "R51 2015/10/05"
|
||||||
|
|
||||||
@ -1634,9 +1634,10 @@ typedef union {
|
|||||||
#define VARASN BIT(5) /* check for var=word */
|
#define VARASN BIT(5) /* check for var=word */
|
||||||
#define ARRAYVAR BIT(6) /* parse x[1 & 2] as one word */
|
#define ARRAYVAR BIT(6) /* parse x[1 & 2] as one word */
|
||||||
#define ESACONLY BIT(7) /* only accept esac keyword */
|
#define ESACONLY BIT(7) /* only accept esac keyword */
|
||||||
#define HEREDELIM BIT(8) /* parsing <<,<<- delimiter */
|
#define CMDWORD BIT(8) /* parsing simple command (alias related) */
|
||||||
#define LQCHAR BIT(9) /* source string contains QCHAR */
|
#define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */
|
||||||
#define HEREDOC BIT(10) /* parsing a here document body */
|
#define LQCHAR BIT(10) /* source string contains QCHAR */
|
||||||
|
#define HEREDOC BIT(11) /* parsing a here document body */
|
||||||
|
|
||||||
#define HERES 10 /* max number of << in line */
|
#define HERES 10 /* max number of << in line */
|
||||||
|
|
||||||
|
6
syn.c
6
syn.c
@ -3,7 +3,7 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
* 2011, 2012, 2013, 2014, 2015
|
* 2011, 2012, 2013, 2014, 2015
|
||||||
* mirabilos <tg@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
|
||||||
* are retained or reproduced in an accompanying document, permission
|
* are retained or reproduced in an accompanying document, permission
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.104 2015/09/06 19:47:01 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.105 2015/10/09 17:48:53 tg Exp $");
|
||||||
|
|
||||||
struct nesting_state {
|
struct nesting_state {
|
||||||
int start_token; /* token than began nesting (eg, FOR) */
|
int start_token; /* token than began nesting (eg, FOR) */
|
||||||
@ -294,7 +294,7 @@ get_command(int cf)
|
|||||||
t->lineno = source->line;
|
t->lineno = source->line;
|
||||||
while (/* CONSTCOND */ 1) {
|
while (/* CONSTCOND */ 1) {
|
||||||
cf = (t->u.evalflags ? ARRAYVAR : 0) |
|
cf = (t->u.evalflags ? ARRAYVAR : 0) |
|
||||||
(XPsize(args) == 0 ? sALIAS|VARASN : 0);
|
(XPsize(args) == 0 ? sALIAS|VARASN : CMDWORD);
|
||||||
switch (tpeek(cf)) {
|
switch (tpeek(cf)) {
|
||||||
case REDIR:
|
case REDIR:
|
||||||
while ((iop = synio(cf)) != NULL) {
|
while ((iop = synio(cf)) != NULL) {
|
||||||
|
Reference in New Issue
Block a user