• add a tree debugging dumper #ifdef DEBUG
• use shf_putc (macro), shf_putchar (function) ipv tputc • replace shf_putchar(x,y) calls for side-effect-less x with shf_putc • plug another bug in the tree code – '\' → "\\" (backslashes must be escaped inside double quotes, too) • adjust testsuite (and, I _had_ wondered…)
This commit is contained in:
parent
6894618bb9
commit
f8659785ac
10
check.t
10
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.417 2011/03/07 20:32:48 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.418 2011/03/08 18:49:48 tg Exp $
|
||||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||||
@ -25,7 +25,7 @@
|
|||||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||||
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)MIRBSD KSH R39 2011/03/07
|
@(#)MIRBSD KSH R39 2011/03/08
|
||||||
description:
|
description:
|
||||||
Check version of shell.
|
Check version of shell.
|
||||||
stdin:
|
stdin:
|
||||||
@ -7434,7 +7434,7 @@ expected-stdout:
|
|||||||
inline_QCHAR_OQUOTE_CQUOTE() {
|
inline_QCHAR_OQUOTE_CQUOTE() {
|
||||||
echo fo\ob\"a\`r\'b\$az
|
echo fo\ob\"a\`r\'b\$az
|
||||||
echo "fo\ob\"a\`r\'b\$az"
|
echo "fo\ob\"a\`r\'b\$az"
|
||||||
echo "fo\ob\\"a\\`r"\'"b\\$az"
|
echo "fo\\ob\\\"a\\\`r"\'"b\\\$az"
|
||||||
}
|
}
|
||||||
function comsub_QCHAR_OQUOTE_CQUOTE { x=$(
|
function comsub_QCHAR_OQUOTE_CQUOTE { x=$(
|
||||||
echo fo\ob\"a\`r\'b\$az
|
echo fo\ob\"a\`r\'b\$az
|
||||||
@ -7442,7 +7442,7 @@ expected-stdout:
|
|||||||
echo 'fo\ob\"a\`r'\''b\$az'
|
echo 'fo\ob\"a\`r'\''b\$az'
|
||||||
); }
|
); }
|
||||||
function comsub_QCHAR_OQUOTE_CQUOTE {
|
function comsub_QCHAR_OQUOTE_CQUOTE {
|
||||||
x=$(echo fo\ob\"a\`r\'b\$az ; echo "fo\ob\"a\`r\'b\$az" ; echo "fo\ob\\"a\\`r"\'"b\\$az" )
|
x=$(echo fo\ob\"a\`r\'b\$az ; echo "fo\ob\"a\`r\'b\$az" ; echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" )
|
||||||
}
|
}
|
||||||
function reread_QCHAR_OQUOTE_CQUOTE { x=$((
|
function reread_QCHAR_OQUOTE_CQUOTE { x=$((
|
||||||
echo fo\ob\"a\`r\'b\$az
|
echo fo\ob\"a\`r\'b\$az
|
||||||
@ -7450,7 +7450,7 @@ expected-stdout:
|
|||||||
echo 'fo\ob\"a\`r'\''b\$az'
|
echo 'fo\ob\"a\`r'\''b\$az'
|
||||||
)|tr u x); }
|
)|tr u x); }
|
||||||
function reread_QCHAR_OQUOTE_CQUOTE {
|
function reread_QCHAR_OQUOTE_CQUOTE {
|
||||||
x=$(( echo fo\ob\"a\`r\'b\$az ; echo "fo\ob\"a\`r\'b\$az" ; echo "fo\ob\\"a\\`r"\'"b\\$az" ) | tr u x )
|
x=$(( echo fo\ob\"a\`r\'b\$az ; echo "fo\ob\"a\`r\'b\$az" ; echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" ) | tr u x )
|
||||||
}
|
}
|
||||||
inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
|
inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
|
||||||
[[ ${foo#blub} = @(bar|baz) ]]
|
[[ ${foo#blub} = @(bar|baz) ]]
|
||||||
|
5
sh.h
5
sh.h
@ -154,9 +154,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.440 2011/03/07 20:32:50 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.441 2011/03/08 18:49:50 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R39 2011/03/07"
|
#define MKSH_VERSION "R39 2011/03/08"
|
||||||
|
|
||||||
#ifndef MKSH_INCLUDES_ONLY
|
#ifndef MKSH_INCLUDES_ONLY
|
||||||
|
|
||||||
@ -1752,6 +1752,7 @@ char *wdcopy(const char *, Area *);
|
|||||||
const char *wdscan(const char *, int);
|
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 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 *);
|
||||||
|
366
tree.c
366
tree.c
@ -22,11 +22,10 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.36 2011/03/06 17:08:14 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.37 2011/03/08 18:49:51 tg Exp $");
|
||||||
|
|
||||||
#define INDENT 8
|
#define INDENT 8
|
||||||
|
|
||||||
#define tputc(c, shf) shf_putchar(c, shf);
|
|
||||||
static void ptree(struct op *, int, struct shf *);
|
static void ptree(struct op *, int, struct shf *);
|
||||||
static void pioact(struct shf *, int, struct ioword *);
|
static void pioact(struct shf *, int, struct ioword *);
|
||||||
static void tputS(const char *, struct shf *);
|
static void tputS(const char *, struct shf *);
|
||||||
@ -202,7 +201,7 @@ ptree(struct op *t, int indent, struct shf *shf)
|
|||||||
if ((iop->flag & IOTYPE) == IOHERE && iop->heredoc &&
|
if ((iop->flag & IOTYPE) == IOHERE && iop->heredoc &&
|
||||||
/* iop->delim[1] == '<' means here string */
|
/* iop->delim[1] == '<' means here string */
|
||||||
(!iop->delim || iop->delim[1] != '<')) {
|
(!iop->delim || iop->delim[1] != '<')) {
|
||||||
tputc('\n', shf);
|
shf_putc('\n', shf);
|
||||||
shf_puts(iop->heredoc, shf);
|
shf_puts(iop->heredoc, shf);
|
||||||
fptreef(shf, indent, "%s",
|
fptreef(shf, indent, "%s",
|
||||||
evalstr(iop->delim, 0));
|
evalstr(iop->delim, 0));
|
||||||
@ -215,7 +214,7 @@ ptree(struct op *t, int indent, struct shf *shf)
|
|||||||
* worth worrying about)
|
* worth worrying about)
|
||||||
*/
|
*/
|
||||||
if (need_nl)
|
if (need_nl)
|
||||||
tputc('\n', shf);
|
shf_putc('\n', shf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +257,7 @@ pioact(struct shf *shf, int indent, struct ioword *iop)
|
|||||||
if (iop->delim)
|
if (iop->delim)
|
||||||
fptreef(shf, indent, "%S ", iop->delim);
|
fptreef(shf, indent, "%S ", iop->delim);
|
||||||
else
|
else
|
||||||
tputc(' ', shf);
|
shf_putc(' ', shf);
|
||||||
} else if (iop->name)
|
} else if (iop->name)
|
||||||
fptreef(shf, indent, (iop->flag & IONAMEXP) ? "%s " : "%S ",
|
fptreef(shf, indent, (iop->flag & IONAMEXP) ? "%s " : "%S ",
|
||||||
iop->name);
|
iop->name);
|
||||||
@ -285,57 +284,56 @@ tputS(const char *wp, struct shf *shf)
|
|||||||
return;
|
return;
|
||||||
case ADELIM:
|
case ADELIM:
|
||||||
case CHAR:
|
case CHAR:
|
||||||
tputc(*wp++, shf);
|
shf_putchar(*wp++, shf);
|
||||||
break;
|
break;
|
||||||
case QCHAR:
|
case QCHAR:
|
||||||
c = *wp++;
|
c = *wp++;
|
||||||
if (!quotelevel || (c == '"' || c == '`' || c == '$'))
|
if (!quotelevel ||
|
||||||
tputc('\\', shf);
|
(c == '"' || c == '`' || c == '$' || c == '\\'))
|
||||||
tputc(c, shf);
|
shf_putc('\\', shf);
|
||||||
|
shf_putc(c, shf);
|
||||||
break;
|
break;
|
||||||
case COMSUB:
|
case COMSUB:
|
||||||
shf_puts("$(", shf);
|
shf_puts("$(", shf);
|
||||||
while (*wp != 0)
|
while ((c = *wp++) != 0)
|
||||||
tputc(*wp++, shf);
|
shf_putc(c, shf);
|
||||||
tputc(')', shf);
|
shf_putc(')', shf);
|
||||||
wp++;
|
|
||||||
break;
|
break;
|
||||||
case EXPRSUB:
|
case EXPRSUB:
|
||||||
shf_puts("$((", shf);
|
shf_puts("$((", shf);
|
||||||
while (*wp != 0)
|
while ((c = *wp++) != 0)
|
||||||
tputc(*wp++, shf);
|
shf_putc(c, shf);
|
||||||
shf_puts("))", shf);
|
shf_puts("))", shf);
|
||||||
wp++;
|
|
||||||
break;
|
break;
|
||||||
case OQUOTE:
|
case OQUOTE:
|
||||||
quotelevel++;
|
quotelevel++;
|
||||||
tputc('"', shf);
|
shf_putc('"', shf);
|
||||||
break;
|
break;
|
||||||
case CQUOTE:
|
case CQUOTE:
|
||||||
if (quotelevel)
|
if (quotelevel)
|
||||||
quotelevel--;
|
quotelevel--;
|
||||||
tputc('"', shf);
|
shf_putc('"', shf);
|
||||||
break;
|
break;
|
||||||
case OSUBST:
|
case OSUBST:
|
||||||
tputc('$', shf);
|
shf_putc('$', shf);
|
||||||
if (*wp++ == '{')
|
if (*wp++ == '{')
|
||||||
tputc('{', shf);
|
shf_putc('{', shf);
|
||||||
while ((c = *wp++) != 0)
|
while ((c = *wp++) != 0)
|
||||||
tputc(c, shf);
|
shf_putc(c, shf);
|
||||||
break;
|
break;
|
||||||
case CSUBST:
|
case CSUBST:
|
||||||
if (*wp++ == '}')
|
if (*wp++ == '}')
|
||||||
tputc('}', shf);
|
shf_putc('}', shf);
|
||||||
break;
|
break;
|
||||||
case OPAT:
|
case OPAT:
|
||||||
tputc(*wp++, shf);
|
shf_putchar(*wp++, shf);
|
||||||
tputc('(', shf);
|
shf_putc('(', shf);
|
||||||
break;
|
break;
|
||||||
case SPAT:
|
case SPAT:
|
||||||
tputc('|', shf);
|
shf_putc('|', shf);
|
||||||
break;
|
break;
|
||||||
case CPAT:
|
case CPAT:
|
||||||
tputc(')', shf);
|
shf_putc(')', shf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -382,7 +380,7 @@ vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
|
|||||||
switch ((c = *fmt++)) {
|
switch ((c = *fmt++)) {
|
||||||
case 'c':
|
case 'c':
|
||||||
/* character (octet, probably) */
|
/* character (octet, probably) */
|
||||||
tputc(va_arg(va, int), shf);
|
shf_putchar(va_arg(va, int), shf);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
/* string */
|
/* string */
|
||||||
@ -410,19 +408,19 @@ vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
|
|||||||
/* newline or space */
|
/* newline or space */
|
||||||
if (shf->flags & SHF_STRING) {
|
if (shf->flags & SHF_STRING) {
|
||||||
if (c == ';' && !prevent_semicolon)
|
if (c == ';' && !prevent_semicolon)
|
||||||
tputc(';', shf);
|
shf_putc(';', shf);
|
||||||
tputc(' ', shf);
|
shf_putc(' ', shf);
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
tputc('\n', shf);
|
shf_putc('\n', shf);
|
||||||
i = indent;
|
i = indent;
|
||||||
while (i >= 8) {
|
while (i >= 8) {
|
||||||
tputc('\t', shf);
|
shf_putc('\t', shf);
|
||||||
i -= 8;
|
i -= 8;
|
||||||
}
|
}
|
||||||
while (i--)
|
while (i--)
|
||||||
tputc(' ', shf);
|
shf_putc(' ', shf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
@ -430,11 +428,11 @@ vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
|
|||||||
pioact(shf, indent, va_arg(va, struct ioword *));
|
pioact(shf, indent, va_arg(va, struct ioword *));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tputc(c, shf);
|
shf_putc(c, shf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
tputc(c, shf);
|
shf_putc(c, shf);
|
||||||
prevent_semicolon = false;
|
prevent_semicolon = false;
|
||||||
dont_trash_prevent_semicolon:
|
dont_trash_prevent_semicolon:
|
||||||
;
|
;
|
||||||
@ -593,20 +591,20 @@ wdstrip(const char *wp, bool keepq, bool make_magic)
|
|||||||
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_putchar(MAGIC, &shf);
|
shf_putc(MAGIC, &shf);
|
||||||
shf_putchar(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_putchar('\\', &shf);
|
shf_putc('\\', &shf);
|
||||||
shf_putchar(c, &shf);
|
shf_putc(c, &shf);
|
||||||
break;
|
break;
|
||||||
case COMSUB:
|
case COMSUB:
|
||||||
shf_puts("$(", &shf);
|
shf_puts("$(", &shf);
|
||||||
while (*wp != 0)
|
while (*wp != 0)
|
||||||
shf_putchar(*wp++, &shf);
|
shf_putchar(*wp++, &shf);
|
||||||
shf_putchar(')', &shf);
|
shf_putc(')', &shf);
|
||||||
break;
|
break;
|
||||||
case EXPRSUB:
|
case EXPRSUB:
|
||||||
shf_puts("$((", &shf);
|
shf_puts("$((", &shf);
|
||||||
@ -619,34 +617,34 @@ wdstrip(const char *wp, bool keepq, bool make_magic)
|
|||||||
case CQUOTE:
|
case CQUOTE:
|
||||||
break;
|
break;
|
||||||
case OSUBST:
|
case OSUBST:
|
||||||
shf_putchar('$', &shf);
|
shf_putc('$', &shf);
|
||||||
if (*wp++ == '{')
|
if (*wp++ == '{')
|
||||||
shf_putchar('{', &shf);
|
shf_putc('{', &shf);
|
||||||
while ((c = *wp++) != 0)
|
while ((c = *wp++) != 0)
|
||||||
shf_putchar(c, &shf);
|
shf_putc(c, &shf);
|
||||||
break;
|
break;
|
||||||
case CSUBST:
|
case CSUBST:
|
||||||
if (*wp++ == '}')
|
if (*wp++ == '}')
|
||||||
shf_putchar('}', &shf);
|
shf_putc('}', &shf);
|
||||||
break;
|
break;
|
||||||
case OPAT:
|
case OPAT:
|
||||||
if (make_magic) {
|
if (make_magic) {
|
||||||
shf_putchar(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_putchar('(', &shf);
|
shf_putc('(', &shf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPAT:
|
case SPAT:
|
||||||
if (make_magic)
|
if (make_magic)
|
||||||
shf_putchar(MAGIC, &shf);
|
shf_putc(MAGIC, &shf);
|
||||||
shf_putchar('|', &shf);
|
shf_putc('|', &shf);
|
||||||
break;
|
break;
|
||||||
case CPAT:
|
case CPAT:
|
||||||
if (make_magic)
|
if (make_magic)
|
||||||
shf_putchar(MAGIC, &shf);
|
shf_putc(MAGIC, &shf);
|
||||||
shf_putchar(')', &shf);
|
shf_putc(')', &shf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -774,3 +772,273 @@ vistree(char *dst, size_t sz, struct op *t)
|
|||||||
*dst = '\0';
|
*dst = '\0';
|
||||||
afree(buf, ATEMP);
|
afree(buf, ATEMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static void
|
||||||
|
dumpchar(struct shf *shf, int c)
|
||||||
|
{
|
||||||
|
if (((c & 0x60) == 0) || ((c & 0x7F) == 0x7F)) {
|
||||||
|
/* C0 or C1 control character or DEL */
|
||||||
|
shf_putc((c & 0x80) ? '$' : '^', shf);
|
||||||
|
c = (c & 0x7F) ^ 0x40;
|
||||||
|
}
|
||||||
|
shf_putc(c, shf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see: tputS */
|
||||||
|
static void
|
||||||
|
dumpwdvar(struct shf *shf, const char *wp)
|
||||||
|
{
|
||||||
|
int c, quotelevel = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
switch(*wp++) {
|
||||||
|
case EOS:
|
||||||
|
shf_puts("EOS", shf);
|
||||||
|
return;
|
||||||
|
case ADELIM:
|
||||||
|
shf_puts("ADELIM=", shf);
|
||||||
|
dumpchar:
|
||||||
|
dumpchar(shf, *wp++);
|
||||||
|
break;
|
||||||
|
case CHAR:
|
||||||
|
shf_puts("CHAR=", shf);
|
||||||
|
goto dumpchar;
|
||||||
|
case QCHAR:
|
||||||
|
shf_puts("QCHAR<", shf);
|
||||||
|
c = *wp++;
|
||||||
|
if (!quotelevel ||
|
||||||
|
(c == '"' || c == '`' || c == '$' || c == '\\'))
|
||||||
|
shf_putc('\\', shf);
|
||||||
|
dumpchar(shf, c);
|
||||||
|
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;
|
||||||
|
case OQUOTE:
|
||||||
|
shf_fprintf(shf, "OQUOTE{%d", ++quotelevel);
|
||||||
|
break;
|
||||||
|
case CQUOTE:
|
||||||
|
shf_fprintf(shf, "%d}CQUOTE", quotelevel);
|
||||||
|
if (quotelevel)
|
||||||
|
quotelevel--;
|
||||||
|
else
|
||||||
|
shf_puts("(err)", shf);
|
||||||
|
break;
|
||||||
|
case OSUBST:
|
||||||
|
shf_puts("OSUBST(", shf);
|
||||||
|
dumpchar(shf, *wp++);
|
||||||
|
shf_puts(")[", shf);
|
||||||
|
while ((c = *wp++) != 0)
|
||||||
|
dumpchar(shf, c);
|
||||||
|
break;
|
||||||
|
case CSUBST:
|
||||||
|
shf_puts("]CSUBST(", shf);
|
||||||
|
dumpchar(shf, *wp++);
|
||||||
|
shf_putc(')', shf);
|
||||||
|
break;
|
||||||
|
case OPAT:
|
||||||
|
shf_puts("OPAT=", shf);
|
||||||
|
dumpchar(shf, *wp++);
|
||||||
|
break;
|
||||||
|
case SPAT:
|
||||||
|
shf_puts("SPAT", shf);
|
||||||
|
break;
|
||||||
|
case CPAT:
|
||||||
|
shf_puts("CPAT", shf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
shf_fprintf(shf, "INVAL<%u>", (uint8_t)wp[-1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
shf_putc(' ', shf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dumptree(struct shf *shf, struct op *t)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char **w, *name;
|
||||||
|
struct op *t1;
|
||||||
|
static int nesting = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < nesting; ++i)
|
||||||
|
shf_putc('\t', shf);
|
||||||
|
++nesting;
|
||||||
|
shf_puts("{tree:" /*}*/, shf);
|
||||||
|
if (t == NULL) {
|
||||||
|
name = "(null)";
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
switch (t->type) {
|
||||||
|
#define OPEN(x) case x: name = #x; shf_puts(" {" #x ":", shf); /*}*/
|
||||||
|
|
||||||
|
OPEN(TCOM)
|
||||||
|
if (t->vars) {
|
||||||
|
i = 0;
|
||||||
|
w = (const char **)t->vars;
|
||||||
|
while (*w) {
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
for (int j = 0; j < nesting; ++j)
|
||||||
|
shf_putc('\t', shf);
|
||||||
|
shf_fprintf(shf, " var%d<", i++);
|
||||||
|
dumpwdvar(shf, *w++);
|
||||||
|
shf_putc('>', shf);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
shf_puts(" #no-vars#", shf);
|
||||||
|
if (t->args) {
|
||||||
|
i = 0;
|
||||||
|
w = t->args;
|
||||||
|
while (*w) {
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
for (int j = 0; j < nesting; ++j)
|
||||||
|
shf_putc('\t', shf);
|
||||||
|
shf_fprintf(shf, " arg%d<", i++);
|
||||||
|
dumpwdvar(shf, *w++);
|
||||||
|
shf_putc('>', shf);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
shf_puts(" #no-args#", shf);
|
||||||
|
break;
|
||||||
|
OPEN(TEXEC)
|
||||||
|
dumpleftandout:
|
||||||
|
t = t->left;
|
||||||
|
dumpandout:
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
dumptree(shf, t);
|
||||||
|
break;
|
||||||
|
OPEN(TPAREN)
|
||||||
|
goto dumpleftandout;
|
||||||
|
OPEN(TPIPE)
|
||||||
|
dumpleftmidrightandout:
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
dumptree(shf, t->left);
|
||||||
|
// middumprightandout:
|
||||||
|
shf_fprintf(shf, "/%s:", name);
|
||||||
|
dumprightandout:
|
||||||
|
t = t->right;
|
||||||
|
goto dumpandout;
|
||||||
|
OPEN(TLIST)
|
||||||
|
goto dumpleftmidrightandout;
|
||||||
|
OPEN(TOR)
|
||||||
|
goto dumpleftmidrightandout;
|
||||||
|
OPEN(TAND)
|
||||||
|
goto dumpleftmidrightandout;
|
||||||
|
OPEN(TBANG)
|
||||||
|
goto dumprightandout;
|
||||||
|
OPEN(TDBRACKET)
|
||||||
|
i = 0;
|
||||||
|
w = t->args;
|
||||||
|
while (*w) {
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
for (int j = 0; j < nesting; ++j)
|
||||||
|
shf_putc('\t', shf);
|
||||||
|
shf_fprintf(shf, " arg%d<", i++);
|
||||||
|
dumpwdvar(shf, *w++);
|
||||||
|
shf_putc('>', shf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
OPEN(TFOR)
|
||||||
|
dumpfor:
|
||||||
|
shf_fprintf(shf, " str<%s>", t->str);
|
||||||
|
if (t->vars != NULL) {
|
||||||
|
i = 0;
|
||||||
|
w = (const char **)t->vars;
|
||||||
|
while (*w) {
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
for (int j = 0; j < nesting; ++j)
|
||||||
|
shf_putc('\t', shf);
|
||||||
|
shf_fprintf(shf, " var%d<", i++);
|
||||||
|
dumpwdvar(shf, *w++);
|
||||||
|
shf_putc('>', shf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto dumpleftandout;
|
||||||
|
OPEN(TSELECT)
|
||||||
|
goto dumpfor;
|
||||||
|
OPEN(TCASE)
|
||||||
|
shf_fprintf(shf, " str<%s>", t->str);
|
||||||
|
i = 0;
|
||||||
|
for (t1 = t->left; t1 != NULL; t1 = t1->right) {
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
for (int j = 0; j < nesting; ++j)
|
||||||
|
shf_putc('\t', shf);
|
||||||
|
shf_fprintf(shf, " sub%d[(", i);
|
||||||
|
w = (const char **)t1->vars;
|
||||||
|
while (*w) {
|
||||||
|
dumpwdvar(shf, *w);
|
||||||
|
if (w[1] != NULL)
|
||||||
|
shf_putc('|', shf);
|
||||||
|
++w;
|
||||||
|
}
|
||||||
|
shf_putc(')', shf);
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
dumptree(shf, t1->left);
|
||||||
|
shf_fprintf(shf, " /%d]", i++);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
OPEN(TWHILE)
|
||||||
|
goto dumpleftmidrightandout;
|
||||||
|
OPEN(TUNTIL)
|
||||||
|
goto dumpleftmidrightandout;
|
||||||
|
OPEN(TBRACE)
|
||||||
|
goto dumpleftandout;
|
||||||
|
OPEN(TCOPROC)
|
||||||
|
goto dumpleftandout;
|
||||||
|
OPEN(TASYNC)
|
||||||
|
goto dumpleftandout;
|
||||||
|
OPEN(TFUNCT)
|
||||||
|
shf_fprintf(shf, " str<%s> ksh<%s>", t->str,
|
||||||
|
t->u.ksh_func ? "yes" : "no");
|
||||||
|
goto dumpleftandout;
|
||||||
|
OPEN(TTIME)
|
||||||
|
goto dumpleftandout;
|
||||||
|
OPEN(TIF)
|
||||||
|
dumpif:
|
||||||
|
shf_putc('\n', shf);
|
||||||
|
dumptree(shf, t->left);
|
||||||
|
t = t->right;
|
||||||
|
if (t->left != NULL) {
|
||||||
|
shf_puts(" /TTHEN:\n", shf);
|
||||||
|
dumptree(shf, t->left);
|
||||||
|
}
|
||||||
|
if (t->right && t->right->type == TELIF) {
|
||||||
|
shf_puts(" /TELIF:", shf);
|
||||||
|
t = t->right;
|
||||||
|
goto dumpif;
|
||||||
|
}
|
||||||
|
if (t->right != NULL) {
|
||||||
|
shf_puts(" /TELSE:\n", shf);
|
||||||
|
dumptree(shf, t->right);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
OPEN(TEOF)
|
||||||
|
dumpunexpected:
|
||||||
|
shf_puts("unexpected", shf);
|
||||||
|
break;
|
||||||
|
OPEN(TELIF)
|
||||||
|
goto dumpunexpected;
|
||||||
|
OPEN(TPAT)
|
||||||
|
goto dumpunexpected;
|
||||||
|
default:
|
||||||
|
name = "TINVALID";
|
||||||
|
shf_fprintf(shf, "{T<%d>:" /*}*/, t->type);
|
||||||
|
goto dumpunexpected;
|
||||||
|
|
||||||
|
#undef OPEN
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
shf_fprintf(shf, /*{*/ " /%s}\n", name);
|
||||||
|
--nesting;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user