summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system/dash/README17
-rw-r--r--system/dash/dash.SlackBuild24
-rw-r--r--system/dash/dash.info10
-rw-r--r--system/dash/patches/dash-0.5.8-git_d7582e6.diff2371
4 files changed, 18 insertions, 2404 deletions
diff --git a/system/dash/README b/system/dash/README
index 4daf9c0301..4f1ca583a5 100644
--- a/system/dash/README
+++ b/system/dash/README
@@ -1,13 +1,4 @@
-DASH is a POSIX-compliant implementation of /bin/sh that aims to be as
-small as possible. It does this without sacrificing speed where possible.
-In fact, it is significantly faster than bash (the GNU Bourne-Again SHell)
-for most tasks.
-
-To patch in fixes from current git, add 'USE_GIT_PATCH=yes' to the command
-line when building, like this:
-
-# USE_GIT_PATCH=yes sh dash.Slackbuild
-
-or, if you use fakeroot to build:
-
-$ fakeroot env USE_GIT_PATCH=yes sh dash.SlackBuild
+DASH is a POSIX-compliant implementation of /bin/sh that aims to be as
+small as possible. It does this without sacrificing speed where
+possible. In fact, it is significantly faster than bash (the GNU
+Bourne-Again SHell) for most tasks.
diff --git a/system/dash/dash.SlackBuild b/system/dash/dash.SlackBuild
index f0c362a7d5..61c42279a9 100644
--- a/system/dash/dash.SlackBuild
+++ b/system/dash/dash.SlackBuild
@@ -3,17 +3,16 @@
# Slackware build script for dash
# Written by Vincent Batts, http://hashbangbash.com/
+# Copyright 2017 Donald Cooley South Haven, Indiana USA
PRGNAM=dash
-VERSION=${VERSION:-0.5.8}
-_PATCH_VERS=${PATCH_VERS:-git_d7582e6}
+VERSION=${VERSION:-0.5.9.1}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
-USE_GIT_PATCH=${USE_GIT_PATCH:-no}
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) ARCH=i486 ;;
+ i?86) ARCH=i586 ;;
arm*) ARCH=arm ;;
*) ARCH=$( uname -m ) ;;
esac
@@ -24,8 +23,8 @@ TMP=${TMP:-/tmp/SBo}
PKG=$TMP/package-$PRGNAM
OUTPUT=${OUTPUT:-/tmp}
-if [ "$ARCH" = "i486" ]; then
- SLKCFLAGS="-O2 -march=i486 -mtune=i686"
+if [ "$ARCH" = "i586" ]; then
+ SLKCFLAGS="-O2 -march=i586 -mtune=i686"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "i686" ]; then
SLKCFLAGS="-O2 -march=i686 -mtune=i686"
@@ -47,13 +46,6 @@ rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
cd $PRGNAM-$VERSION
-# add fixes from upstream devel, if requested
-if [ "$USE_GIT_PATCH" = "yes" ] && \
- [ -f $CWD/patches/dash-${VERSION}-${_PATCH_VERS}.diff ]; then
- patch -p1 < $CWD/patches/dash-${VERSION}-${_PATCH_VERS}.diff
- VERSION="${VERSION}.${_PATCH_VERS}"
-fi
-
chown -R root:root .
find -L . \
\( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 -o -perm 511 \) \
@@ -78,14 +70,16 @@ make install DESTDIR=$PKG
mkdir -p $PKG/usr/bin
( cd $PKG/usr/bin ; ln -s /bin/dash dash )
-find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \
+find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
find $PKG/usr/man -type f -exec gzip -9 {} \;
for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
-cp -a COPYING ChangeLog $PKG/usr/doc/$PRGNAM-$VERSION
+cp -a \
+ COPYING ChangeLog \
+ $PKG/usr/doc/$PRGNAM-$VERSION
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
mkdir -p $PKG/install
diff --git a/system/dash/dash.info b/system/dash/dash.info
index 6d206c8caa..5603cdd0bc 100644
--- a/system/dash/dash.info
+++ b/system/dash/dash.info
@@ -1,10 +1,10 @@
PRGNAM="dash"
-VERSION="0.5.8"
+VERSION="0.5.9.1"
HOMEPAGE="http://gondor.apana.org.au/~herbert/dash/"
-DOWNLOAD="http://gondor.apana.org.au/~herbert/dash/files/dash-0.5.8.tar.gz"
-MD5SUM="5c152209680dab3c319e8923f6c51378"
+DOWNLOAD="https://sourceforge.net/projects/slackbuildsdirectlinks/files/dash/dash-0.5.9.1.tar.gz"
+MD5SUM="6472702a8d9760d166ef8333dcb527a6"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
-MAINTAINER="John Vogel"
-EMAIL="jvogel4@stny.rr.com"
+MAINTAINER="Donald Cooley"
+EMAIL="chytraeu@sdf.org"
diff --git a/system/dash/patches/dash-0.5.8-git_d7582e6.diff b/system/dash/patches/dash-0.5.8-git_d7582e6.diff
deleted file mode 100644
index ac5c6903d5..0000000000
--- a/system/dash/patches/dash-0.5.8-git_d7582e6.diff
+++ /dev/null
@@ -1,2371 +0,0 @@
-diff -Naur dash-0.5.8/ChangeLog dash-0.5.8-git_d7582e6/ChangeLog
---- dash-0.5.8/ChangeLog 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/ChangeLog 2015-08-05 13:55:25.055358032 -0400
-@@ -1,3 +1,73 @@
-+2014-11-17 Stéphane Aulery <saulery@free.fr>
-+
-+ * Correct typo in manual page.
-+ * Document redirection file descriptor limitation.
-+
-+2014-10-30 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Catch variable length expansions on non-existant specials.
-+
-+2014-10-28 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Removed unnecessary pungetc on EOF from parser.
-+ * Simplify EOF/newline handling in list parser.
-+
-+2014-10-27 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Add printf support for format string a, A, and F.
-+ * Handle embedded NULs correctly in printf.
-+ * Replace open-coded flushall in preadbuffer.
-+ * Add likely tag in outmem.
-+ * Add ifdefs around MEM_OUT handling in outmem.
-+ * Remove unnecessary restoration of format string in printf.
-+ * Remove getintmax in printf.
-+ * Use error instead of warnx for fatal errors in printf.
-+ * Optimise handling of backslash octals in printf.
-+ * Simplify echo command.
-+ * Handle -- in dotcmd.
-+
-+2014-10-13 Eric Blake <eblake@redhat.com>
-+
-+ * cd: support drive letters on Cygwin.
-+
-+2014-10-08 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Split unquoted $@/$* correctly when IFS is set but empty.
-+ * Do not split quoted VSLENGTH and VSTRIM.
-+ * Optimise nulonly away and just use quoted as before.
-+
-+2014-10-07 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Use setvareq to set OPTIND initially.
-+
-+2014-10-06 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Exit without arguments in a trap should use status outside traps.
-+ * Do not allow break to break across function calls.
-+ * Move common skipcount logic into skiploop.
-+ * Allow return in loop conditional to set exit status.
-+ * Return without arguments in a trap should use status outside traps.
-+
-+2014-10-03 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Do not clobber exitstatus in evalcommand.
-+
-+2014-10-02 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Fix use-after-free in dotrap/evalstring.
-+ * Make sure evalskip is zero before running traps.
-+ * Set exitstatus in onint.
-+
-+2014-09-29 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Kill pgetc_macro.
-+ * Handle backslash newlines properly after dollar sign.
-+ * Add nlprompt/nlnoprompt helpers.
-+
-+2014-09-28 Herbert Xu <herbert@gondor.apana.org.au>
-+
-+ * Correctly handle test ! ! = !.
-+
- 2014-09-26 Herbert Xu <herbert@gondor.apana.org.au>
-
- * Small optimisation of command -pv change.
-diff -Naur dash-0.5.8/Makefile.in dash-0.5.8-git_d7582e6/Makefile.in
---- dash-0.5.8/Makefile.in 2014-09-28 04:19:40.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/Makefile.in 2015-08-05 13:57:40.555361584 -0400
-@@ -1,4 +1,4 @@
--# Makefile.in generated by automake 1.11.6 from Makefile.am.
-+# Makefile.in generated by automake 1.11.5 from Makefile.am.
- # @configure_input@
-
- # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-@@ -527,7 +527,7 @@
- *.zip*) \
- unzip $(distdir).zip ;;\
- esac
-- chmod -R a-w $(distdir); chmod u+w $(distdir)
-+ chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
- chmod a-w $(distdir)
-diff -Naur dash-0.5.8/aclocal.m4 dash-0.5.8-git_d7582e6/aclocal.m4
---- dash-0.5.8/aclocal.m4 2014-09-28 04:19:39.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/aclocal.m4 2015-08-05 13:57:39.728694896 -0400
-@@ -1,4 +1,4 @@
--# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
-+# generated automatically by aclocal 1.11.5 -*- Autoconf -*-
-
- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
-@@ -38,7 +38,7 @@
- [am__api_version='1.11'
- dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
- dnl require some minimum version. Point them to the right macro.
--m4_if([$1], [1.11.6], [],
-+m4_if([$1], [1.11.5], [],
- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
- ])
-
-@@ -54,7 +54,7 @@
- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
- # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
- AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
--[AM_AUTOMAKE_VERSION([1.11.6])dnl
-+[AM_AUTOMAKE_VERSION([1.11.5])dnl
- m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
- _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-diff -Naur dash-0.5.8/config.h.in dash-0.5.8-git_d7582e6/config.h.in
---- dash-0.5.8/config.h.in 2014-09-28 04:19:39.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/config.h.in 2015-08-05 13:57:40.062028238 -0400
-@@ -88,6 +88,9 @@
- /* Define to 1 if you have the <sys/types.h> header file. */
- #undef HAVE_SYS_TYPES_H
-
-+/* Define if your faccessat tells root all files are executable */
-+#undef HAVE_TRADITIONAL_FACCESSAT
-+
- /* Define to 1 if you have the <unistd.h> header file. */
- #undef HAVE_UNISTD_H
-
-diff -Naur dash-0.5.8/configure dash-0.5.8-git_d7582e6/configure
---- dash-0.5.8/configure 2014-09-28 04:19:40.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/configure 2015-08-05 13:57:40.772028257 -0400
-@@ -714,6 +714,7 @@
- enable_static
- enable_fnmatch
- enable_glob
-+enable_test_workaround
- with_libedit
- enable_lineno
- '
-@@ -1347,6 +1348,9 @@
- --enable-static Build statical linked program
- --enable-fnmatch Use fnmatch(3) from libc
- --enable-glob Use glob(3) from libc
-+ --enable-test-workaround
-+ Guard against faccessat(2) that tells root all files
-+ are executable
- --disable-lineno Disable LINENO support
-
- Optional Packages:
-@@ -4614,6 +4618,29 @@
- done
-
-
-+
-+# Check whether --enable-test-workaround was given.
-+if test "${enable_test_workaround+set}" = set; then :
-+ enableval=$enable_test_workaround;
-+else
-+ enable_test_workaround=auto
-+fi
-+
-+
-+if test "enable_test_workaround" = "auto" &&
-+ test "$ac_cv_func_faccessat" = yes; then
-+ case `uname -s 2>/dev/null` in
-+ GNU/kFreeBSD | \
-+ FreeBSD)
-+ enable_test_workaround=yes
-+ esac
-+fi
-+if test "$enable_test_workaround" = "yes"; then
-+
-+$as_echo "#define HAVE_TRADITIONAL_FACCESSAT 1" >>confdefs.h
-+
-+fi
-+
- if test "$enable_fnmatch" = yes; then
- use_fnmatch=
- for ac_func in fnmatch
-diff -Naur dash-0.5.8/configure.ac dash-0.5.8-git_d7582e6/configure.ac
---- dash-0.5.8/configure.ac 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/configure.ac 2015-08-05 13:55:25.055358032 -0400
-@@ -90,6 +90,37 @@
- sigsetmask stpcpy strchrnul strsignal strtod strtoimax \
- strtoumax sysconf)
-
-+dnl Check whether it's worth working around FreeBSD PR kern/125009.
-+dnl The traditional behavior of access/faccessat is crazy, but
-+dnl POSIX.1-2008 explicitly allows those functions to misbehave.
-+dnl
-+dnl Unaffected kernels:
-+dnl
-+dnl - all versions of Linux
-+dnl - NetBSD sys/kern/vfs_subr.c 1.64, 1997-04-23
-+dnl - FreeBSD 9 (r212002), 2010-09-10
-+dnl - OpenBSD sys/kern/vfs_subr.c 1.166, 2008-06-09
-+dnl
-+dnl Also worked around in Debian's libc0.1 2.13-19 when using
-+dnl kFreeBSD 8.
-+
-+AC_ARG_ENABLE(test-workaround, AS_HELP_STRING(--enable-test-workaround, \
-+ [Guard against faccessat(2) that tells root all files are executable]),,
-+ [enable_test_workaround=auto])
-+
-+if test "enable_test_workaround" = "auto" &&
-+ test "$ac_cv_func_faccessat" = yes; then
-+ case `uname -s 2>/dev/null` in
-+ GNU/kFreeBSD | \
-+ FreeBSD)
-+ enable_test_workaround=yes
-+ esac
-+fi
-+if test "$enable_test_workaround" = "yes"; then
-+ AC_DEFINE([HAVE_TRADITIONAL_FACCESSAT], [1],
-+ [Define if your faccessat tells root all files are executable])
-+fi
-+
- if test "$enable_fnmatch" = yes; then
- use_fnmatch=
- AC_CHECK_FUNCS(fnmatch, use_fnmatch=yes)
-diff -Naur dash-0.5.8/src/Makefile.am dash-0.5.8-git_d7582e6/src/Makefile.am
---- dash-0.5.8/src/Makefile.am 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/Makefile.am 2015-08-05 13:55:25.058691365 -0400
-@@ -26,7 +26,7 @@
- dash_SOURCES = \
- $(dash_CFILES) \
- alias.h arith_yacc.h bltin/bltin.h cd.h error.h eval.h exec.h \
-- expand.h hetio.h \
-+ expand.h \
- init.h input.h jobs.h machdep.h mail.h main.h memalloc.h miscbltin.h \
- myhistedit.h mystring.h options.h output.h parser.h redir.h shell.h \
- show.h system.h trap.h var.h
-diff -Naur dash-0.5.8/src/Makefile.in dash-0.5.8-git_d7582e6/src/Makefile.in
---- dash-0.5.8/src/Makefile.in 2014-09-28 04:19:40.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/Makefile.in 2015-08-05 13:57:40.525361584 -0400
-@@ -1,4 +1,4 @@
--# Makefile.in generated by automake 1.11.6 from Makefile.am.
-+# Makefile.in generated by automake 1.11.5 from Makefile.am.
- # @configure_input@
-
- # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-@@ -236,7 +236,7 @@
- dash_SOURCES = \
- $(dash_CFILES) \
- alias.h arith_yacc.h bltin/bltin.h cd.h error.h eval.h exec.h \
-- expand.h hetio.h \
-+ expand.h \
- init.h input.h jobs.h machdep.h mail.h main.h memalloc.h miscbltin.h \
- myhistedit.h mystring.h options.h output.h parser.h redir.h shell.h \
- show.h system.h trap.h var.h
-diff -Naur dash-0.5.8/src/bltin/printf.c dash-0.5.8-git_d7582e6/src/bltin/printf.c
---- dash-0.5.8/src/bltin/printf.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/bltin/printf.c 2015-08-05 13:55:25.058691365 -0400
-@@ -40,12 +40,11 @@
- #include <string.h>
- #include <unistd.h>
-
--static int conv_escape_str(char *);
-+static int conv_escape_str(char *, char **);
- static char *conv_escape(char *, int *);
- static int getchr(void);
- static double getdouble(void);
--static intmax_t getintmax(void);
--static uintmax_t getuintmax(void);
-+static uintmax_t getuintmax(int);
- static char *getstr(void);
- static char *mklong(const char *, const char *);
- static void check_conversion(const char *, const char *);
-@@ -73,6 +72,53 @@
- } \
- }
-
-+#define ASPF(sp, f, func) ({ \
-+ int ret; \
-+ switch ((char *)param - (char *)array) { \
-+ default: \
-+ ret = xasprintf(sp, f, array[0], array[1], func); \
-+ break; \
-+ case sizeof(*param): \
-+ ret = xasprintf(sp, f, array[0], func); \
-+ break; \
-+ case 0: \
-+ ret = xasprintf(sp, f, func); \
-+ break; \
-+ } \
-+ ret; \
-+})
-+
-+
-+static int print_escape_str(const char *f, int *param, int *array, char *s)
-+{
-+ struct stackmark smark;
-+ char *p, *q;
-+ int done;
-+ int len;
-+ int total;
-+
-+ setstackmark(&smark);
-+ done = conv_escape_str(s, &p);
-+ q = stackblock();
-+ len = p - q;
-+
-+ p = makestrspace(len, p);
-+ memset(p, 'X', len - 1);
-+ p[len - 1] = 0;
-+
-+ q = stackblock();
-+ total = ASPF(&p, f, p);
-+
-+ len = strchrnul(p, 'X') - p;
-+ memcpy(p + len, q, strchrnul(p + len, ' ') - (p + len));
-+
-+ out1mem(p, total);
-+
-+ popstackmark(&smark);
-+ return done;
-+}
-+
-+
- int printfcmd(int argc, char *argv[])
- {
- char *fmt;
-@@ -86,10 +132,8 @@
- argv = argptr;
- format = *argv;
-
-- if (!format) {
-- warnx("usage: printf format [arg ...]");
-- goto err;
-- }
-+ if (!format)
-+ error("usage: printf format [arg ...]");
-
- gargv = ++argv;
-
-@@ -132,39 +176,33 @@
- /* skip to field width */
- fmt += strspn(fmt, SKIP1);
- if (*fmt == '*')
-- *param++ = getintmax();
-+ *param++ = getuintmax(1);
-
- /* skip to possible '.', get following precision */
- fmt += strspn(fmt, SKIP2);
- if (*fmt == '.')
- ++fmt;
- if (*fmt == '*')
-- *param++ = getintmax();
-+ *param++ = getuintmax(1);
-
- fmt += strspn(fmt, SKIP2);
-
- ch = *fmt;
-- if (!ch) {
-- warnx("missing format character");
-- goto err;
-- }
-+ if (!ch)
-+ error("missing format character");
- /* null terminate format string to we can use it
- as an argument to printf. */
- nextch = fmt[1];
- fmt[1] = 0;
- switch (ch) {
-
-- case 'b': {
-- int done = conv_escape_str(getstr());
-- char *p = stackblock();
-+ case 'b':
- *fmt = 's';
-- PF(start, p);
- /* escape if a \c was encountered */
-- if (done)
-+ if (print_escape_str(start, param, array,
-+ getstr()))
- goto out;
-- *fmt = 'b';
- break;
-- }
- case 'c': {
- int p = getchr();
- PF(start, p);
-@@ -177,23 +215,26 @@
- }
- case 'd':
- case 'i': {
-- intmax_t p = getintmax();
-- char *f = mklong(start, fmt);
-- PF(f, p);
-+ uintmax_t p = getuintmax(1);
-+ start = mklong(start, fmt);
-+ PF(start, p);
- break;
- }
- case 'o':
- case 'u':
- case 'x':
- case 'X': {
-- uintmax_t p = getuintmax();
-- char *f = mklong(start, fmt);
-- PF(f, p);
-+ uintmax_t p = getuintmax(0);
-+ start = mklong(start, fmt);
-+ PF(start, p);
- break;
- }
-+ case 'a':
-+ case 'A':
- case 'e':
- case 'E':
- case 'f':
-+ case 'F':
- case 'g':
- case 'G': {
- double p = getdouble();
-@@ -201,8 +242,7 @@
- break;
- }
- default:
-- warnx("%s: invalid directive", start);
-- goto err;
-+ error("%s: invalid directive", start);
- }
- *++fmt = nextch;
- }
-@@ -210,8 +250,6 @@
-
- out:
- return rval;
--err:
-- return 1;
- }
-
-
-@@ -220,8 +258,9 @@
- * Halts processing string if a \c escape is encountered.
- */
- static int
--conv_escape_str(char *str)
-+conv_escape_str(char *str, char **sp)
- {
-+ int c;
- int ch;
- char *cp;
-
-@@ -229,16 +268,14 @@
- STARTSTACKSTR(cp);
-
- do {
-- int c;
--
-- ch = *str++;
-+ c = ch = *str++;
- if (ch != '\\')
- continue;
-
-- ch = *str++;
-- if (ch == 'c') {
-+ c = *str++;
-+ if (c == 'c') {
- /* \c as in SYSV echo - abort all processing.... */
-- ch = 0x100;
-+ c = ch = 0x100;
- continue;
- }
-
-@@ -247,25 +284,14 @@
- * They start with a \0, and are followed by 0, 1, 2,
- * or 3 octal digits.
- */
-- if (ch == '0') {
-- unsigned char i;
-- i = 3;
-- ch = 0;
-- do {
-- unsigned k = octtobin(*str);
-- if (k > 7)
-- break;
-- str++;
-- ch <<= 3;
-- ch += k;
-- } while (--i);
-- continue;
-- }
-+ if (c == '0' && isodigit(*str))
-+ str++;
-
- /* Finally test for sequences valid in the format string */
- str = conv_escape(str - 1, &c);
-- ch = c;
-- } while (STPUTC(ch, cp), (char)ch);
-+ } while (STPUTC(c, cp), (char)ch);
-+
-+ *sp = cp;
-
- return ch;
- }
-@@ -283,12 +309,11 @@
-
- switch (ch) {
- default:
-- case 0:
-- value = '\\';
-- goto out;
-+ if (!isodigit(*str)) {
-+ value = '\\';
-+ goto out;
-+ }
-
-- case '0': case '1': case '2': case '3':
-- case '4': case '5': case '6': case '7':
- ch = 3;
- value = 0;
- do {
-@@ -357,30 +382,8 @@
- return val;
- }
-
--static intmax_t
--getintmax(void)
--{
-- intmax_t val = 0;
-- char *cp, *ep;
--
-- cp = *gargv;
-- if (cp == NULL)
-- goto out;
-- gargv++;
--
-- val = (unsigned char) cp[1];
-- if (*cp == '\"' || *cp == '\'')
-- goto out;
--
-- errno = 0;
-- val = strtoimax(cp, &ep, 0);
-- check_conversion(cp, ep);
--out:
-- return val;
--}
--
- static uintmax_t
--getuintmax(void)
-+getuintmax(int sign)
- {
- uintmax_t val = 0;
- char *cp, *ep;
-@@ -395,7 +398,7 @@
- goto out;
-
- errno = 0;
-- val = strtoumax(cp, &ep, 0);
-+ val = sign ? strtoimax(cp, &ep, 0) : strtoumax(cp, &ep, 0);
- check_conversion(cp, ep);
- out:
- return val;
-@@ -439,34 +442,21 @@
- int
- echocmd(int argc, char **argv)
- {
-- int nonl = 0;
-- struct output *outs = out1;
-+ int nonl;
-
-- if (!*++argv)
-- goto end;
-- if (equal(*argv, "-n")) {
-- nonl = ~nonl;
-- if (!*++argv)
-- goto end;
-- }
-+ nonl = *++argv ? equal(*argv, "-n") : 0;
-+ argv += nonl;
-
- do {
- int c;
-
-- nonl += conv_escape_str(*argv);
-- outstr(stackblock(), outs);
-+ if (likely(*argv))
-+ nonl += print_escape_str("%s", NULL, NULL, *argv++);
- if (nonl > 0)
- break;
-
-- c = ' ';
-- if (!*++argv) {
--end:
-- if (nonl) {
-- break;
-- }
-- c = '\n';
-- }
-- outc(c, outs);
-+ c = *argv ? ' ' : '\n';
-+ out1c(c);
- } while (*argv);
- return 0;
- }
-diff -Naur dash-0.5.8/src/bltin/test.c dash-0.5.8-git_d7582e6/src/bltin/test.c
---- dash-0.5.8/src/bltin/test.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/bltin/test.c 2015-08-05 13:55:25.058691365 -0400
-@@ -155,6 +155,14 @@
- static int bash_group_member(gid_t);
- #endif
-
-+#ifdef HAVE_FACCESSAT
-+# ifdef HAVE_TRADITIONAL_FACCESSAT
-+static inline int faccessat_confused_about_superuser(void) { return 1; }
-+# else
-+static inline int faccessat_confused_about_superuser(void) { return 0; }
-+# endif
-+#endif
-+
- static inline intmax_t getn(const char *s)
- {
- return atomax10(s);
-@@ -177,7 +185,7 @@
- {
- const struct t_op *op;
- enum token n;
-- int res;
-+ int res = 1;
-
- if (*argv[0] == '[') {
- if (*argv[--argc] != ']')
-@@ -185,11 +193,12 @@
- argv[argc] = NULL;
- }
-
-+recheck:
- argv++;
- argc--;
-
- if (argc < 1)
-- return 1;
-+ return res;
-
- /*
- * POSIX prescriptions: he who wrote this deserves the Nobel
-@@ -209,6 +218,9 @@
- argv[--argc] = NULL;
- argv++;
- argc--;
-+ } else if (!strcmp(argv[0], "!")) {
-+ res = 0;
-+ goto recheck;
- }
- }
-
-@@ -216,7 +228,7 @@
-
- eval:
- t_wp = argv;
-- res = !oexpr(n);
-+ res ^= oexpr(n);
- argv = t_wp;
-
- if (argv[0] != NULL && argv[1] != NULL)
-@@ -489,8 +501,20 @@
- }
-
- #ifdef HAVE_FACCESSAT
-+static int has_exec_bit_set(const char *path)
-+{
-+ struct stat64 st;
-+
-+ if (stat64(path, &st))
-+ return 0;
-+ return st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH);
-+}
-+
- static int test_file_access(const char *path, int mode)
- {
-+ if (faccessat_confused_about_superuser() &&
-+ mode == X_OK && geteuid() == 0 && !has_exec_bit_set(path))
-+ return 0;
- return !faccessat(AT_FDCWD, path, mode, AT_EACCESS);
- }
- #else /* HAVE_FACCESSAT */
-diff -Naur dash-0.5.8/src/cd.c dash-0.5.8-git_d7582e6/src/cd.c
---- dash-0.5.8/src/cd.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/cd.c 2015-08-05 13:55:25.058691365 -0400
-@@ -38,6 +38,9 @@
- #include <string.h>
- #include <unistd.h>
- #include <limits.h>
-+#ifdef __CYGWIN__
-+#include <sys/cygwin.h>
-+#endif
-
- /*
- * The cd and pwd commands.
-@@ -194,6 +197,17 @@
- char *cdcomppath;
- const char *lim;
-
-+#ifdef __CYGWIN__
-+ /* On cygwin, thanks to drive letters, some absolute paths do
-+ not begin with slash; but cygwin includes a function that
-+ forces normalization to the posix form */
-+ char pathbuf[PATH_MAX];
-+ if (cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_RELATIVE, dir, pathbuf,
-+ sizeof(pathbuf)) < 0)
-+ sh_error("can't normalize %s", dir);
-+ dir = pathbuf;
-+#endif
-+
- cdcomppath = sstrdup(dir);
- STARTSTACKSTR(new);
- if (*dir != '/') {
-diff -Naur dash-0.5.8/src/dash.1 dash-0.5.8-git_d7582e6/src/dash.1
---- dash-0.5.8/src/dash.1 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/dash.1 2015-08-05 13:55:25.058691365 -0400
-@@ -385,7 +385,7 @@
- Following is a list of the possible redirections.
- The
- .Bq n
--is an optional number, as in
-+is an optional number between 0 and 9, as in
- .Sq 3
- (not
- .Sq Bq 3 ) ,
-@@ -402,11 +402,13 @@
- .It [n] Ns \*[Lt] file
- Redirect standard input (or n) from file.
- .It [n1] Ns \*[Lt]& Ns n2
--Duplicate standard input (or n1) from file descriptor n2.
-+Copy file descriptor n2 as stdout (or fd n1).
-+fd n2.
- .It [n] Ns \*[Lt]&-
- Close standard input (or n).
- .It [n1] Ns \*[Gt]& Ns n2
--Duplicate standard output (or n1) to n2.
-+Copy file descriptor n2 as stdin (or fd n1).
-+fd n2.
- .It [n] Ns \*[Gt]&-
- Close standard output (or n).
- .It [n] Ns \*[Lt]\*[Gt] file
-@@ -596,7 +598,7 @@
- characters.
- The commands in a list are executed in the order they are written.
- If command is followed by an ampersand, the shell starts the
--command and immediately proceed onto the next command; otherwise it waits
-+command and immediately proceeds onto the next command; otherwise it waits
- for the command to terminate before proceeding to the next one.
- .Ss Short-Circuit List Operators
- .Dq &&
-@@ -1400,14 +1402,9 @@
- .Va optstring
- all errors will be ignored.
- .Pp
--A nonzero value is returned when the last option is reached.
--If there are no remaining arguments,
-+After the last option
- .Ic getopts
--will set
--.Va var
--to the special option,
--.Dq -- ,
--otherwise, it will set
-+will return a non-zero value and set
- .Va var
- to
- .Dq \&? .
-diff -Naur dash-0.5.8/src/error.c dash-0.5.8-git_d7582e6/src/error.c
---- dash-0.5.8/src/error.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/error.c 2015-08-05 13:55:25.058691365 -0400
-@@ -105,6 +105,7 @@
- signal(SIGINT, SIG_DFL);
- raise(SIGINT);
- }
-+ exitstatus = SIGINT + 128;
- exraise(EXINT);
- /* NOTREACHED */
- }
-diff -Naur dash-0.5.8/src/eval.c dash-0.5.8-git_d7582e6/src/eval.c
---- dash-0.5.8/src/eval.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/eval.c 2015-08-05 13:55:25.058691365 -0400
-@@ -74,6 +74,7 @@
- char *commandname;
- int exitstatus; /* exit status of last command */
- int back_exitstatus; /* exit status of backquoted command */
-+int savestatus = -1; /* exit status of last command outside traps */
-
-
- #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
-@@ -114,6 +115,10 @@
- RESET {
- evalskip = 0;
- loopnest = 0;
-+ if (savestatus >= 0) {
-+ exitstatus = savestatus;
-+ savestatus = -1;
-+ }
- }
- #endif
-
-@@ -160,6 +165,7 @@
- struct stackmark smark;
- int status;
-
-+ s = sstrdup(s);
- setinputstring(s);
- setstackmark(&smark);
-
-@@ -171,7 +177,9 @@
- if (evalskip)
- break;
- }
-+ popstackmark(&smark);
- popfile();
-+ stunalloc(s);
-
- return status;
- }
-@@ -194,6 +202,9 @@
- TRACE(("evaltree(NULL) called\n"));
- goto out;
- }
-+
-+ dotrap();
-+
- #ifndef SMALL
- displayhist = 1; /* show history substitutions done with fc */
- #endif
-@@ -305,8 +316,7 @@
- if (checkexit & exitstatus)
- goto exexit;
-
-- if (pendingsigs)
-- dotrap();
-+ dotrap();
-
- if (flags & EV_EXIT) {
- exexit:
-@@ -329,27 +339,45 @@
- #endif
-
-
-+static int skiploop(void)
-+{
-+ int skip = evalskip;
-+
-+ switch (skip) {
-+ case 0:
-+ break;
-+
-+ case SKIPBREAK:
-+ case SKIPCONT:
-+ if (likely(--skipcount <= 0)) {
-+ evalskip = 0;
-+ break;
-+ }
-+
-+ skip = SKIPBREAK;
-+ break;
-+ }
-+
-+ return skip;
-+}
-+
-+
- STATIC void
- evalloop(union node *n, int flags)
- {
-+ int skip;
- int status;
-
- loopnest++;
- status = 0;
- flags &= EV_TESTED;
-- for (;;) {
-+ do {
- int i;
-
- evaltree(n->nbinary.ch1, EV_TESTED);
-- if (evalskip) {
--skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
-- evalskip = 0;
-- continue;
-- }
-- if (evalskip == SKIPBREAK && --skipcount <= 0)
-- evalskip = 0;
-- break;
-- }
-+ skip = skiploop();
-+ if (skip)
-+ continue;
- i = exitstatus;
- if (n->type != NWHILE)
- i = !i;
-@@ -357,11 +385,11 @@
- break;
- evaltree(n->nbinary.ch2, flags);
- status = exitstatus;
-- if (evalskip)
-- goto skipping;
-- }
-+ skip = skiploop();
-+ } while (!(skip & ~SKIPCONT));
-+ if (skip != SKIPFUNC)
-+ exitstatus = status;
- loopnest--;
-- exitstatus = status;
- }
-
-
-@@ -382,9 +410,6 @@
- arglist.lastp = &arglist.list;
- for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
- expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
-- /* XXX */
-- if (evalskip)
-- goto out;
- }
- *arglist.lastp = NULL;
-
-@@ -394,18 +419,10 @@
- for (sp = arglist.list ; sp ; sp = sp->next) {
- setvar(n->nfor.var, sp->text, 0);
- evaltree(n->nfor.body, flags);
-- if (evalskip) {
-- if (evalskip == SKIPCONT && --skipcount <= 0) {
-- evalskip = 0;
-- continue;
-- }
-- if (evalskip == SKIPBREAK && --skipcount <= 0)
-- evalskip = 0;
-+ if (skiploop() & ~SKIPCONT)
- break;
-- }
- }
- loopnest--;
--out:
- popstackmark(&smark);
- }
-
-@@ -848,21 +865,12 @@
- listsetvar(varlist.list, VEXPORT);
- }
- if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
-- int status;
-- int i;
--
-- i = exception;
-- if (i == EXEXIT)
-- goto raise;
--
-- status = (i == EXINT) ? SIGINT + 128 : 2;
-- exitstatus = status;
--
-- if (i == EXINT || spclbltin > 0) {
--raise:
-- longjmp(handler->loc, 1);
-+ if (exception == EXERROR && spclbltin <= 0) {
-+ FORCEINTON;
-+ break;
- }
-- FORCEINTON;
-+raise:
-+ longjmp(handler->loc, 1);
- }
- break;
-
-@@ -927,9 +935,11 @@
- struct jmploc jmploc;
- int e;
- int savefuncline;
-+ int saveloopnest;
-
- saveparam = shellparam;
- savefuncline = funcline;
-+ saveloopnest = loopnest;
- savehandler = handler;
- if ((e = setjmp(jmploc.loc))) {
- goto funcdone;
-@@ -939,6 +949,7 @@
- shellparam.malloc = 0;
- func->count++;
- funcline = func->n.ndefun.linno;
-+ loopnest = 0;
- INTON;
- shellparam.nparam = argc - 1;
- shellparam.p = argv + 1;
-@@ -949,13 +960,14 @@
- poplocalvars(0);
- funcdone:
- INTOFF;
-+ loopnest = saveloopnest;
- funcline = savefuncline;
- freefunc(func);
- freeparam(&shellparam);
- shellparam = saveparam;
- handler = savehandler;
- INTON;
-- evalskip &= ~SKIPFUNC;
-+ evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
- return e;
- }
-
-@@ -1035,12 +1047,23 @@
- int
- returncmd(int argc, char **argv)
- {
-+ int skip;
-+ int status;
-+
- /*
- * If called outside a function, do what ksh does;
- * skip the rest of the file.
- */
-- evalskip = SKIPFUNC;
-- return argv[1] ? number(argv[1]) : exitstatus;
-+ if (argv[1]) {
-+ skip = SKIPFUNC;
-+ status = number(argv[1]);
-+ } else {
-+ skip = SKIPFUNCDEF;
-+ status = exitstatus;
-+ }
-+ evalskip = skip;
-+
-+ return status;
- }
-
-
-diff -Naur dash-0.5.8/src/eval.h dash-0.5.8-git_d7582e6/src/eval.h
---- dash-0.5.8/src/eval.h 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/eval.h 2015-08-05 13:55:25.058691365 -0400
-@@ -37,6 +37,7 @@
- extern char *commandname; /* currently executing command */
- extern int exitstatus; /* exit status of last command */
- extern int back_exitstatus; /* exit status of backquoted command */
-+extern int savestatus; /* exit status of last command outside traps */
-
-
- struct backcmd { /* result of evalbackcmd */
-@@ -61,3 +62,4 @@
- #define SKIPBREAK (1 << 0)
- #define SKIPCONT (1 << 1)
- #define SKIPFUNC (1 << 2)
-+#define SKIPFUNCDEF (1 << 3)
-diff -Naur dash-0.5.8/src/expand.c dash-0.5.8-git_d7582e6/src/expand.c
---- dash-0.5.8/src/expand.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/expand.c 2015-08-05 13:55:25.058691365 -0400
-@@ -116,7 +116,7 @@
- STATIC char *evalvar(char *, int);
- STATIC size_t strtodest(const char *, const char *, int);
- STATIC void memtodest(const char *, size_t, const char *, int);
--STATIC ssize_t varvalue(char *, int, int);
-+STATIC ssize_t varvalue(char *, int, int, int *);
- STATIC void expandmeta(struct strlist *, int);
- #ifdef HAVE_GLOB
- STATIC void addglob(const glob_t *);
-@@ -736,7 +736,7 @@
- p = strchr(p, '=') + 1;
-
- again:
-- varlen = varvalue(var, varflags, flag);
-+ varlen = varvalue(var, varflags, flag, &quoted);
- if (varflags & VSNUL)
- varlen--;
-
-@@ -751,28 +751,22 @@
- argstr(p, flag | EXP_TILDE | EXP_WORD);
- goto end;
- }
-- if (easy)
-- goto record;
-- goto end;
-+ goto record;
- }
-
- if (subtype == VSASSIGN || subtype == VSQUESTION) {
-- if (varlen < 0) {
-- if (subevalvar(p, var, 0, subtype, startloc,
-- varflags, flag & ~QUOTES_ESC)) {
-- varflags &= ~VSNUL;
-- /*
-- * Remove any recorded regions beyond
-- * start of variable
-- */
-- removerecordregions(startloc);
-- goto again;
-- }
-- goto end;
-- }
-- if (easy)
-+ if (varlen >= 0)
- goto record;
-- goto end;
-+
-+ subevalvar(p, var, 0, subtype, startloc, varflags,
-+ flag & ~QUOTES_ESC);
-+ varflags &= ~VSNUL;
-+ /*
-+ * Remove any recorded regions beyond
-+ * start of variable
-+ */
-+ removerecordregions(startloc);
-+ goto again;
- }
-
- if (varlen < 0 && uflag)
-@@ -784,9 +778,9 @@
- }
-
- if (subtype == VSNORMAL) {
-+record:
- if (!easy)
- goto end;
--record:
- recordregion(startloc, expdest - (char *)stackblock(), quoted);
- goto end;
- }
-@@ -892,7 +886,7 @@
- */
-
- STATIC ssize_t
--varvalue(char *name, int varflags, int flags)
-+varvalue(char *name, int varflags, int flags, int *quotedp)
- {
- int num;
- char *p;
-@@ -901,13 +895,13 @@
- char sepc;
- char **ap;
- char const *syntax;
-- int quoted = flags & EXP_QUOTED;
-+ int quoted = *quotedp;
- int subtype = varflags & VSTYPE;
- int discard = subtype == VSPLUS || subtype == VSLENGTH;
- int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL;
- ssize_t len = 0;
-
-- sep = quoted ? ((flags & EXP_FULL) << CHAR_BIT) : 0;
-+ sep = (flags & EXP_FULL) << CHAR_BIT;
- syntax = quoted ? DQSYNTAX : BASESYNTAX;
-
- switch (*name) {
-@@ -938,15 +932,18 @@
- expdest = p;
- break;
- case '@':
-- if (sep)
-+ if (quoted && sep)
- goto param;
- /* fall through */
- case '*':
-- sep = ifsset() ? ifsval()[0] : ' ';
-+ if (quoted)
-+ sep = 0;
-+ sep |= ifsset() ? ifsval()[0] : ' ';
- param:
-+ sepc = sep;
-+ *quotedp = !sepc;
- if (!(ap = shellparam.p))
- return -1;
-- sepc = sep;
- while ((p = *ap++)) {
- len += strtodest(p, syntax, quotes);
-
-diff -Naur dash-0.5.8/src/hetio.h dash-0.5.8-git_d7582e6/src/hetio.h
---- dash-0.5.8/src/hetio.h 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/hetio.h 1969-12-31 19:00:00.000000000 -0500
-@@ -1,22 +0,0 @@
--/*
-- * Termios command line History and Editting for NetBSD sh (ash)
-- * Copyright (c) 1999
-- * Main code: Adam Rogoyski <rogoyski@cs.utexas.edu>
-- * Etc: Dave Cinege <dcinege@psychosis.com>
-- *
-- * You may use this code as you wish, so long as the original author(s)
-- * are attributed in any redistributions of the source code.
-- * This code is 'as is' with no warranty.
-- * This code may safely be consumed by a BSD or GPL license.
-- *
-- * v 0.5 19990328 Initial release
-- *
-- * Future plans: Simple file and path name completion. (like BASH)
-- *
-- */
--
--void hetio_init(void);
--int hetio_read_input(int fd);
--void hetio_reset_term(void);
--
--extern int hetio_inter;
-diff -Naur dash-0.5.8/src/histedit.c dash-0.5.8-git_d7582e6/src/histedit.c
---- dash-0.5.8/src/histedit.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/histedit.c 2015-08-05 13:55:25.062024698 -0400
-@@ -372,8 +372,7 @@
- out2str(s);
- }
-
-- evalstring(strcpy(stalloc(strlen(s) + 1), s),
-- 0);
-+ evalstring(s, 0);
- if (displayhist && hist) {
- /*
- * XXX what about recursive and
-diff -Naur dash-0.5.8/src/input.c dash-0.5.8-git_d7582e6/src/input.c
---- dash-0.5.8/src/input.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/input.c 2015-08-05 13:55:25.062024698 -0400
-@@ -58,45 +58,10 @@
- #include "myhistedit.h"
- #endif
-
--#ifdef HETIO
--#include "hetio.h"
--#endif
--
- #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
- #define IBUFSIZ (BUFSIZ + 1)
-
--MKINIT
--struct strpush {
-- struct strpush *prev; /* preceding string on stack */
-- char *prevstring;
-- int prevnleft;
-- struct alias *ap; /* if push was associated with an alias */
-- char *string; /* remember the string since it may change */
--};
--
--/*
-- * The parsefile structure pointed to by the global variable parsefile
-- * contains information about the current file being read.
-- */
-
--MKINIT
--struct parsefile {
-- struct parsefile *prev; /* preceding file on stack */
-- int linno; /* current line */
-- int fd; /* file descriptor (or -1 if string) */
-- int nleft; /* number of chars left in this line */
-- int lleft; /* number of chars left in this buffer */
-- char *nextc; /* next char in buffer */
-- char *buf; /* input buffer */
-- struct strpush *strpush; /* for pushing strings at this level */
-- struct strpush basestrpush; /* so pushing one is fast */
--};
--
--
--int plinno = 1; /* input line number */
--int parsenleft; /* copy of parsefile->nleft */
--MKINIT int parselleft; /* copy of parsefile->lleft */
--char *parsenextc; /* copy of parsefile->nextc */
- MKINIT struct parsefile basepf; /* top level input file */
- MKINIT char basebuf[IBUFSIZ]; /* buffer for top level input file */
- struct parsefile *parsefile = &basepf; /* current input file */
-@@ -109,6 +74,7 @@
- STATIC void pushfile(void);
- static int preadfd(void);
- static void setinputfd(int fd, int push);
-+static int preadbuffer(void);
-
- #ifdef mkinit
- INCLUDE <stdio.h>
-@@ -117,10 +83,12 @@
-
- INIT {
- basepf.nextc = basepf.buf = basebuf;
-+ basepf.linno = 1;
- }
-
- RESET {
-- parselleft = parsenleft = 0; /* clear input buffer */
-+ /* clear input buffer */
-+ basepf.lleft = basepf.nleft = 0;
- popallfiles();
- }
- #endif
-@@ -134,7 +102,20 @@
- int
- pgetc(void)
- {
-- return pgetc_macro();
-+ int c;
-+
-+ if (parsefile->unget)
-+ return parsefile->lastc[--parsefile->unget];
-+
-+ if (--parsefile->nleft >= 0)
-+ c = (signed char)*parsefile->nextc++;
-+ else
-+ c = preadbuffer();
-+
-+ parsefile->lastc[1] = parsefile->lastc[0];
-+ parsefile->lastc[0] = c;
-+
-+ return c;
- }
-
-
-@@ -147,7 +128,7 @@
- {
- int c;
- do {
-- c = pgetc_macro();
-+ c = pgetc();
- } while (c == PEOA);
- return c;
- }
-@@ -158,7 +139,7 @@
- {
- int nr;
- char *buf = parsefile->buf;
-- parsenextc = buf;
-+ parsefile->nextc = buf;
-
- retry:
- #ifndef SMALL
-@@ -184,11 +165,6 @@
-
- } else
- #endif
--
--#ifdef HETIO
-- nr = hetio_read_input(parsefile->fd);
-- if (nr == -255)
--#endif
- nr = read(parsefile->fd, buf, IBUFSIZ - 1);
-
-
-@@ -219,8 +195,7 @@
- * 4) Process input up to the next newline, deleting nul characters.
- */
-
--int
--preadbuffer(void)
-+static int preadbuffer(void)
- {
- char *q;
- int more;
-@@ -229,34 +204,33 @@
- #endif
- char savec;
-
-- while (unlikely(parsefile->strpush)) {
-+ if (unlikely(parsefile->strpush)) {
- if (
-- parsenleft == -1 && parsefile->strpush->ap &&
-- parsenextc[-1] != ' ' && parsenextc[-1] != '\t'
-+ parsefile->nleft == -1 &&
-+ parsefile->strpush->ap &&
-+ parsefile->nextc[-1] != ' ' &&
-+ parsefile->nextc[-1] != '\t'
- ) {
- return PEOA;
- }
- popstring();
-- if (--parsenleft >= 0)
-- return (signed char)*parsenextc++;
-+ return pgetc();
- }
-- if (unlikely(parsenleft == EOF_NLEFT || parsefile->buf == NULL))
-+ if (unlikely(parsefile->nleft == EOF_NLEFT ||
-+ parsefile->buf == NULL))
- return PEOF;
-- flushout(&output);
--#ifdef FLUSHERR
-- flushout(&errout);
--#endif
-+ flushall();
-
-- more = parselleft;
-+ more = parsefile->lleft;
- if (more <= 0) {
- again:
- if ((more = preadfd()) <= 0) {
-- parselleft = parsenleft = EOF_NLEFT;
-+ parsefile->lleft = parsefile->nleft = EOF_NLEFT;
- return PEOF;
- }
- }
-
-- q = parsenextc;
-+ q = parsefile->nextc;
-
- /* delete nul characters */
- #ifndef SMALL
-@@ -274,7 +248,7 @@
- q++;
-
- if (c == '\n') {
-- parsenleft = q - parsenextc - 1;
-+ parsefile->nleft = q - parsefile->nextc - 1;
- break;
- }
-
-@@ -291,13 +265,13 @@
- }
-
- if (more <= 0) {
-- parsenleft = q - parsenextc - 1;
-- if (parsenleft < 0)
-+ parsefile->nleft = q - parsefile->nextc - 1;
-+ if (parsefile->nleft < 0)
- goto again;
- break;
- }
- }
-- parselleft = more;
-+ parsefile->lleft = more;
-
- savec = *q;
- *q = '\0';
-@@ -307,13 +281,13 @@
- HistEvent he;
- INTOFF;
- history(hist, &he, whichprompt == 1? H_ENTER : H_APPEND,
-- parsenextc);
-+ parsefile->nextc);
- INTON;
- }
- #endif
-
- if (vflag) {
-- out2str(parsenextc);
-+ out2str(parsefile->nextc);
- #ifdef FLUSHERR
- flushout(out2);
- #endif
-@@ -321,19 +295,18 @@
-
- *q = savec;
-
-- return (signed char)*parsenextc++;
-+ return (signed char)*parsefile->nextc++;
- }
-
- /*
-- * Undo the last call to pgetc. Only one character may be pushed back.
-+ * Undo a call to pgetc. Only two characters may be pushed back.
- * PEOF may be pushed back.
- */
-
- void
- pungetc(void)
- {
-- parsenleft++;
-- parsenextc--;
-+ parsefile->unget++;
- }
-
- /*
-@@ -355,15 +328,18 @@
- parsefile->strpush = sp;
- } else
- sp = parsefile->strpush = &(parsefile->basestrpush);
-- sp->prevstring = parsenextc;
-- sp->prevnleft = parsenleft;
-+ sp->prevstring = parsefile->nextc;
-+ sp->prevnleft = parsefile->nleft;
-+ sp->unget = parsefile->unget;
-+ memcpy(sp->lastc, parsefile->lastc, sizeof(sp->lastc));
- sp->ap = (struct alias *)ap;
- if (ap) {
- ((struct alias *)ap)->flag |= ALIASINUSE;
- sp->string = s;
- }
-- parsenextc = s;
-- parsenleft = len;
-+ parsefile->nextc = s;
-+ parsefile->nleft = len;
-+ parsefile->unget = 0;
- INTON;
- }
-
-@@ -374,7 +350,8 @@
-
- INTOFF;
- if (sp->ap) {
-- if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
-+ if (parsefile->nextc[-1] == ' ' ||
-+ parsefile->nextc[-1] == '\t') {
- checkkwd |= CHKALIAS;
- }
- if (sp->string != sp->ap->val) {
-@@ -385,8 +362,10 @@
- unalias(sp->ap->name);
- }
- }
-- parsenextc = sp->prevstring;
-- parsenleft = sp->prevnleft;
-+ parsefile->nextc = sp->prevstring;
-+ parsefile->nleft = sp->prevnleft;
-+ parsefile->unget = sp->unget;
-+ memcpy(parsefile->lastc, sp->lastc, sizeof(sp->lastc));
- /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
- parsefile->strpush = sp->prev;
- if (sp != &(parsefile->basestrpush))
-@@ -435,7 +414,7 @@
- parsefile->fd = fd;
- if (parsefile->buf == NULL)
- parsefile->buf = ckmalloc(IBUFSIZ);
-- parselleft = parsenleft = 0;
-+ parsefile->lleft = parsefile->nleft = 0;
- plinno = 1;
- }
-
-@@ -449,8 +428,8 @@
- {
- INTOFF;
- pushfile();
-- parsenextc = string;
-- parsenleft = strlen(string);
-+ parsefile->nextc = string;
-+ parsefile->nleft = strlen(string);
- parsefile->buf = NULL;
- plinno = 1;
- INTON;
-@@ -468,15 +447,12 @@
- {
- struct parsefile *pf;
-
-- parsefile->nleft = parsenleft;
-- parsefile->lleft = parselleft;
-- parsefile->nextc = parsenextc;
-- parsefile->linno = plinno;
- pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
- pf->prev = parsefile;
- pf->fd = -1;
- pf->strpush = NULL;
- pf->basestrpush.prev = NULL;
-+ pf->unget = 0;
- parsefile = pf;
- }
-
-@@ -495,10 +471,6 @@
- popstring();
- parsefile = pf->prev;
- ckfree(pf);
-- parsenleft = parsefile->nleft;
-- parselleft = parsefile->lleft;
-- parsenextc = parsefile->nextc;
-- plinno = parsefile->linno;
- INTON;
- }
-
-diff -Naur dash-0.5.8/src/input.h dash-0.5.8-git_d7582e6/src/input.h
---- dash-0.5.8/src/input.h 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/input.h 2015-08-05 13:55:25.062024698 -0400
-@@ -41,18 +41,56 @@
- INPUT_NOFILE_OK = 2,
- };
-
-+struct alias;
-+
-+struct strpush {
-+ struct strpush *prev; /* preceding string on stack */
-+ char *prevstring;
-+ int prevnleft;
-+ struct alias *ap; /* if push was associated with an alias */
-+ char *string; /* remember the string since it may change */
-+
-+ /* Remember last two characters for pungetc. */
-+ int lastc[2];
-+
-+ /* Number of outstanding calls to pungetc. */
-+ int unget;
-+};
-+
-+/*
-+ * The parsefile structure pointed to by the global variable parsefile
-+ * contains information about the current file being read.
-+ */
-+
-+struct parsefile {
-+ struct parsefile *prev; /* preceding file on stack */
-+ int linno; /* current line */
-+ int fd; /* file descriptor (or -1 if string) */
-+ int nleft; /* number of chars left in this line */
-+ int lleft; /* number of chars left in this buffer */
-+ char *nextc; /* next char in buffer */
-+ char *buf; /* input buffer */
-+ struct strpush *strpush; /* for pushing strings at this level */
-+ struct strpush basestrpush; /* so pushing one is fast */
-+
-+ /* Remember last two characters for pungetc. */
-+ int lastc[2];
-+
-+ /* Number of outstanding calls to pungetc. */
-+ int unget;
-+};
-+
-+extern struct parsefile *parsefile;
-+
- /*
- * The input line number. Input.c just defines this variable, and saves
- * and restores it when files are pushed and popped. The user of this
- * package must set its value.
- */
--extern int plinno;
--extern int parsenleft; /* number of characters left in input buffer */
--extern char *parsenextc; /* next character in input buffer */
-+#define plinno (parsefile->linno)
-
- int pgetc(void);
- int pgetc2(void);
--int preadbuffer(void);
- void pungetc(void);
- void pushstring(char *, void *);
- void popstring(void);
-@@ -61,6 +99,3 @@
- void popfile(void);
- void popallfiles(void);
- void closescript(void);
--
--#define pgetc_macro() \
-- (--parsenleft >= 0 ? (signed char)*parsenextc++ : preadbuffer())
-diff -Naur dash-0.5.8/src/main.c dash-0.5.8-git_d7582e6/src/main.c
---- dash-0.5.8/src/main.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/main.c 2015-08-05 13:55:25.062024698 -0400
-@@ -60,10 +60,6 @@
- #include "exec.h"
- #include "cd.h"
-
--#ifdef HETIO
--#include "hetio.h"
--#endif
--
- #define PROFILE 0
-
- int rootpid;
-@@ -206,10 +202,6 @@
- int numeof = 0;
-
- TRACE(("cmdloop(%d) called\n", top));
--#ifdef HETIO
-- if(iflag && top)
-- hetio_init();
--#endif
- for (;;) {
- int skip;
-
-@@ -242,7 +234,7 @@
-
- skip = evalskip;
- if (skip) {
-- evalskip &= ~SKIPFUNC;
-+ evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
- break;
- }
- }
-@@ -321,15 +313,19 @@
- {
- int status = 0;
-
-- if (argc >= 2) { /* That's what SVR2 does */
-+ nextopt(nullstr);
-+ argv = argptr;
-+
-+ if (*argv) {
- char *fullname;
-
-- fullname = find_dot_file(argv[1]);
-+ fullname = find_dot_file(*argv);
- setinputfile(fullname, INPUT_PUSH_FILE);
- commandname = fullname;
- status = cmdloop(0);
- popfile();
- }
-+
- return status;
- }
-
-@@ -339,8 +335,15 @@
- {
- if (stoppedjobs())
- return 0;
-- if (argc > 1)
-- exitstatus = number(argv[1]);
-+
-+ if (argc > 1) {
-+ int status = number(argv[1]);
-+
-+ exitstatus = status;
-+ if (savestatus >= 0)
-+ savestatus = status;
-+ }
-+
- exraise(EXEXIT);
- /* NOTREACHED */
- }
-diff -Naur dash-0.5.8/src/mkbuiltins dash-0.5.8-git_d7582e6/src/mkbuiltins
---- dash-0.5.8/src/mkbuiltins 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/mkbuiltins 2015-08-05 13:55:25.062024698 -0400
-@@ -69,7 +69,7 @@
- #include "builtins.h"
-
- !
--< $builtins sed '/^#/d; /^$/d' > $temp
-+< $builtins sed '/^#/d; /^ *$/d' > $temp
- awk '{ printf "int %s(int, char **);\n", $1}' $temp
- echo '
- const struct builtincmd builtincmd[] = {'
-@@ -78,7 +78,7 @@
- if ($i ~ /^-/)
- line = $(++i) "\t" line
- print line
-- }}' $temp | LC_COLLATE=C sort -k 1,1 | tee $temp2 | awk '{
-+ }}' $temp | LC_ALL= LC_COLLATE=C sort -k 1,1 | tee $temp2 | awk '{
- opt = ""
- if (NF > 2) {
- opt = substr($2, 2)
-@@ -97,8 +97,9 @@
- */
-
- !
--sed 's/ -[a-z]*//' $temp2 | nl -b a -v 0 | LC_COLLATE=C sort -u -k 3,3 |
--tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ |
-+sed 's/ -[a-z]*//' $temp2 | nl -b a -v 0 |
-+ LC_ALL= LC_COLLATE=C sort -u -k 3,3 |
-+ tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ |
- awk '{ printf "#define %s (builtincmd + %d)\n", $3, $1}'
- printf '\n#define NUMBUILTINS %d\n' $(wc -l < $temp2)
- echo '
-diff -Naur dash-0.5.8/src/output.c dash-0.5.8-git_d7582e6/src/output.c
---- dash-0.5.8/src/output.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/output.c 2015-08-05 13:55:25.062024698 -0400
-@@ -99,9 +99,6 @@
- struct output *out2 = &errout;
-
-
--#ifndef USE_GLIBC_STDIO
--static void __outstr(const char *, size_t, struct output *);
--#endif
- static int xvsnprintf(char *, size_t, const char *, va_list);
-
-
-@@ -134,16 +131,20 @@
- #endif
-
-
--#ifndef USE_GLIBC_STDIO
--static void
--__outstr(const char *p, size_t len, struct output *dest)
-+void
-+outmem(const char *p, size_t len, struct output *dest)
- {
-+#ifdef USE_GLIBC_STDIO
-+ INTOFF;
-+ fwrite(p, 1, len, dest->stream);
-+ INTON;
-+#else
- size_t bufsize;
- size_t offset;
- size_t nleft;
-
- nleft = dest->end - dest->nextc;
-- if (nleft >= len) {
-+ if (likely(nleft >= len)) {
- buffered:
- dest->nextc = mempcpy(dest->nextc, p, len);
- return;
-@@ -153,10 +154,13 @@
- if (!bufsize) {
- ;
- } else if (dest->buf == NULL) {
-+#ifdef notyet
- if (dest->fd == MEM_OUT && len > bufsize) {
- bufsize = len;
- }
-+#endif
- offset = 0;
-+#ifdef notyet
- goto alloc;
- } else if (dest->fd == MEM_OUT) {
- offset = bufsize;
-@@ -168,6 +172,7 @@
- if (bufsize < offset)
- goto err;
- alloc:
-+#endif
- INTOFF;
- dest->buf = ckrealloc(dest->buf, bufsize);
- dest->bufsize = bufsize;
-@@ -183,11 +188,13 @@
- goto buffered;
-
- if ((xwrite(dest->fd, p, len))) {
-+#ifdef notyet
- err:
-+#endif
- dest->flags |= OUTPUT_ERR;
- }
--}
- #endif
-+}
-
-
- void
-@@ -201,7 +208,7 @@
- size_t len;
-
- len = strlen(p);
-- __outstr(p, len, file);
-+ outmem(p, len, file);
- #endif
- }
-
-@@ -213,7 +220,7 @@
- outcslow(int c, struct output *dest)
- {
- char buf = c;
-- __outstr(&buf, 1, dest);
-+ outmem(&buf, 1, dest);
- }
- #endif
-
-@@ -283,35 +290,58 @@
- }
-
-
-+static int xvasprintf(char **sp, size_t size, const char *f, va_list ap)
-+{
-+ char *s;
-+ int len;
-+ va_list ap2;
-+
-+ va_copy(ap2, ap);
-+ len = xvsnprintf(*sp, size, f, ap2);
-+ va_end(ap2);
-+ if (len < 0)
-+ sh_error("xvsnprintf failed");
-+ if (len < size)
-+ return len;
-+
-+ s = stalloc((len >= stackblocksize() ? len : stackblocksize()) + 1);
-+ *sp = s;
-+ len = xvsnprintf(s, len + 1, f, ap);
-+ return len;
-+}
-+
-+
-+int xasprintf(char **sp, const char *f, ...)
-+{
-+ va_list ap;
-+ int ret;
-+
-+ va_start(ap, f);
-+ ret = xvasprintf(sp, 0, f, ap);
-+ va_end(ap);
-+ return ret;
-+}
-+
-+
- #ifndef USE_GLIBC_STDIO
- void
- doformat(struct output *dest, const char *f, va_list ap)
- {
- struct stackmark smark;
- char *s;
-- int len, ret;
-- size_t size;
-- va_list ap2;
-+ int len;
-+ int olen;
-
-- va_copy(ap2, ap);
-- size = dest->end - dest->nextc;
-- len = xvsnprintf(dest->nextc, size, f, ap2);
-- va_end(ap2);
-- if (len < 0) {
-- dest->flags |= OUTPUT_ERR;
-- return;
-- }
-- if (len < size) {
-+ setstackmark(&smark);
-+ s = dest->nextc;
-+ olen = dest->end - dest->nextc;
-+ len = xvasprintf(&s, olen, f, ap);
-+ if (likely(olen > len)) {
- dest->nextc += len;
-- return;
-+ goto out;
- }
-- setstackmark(&smark);
-- s = stalloc((len >= stackblocksize() ? len : stackblocksize()) + 1);
-- ret = xvsnprintf(s, len + 1, f, ap);
-- if (ret == len)
-- __outstr(s, len, dest);
-- else
-- dest->flags |= OUTPUT_ERR;
-+ outmem(s, len, dest);
-+out:
- popstackmark(&smark);
- }
- #endif
-diff -Naur dash-0.5.8/src/output.h dash-0.5.8-git_d7582e6/src/output.h
---- dash-0.5.8/src/output.h 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/output.h 2015-08-05 13:55:25.062024698 -0400
-@@ -63,6 +63,7 @@
- extern struct output *out1;
- extern struct output *out2;
-
-+void outmem(const char *, size_t, struct output *);
- void outstr(const char *, struct output *);
- #ifndef USE_GLIBC_STDIO
- void outcslow(int, struct output *);
-@@ -75,6 +76,7 @@
- __attribute__((__format__(__printf__,1,2)));
- int fmtstr(char *, size_t, const char *, ...)
- __attribute__((__format__(__printf__,3,4)));
-+int xasprintf(char **, const char *, ...);
- #ifndef USE_GLIBC_STDIO
- void doformat(struct output *, const char *, va_list);
- #endif
-@@ -115,6 +117,7 @@
- #endif
- #define out1c(c) outc((c), out1)
- #define out2c(c) outcslow((c), out2)
-+#define out1mem(s, l) outmem((s), (l), out1)
- #define out1str(s) outstr((s), out1)
- #define out2str(s) outstr((s), out2)
- #define outerr(f) (f)->flags
-diff -Naur dash-0.5.8/src/parser.c dash-0.5.8-git_d7582e6/src/parser.c
---- dash-0.5.8/src/parser.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/parser.c 2015-08-05 13:55:25.062024698 -0400
-@@ -135,19 +135,13 @@
- union node *
- parsecmd(int interact)
- {
-- int t;
--
- tokpushback = 0;
-+ checkkwd = 0;
-+ heredoclist = 0;
- doprompt = interact;
- if (doprompt)
- setprompt(doprompt);
- needprompt = 0;
-- t = readtoken();
-- if (t == TEOF)
-- return NEOF;
-- if (t == TNL)
-- return NULL;
-- tokpushback++;
- return list(1);
- }
-
-@@ -158,11 +152,27 @@
- union node *n1, *n2, *n3;
- int tok;
-
-- checkkwd = CHKNL | CHKKWD | CHKALIAS;
-- if (nlflag == 2 && tokendlist[peektoken()])
-- return NULL;
- n1 = NULL;
- for (;;) {
-+ switch (peektoken()) {
-+ case TNL:
-+ if (!(nlflag & 1))
-+ break;
-+ parseheredoc();
-+ return n1;
-+
-+ case TEOF:
-+ if (!n1 && (nlflag & 1))
-+ n1 = NEOF;
-+ parseheredoc();
-+ return n1;
-+ }
-+
-+ checkkwd = CHKNL | CHKKWD | CHKALIAS;
-+ if (nlflag == 2 && tokendlist[peektoken()])
-+ return n1;
-+ nlflag |= 2;
-+
- n2 = andor();
- tok = readtoken();
- if (tok == TBACKGND) {
-@@ -189,31 +199,15 @@
- n1 = n3;
- }
- switch (tok) {
-- case TBACKGND:
-- case TSEMI:
-- tok = readtoken();
-- /* fall through */
- case TNL:
-- if (tok == TNL) {
-- parseheredoc();
-- if (nlflag == 1)
-- return n1;
-- } else {
-- tokpushback++;
-- }
-- checkkwd = CHKNL | CHKKWD | CHKALIAS;
-- if (tokendlist[peektoken()])
-- return n1;
-- break;
- case TEOF:
-- if (heredoclist)
-- parseheredoc();
-- else
-- pungetc(); /* push back EOF on input */
- tokpushback++;
-- return n1;
-+ /* fall through */
-+ case TBACKGND:
-+ case TSEMI:
-+ break;
- default:
-- if (nlflag == 1)
-+ if ((nlflag & 1))
- synexpect(-1);
- tokpushback++;
- return n1;
-@@ -743,6 +737,19 @@
- return (t);
- }
-
-+static void nlprompt(void)
-+{
-+ plinno++;
-+ if (doprompt)
-+ setprompt(2);
-+}
-+
-+static void nlnoprompt(void)
-+{
-+ plinno++;
-+ needprompt = doprompt;
-+}
-+
-
- /*
- * Read the next input token.
-@@ -775,7 +782,7 @@
- setprompt(2);
- }
- for (;;) { /* until token or start of word found */
-- c = pgetc_macro();
-+ c = pgetc();
- switch (c) {
- case ' ': case '\t':
- case PEOA:
-@@ -786,16 +793,13 @@
- continue;
- case '\\':
- if (pgetc() == '\n') {
-- plinno++;
-- if (doprompt)
-- setprompt(2);
-+ nlprompt();
- continue;
- }
- pungetc();
- goto breakloop;
- case '\n':
-- plinno++;
-- needprompt = doprompt;
-+ nlnoprompt();
- RETURN(TNL);
- case PEOF:
- RETURN(TEOF);
-@@ -827,6 +831,22 @@
- #undef RETURN
- }
-
-+static int pgetc_eatbnl(void)
-+{
-+ int c;
-+
-+ while ((c = pgetc()) == '\\') {
-+ if (pgetc() != '\n') {
-+ pungetc();
-+ break;
-+ }
-+
-+ nlprompt();
-+ }
-+
-+ return c;
-+}
-+
-
-
- /*
-@@ -895,9 +915,7 @@
- if (syntax == BASESYNTAX)
- goto endword; /* exit outer loop */
- USTPUTC(c, out);
-- plinno++;
-- if (doprompt)
-- setprompt(2);
-+ nlprompt();
- c = pgetc();
- goto loop; /* continue outer loop */
- case CWORD:
-@@ -916,9 +934,7 @@
- USTPUTC('\\', out);
- pungetc();
- } else if (c == '\n') {
-- plinno++;
-- if (doprompt)
-- setprompt(2);
-+ nlprompt();
- } else {
- if (
- dblquote &&
-@@ -1009,7 +1025,7 @@
- USTPUTC(c, out);
- }
- }
-- c = pgetc_macro();
-+ c = pgetc();
- }
- }
- endword:
-@@ -1074,8 +1090,7 @@
-
- if (c == '\n' || c == PEOF) {
- c = PEOF;
-- plinno++;
-- needprompt = doprompt;
-+ nlnoprompt();
- } else {
- int len;
-
-@@ -1179,7 +1194,7 @@
- char *p;
- static const char types[] = "}-+?=";
-
-- c = pgetc();
-+ c = pgetc_eatbnl();
- if (
- (checkkwd & CHKEOFMARK) ||
- c <= PEOA ||
-@@ -1188,7 +1203,7 @@
- USTPUTC('$', out);
- pungetc();
- } else if (c == '(') { /* $(command) or $((arith)) */
-- if (pgetc() == '(') {
-+ if (pgetc_eatbnl() == '(') {
- PARSEARITH();
- } else {
- pungetc();
-@@ -1200,25 +1215,24 @@
- STADJUST(1, out);
- subtype = VSNORMAL;
- if (likely(c == '{')) {
-- c = pgetc();
-+ c = pgetc_eatbnl();
- subtype = 0;
- }
- varname:
- if (is_name(c)) {
- do {
- STPUTC(c, out);
-- c = pgetc();
-+ c = pgetc_eatbnl();
- } while (is_in_name(c));
- } else if (is_digit(c)) {
- do {
- STPUTC(c, out);
-- c = pgetc();
-+ c = pgetc_eatbnl();
- } while (is_digit(c));
-- }
-- else if (is_special(c)) {
-+ } else {
- int cc = c;
-
-- c = pgetc();
-+ c = pgetc_eatbnl();
-
- if (!subtype && cc == '#') {
- subtype = VSLENGTH;
-@@ -1227,7 +1241,7 @@
- goto varname;
-
- cc = c;
-- c = pgetc();
-+ c = pgetc_eatbnl();
- if (cc == '}' || c != '}') {
- pungetc();
- subtype = 0;
-@@ -1236,16 +1250,20 @@
- }
- }
-
-+ if (!is_special(cc)) {
-+ if (subtype == VSLENGTH)
-+ subtype = 0;
-+ goto badsub;
-+ }
-+
- USTPUTC(cc, out);
- }
-- else
-- goto badsub;
-
- if (subtype == 0) {
- switch (c) {
- case ':':
- subtype = VSNUL;
-- c = pgetc();
-+ c = pgetc_eatbnl();
- /*FALLTHROUGH*/
- default:
- p = strchr(types, c);
-@@ -1259,7 +1277,7 @@
- int cc = c;
- subtype = c == '#' ? VSTRIMLEFT :
- VSTRIMRIGHT;
-- c = pgetc();
-+ c = pgetc_eatbnl();
- if (c == cc)
- subtype++;
- else
-@@ -1324,9 +1342,7 @@
-
- case '\\':
- if ((pc = pgetc()) == '\n') {
-- plinno++;
-- if (doprompt)
-- setprompt(2);
-+ nlprompt();
- /*
- * If eating a newline, avoid putting
- * the newline into the new character
-@@ -1348,8 +1364,7 @@
- synerror("EOF in backquote substitution");
-
- case '\n':
-- plinno++;
-- needprompt = doprompt;
-+ nlnoprompt();
- break;
-
- default:
-@@ -1427,10 +1442,6 @@
-
- #ifdef mkinit
- INCLUDE "parser.h"
--RESET {
-- tokpushback = 0;
-- checkkwd = 0;
--}
- #endif
-
-
-diff -Naur dash-0.5.8/src/trap.c dash-0.5.8-git_d7582e6/src/trap.c
---- dash-0.5.8/src/trap.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/trap.c 2015-08-05 13:55:25.062024698 -0400
-@@ -51,10 +51,6 @@
- #include "trap.h"
- #include "mystring.h"
-
--#ifdef HETIO
--#include "hetio.h"
--#endif
--
- /*
- * Sigmode records the current value of the signal handlers for the various
- * modes. A value of zero means that the current handler is not known.
-@@ -314,25 +310,40 @@
- char *p;
- char *q;
- int i;
-- int savestatus;
-+ int status, last_status;
-
-- savestatus = exitstatus;
-+ if (!pendingsigs)
-+ return;
-+
-+ status = savestatus;
-+ last_status = status;
-+ if (likely(status < 0)) {
-+ status = exitstatus;
-+ savestatus = status;
-+ }
- pendingsigs = 0;
- barrier();
-
- for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
- if (!*q)
- continue;
-+
-+ if (evalskip) {
-+ pendingsigs = i + 1;
-+ break;
-+ }
-+
- *q = 0;
-
- p = trap[i + 1];
- if (!p)
- continue;
- evalstring(p, 0);
-- exitstatus = savestatus;
-- if (evalskip)
-- break;
-+ if (evalskip != SKIPFUNC)
-+ exitstatus = status;
- }
-+
-+ savestatus = last_status;
- }
-
-
-@@ -366,18 +377,11 @@
- {
- struct jmploc loc;
- char *p;
-- volatile int status;
-
--#ifdef HETIO
-- hetio_reset_term();
--#endif
-- status = exitstatus;
-- TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
-- if (setjmp(loc.loc)) {
-- if (exception == EXEXIT)
-- status = exitstatus;
-+ savestatus = exitstatus;
-+ TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus));
-+ if (setjmp(loc.loc))
- goto out;
-- }
- handler = &loc;
- if ((p = trap[0])) {
- trap[0] = NULL;
-@@ -392,7 +396,7 @@
- if (likely(!setjmp(loc.loc)))
- setjobctl(0);
- flushall();
-- _exit(status);
-+ _exit(savestatus);
- /* NOTREACHED */
- }
-
-diff -Naur dash-0.5.8/src/var.c dash-0.5.8-git_d7582e6/src/var.c
---- dash-0.5.8/src/var.c 2014-09-28 04:19:32.000000000 -0400
-+++ dash-0.5.8-git_d7582e6/src/var.c 2015-08-05 13:55:25.065358031 -0400
-@@ -80,6 +80,7 @@
- #else
- const char defifs[] = " \t\n";
- #endif
-+MKINIT char defoptindvar[] = "OPTIND=1";
-
- int lineno;
- char linenovar[sizeof("LINENO=")+sizeof(int)*CHAR_BIT/3+1] = "LINENO=";
-@@ -100,7 +101,7 @@
- { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0 },
- { 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0 },
- { 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0 },
-- { 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset },
-+ { 0, VSTRFIXED|VTEXTFIXED, defoptindvar, getoptsreset },
- #ifdef WITH_LINENO
- { 0, VSTRFIXED|VTEXTFIXED, linenovar, 0 },
- #endif
-@@ -142,7 +143,7 @@
- }
- }
-
-- setvarint("OPTIND", 1, 0);
-+ setvareq(defoptindvar, VTEXTFIXED);
-
- fmtstr(ppid + 5, sizeof(ppid) - 5, "%ld", (long) getppid());
- setvareq(ppid, VTEXTFIXED);