• make EXPRSUB not initiate an ASCIIZ string any more but a wdstring
(token stream, lexer output / parser input), EOS terminated, let SASPAREN use the same lexing as SBASE (e.g. COMSUB recursively) • make wdstrip recursive • fix processing of COMSUB in wdstrip ⇒ pass comsub-1 test • expose another debugging function
This commit is contained in:
parent
fb1392fb6b
commit
17dbd3bd83
21
eval.c
21
eval.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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
|
* string expansion
|
||||||
@ -291,15 +291,19 @@ expand(const char *cp, /* input word */
|
|||||||
newlines = 0;
|
newlines = 0;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case EXPRSUB:
|
case EXPRSUB: {
|
||||||
|
char *xp;
|
||||||
|
|
||||||
|
xp = wdstrip(sp, true, false);
|
||||||
|
sp = wdscan(sp, EOS);
|
||||||
word = IFS_WORD;
|
word = IFS_WORD;
|
||||||
tilde_ok = 0;
|
tilde_ok = 0;
|
||||||
if (f & DONTRUNCOMMAND) {
|
if (f & DONTRUNCOMMAND) {
|
||||||
|
c = strlen(xp);
|
||||||
*dp++ = '$'; *dp++ = '('; *dp++ = '(';
|
*dp++ = '$'; *dp++ = '('; *dp++ = '(';
|
||||||
while (*sp != '\0') {
|
XcheckN(ds, dp, c + 2);
|
||||||
Xcheck(ds, dp);
|
memcpy(dp, xp, c);
|
||||||
*dp++ = *sp++;
|
dp += c;
|
||||||
}
|
|
||||||
*dp++ = ')'; *dp++ = ')';
|
*dp++ = ')'; *dp++ = ')';
|
||||||
} else {
|
} else {
|
||||||
struct tbl v;
|
struct tbl v;
|
||||||
@ -309,15 +313,16 @@ expand(const char *cp, /* input word */
|
|||||||
/* not default */
|
/* not default */
|
||||||
v.type = 10;
|
v.type = 10;
|
||||||
v.name[0] = '\0';
|
v.name[0] = '\0';
|
||||||
v_evaluate(&v, substitute(sp, 0),
|
v_evaluate(&v, substitute(xp, 0),
|
||||||
KSH_UNWIND_ERROR, true);
|
KSH_UNWIND_ERROR, true);
|
||||||
sp = strnul(sp) + 1;
|
|
||||||
for (p = str_val(&v); *p; ) {
|
for (p = str_val(&v); *p; ) {
|
||||||
Xcheck(ds, dp);
|
Xcheck(ds, dp);
|
||||||
*dp++ = *p++;
|
*dp++ = *p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
afree(xp, ATEMP);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
case OSUBST: {
|
case OSUBST: {
|
||||||
/* ${{#}var{:}[=+-?#%]word} */
|
/* ${{#}var{:}[=+-?#%]word} */
|
||||||
/*-
|
/*-
|
||||||
|
9
lex.c
9
lex.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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
|
* states while lexing word
|
||||||
@ -246,6 +246,7 @@ yylex(int cf)
|
|||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case SBASE:
|
case SBASE:
|
||||||
|
subst_base:
|
||||||
if (c == '[' && (cf & (VARASN|ARRAYVAR))) {
|
if (c == '[' && (cf & (VARASN|ARRAYVAR))) {
|
||||||
/* temporary */
|
/* temporary */
|
||||||
*wp = EOS;
|
*wp = EOS;
|
||||||
@ -587,10 +588,10 @@ yylex(int cf)
|
|||||||
else if (c == ')') {
|
else if (c == ')') {
|
||||||
statep->nparen--;
|
statep->nparen--;
|
||||||
if (statep->nparen == 1) {
|
if (statep->nparen == 1) {
|
||||||
|
*wp++ = EOS;
|
||||||
if ((c2 = getsc()) == /*(*/')') {
|
if ((c2 = getsc()) == /*(*/')') {
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
/* end of EXPRSUB */
|
/* end of EXPRSUB */
|
||||||
*wp++ = 0;
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
Source *s;
|
Source *s;
|
||||||
@ -601,7 +602,6 @@ yylex(int cf)
|
|||||||
* assume we were really
|
* assume we were really
|
||||||
* parsing a $(...) expression
|
* parsing a $(...) expression
|
||||||
*/
|
*/
|
||||||
*wp = EOS;
|
|
||||||
wp = Xrestpos(ws, wp,
|
wp = Xrestpos(ws, wp,
|
||||||
statep->ls_start);
|
statep->ls_start);
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
@ -619,8 +619,7 @@ yylex(int cf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*wp++ = c;
|
goto subst_base;
|
||||||
break;
|
|
||||||
|
|
||||||
case SQBRACE:
|
case SQBRACE:
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
|
5
sh.h
5
sh.h
@ -154,7 +154,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#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
|
#endif
|
||||||
#define MKSH_VERSION "R39 2011/03/08"
|
#define MKSH_VERSION "R39 2011/03/08"
|
||||||
|
|
||||||
@ -1149,7 +1149,7 @@ struct op {
|
|||||||
#define CHAR 1 /* unquoted character */
|
#define CHAR 1 /* unquoted character */
|
||||||
#define QCHAR 2 /* quoted character */
|
#define QCHAR 2 /* quoted character */
|
||||||
#define COMSUB 3 /* $() substitution (0 terminated) */
|
#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 OQUOTE 5 /* opening " or ' */
|
||||||
#define CQUOTE 6 /* closing " or ' */
|
#define CQUOTE 6 /* closing " or ' */
|
||||||
#define OSUBST 7 /* opening ${ subst (followed by { or X) */
|
#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);
|
char *wdstrip(const char *, bool, bool);
|
||||||
void tfree(struct op *, Area *);
|
void tfree(struct op *, Area *);
|
||||||
void dumptree(struct shf *, struct op *);
|
void dumptree(struct shf *, struct op *);
|
||||||
|
void dumpwdvar(struct shf *, const char *);
|
||||||
void vistree(char *, size_t, struct op *)
|
void vistree(char *, size_t, struct op *)
|
||||||
MKSH_A_BOUNDED(string, 1, 2);
|
MKSH_A_BOUNDED(string, 1, 2);
|
||||||
void fpFUNCTf(struct shf *, int, bool, const char *, struct op *);
|
void fpFUNCTf(struct shf *, int, bool, const char *, struct op *);
|
||||||
|
82
tree.c
82
tree.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#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
|
#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 void vfptreef(struct shf *, int, const char *, va_list);
|
||||||
static struct ioword **iocopy(struct ioword **, Area *);
|
static struct ioword **iocopy(struct ioword **, Area *);
|
||||||
static void iofree(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 */
|
/* "foo& ; bar" and "foo |& ; bar" are invalid */
|
||||||
static bool prevent_semicolon = false;
|
static bool prevent_semicolon = false;
|
||||||
@ -301,8 +302,8 @@ tputS(const char *wp, struct shf *shf)
|
|||||||
break;
|
break;
|
||||||
case EXPRSUB:
|
case EXPRSUB:
|
||||||
shf_puts("$((", shf);
|
shf_puts("$((", shf);
|
||||||
while ((c = *wp++) != 0)
|
tputS(wp, shf);
|
||||||
shf_putc(c, shf);
|
wp = wdscan(wp, EOS);
|
||||||
shf_puts("))", shf);
|
shf_puts("))", shf);
|
||||||
break;
|
break;
|
||||||
case OQUOTE:
|
case OQUOTE:
|
||||||
@ -526,8 +527,10 @@ wdscan(const char *wp, int c)
|
|||||||
case QCHAR:
|
case QCHAR:
|
||||||
wp++;
|
wp++;
|
||||||
break;
|
break;
|
||||||
case COMSUB:
|
|
||||||
case EXPRSUB:
|
case EXPRSUB:
|
||||||
|
wp = wdscan(wp, EOS);
|
||||||
|
break;
|
||||||
|
case COMSUB:
|
||||||
while (*wp++ != 0)
|
while (*wp++ != 0)
|
||||||
;
|
;
|
||||||
break;
|
break;
|
||||||
@ -571,9 +574,17 @@ char *
|
|||||||
wdstrip(const char *wp, bool keepq, bool make_magic)
|
wdstrip(const char *wp, bool keepq, bool make_magic)
|
||||||
{
|
{
|
||||||
struct shf shf;
|
struct shf shf;
|
||||||
int c;
|
|
||||||
|
|
||||||
shf_sopen(NULL, 32, SHF_WR | SHF_DYNAMIC, &shf);
|
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:
|
* problems:
|
||||||
@ -584,67 +595,66 @@ wdstrip(const char *wp, bool keepq, bool make_magic)
|
|||||||
while (1)
|
while (1)
|
||||||
switch (*wp++) {
|
switch (*wp++) {
|
||||||
case EOS:
|
case EOS:
|
||||||
/* shf_sclose NUL terminates */
|
return;
|
||||||
return (shf_sclose(&shf));
|
|
||||||
case ADELIM:
|
case ADELIM:
|
||||||
case CHAR:
|
case CHAR:
|
||||||
c = *wp++;
|
c = *wp++;
|
||||||
if (make_magic && (ISMAGIC(c) || c == '[' || c == NOT ||
|
if (make_magic && (ISMAGIC(c) || c == '[' || c == NOT ||
|
||||||
c == '-' || c == ']' || c == '*' || c == '?'))
|
c == '-' || c == ']' || c == '*' || c == '?'))
|
||||||
shf_putc(MAGIC, &shf);
|
shf_putc(MAGIC, shf);
|
||||||
shf_putc(c, &shf);
|
shf_putc(c, shf);
|
||||||
break;
|
break;
|
||||||
case QCHAR:
|
case QCHAR:
|
||||||
c = *wp++;
|
c = *wp++;
|
||||||
if (keepq && (c == '"' || c == '`' || c == '$' || c == '\\'))
|
if (keepq && (c == '"' || c == '`' || c == '$' || c == '\\'))
|
||||||
shf_putc('\\', &shf);
|
shf_putc('\\', shf);
|
||||||
shf_putc(c, &shf);
|
shf_putc(c, shf);
|
||||||
break;
|
break;
|
||||||
case COMSUB:
|
case COMSUB:
|
||||||
shf_puts("$(", &shf);
|
shf_puts("$(", shf);
|
||||||
while (*wp != 0)
|
while ((c = *wp++) != 0)
|
||||||
shf_putchar(*wp++, &shf);
|
shf_putc(c, shf);
|
||||||
shf_putc(')', &shf);
|
shf_putc(')', shf);
|
||||||
break;
|
break;
|
||||||
case EXPRSUB:
|
case EXPRSUB:
|
||||||
shf_puts("$((", &shf);
|
shf_puts("$((", shf);
|
||||||
while (*wp != 0)
|
wdstrip_internal(shf, wp, keepq, make_magic);
|
||||||
shf_putchar(*wp++, &shf);
|
wp = wdscan(wp, EOS);
|
||||||
shf_puts("))", &shf);
|
shf_puts("))", shf);
|
||||||
break;
|
break;
|
||||||
case OQUOTE:
|
case OQUOTE:
|
||||||
break;
|
break;
|
||||||
case CQUOTE:
|
case CQUOTE:
|
||||||
break;
|
break;
|
||||||
case OSUBST:
|
case OSUBST:
|
||||||
shf_putc('$', &shf);
|
shf_putc('$', shf);
|
||||||
if (*wp++ == '{')
|
if (*wp++ == '{')
|
||||||
shf_putc('{', &shf);
|
shf_putc('{', shf);
|
||||||
while ((c = *wp++) != 0)
|
while ((c = *wp++) != 0)
|
||||||
shf_putc(c, &shf);
|
shf_putc(c, shf);
|
||||||
break;
|
break;
|
||||||
case CSUBST:
|
case CSUBST:
|
||||||
if (*wp++ == '}')
|
if (*wp++ == '}')
|
||||||
shf_putc('}', &shf);
|
shf_putc('}', shf);
|
||||||
break;
|
break;
|
||||||
case OPAT:
|
case OPAT:
|
||||||
if (make_magic) {
|
if (make_magic) {
|
||||||
shf_putc(MAGIC, &shf);
|
shf_putc(MAGIC, shf);
|
||||||
shf_putchar(*wp++ | 0x80, &shf);
|
shf_putchar(*wp++ | 0x80, shf);
|
||||||
} else {
|
} else {
|
||||||
shf_putchar(*wp++, &shf);
|
shf_putchar(*wp++, shf);
|
||||||
shf_putc('(', &shf);
|
shf_putc('(', shf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPAT:
|
case SPAT:
|
||||||
if (make_magic)
|
if (make_magic)
|
||||||
shf_putc(MAGIC, &shf);
|
shf_putc(MAGIC, shf);
|
||||||
shf_putc('|', &shf);
|
shf_putc('|', shf);
|
||||||
break;
|
break;
|
||||||
case CPAT:
|
case CPAT:
|
||||||
if (make_magic)
|
if (make_magic)
|
||||||
shf_putc(MAGIC, &shf);
|
shf_putc(MAGIC, shf);
|
||||||
shf_putc(')', &shf);
|
shf_putc(')', shf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -786,7 +796,7 @@ dumpchar(struct shf *shf, int c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* see: tputS */
|
/* see: tputS */
|
||||||
static void
|
void
|
||||||
dumpwdvar(struct shf *shf, const char *wp)
|
dumpwdvar(struct shf *shf, const char *wp)
|
||||||
{
|
{
|
||||||
int c, quotelevel = 0;
|
int c, quotelevel = 0;
|
||||||
@ -814,15 +824,17 @@ dumpwdvar(struct shf *shf, const char *wp)
|
|||||||
goto closeandout;
|
goto closeandout;
|
||||||
case COMSUB:
|
case COMSUB:
|
||||||
shf_puts("COMSUB<", shf);
|
shf_puts("COMSUB<", shf);
|
||||||
dumpsub:
|
|
||||||
while ((c = *wp++) != 0)
|
while ((c = *wp++) != 0)
|
||||||
dumpchar(shf, c);
|
dumpchar(shf, c);
|
||||||
closeandout:
|
closeandout:
|
||||||
shf_putc('>', shf);
|
shf_putc('>', shf);
|
||||||
break;
|
break;
|
||||||
case EXPRSUB:
|
case EXPRSUB:
|
||||||
shf_puts("EXPRSUB<", shf);
|
shf_puts("EXPRSUB[", shf);
|
||||||
goto dumpsub;
|
dumpwdvar(shf, wp);
|
||||||
|
wp = wdscan(wp, EOS);
|
||||||
|
shf_puts("]EXPRSUB", shf);
|
||||||
|
break;
|
||||||
case OQUOTE:
|
case OQUOTE:
|
||||||
shf_fprintf(shf, "OQUOTE{%d", ++quotelevel);
|
shf_fprintf(shf, "OQUOTE{%d", ++quotelevel);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user