Hello community,

here is the log from the commit of package dash for openSUSE:Factory checked in 
at 2018-11-08 09:40:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dash (Old)
 and      /work/SRC/openSUSE:Factory/.dash.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dash"

Thu Nov  8 09:40:54 2018 rev:19 rq:645115 version:0.5.10

Changes:
--------
--- /work/SRC/openSUSE:Factory/dash/dash.changes        2018-04-26 
13:33:43.405552246 +0200
+++ /work/SRC/openSUSE:Factory/.dash.new/dash.changes   2018-11-08 
09:40:58.309626714 +0100
@@ -1,0 +2,10 @@
+Thu Oct 25 06:07:40 UTC 2018 - [email protected]
+
+- update to version 0.5.10
+  * For complete list of changes, see:
+    
https://git.kernel.org/pub/scm/utils/dash/dash.git/log/?qt=range&q=v0.5.9.1..v0.5.10
+- remove upstreamed patches:
+  * drop dash-0.5.7-do-not-close-stderr.patch
+  * drop dash-remove-backslash-before-in-double-quotes-in-variable.patch
+
+-------------------------------------------------------------------

Old:
----
  dash-0.5.7-do-not-close-stderr.patch
  dash-0.5.9.1.tar.gz
  dash-remove-backslash-before-in-double-quotes-in-variable.patch

New:
----
  dash-0.5.10.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dash.spec ++++++
--- /var/tmp/diff_new_pack.LGotOp/_old  2018-11-08 09:40:58.965625954 +0100
+++ /var/tmp/diff_new_pack.LGotOp/_new  2018-11-08 09:40:58.969625950 +0100
@@ -13,22 +13,18 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           dash
-Version:        0.5.9.1
+Version:        0.5.10
 Release:        0
 Summary:        POSIX-compliant Implementation of /bin/sh
 License:        BSD-3-Clause
 Group:          System/Shells
 Url:            http://gondor.apana.org.au/~herbert/dash/
 Source:         
http://gondor.apana.org.au/~herbert/dash/files/dash-%{version}.tar.gz
-# PATCH-FIX-UPSTREAM dash-0.5.7-do-not-close-stderr.patch [email protected] -- 
Prevents closing stderr when /dev/tty fails to open (backported from upstream 
git)
-Patch0:         dash-0.5.7-do-not-close-stderr.patch
-# PATCH-FIX-UPSTREAM 
dash-remove-backslash-before-in-double-quotes-in-variable.patch 
[email protected] -- Remove backslash before } in double-quotes in variable as 
it prevents the closing brace from terminating the substitution (from 
FreeBSD/Debian)
-Patch1:         dash-remove-backslash-before-in-double-quotes-in-variable.patch
 BuildRequires:  libedit-devel
 
 %description
@@ -37,8 +33,6 @@
 
 %prep
 %setup -q
-%patch0 -p1
-%patch1 -p1
 
 %build
 %configure \

++++++ dash-0.5.9.1.tar.gz -> dash-0.5.10.tar.gz ++++++
++++ 1713 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/config.h.in new/dash-0.5.10/config.h.in
--- old/dash-0.5.9.1/config.h.in        2016-09-23 16:51:24.000000000 +0200
+++ new/dash-0.5.10/config.h.in 2018-05-03 10:48:01.000000000 +0200
@@ -79,6 +79,9 @@
 /* Define to 1 if you have the `strtoumax' function. */
 #undef HAVE_STRTOUMAX
 
+/* Define if your `struct stat' has `st_mtim' */
+#undef HAVE_ST_MTIM
+
 /* Define to 1 if you have the `sysconf' function. */
 #undef HAVE_SYSCONF
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/configure.ac new/dash-0.5.10/configure.ac
--- old/dash-0.5.9.1/configure.ac       2016-09-23 16:51:08.000000000 +0200
+++ new/dash-0.5.10/configure.ac        2018-05-03 10:46:32.000000000 +0200
@@ -1,5 +1,5 @@
-AC_INIT(dash, 0.5.9.1)
-AM_INIT_AUTOMAKE([foreign])
+AC_INIT(dash, 0.5.10)
+AM_INIT_AUTOMAKE([foreign subdir-objects])
 AC_CONFIG_SRCDIR([src/main.c])
 
 AC_CONFIG_HEADERS(config.h)
@@ -149,6 +149,20 @@
        AC_DEFINE(open64, open, [64-bit operations are the same as 32-bit])
 ])
 
+dnl Check if struct stat has st_mtim.
+AC_MSG_CHECKING(for stat::st_mtim)
+AC_COMPILE_IFELSE(
+[AC_LANG_PROGRAM([#include <time.h>
+#include <sys/time.h>
+#include <sys/stat.h>],
+[struct stat foo; return sizeof(foo.st_mtim.tv_sec)])],
+have_st_mtim=yes, have_st_mtim=no)
+AC_MSG_RESULT($have_st_mtim)
+if test "$have_st_mtim" = "yes"; then
+       AC_DEFINE([HAVE_ST_MTIM], [1],
+               [Define if your `struct stat' has `st_mtim'])
+fi
+
 AC_ARG_WITH(libedit, AS_HELP_STRING(--with-libedit, [Compile with libedit 
support]))
 use_libedit=
 if test "$with_libedit" = "yes"; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/bltin/printf.c new/dash-0.5.10/src/bltin/printf.c
--- old/dash-0.5.9.1/src/bltin/printf.c 2016-09-02 16:11:15.000000000 +0200
+++ new/dash-0.5.10/src/bltin/printf.c  2018-04-02 18:16:35.000000000 +0200
@@ -98,20 +98,27 @@
        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;
+       done = conv_escape_str(s, &q);
+       p = stackblock();
+       len = q - p;
+       total = len - 1;
+
+       q[-1] = (!!((f[1] - 's') | done) - 1) & f[2];
+       total += !!q[-1];
+       if (f[1] == 's')
+               goto easy;
+
+       p = makestrspace(len, q);
+       memset(p, 'X', total);
+       p[total] = 0;
 
        q = stackblock();
        total = ASPF(&p, f, p);
 
        len = strchrnul(p, 'X') - p;
-       memcpy(p + len, q, strchrnul(p + len, ' ') - (p + len));
+       memcpy(p + len, q, strspn(p + len, "X"));
 
+easy:
        out1mem(p, total);
 
        popstackmark(&smark);
@@ -209,6 +216,7 @@
                                if (print_escape_str(start, param, array,
                                                     getstr()))
                                        goto out;
+                               *fmt = 'b';
                                break;
                        case 'c': {
                                int p = getchr();
@@ -449,21 +457,22 @@
 int
 echocmd(int argc, char **argv)
 {
+       const char *lastfmt = snlfmt;
        int nonl;
 
-       nonl = *++argv ? equal(*argv, "-n") : 0;
-       argv += nonl;
+       if (*++argv && equal(*argv, "-n")) {
+               argv++;
+               lastfmt = "%s";
+       }
 
        do {
-               int c;
+               const char *fmt = "%s ";
+               char *s = *argv;
+
+               if (!s || !*++argv)
+                       fmt = lastfmt;
 
-               if (likely(*argv))
-                       nonl += print_escape_str("%s", NULL, NULL, *argv++);
-               if (likely((nonl + !*argv) > 1))
-                       break;
-
-               c = *argv ? ' ' : '\n';
-               out1c(c);
-       } while (*argv);
+               nonl = print_escape_str(fmt, NULL, NULL, s ?: nullstr);
+       } while (!nonl && *argv);
        return 0;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/bltin/test.c new/dash-0.5.10/src/bltin/test.c
--- old/dash-0.5.9.1/src/bltin/test.c   2015-08-13 14:53:43.000000000 +0200
+++ new/dash-0.5.10/src/bltin/test.c    2018-03-21 17:25:35.000000000 +0100
@@ -476,9 +476,17 @@
 {
        struct stat b1, b2;
 
+#ifdef HAVE_ST_MTIM
+       return (stat (f1, &b1) == 0 &&
+               stat (f2, &b2) == 0 &&
+               ( b1.st_mtim.tv_sec > b2.st_mtim.tv_sec ||
+                (b1.st_mtim.tv_sec == b2.st_mtim.tv_sec && (b1.st_mtim.tv_nsec 
> b2.st_mtim.tv_nsec )))
+       );
+#else
        return (stat (f1, &b1) == 0 &&
                stat (f2, &b2) == 0 &&
                b1.st_mtime > b2.st_mtime);
+#endif
 }
 
 static int
@@ -486,9 +494,17 @@
 {
        struct stat b1, b2;
 
+#ifdef HAVE_ST_MTIM
+       return (stat (f1, &b1) == 0 &&
+               stat (f2, &b2) == 0 &&
+               (b1.st_mtim.tv_sec < b2.st_mtim.tv_sec ||
+                (b1.st_mtim.tv_sec == b2.st_mtim.tv_sec && (b1.st_mtim.tv_nsec 
< b2.st_mtim.tv_nsec )))
+       );
+#else
        return (stat (f1, &b1) == 0 &&
                stat (f2, &b2) == 0 &&
                b1.st_mtime < b2.st_mtime);
+#endif
 }
 
 static int
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/dash.1 new/dash-0.5.10/src/dash.1
--- old/dash-0.5.9.1/src/dash.1 2016-06-06 16:42:13.000000000 +0200
+++ new/dash-0.5.10/src/dash.1  2018-04-19 12:19:29.000000000 +0200
@@ -606,11 +606,11 @@
 .Dq ||
 are AND-OR list operators.
 .Dq &&
-executes the first command, and then executes the second command iff the
-exit status of the first command is zero.
+executes the first command, and then executes the second command if and only
+if the exit status of the first command is zero.
 .Dq ||
-is similar, but executes the second command iff the exit status of the first
-command is nonzero.
+is similar, but executes the second command if and only if the exit status
+of the first command is nonzero.
 .Dq &&
 and
 .Dq ||
@@ -2226,13 +2226,12 @@
 similar to a subset of those described in the vi man page.
 The command
 .Ql set -o vi
-enables vi-mode editing and place sh into vi insert mode.
+enables vi-mode editing and places sh into vi insert mode.
 With vi-mode
 enabled, sh can be switched between insert mode and command mode.
-The editor is not described in full here, but will be in a later document.
-It's similar to vi: typing
+It is similar to vi: typing
 .Aq ESC
-will throw you into command VI command mode.
+enters vi command mode.
 Hitting
 .Aq return
 while in command mode will pass the line to the shell.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/eval.c new/dash-0.5.10/src/eval.c
--- old/dash-0.5.9.1/src/eval.c 2016-09-02 16:12:23.000000000 +0200
+++ new/dash-0.5.10/src/eval.c  2018-04-19 12:19:48.000000000 +0200
@@ -694,6 +694,7 @@
 #endif
 {
        struct localvar_list *localvar_stop;
+       struct parsefile *file_stop;
        struct redirtab *redir_stop;
        struct stackmark smark;
        union node *argp;
@@ -722,6 +723,7 @@
        TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
        setstackmark(&smark);
        localvar_stop = pushlocalvars();
+       file_stop = parsefile;
        back_exitstatus = 0;
 
        cmdentry.cmdtype = CMDBUILTIN;
@@ -848,6 +850,8 @@
                goto out;
        }
 
+       jp = NULL;
+
        /* Execute the command. */
        switch (cmdentry.cmdtype) {
        default:
@@ -856,7 +860,6 @@
                        INTOFF;
                        jp = makejob(cmd, 1);
                        if (forkshell(jp, cmd, FORK_FG) != 0) {
-                               status = waitforjob(jp);
                                INTON;
                                break;
                        }
@@ -875,26 +878,26 @@
                if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
                        if (exception == EXERROR && spclbltin <= 0) {
                                FORCEINTON;
-                               goto readstatus;
+                               break;
                        }
 raise:
                        longjmp(handler->loc, 1);
                }
-               goto readstatus;
+               break;
 
        case CMDFUNCTION:
-               poplocalvars(1);
                if (evalfun(cmdentry.u.func, argc, argv, flags))
                        goto raise;
-readstatus:
-               status = exitstatus;
                break;
        }
 
+       status = waitforjob(jp);
+
 out:
        if (cmd->ncmd.redirect)
                popredir(execcmd);
        unwindredir(redir_stop);
+       unwindfiles(file_stop);
        unwindlocalvars(localvar_stop);
        if (lastarg)
                /* dsl: I think this is intended to be used to support
@@ -967,9 +970,7 @@
        shellparam.p = argv + 1;
        shellparam.optind = 1;
        shellparam.optoff = -1;
-       pushlocalvars();
        evaltree(func->n.ndefun.body, flags & EV_TESTED);
-       poplocalvars(0);
 funcdone:
        INTOFF;
        loopnest = saveloopnest;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/exec.c new/dash-0.5.10/src/exec.c
--- old/dash-0.5.9.1/src/exec.c 2014-10-02 15:20:56.000000000 +0200
+++ new/dash-0.5.10/src/exec.c  2018-03-10 09:01:09.000000000 +0100
@@ -743,8 +743,6 @@
        struct tblentry *cmdp;
        const struct alias *ap;
 
-       path = path ?: pathval();
-
        if (verbose) {
                outstr(command, out);
        }
@@ -767,8 +765,17 @@
                goto out;
        }
 
-       /* Then check if it is a tracked alias */
-       if ((cmdp = cmdlookup(command, 0)) != NULL) {
+       /* Then if the standard search path is used, check if it is
+        * a tracked alias.
+        */
+       if (path == NULL) {
+               path = pathval();
+               cmdp = cmdlookup(command, 0);
+       } else {
+               cmdp = NULL;
+       }
+
+       if (cmdp != NULL) {
                entry.cmdtype = cmdp->cmdtype;
                entry.u = cmdp->param;
        } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/expand.c new/dash-0.5.10/src/expand.c
--- old/dash-0.5.9.1/src/expand.c       2016-09-23 16:50:15.000000000 +0200
+++ new/dash-0.5.10/src/expand.c        2018-04-19 12:19:29.000000000 +0200
@@ -45,7 +45,9 @@
 #include <inttypes.h>
 #include <limits.h>
 #include <string.h>
+#ifdef HAVE_FNMATCH
 #include <fnmatch.h>
+#endif
 #ifdef HAVE_GLOB
 #include <glob.h>
 #endif
@@ -83,7 +85,7 @@
 #define RMESCAPE_HEAP  0x10    /* Malloc strings instead of stalloc */
 
 /* Add CTLESC when necessary. */
-#define QUOTES_ESC     (EXP_FULL | EXP_CASE | EXP_QPAT)
+#define QUOTES_ESC     (EXP_FULL | EXP_CASE)
 /* Do not skip NUL characters. */
 #define QUOTES_KEEPNUL EXP_TILDE
 
@@ -117,12 +119,12 @@
 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, int *);
+STATIC ssize_t varvalue(char *, int, int, int);
 STATIC void expandmeta(struct strlist *, int);
 #ifdef HAVE_GLOB
 STATIC void addglob(const glob_t *);
 #else
-STATIC void expmeta(char *, char *);
+STATIC void expmeta(char *, unsigned, unsigned);
 STATIC struct strlist *expsort(struct strlist *);
 STATIC struct strlist *msort(struct strlist *, int);
 #endif
@@ -316,13 +318,13 @@
                case CTLENDVAR: /* ??? */
                        goto breakloop;
                case CTLQUOTEMARK:
-                       inquotes ^= EXP_QUOTED;
                        /* "$@" syntax adherence hack */
-                       if (inquotes && !memcmp(p, dolatstr + 1,
-                                               DOLATSTRLEN - 1)) {
-                               p = evalvar(p + 1, flag | inquotes) + 1;
+                       if (!inquotes && !memcmp(p, dolatstr + 1,
+                                                DOLATSTRLEN - 1)) {
+                               p = evalvar(p + 1, flag | EXP_QUOTED) + 1;
                                goto start;
                        }
+                       inquotes ^= EXP_QUOTED;
 addquote:
                        if (flag & QUOTES_ESC) {
                                p--;
@@ -333,16 +335,6 @@
                case CTLESC:
                        startloc++;
                        length++;
-
-                       /*
-                        * Quoted parameter expansion pattern: remove quote
-                        * unless inside inner quotes or we have a literal
-                        * backslash.
-                        */
-                       if (((flag | inquotes) & (EXP_QPAT | EXP_QUOTED)) ==
-                           EXP_QPAT && *p != '\\')
-                               break;
-
                        goto addquote;
                case CTLVAR:
                        p = evalvar(p, flag | inquotes);
@@ -651,8 +643,7 @@
        char *(*scan)(char *, char *, char *, char *, int , int);
 
        argstr(p, EXP_TILDE | (subtype != VSASSIGN && subtype != VSQUESTION ?
-                              (flag & (EXP_QUOTED | EXP_QPAT) ?
-                               EXP_QPAT : EXP_CASE) : 0));
+                              EXP_CASE : 0));
        STPUTC('\0', expdest);
        argbackq = saveargbackq;
        startp = stackblock() + startloc;
@@ -721,7 +712,6 @@
        int c;
        int startloc;
        ssize_t varlen;
-       int easy;
        int quoted;
 
        varflags = *p++;
@@ -732,12 +722,11 @@
 
        quoted = flag & EXP_QUOTED;
        var = p;
-       easy = (!quoted || (*var == '@' && shellparam.nparam));
        startloc = expdest - (char *)stackblock();
        p = strchr(p, '=') + 1;
 
 again:
-       varlen = varvalue(var, varflags, flag, &quoted);
+       varlen = varvalue(var, varflags, flag, quoted);
        if (varflags & VSNUL)
                varlen--;
 
@@ -780,8 +769,11 @@
 
        if (subtype == VSNORMAL) {
 record:
-               if (!easy)
-                       goto end;
+               if (quoted) {
+                       quoted = *var == '@' && shellparam.nparam;
+                       if (!quoted)
+                               goto end;
+               }
                recordregion(startloc, expdest - (char *)stackblock(), quoted);
                goto end;
        }
@@ -857,8 +849,7 @@
                if (c) {
                        if ((quotes & QUOTES_ESC) &&
                            ((syntax[c] == CCTL) ||
-                            (((quotes & EXP_FULL) || syntax != BASESYNTAX) &&
-                             syntax[c] == CBACK)))
+                            (syntax != BASESYNTAX && syntax[c] == CBACK)))
                                USTPUTC(CTLESC, q);
                } else if (!(quotes & QUOTES_KEEPNUL))
                        continue;
@@ -887,7 +878,7 @@
  */
 
 STATIC ssize_t
-varvalue(char *name, int varflags, int flags, int *quotedp)
+varvalue(char *name, int varflags, int flags, int quoted)
 {
        int num;
        char *p;
@@ -896,11 +887,11 @@
        char sepc;
        char **ap;
        char const *syntax;
-       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;
+       char c;
 
        sep = (flags & EXP_FULL) << CHAR_BIT;
        syntax = quoted ? DQSYNTAX : BASESYNTAX;
@@ -925,7 +916,7 @@
        case '-':
                p = makestrspace(NOPTS, expdest);
                for (i = NOPTS - 1; i >= 0; i--) {
-                       if (optlist[i]) {
+                       if (optlist[i] && optletters[i]) {
                                USTPUTC(optletters[i], p);
                                len++;
                        }
@@ -937,12 +928,25 @@
                        goto param;
                /* fall through */
        case '*':
-               if (quoted)
-                       sep = 0;
-               sep |= ifsset() ? ifsval()[0] : ' ';
+               /* We will set c to 0 or ~0 depending on whether
+                * we're doing field splitting.  We won't do field
+                * splitting if either we're quoted or sep is zero.
+                *
+                * Instead of testing (quoted || !sep) the following
+                * trick optimises away any branches by using the
+                * fact that EXP_QUOTED (which is the only bit that
+                * can be set in quoted) is the same as EXP_FULL <<
+                * CHAR_BIT (which is the only bit that can be set
+                * in sep).
+                */
+#if EXP_QUOTED >> CHAR_BIT != EXP_FULL
+#error The following two lines expect EXP_QUOTED == EXP_FULL << CHAR_BIT
+#endif
+               c = !((quoted | ~sep) & EXP_QUOTED) - 1;
+               sep &= ~quoted;
+               sep |= ifsset() ? (unsigned char)(c & ifsval()[0]) : ' ';
 param:
                sepc = sep;
-               *quotedp = !sepc;
                if (!(ap = shellparam.p))
                        return -1;
                while ((p = *ap++)) {
@@ -1041,7 +1045,10 @@
                realifs = ifsset() ? ifsval() : defifs;
                ifsp = &ifsfirst;
                do {
+                       int afternul;
+
                        p = string + ifsp->begoff;
+                       afternul = nulonly;
                        nulonly = ifsp->nulonly;
                        ifs = nulonly ? nullstr : realifs;
                        ifsspc = 0;
@@ -1106,7 +1113,7 @@
                                }
 
                                if (isifs) {
-                                       if (!nulonly)
+                                       if (!(afternul || nulonly))
                                                ifsspc = isdefifs;
                                        /* Ignore IFS whitespace at start */
                                        if (q == start && ifsspc) {
@@ -1197,7 +1204,8 @@
                        ckfree(p);
                switch (i) {
                case 0:
-                       if (!(pglob.gl_flags & GLOB_MAGCHAR))
+                       if ((pglob.gl_flags & (GLOB_NOMAGIC | GLOB_NOCHECK)) ==
+                           (GLOB_NOMAGIC | GLOB_NOCHECK))
                                goto nometa2;
                        addglob(&pglob);
                        globfree(&pglob);
@@ -1238,6 +1246,7 @@
 
 #else  /* HAVE_GLOB */
 STATIC char *expdir;
+STATIC unsigned expdir_max;
 
 
 STATIC void
@@ -1252,6 +1261,7 @@
                struct strlist **savelastp;
                struct strlist *sp;
                char *p;
+               unsigned len;
 
                if (fflag)
                        goto nometa;
@@ -1261,12 +1271,11 @@
 
                INTOFF;
                p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP);
-               {
-                       int i = strlen(str->text);
-                       expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
-               }
+               len = strlen(p);
+               expdir_max = len + PATH_MAX;
+               expdir = ckmalloc(expdir_max);
 
-               expmeta(expdir, p);
+               expmeta(p, len, 0);
                ckfree(expdir);
                if (p != str->text)
                        ckfree(p);
@@ -1296,8 +1305,9 @@
  */
 
 STATIC void
-expmeta(char *enddir, char *name)
+expmeta(char *name, unsigned name_len, unsigned expdir_len)
 {
+       char *enddir = expdir + expdir_len;
        char *p;
        const char *cp;
        char *start;
@@ -1330,7 +1340,7 @@
                                }
                        }
                } else {
-                       if (*p == '\\')
+                       if (*p == '\\' && p[1])
                                esc++;
                        if (p[esc] == '/') {
                                if (metaflag)
@@ -1340,15 +1350,15 @@
                }
        }
        if (metaflag == 0) {    /* we've reached the end of the file name */
-               if (enddir != expdir)
-                       metaflag++;
+               if (!expdir_len)
+                       return;
                p = name;
                do {
-                       if (*p == '\\')
+                       if (*p == '\\' && p[1])
                                p++;
                        *enddir++ = *p;
                } while (*p++);
-               if (metaflag == 0 || lstat64(expdir, &statb) >= 0)
+               if (lstat64(expdir, &statb) >= 0)
                        addfname(expdir);
                return;
        }
@@ -1356,23 +1366,18 @@
        if (name < start) {
                p = name;
                do {
-                       if (*p == '\\')
+                       if (*p == '\\' && p[1])
                                p++;
                        *enddir++ = *p++;
                } while (p < start);
        }
-       if (enddir == expdir) {
+       *enddir = 0;
+       cp = expdir;
+       expdir_len = enddir - cp;
+       if (!expdir_len)
                cp = ".";
-       } else if (enddir == expdir + 1 && *expdir == '/') {
-               cp = "/";
-       } else {
-               cp = expdir;
-               enddir[-1] = '\0';
-       }
        if ((dirp = opendir(cp)) == NULL)
                return;
-       if (enddir != expdir)
-               enddir[-1] = '/';
        if (*endname == 0) {
                atend = 1;
        } else {
@@ -1380,6 +1385,7 @@
                *endname = '\0';
                endname += esc + 1;
        }
+       name_len -= endname - name;
        matchdot = 0;
        p = start;
        if (*p == '\\')
@@ -1394,11 +1400,22 @@
                                scopy(dp->d_name, enddir);
                                addfname(expdir);
                        } else {
-                               for (p = enddir, cp = dp->d_name;
-                                    (*p++ = *cp++) != '\0';)
-                                       continue;
-                               p[-1] = '/';
-                               expmeta(p, endname);
+                               unsigned offset;
+                               unsigned len;
+
+                               p = stpcpy(enddir, dp->d_name);
+                               *p = '/';
+
+                               offset = p - expdir + 1;
+                               len = offset + name_len + NAME_MAX;
+                               if (len > expdir_max) {
+                                       len += PATH_MAX;
+                                       expdir = ckrealloc(expdir, len);
+                                       expdir_max = len;
+                               }
+
+                               expmeta(endname, name_len, offset);
+                               enddir = expdir + expdir_len;
                        }
                }
        }
@@ -1644,7 +1661,6 @@
 _rmescapes(char *str, int flag)
 {
        char *p, *q, *r;
-       unsigned inquotes;
        int notescaped;
        int globbing;
 
@@ -1674,24 +1690,23 @@
                        q = mempcpy(q, str, len);
                }
        }
-       inquotes = 0;
        globbing = flag & RMESCAPE_GLOB;
        notescaped = globbing;
        while (*p) {
                if (*p == (char)CTLQUOTEMARK) {
-                       inquotes = ~inquotes;
                        p++;
                        notescaped = globbing;
                        continue;
                }
+               if (*p == '\\') {
+                       /* naked back slash */
+                       notescaped = 0;
+                       goto copy;
+               }
                if (*p == (char)CTLESC) {
                        p++;
                        if (notescaped)
                                *q++ = '\\';
-               } else if (*p == '\\' && !inquotes) {
-                       /* naked back slash */
-                       notescaped = 0;
-                       goto copy;
                }
                notescaped = globbing;
 copy:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/expand.h new/dash-0.5.10/src/expand.h
--- old/dash-0.5.9.1/src/expand.h       2016-09-02 16:11:15.000000000 +0200
+++ new/dash-0.5.10/src/expand.h        2018-04-02 18:16:35.000000000 +0200
@@ -55,7 +55,6 @@
 #define        EXP_VARTILDE    0x4     /* expand tildes in an assignment */
 #define        EXP_REDIR       0x8     /* file glob for a redirection (1 match 
only) */
 #define EXP_CASE       0x10    /* keeps quotes around for CASE pattern */
-#define EXP_QPAT       0x20    /* pattern in quoted parameter expansion */
 #define EXP_VARTILDE2  0x40    /* expand tildes after colons only */
 #define EXP_WORD       0x80    /* expand word in parameter expansion */
 #define EXP_QUOTED     0x100   /* expand word in double quotes */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/histedit.c new/dash-0.5.10/src/histedit.c
--- old/dash-0.5.9.1/src/histedit.c     2014-09-30 12:57:27.000000000 +0200
+++ new/dash-0.5.10/src/histedit.c      2018-03-10 09:01:43.000000000 +0100
@@ -39,6 +39,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <getopt.h>
 /*
  * Editline and history functions (and glue).
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/input.c new/dash-0.5.10/src/input.c
--- old/dash-0.5.9.1/src/input.c        2015-05-26 04:45:57.000000000 +0200
+++ new/dash-0.5.10/src/input.c 2018-04-19 12:19:29.000000000 +0200
@@ -147,8 +147,12 @@
                static const char *rl_cp;
                static int el_len;
 
-               if (rl_cp == NULL)
+               if (rl_cp == NULL) {
+                       struct stackmark smark;
+                       pushstackmark(&smark, stackblocksize());
                        rl_cp = el_gets(el, &el_len);
+                       popstackmark(&smark);
+               }
                if (rl_cp == NULL)
                        nr = 0;
                else {
@@ -475,6 +479,13 @@
 }
 
 
+void unwindfiles(struct parsefile *stop)
+{
+       while (parsefile != stop)
+               popfile();
+}
+
+
 /*
  * Return to top level.
  */
@@ -482,8 +493,7 @@
 void
 popallfiles(void)
 {
-       while (parsefile != &basepf)
-               popfile();
+       unwindfiles(&basepf);
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/input.h new/dash-0.5.10/src/input.h
--- old/dash-0.5.9.1/src/input.h        2015-05-26 04:45:57.000000000 +0200
+++ new/dash-0.5.10/src/input.h 2018-04-19 12:19:29.000000000 +0200
@@ -97,5 +97,6 @@
 int setinputfile(const char *, int);
 void setinputstring(char *);
 void popfile(void);
+void unwindfiles(struct parsefile *);
 void popallfiles(void);
 void closescript(void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/jobs.c new/dash-0.5.10/src/jobs.c
--- old/dash-0.5.9.1/src/jobs.c 2016-09-02 16:12:23.000000000 +0200
+++ new/dash-0.5.10/src/jobs.c  2018-04-19 12:19:29.000000000 +0200
@@ -53,6 +53,7 @@
 #include <termios.h>
 #undef CEOF                    /* syntax.h redefines this */
 #endif
+#include "eval.h"
 #include "redir.h"
 #include "show.h"
 #include "main.h"
@@ -648,7 +649,7 @@
        return retval;
 
 sigout:
-       retval = 128 + pendingsigs;
+       retval = 128 + pending_sig;
        goto out;
 }
 
@@ -973,10 +974,11 @@
 {
        int st;
 
-       TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
-       while (jp->state == JOBRUNNING) {
+       TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0));
+       while ((jp && jp->state == JOBRUNNING) || gotsigchld)
                dowait(DOWAIT_BLOCK, jp);
-       }
+       if (!jp)
+               return exitstatus;
        st = getstatus(jp);
 #if JOBS
        if (jp->jobctl) {
@@ -1147,7 +1149,7 @@
                sigfillset(&mask);
                sigprocmask(SIG_SETMASK, &mask, &oldmask);
 
-               while (!gotsigchld && !pendingsigs)
+               while (!gotsigchld && !pending_sig)
                        sigsuspend(&oldmask);
 
                sigclearmask();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/miscbltin.c new/dash-0.5.10/src/miscbltin.c
--- old/dash-0.5.9.1/src/miscbltin.c    2016-09-02 16:11:15.000000000 +0200
+++ new/dash-0.5.10/src/miscbltin.c     2018-03-10 08:59:26.000000000 +0100
@@ -152,7 +152,7 @@
                case 1:
                        break;
                default:
-                       if (errno == EINTR && !pendingsigs)
+                       if (errno == EINTR && !pending_sig)
                                continue;
                                /* fall through */
                case 0:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/mystring.c new/dash-0.5.10/src/mystring.c
--- old/dash-0.5.9.1/src/mystring.c     2014-09-28 10:19:32.000000000 +0200
+++ new/dash-0.5.10/src/mystring.c      2018-03-10 09:01:43.000000000 +0100
@@ -125,7 +125,7 @@
        errno = 0;
        r = strtoimax(s, &p, base);
 
-       if (errno != 0)
+       if (errno == ERANGE)
                badnum(s);
 
        /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/parser.c new/dash-0.5.10/src/parser.c
--- old/dash-0.5.9.1/src/parser.c       2014-11-17 05:56:01.000000000 +0100
+++ new/dash-0.5.10/src/parser.c        2018-04-19 12:19:29.000000000 +0200
@@ -80,6 +80,18 @@
        int striptabs;          /* if set, strip leading tabs */
 };
 
+struct synstack {
+       const char *syntax;
+       struct synstack *prev;
+       struct synstack *next;
+       int innerdq;
+       int varpushed;
+       int dblquote;
+       int varnest;            /* levels of variables expansion */
+       int parenlevel;         /* levels of parens in arithmetic */
+       int dqvarnest;          /* levels of variables expansion within double 
quotes */
+};
+
 
 
 struct heredoc *heredoclist;   /* list of here documents to read */
@@ -106,6 +118,7 @@
 STATIC int peektoken(void);
 STATIC int readtoken(void);
 STATIC int xxreadtoken(void);
+STATIC int pgetc_eatbnl();
 STATIC int readtoken1(int, char const *, char *, int);
 STATIC void synexpect(int) __attribute__((__noreturn__));
 STATIC void synerror(const char *) __attribute__((__noreturn__));
@@ -656,8 +669,10 @@
                if (needprompt) {
                        setprompt(2);
                }
-               readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : 
DQSYNTAX,
-                               here->eofmark, here->striptabs);
+               if (here->here->type == NHERE)
+                       readtoken1(pgetc(), SQSYNTAX, here->eofmark, 
here->striptabs);
+               else
+                       readtoken1(pgetc_eatbnl(), DQSYNTAX, here->eofmark, 
here->striptabs);
                n = (union node *)stalloc(sizeof (struct narg));
                n->narg.type = NARG;
                n->narg.next = NULL;
@@ -782,7 +797,7 @@
                setprompt(2);
        }
        for (;;) {      /* until token or start of word found */
-               c = pgetc();
+               c = pgetc_eatbnl();
                switch (c) {
                case ' ': case '\t':
                case PEOA:
@@ -791,30 +806,23 @@
                        while ((c = pgetc()) != '\n' && c != PEOF);
                        pungetc();
                        continue;
-               case '\\':
-                       if (pgetc() == '\n') {
-                               nlprompt();
-                               continue;
-                       }
-                       pungetc();
-                       goto breakloop;
                case '\n':
                        nlnoprompt();
                        RETURN(TNL);
                case PEOF:
                        RETURN(TEOF);
                case '&':
-                       if (pgetc() == '&')
+                       if (pgetc_eatbnl() == '&')
                                RETURN(TAND);
                        pungetc();
                        RETURN(TBACKGND);
                case '|':
-                       if (pgetc() == '|')
+                       if (pgetc_eatbnl() == '|')
                                RETURN(TOR);
                        pungetc();
                        RETURN(TPIPE);
                case ';':
-                       if (pgetc() == ';')
+                       if (pgetc_eatbnl() == ';')
                                RETURN(TENDCASE);
                        pungetc();
                        RETURN(TSEMI);
@@ -822,11 +830,9 @@
                        RETURN(TLP);
                case ')':
                        RETURN(TRP);
-               default:
-                       goto breakloop;
                }
+               break;
        }
-breakloop:
        return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
 #undef RETURN
 }
@@ -836,7 +842,7 @@
        int c;
 
        while ((c = pgetc()) == '\\') {
-               if (pgetc() != '\n') {
+               if (pgetc2() != '\n') {
                        pungetc();
                        break;
                }
@@ -847,6 +853,21 @@
        return c;
 }
 
+static void synstack_push(struct synstack **stack, struct synstack *next,
+                         const char *syntax)
+{
+       memset(next, 0, sizeof(*next));
+       next->syntax = syntax;
+       next->next = *stack;
+       (*stack)->prev = next;
+       *stack = next;
+}
+
+static void synstack_pop(struct synstack **stack)
+{
+       *stack = (*stack)->next;
+}
+
 
 
 /*
@@ -876,24 +897,15 @@
        size_t len;
        struct nodelist *bqlist;
        int quotef;
-       int dblquote;
-       int varnest;    /* levels of variables expansion */
-       int arinest;    /* levels of arithmetic expansion */
-       int parenlevel; /* levels of parens in arithmetic */
-       int dqvarnest;  /* levels of variables expansion within double quotes */
        int oldstyle;
-       /* syntax before arithmetic */
-       char const *uninitialized_var(prevsyntax);
+       /* syntax stack */
+       struct synstack synbase = { .syntax = syntax };
+       struct synstack *synstack = &synbase;
 
-       dblquote = 0;
        if (syntax == DQSYNTAX)
-               dblquote = 1;
+               synstack->dblquote = 1;
        quotef = 0;
        bqlist = NULL;
-       varnest = 0;
-       arinest = 0;
-       parenlevel = 0;
-       dqvarnest = 0;
 
        STARTSTACKSTR(out);
        loop: { /* for each line, until end of word */
@@ -901,28 +913,30 @@
                if (c == '\034' && doprompt
                 && attyset() && ! equal(termval(), "emacs")) {
                        attyline();
-                       if (syntax == BASESYNTAX)
+                       if (synstack->syntax == BASESYNTAX)
                                return readtoken();
-                       c = pgetc();
+                       c = syntax == SQSYNTAX ? pgetc() : pgetc_eatbnl();
                        goto loop;
                }
 #endif
                CHECKEND();     /* set c to PEOF if at end of here document */
                for (;;) {      /* until end of line or end of word */
                        CHECKSTRSPACE(4, out);  /* permit 4 calls to USTPUTC */
-                       switch(syntax[c]) {
+                       switch(synstack->syntax[c]) {
                        case CNL:       /* '\n' */
-                               if (syntax == BASESYNTAX)
+                               if (synstack->syntax == BASESYNTAX &&
+                                   !synstack->varnest)
                                        goto endword;   /* exit outer loop */
                                USTPUTC(c, out);
                                nlprompt();
-                               c = pgetc();
+                               c = syntax == SQSYNTAX ? pgetc() : 
pgetc_eatbnl();
                                goto loop;              /* continue outer loop 
*/
                        case CWORD:
                                USTPUTC(c, out);
                                break;
                        case CCTL:
-                               if (eofmark == NULL || dblquote)
+                               if ((!eofmark) | synstack->dblquote |
+                                   synstack->varnest)
                                        USTPUTC(CTLESC, out);
                                USTPUTC(c, out);
                                break;
@@ -933,17 +947,20 @@
                                        USTPUTC(CTLESC, out);
                                        USTPUTC('\\', out);
                                        pungetc();
-                               } else if (c == '\n') {
-                                       nlprompt();
                                } else {
                                        if (
-                                               dblquote &&
+                                               synstack->dblquote &&
                                                c != '\\' && c != '`' &&
                                                c != '$' && (
                                                        c != '"' ||
-                                                       eofmark != NULL
+                                                       (eofmark != NULL &&
+                                                        !synstack->varnest)
+                                               ) && (
+                                                       c != '}' ||
+                                                       !synstack->varnest
                                                )
                                        ) {
+                                               USTPUTC(CTLESC, out);
                                                USTPUTC('\\', out);
                                        }
                                        USTPUTC(CTLESC, out);
@@ -952,55 +969,64 @@
                                }
                                break;
                        case CSQUOTE:
-                               syntax = SQSYNTAX;
+                               synstack->syntax = SQSYNTAX;
 quotemark:
                                if (eofmark == NULL) {
                                        USTPUTC(CTLQUOTEMARK, out);
                                }
                                break;
                        case CDQUOTE:
-                               syntax = DQSYNTAX;
-                               dblquote = 1;
+                               synstack->syntax = DQSYNTAX;
+                               synstack->dblquote = 1;
+toggledq:
+                               if (synstack->varnest)
+                                       synstack->innerdq ^= 1;
                                goto quotemark;
                        case CENDQUOTE:
-                               if (eofmark && !varnest)
+                               if (eofmark && !synstack->varnest) {
                                        USTPUTC(c, out);
-                               else {
-                                       if (dqvarnest == 0) {
-                                               syntax = BASESYNTAX;
-                                               dblquote = 0;
-                                       }
-                                       quotef++;
-                                       goto quotemark;
+                                       break;
                                }
-                               break;
+
+                               if (synstack->dqvarnest == 0) {
+                                       synstack->syntax = BASESYNTAX;
+                                       synstack->dblquote = 0;
+                               }
+
+                               quotef++;
+
+                               if (c == '"')
+                                       goto toggledq;
+
+                               goto quotemark;
                        case CVAR:      /* '$' */
                                PARSESUB();             /* parse substitution */
                                break;
                        case CENDVAR:   /* '}' */
-                               if (varnest > 0) {
-                                       varnest--;
-                                       if (dqvarnest > 0) {
-                                               dqvarnest--;
-                                       }
+                               if (!synstack->innerdq &&
+                                   synstack->varnest > 0) {
+                                       if (!--synstack->varnest &&
+                                           synstack->varpushed)
+                                               synstack_pop(&synstack);
+                                       else if (synstack->dqvarnest > 0)
+                                               synstack->dqvarnest--;
                                        USTPUTC(CTLENDVAR, out);
                                } else {
                                        USTPUTC(c, out);
                                }
                                break;
                        case CLP:       /* '(' in arithmetic */
-                               parenlevel++;
+                               synstack->parenlevel++;
                                USTPUTC(c, out);
                                break;
                        case CRP:       /* ')' in arithmetic */
-                               if (parenlevel > 0) {
+                               if (synstack->parenlevel > 0) {
                                        USTPUTC(c, out);
-                                       --parenlevel;
+                                       --synstack->parenlevel;
                                } else {
-                                       if (pgetc() == ')') {
+                                       if (pgetc_eatbnl() == ')') {
                                                USTPUTC(CTLENDARI, out);
-                                               if (!--arinest)
-                                                       syntax = prevsyntax;
+                                               synstack_pop(&synstack);
                                        } else {
                                                /*
                                                 * unbalanced parens
@@ -1012,6 +1038,11 @@
                                }
                                break;
                        case CBQUOTE:   /* '`' */
+                               if (checkkwd & CHKEOFMARK) {
+                                       USTPUTC('`', out);
+                                       break;
+                               }
+
                                PARSEBACKQOLD();
                                break;
                        case CEOF:
@@ -1019,21 +1050,21 @@
                        case CIGN:
                                break;
                        default:
-                               if (varnest == 0)
+                               if (synstack->varnest == 0)
                                        goto endword;   /* exit outer loop */
                                if (c != PEOA) {
                                        USTPUTC(c, out);
                                }
                        }
-                       c = pgetc();
+                       c = syntax == SQSYNTAX ? pgetc() : pgetc_eatbnl();
                }
        }
 endword:
-       if (syntax == ARISYNTAX)
+       if (synstack->syntax == ARISYNTAX)
                synerror("Missing '))'");
-       if (syntax != BASESYNTAX && eofmark == NULL)
+       if (synstack->syntax != BASESYNTAX && eofmark == NULL)
                synerror("Unterminated quoted string");
-       if (varnest != 0) {
+       if (synstack->varnest != 0) {
                /* { */
                synerror("Missing '}'");
        }
@@ -1132,7 +1163,7 @@
        np = (union node *)stalloc(sizeof (struct nfile));
        if (c == '>') {
                np->nfile.fd = 1;
-               c = pgetc();
+               c = pgetc_eatbnl();
                if (c == '>')
                        np->type = NAPPEND;
                else if (c == '|')
@@ -1145,7 +1176,7 @@
                }
        } else {        /* c == '<' */
                np->nfile.fd = 0;
-               switch (c = pgetc()) {
+               switch (c = pgetc_eatbnl()) {
                case '<':
                        if (sizeof (struct nfile) != sizeof (struct nhere)) {
                                np = (union node *)stalloc(sizeof (struct 
nhere));
@@ -1154,7 +1185,7 @@
                        np->type = NHERE;
                        heredoc = (struct heredoc *)stalloc(sizeof (struct 
heredoc));
                        heredoc->here = np;
-                       if ((c = pgetc()) == '-') {
+                       if ((c = pgetc_eatbnl()) == '-') {
                                heredoc->striptabs = 1;
                        } else {
                                heredoc->striptabs = 0;
@@ -1210,6 +1241,8 @@
                        PARSEBACKQNEW();
                }
        } else {
+               const char *newsyn = synstack->syntax;
+
                USTPUTC(CTLVAR, out);
                typeloc = out - (char *)stackblock();
                STADJUST(1, out);
@@ -1229,7 +1262,7 @@
                                STPUTC(c, out);
                                c = pgetc_eatbnl();
                        } while (is_digit(c));
-               } else {
+               } else if (c != '}') {
                        int cc = c;
 
                        c = pgetc_eatbnl();
@@ -1257,9 +1290,12 @@
                        }
 
                        USTPUTC(cc, out);
-               }
+               } else
+                       goto badsub;
 
                if (subtype == 0) {
+                       int cc = c;
+
                        switch (c) {
                        case ':':
                                subtype = VSNUL;
@@ -1273,27 +1309,41 @@
                                break;
                        case '%':
                        case '#':
-                               {
-                                       int cc = c;
-                                       subtype = c == '#' ? VSTRIMLEFT :
-                                                            VSTRIMRIGHT;
-                                       c = pgetc_eatbnl();
-                                       if (c == cc)
-                                               subtype++;
-                                       else
-                                               pungetc();
-                                       break;
-                               }
+                               subtype = c == '#' ? VSTRIMLEFT :
+                                                    VSTRIMRIGHT;
+                               c = pgetc_eatbnl();
+                               if (c == cc)
+                                       subtype++;
+                               else
+                                       pungetc();
+
+                               newsyn = BASESYNTAX;
+                               break;
                        }
                } else {
 badsub:
                        pungetc();
                }
+
+               if (newsyn == ARISYNTAX)
+                       newsyn = DQSYNTAX;
+
+               if ((newsyn != synstack->syntax || synstack->innerdq) &&
+                   subtype != VSNORMAL) {
+                       synstack_push(&synstack,
+                                     synstack->prev ?:
+                                     alloca(sizeof(*synstack)),
+                                     newsyn);
+
+                       synstack->varpushed++;
+                       synstack->dblquote = newsyn != BASESYNTAX;
+               }
+
                *((char *)stackblock() + typeloc) = subtype;
                if (subtype != VSNORMAL) {
-                       varnest++;
-                       if (dblquote)
-                               dqvarnest++;
+                       synstack->varnest++;
+                       if (synstack->dblquote)
+                               synstack->dqvarnest++;
                }
                STPUTC('=', out);
        }
@@ -1336,23 +1386,14 @@
                        if (needprompt) {
                                setprompt(2);
                        }
-                       switch (pc = pgetc()) {
+                       switch (pc = pgetc_eatbnl()) {
                        case '`':
                                goto done;
 
                        case '\\':
-                                if ((pc = pgetc()) == '\n') {
-                                       nlprompt();
-                                       /*
-                                        * If eating a newline, avoid putting
-                                        * the newline into the new character
-                                        * stream (via the STPUTC after the
-                                        * switch).
-                                        */
-                                       continue;
-                               }
+                                pc = pgetc_eatbnl();
                                 if (pc != '\\' && pc != '`' && pc != '$'
-                                    && (!dblquote || pc != '"'))
+                                    && (!synstack->dblquote || pc != '"'))
                                         STPUTC('\\', pout);
                                if (pc > PEOA) {
                                        break;
@@ -1428,10 +1469,10 @@
  */
 parsearith: {
 
-       if (++arinest == 1) {
-               prevsyntax = syntax;
-               syntax = ARISYNTAX;
-       }
+       synstack_push(&synstack,
+                     synstack->prev ?: alloca(sizeof(*synstack)),
+                     ARISYNTAX);
+       synstack->dblquote = 1;
        USTPUTC(CTLARI, out);
        goto parsearith_return;
 }
@@ -1529,7 +1570,7 @@
        saveprompt = doprompt;
        doprompt = 0;
 
-       readtoken1(pgetc(), DQSYNTAX, FAKEEOFMARK, 0);
+       readtoken1(pgetc_eatbnl(), DQSYNTAX, FAKEEOFMARK, 0);
 
        doprompt = saveprompt;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/redir.c new/dash-0.5.10/src/redir.c
--- old/dash-0.5.9.1/src/redir.c        2014-10-02 15:24:53.000000000 +0200
+++ new/dash-0.5.10/src/redir.c 2018-04-19 12:19:28.000000000 +0200
@@ -192,7 +192,7 @@
                        } else if (!S_ISREG(sb.st_mode)) {
                                if ((f = open64(fname, O_WRONLY, 0666)) < 0)
                                        goto ecreate;
-                               if (fstat64(f, &sb) < 0 && S_ISREG(sb.st_mode)) 
{
+                               if (!fstat64(f, &sb) && S_ISREG(sb.st_mode)) {
                                        close(f);
                                        errno = EEXIST;
                                        goto ecreate;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/trap.c new/dash-0.5.10/src/trap.c
--- old/dash-0.5.9.1/src/trap.c 2016-09-02 16:12:23.000000000 +0200
+++ new/dash-0.5.10/src/trap.c  2018-03-10 08:59:26.000000000 +0100
@@ -73,7 +73,7 @@
 /* indicates specified signal received */
 static char gotsig[NSIG - 1];
 /* last pending signal */
-volatile sig_atomic_t pendingsigs;
+volatile sig_atomic_t pending_sig;
 /* received SIGCHLD */
 int gotsigchld;
 
@@ -291,7 +291,7 @@
        }
 
        gotsig[signo - 1] = 1;
-       pendingsigs = signo;
+       pending_sig = signo;
 
        if (signo == SIGINT && !trap[SIGINT]) {
                if (!suppressint)
@@ -314,7 +314,7 @@
        int i;
        int status, last_status;
 
-       if (!pendingsigs)
+       if (!pending_sig)
                return;
 
        status = savestatus;
@@ -323,7 +323,7 @@
                status = exitstatus;
                savestatus = status;
        }
-       pendingsigs = 0;
+       pending_sig = 0;
        barrier();
 
        for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
@@ -331,7 +331,7 @@
                        continue;
 
                if (evalskip) {
-                       pendingsigs = i + 1;
+                       pending_sig = i + 1;
                        break;
                }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/dash-0.5.9.1/src/trap.h new/dash-0.5.10/src/trap.h
--- old/dash-0.5.9.1/src/trap.h 2016-06-06 13:38:43.000000000 +0200
+++ new/dash-0.5.10/src/trap.h  2018-03-10 08:59:26.000000000 +0100
@@ -38,7 +38,7 @@
 
 extern int trapcnt;
 extern char sigmode[];
-extern volatile sig_atomic_t pendingsigs;
+extern volatile sig_atomic_t pending_sig;
 extern int gotsigchld;
 
 int trapcmd(int, char **);


Reply via email to