From 17dbd3bd835d5a8518198d844720ad1a4e1c4ed2 Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 12 Mar 2011 21:41:15 +0000 Subject: [PATCH] =?UTF-8?q?=E2=80=A2=20make=20EXPRSUB=20not=20initiate=20a?= =?UTF-8?q?n=20ASCIIZ=20string=20any=20more=20but=20a=20wdstring=20=20=20(?= =?UTF-8?q?token=20stream,=20lexer=20output=20/=20parser=20input),=20EOS?= =?UTF-8?q?=20terminated,=20let=20=20=20SASPAREN=20use=20the=20same=20lexi?= =?UTF-8?q?ng=20as=20SBASE=20(e.g.=20COMSUB=20recursively)=20=E2=80=A2=20m?= =?UTF-8?q?ake=20wdstrip=20recursive=20=E2=80=A2=20fix=20processing=20of?= =?UTF-8?q?=20COMSUB=20in=20wdstrip=20=E2=87=92=20pass=20comsub-1=20test?= =?UTF-8?q?=20=E2=80=A2=20expose=20another=20debugging=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eval.c | 21 +++++++++------ lex.c | 9 +++---- sh.h | 5 ++-- tree.c | 82 +++++++++++++++++++++++++++++++++------------------------- 4 files changed, 67 insertions(+), 50 deletions(-) diff --git a/eval.c b/eval.c index 07471fa..3236966 100644 --- a/eval.c +++ b/eval.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.95 2011/03/07 20:30:36 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.96 2011/03/12 21:41:13 tg Exp $"); /* * string expansion @@ -291,15 +291,19 @@ expand(const char *cp, /* input word */ newlines = 0; } continue; - case EXPRSUB: + case EXPRSUB: { + char *xp; + + xp = wdstrip(sp, true, false); + sp = wdscan(sp, EOS); word = IFS_WORD; tilde_ok = 0; if (f & DONTRUNCOMMAND) { + c = strlen(xp); *dp++ = '$'; *dp++ = '('; *dp++ = '('; - while (*sp != '\0') { - Xcheck(ds, dp); - *dp++ = *sp++; - } + XcheckN(ds, dp, c + 2); + memcpy(dp, xp, c); + dp += c; *dp++ = ')'; *dp++ = ')'; } else { struct tbl v; @@ -309,15 +313,16 @@ expand(const char *cp, /* input word */ /* not default */ v.type = 10; v.name[0] = '\0'; - v_evaluate(&v, substitute(sp, 0), + v_evaluate(&v, substitute(xp, 0), KSH_UNWIND_ERROR, true); - sp = strnul(sp) + 1; for (p = str_val(&v); *p; ) { Xcheck(ds, dp); *dp++ = *p++; } } + afree(xp, ATEMP); continue; + } case OSUBST: { /* ${{#}var{:}[=+-?#%]word} */ /*- diff --git a/lex.c b/lex.c index ae60ee9..d2736d8 100644 --- a/lex.c +++ b/lex.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.130 2011/03/12 20:20:16 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.131 2011/03/12 21:41:13 tg Exp $"); /* * states while lexing word @@ -246,6 +246,7 @@ yylex(int cf) } /* FALLTHROUGH */ case SBASE: + subst_base: if (c == '[' && (cf & (VARASN|ARRAYVAR))) { /* temporary */ *wp = EOS; @@ -587,10 +588,10 @@ yylex(int cf) else if (c == ')') { statep->nparen--; if (statep->nparen == 1) { + *wp++ = EOS; if ((c2 = getsc()) == /*(*/')') { POP_STATE(); /* end of EXPRSUB */ - *wp++ = 0; break; } else { Source *s; @@ -601,7 +602,6 @@ yylex(int cf) * assume we were really * parsing a $(...) expression */ - *wp = EOS; wp = Xrestpos(ws, wp, statep->ls_start); POP_STATE(); @@ -619,8 +619,7 @@ yylex(int cf) } } } - *wp++ = c; - break; + goto subst_base; case SQBRACE: if (c == '\\') { diff --git a/sh.h b/sh.h index b5d332e..4a61989 100644 --- a/sh.h +++ b/sh.h @@ -154,7 +154,7 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.441 2011/03/08 18:49:50 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.442 2011/03/12 21:41:14 tg Exp $"); #endif #define MKSH_VERSION "R39 2011/03/08" @@ -1149,7 +1149,7 @@ struct op { #define CHAR 1 /* unquoted character */ #define QCHAR 2 /* quoted character */ #define COMSUB 3 /* $() substitution (0 terminated) */ -#define EXPRSUB 4 /* $(()) substitution (0 terminated) */ +#define EXPRSUB 4 /* $(()) substitution (EOS terminated wdstring) */ #define OQUOTE 5 /* opening " or ' */ #define CQUOTE 6 /* closing " or ' */ #define OSUBST 7 /* opening ${ subst (followed by { or X) */ @@ -1753,6 +1753,7 @@ const char *wdscan(const char *, int); char *wdstrip(const char *, bool, bool); void tfree(struct op *, Area *); void dumptree(struct shf *, struct op *); +void dumpwdvar(struct shf *, const char *); void vistree(char *, size_t, struct op *) MKSH_A_BOUNDED(string, 1, 2); void fpFUNCTf(struct shf *, int, bool, const char *, struct op *); diff --git a/tree.c b/tree.c index 640b2b2..e3f9205 100644 --- a/tree.c +++ b/tree.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.37 2011/03/08 18:49:51 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.38 2011/03/12 21:41:15 tg Exp $"); #define INDENT 8 @@ -32,6 +32,7 @@ static void tputS(const char *, struct shf *); static void vfptreef(struct shf *, int, const char *, va_list); static struct ioword **iocopy(struct ioword **, Area *); static void iofree(struct ioword **, Area *); +static void wdstrip_internal(struct shf *, const char *, bool, bool); /* "foo& ; bar" and "foo |& ; bar" are invalid */ static bool prevent_semicolon = false; @@ -301,8 +302,8 @@ tputS(const char *wp, struct shf *shf) break; case EXPRSUB: shf_puts("$((", shf); - while ((c = *wp++) != 0) - shf_putc(c, shf); + tputS(wp, shf); + wp = wdscan(wp, EOS); shf_puts("))", shf); break; case OQUOTE: @@ -526,8 +527,10 @@ wdscan(const char *wp, int c) case QCHAR: wp++; break; - case COMSUB: case EXPRSUB: + wp = wdscan(wp, EOS); + break; + case COMSUB: while (*wp++ != 0) ; break; @@ -571,9 +574,17 @@ char * wdstrip(const char *wp, bool keepq, bool make_magic) { struct shf shf; - int c; shf_sopen(NULL, 32, SHF_WR | SHF_DYNAMIC, &shf); + wdstrip_internal(&shf, wp, keepq, make_magic); + /* shf_sclose NUL terminates */ + return (shf_sclose(&shf)); +} + +static void +wdstrip_internal(struct shf *shf, const char *wp, bool keepq, bool make_magic) +{ + int c; /*- * problems: @@ -584,67 +595,66 @@ wdstrip(const char *wp, bool keepq, bool make_magic) while (1) switch (*wp++) { case EOS: - /* shf_sclose NUL terminates */ - return (shf_sclose(&shf)); + return; case ADELIM: case CHAR: c = *wp++; if (make_magic && (ISMAGIC(c) || c == '[' || c == NOT || c == '-' || c == ']' || c == '*' || c == '?')) - shf_putc(MAGIC, &shf); - shf_putc(c, &shf); + shf_putc(MAGIC, shf); + shf_putc(c, shf); break; case QCHAR: c = *wp++; if (keepq && (c == '"' || c == '`' || c == '$' || c == '\\')) - shf_putc('\\', &shf); - shf_putc(c, &shf); + shf_putc('\\', shf); + shf_putc(c, shf); break; case COMSUB: - shf_puts("$(", &shf); - while (*wp != 0) - shf_putchar(*wp++, &shf); - shf_putc(')', &shf); + shf_puts("$(", shf); + while ((c = *wp++) != 0) + shf_putc(c, shf); + shf_putc(')', shf); break; case EXPRSUB: - shf_puts("$((", &shf); - while (*wp != 0) - shf_putchar(*wp++, &shf); - shf_puts("))", &shf); + shf_puts("$((", shf); + wdstrip_internal(shf, wp, keepq, make_magic); + wp = wdscan(wp, EOS); + shf_puts("))", shf); break; case OQUOTE: break; case CQUOTE: break; case OSUBST: - shf_putc('$', &shf); + shf_putc('$', shf); if (*wp++ == '{') - shf_putc('{', &shf); + shf_putc('{', shf); while ((c = *wp++) != 0) - shf_putc(c, &shf); + shf_putc(c, shf); break; case CSUBST: if (*wp++ == '}') - shf_putc('}', &shf); + shf_putc('}', shf); break; case OPAT: if (make_magic) { - shf_putc(MAGIC, &shf); - shf_putchar(*wp++ | 0x80, &shf); + shf_putc(MAGIC, shf); + shf_putchar(*wp++ | 0x80, shf); } else { - shf_putchar(*wp++, &shf); - shf_putc('(', &shf); + shf_putchar(*wp++, shf); + shf_putc('(', shf); } break; case SPAT: if (make_magic) - shf_putc(MAGIC, &shf); - shf_putc('|', &shf); + shf_putc(MAGIC, shf); + shf_putc('|', shf); break; case CPAT: if (make_magic) - shf_putc(MAGIC, &shf); - shf_putc(')', &shf); + shf_putc(MAGIC, shf); + shf_putc(')', shf); break; } } @@ -786,7 +796,7 @@ dumpchar(struct shf *shf, int c) } /* see: tputS */ -static void +void dumpwdvar(struct shf *shf, const char *wp) { int c, quotelevel = 0; @@ -814,15 +824,17 @@ dumpwdvar(struct shf *shf, const char *wp) goto closeandout; case COMSUB: shf_puts("COMSUB<", shf); - dumpsub: while ((c = *wp++) != 0) dumpchar(shf, c); closeandout: shf_putc('>', shf); break; case EXPRSUB: - shf_puts("EXPRSUB<", shf); - goto dumpsub; + shf_puts("EXPRSUB[", shf); + dumpwdvar(shf, wp); + wp = wdscan(wp, EOS); + shf_puts("]EXPRSUB", shf); + break; case OQUOTE: shf_fprintf(shf, "OQUOTE{%d", ++quotelevel); break;