On 3/8/18 1:40 AM, Harald van Dijk wrote:
If the syntax stack is to be stored on the actual stack, then real
recursion could be used instead, as attached.
Even though it won't be accepted in dash, I continued with this approach
for my own use. I've now got it to about 1800 bytes smaller (at -Os -s).
After the other changes I'd done, it became apparent to me that the
syntax tables were unnecessary, and that they'd become fairly easy to
get rid of. This was a big space saver that may be possible to apply to
your version as well.
Cheers,
Harald van Dijk
diff --git a/src/expand.c b/src/expand.c
index 2a50830..acd5fdf 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -83,7 +83,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
@@ -115,8 +115,8 @@ STATIC char *exptilde(char *, char *, int);
STATIC void expbackq(union node *, int);
STATIC const char *subevalvar(char *, char *, int, int, int, int, int);
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 size_t strtodest(const char *, int);
+STATIC void memtodest(const char *, size_t, int);
STATIC ssize_t varvalue(char *, int, int, int *);
STATIC void expandmeta(struct strlist *, int);
#ifdef HAVE_GLOB
@@ -333,16 +333,6 @@ addquote:
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);
@@ -396,7 +386,7 @@ done:
if (!home || !*home)
goto lose;
*p = c;
- strtodest(home, SQSYNTAX, quotes);
+ strtodest(home, quotes | EXP_QUOTED);
return (p);
lose:
*p = c;
@@ -521,7 +511,6 @@ expbackq(union node *cmd, int flag)
char *p;
char *dest;
int startloc;
- char const *syntax = flag & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
struct stackmark smark;
INTOFF;
@@ -535,7 +524,7 @@ expbackq(union node *cmd, int flag)
if (i == 0)
goto read;
for (;;) {
- memtodest(p, i, syntax, flag & QUOTES_ESC);
+ memtodest(p, i, flag & (QUOTES_ESC | EXP_QUOTED));
read:
if (in.fd < 0)
break;
@@ -651,8 +640,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla
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;
@@ -844,7 +832,7 @@ end:
*/
STATIC void
-memtodest(const char *p, size_t len, const char *syntax, int quotes) {
+memtodest(const char *p, size_t len, int quotes) {
char *q;
if (unlikely(!len))
@@ -855,11 +843,17 @@ memtodest(const char *p, size_t len, const char *syntax, int quotes) {
do {
int c = (signed char)*p++;
if (c) {
- if ((quotes & QUOTES_ESC) &&
- ((syntax[c] == CCTL) ||
- (((quotes & EXP_FULL) || syntax != BASESYNTAX) &&
- syntax[c] == CBACK)))
-USTPUTC(CTLESC, q);
+ if (quotes & QUOTES_ESC) {
+switch (c) {
+ case '\\':
+ case '!': case '*': case '?': case '[': case '=':
+ case '~': case ':': case '/': case '-': case ']':
+ if (quotes & EXP_QUOTED)
+ case CTLVARS:
+ USTPUTC(CTLESC, q);
+ break;
+}
+ }
} else if (!(quotes & QUOTES_KEEPNUL))
continue;
USTPUTC(c, q);
@@ -870,13 +864,10 @@ memtodest(const char *p, size_t len, const char *syntax, int quotes) {
STATIC size_t
-strtodest(p, syntax, quotes)
- const char *p;
- const char *syntax;
- int quotes;
+strtodest(const char *p, int quotes)
{
size_t len = strlen(p);
- memtodest(p, len, syntax, quotes);
+ memtodest(p, len, quotes);
return len;
}
@@ -895,15 +886,13 @@ varvalue(char *name, int varflags, int flags, int *quotedp)
int sep;
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;
+ int quotes = quoted | (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL;
ssize_t len = 0;
sep = (flags & EXP_FULL) << CHAR_BIT;
- syntax = quoted ? DQSYNTAX : BASESYNTAX;
switch (*name) {
case '$':
@@ -946,11 +935,11 @@ param:
if (!(ap = shellparam.p))
return -1;
while ((p = *ap++)) {
- len += strtodest(p, syntax, quotes);
+ len += strtodest(p, quotes);
if (*ap && sep) {
len++;
-memtodest(, 1, syntax, quotes);
+