revert most of commitid 3ec342c92b3a8874 and fixup the rest;

this should bring us closer to POSIX again
This commit is contained in:
tg
2015-10-09 17:48:53 +00:00
parent 3fc8b5eb94
commit af35e9a6de
8 changed files with 72 additions and 58 deletions

13
check.t
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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) {