/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- * 2011, 2012
+ * 2011, 2012, 2013, 2015
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
#include "sh.h"
-__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.67 2012/12/04 01:10:35 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.73 2015/04/11 22:03:32 tg Exp $");
#define INDENT 8
static void ptree(struct op *, int, struct shf *);
-static void pioact(struct shf *, int, struct ioword *);
+static void pioact(struct shf *, struct ioword *);
static const char *wdvarput(struct shf *, const char *, int, int);
static void vfptreef(struct shf *, int, const char *, va_list);
static struct ioword **iocopy(struct ioword **, Area *);
t->ioact != NULL && t->ioact[0] != NULL &&
t->ioact[1] == NULL &&
/* of type "here document" (or "here string") */
- (t->ioact[0]->flag & IOTYPE) == IOHERE) {
+ (t->ioact[0]->ioflag & IOTYPE) == IOHERE) {
fptreef(shf, indent, "%S", t->vars[0]);
break;
}
bool need_nl = false;
while (*ioact != NULL)
- pioact(shf, indent, *ioact++);
+ pioact(shf, *ioact++);
/* Print here documents after everything else... */
ioact = t->ioact;
while (*ioact != NULL) {
struct ioword *iop = *ioact++;
/* heredoc is NULL when tracing (set -x) */
- if ((iop->flag & (IOTYPE | IOHERESTR)) == IOHERE &&
+ if ((iop->ioflag & (IOTYPE | IOHERESTR)) == IOHERE &&
iop->heredoc) {
shf_putc('\n', shf);
shf_puts(iop->heredoc, shf);
fptreef(shf, indent, "%s",
- iop->flag & IONDELIM ? "<<" :
+ iop->ioflag & IONDELIM ? "<<" :
evalstr(iop->delim, 0));
need_nl = true;
}
}
static void
-pioact(struct shf *shf, int indent, struct ioword *iop)
+pioact(struct shf *shf, struct ioword *iop)
{
- int flag = iop->flag;
- int type = flag & IOTYPE;
- int expected;
+ unsigned short flag = iop->ioflag;
+ unsigned short type = flag & IOTYPE;
+ short expected;
expected = (type == IOREAD || type == IORDWR || type == IOHERE) ? 0 :
(type == IOCAT || type == IOWRITE) ? 1 :
(type == IODUP && (iop->unit == !(flag & IORDUP))) ? iop->unit :
iop->unit + 1;
if (iop->unit != expected)
- shf_fprintf(shf, "%d", iop->unit);
+ shf_fprintf(shf, "%d", (int)iop->unit);
switch (type) {
case IOREAD:
- shf_puts("<", shf);
+ shf_putc('<', shf);
break;
case IOHERE:
- shf_puts(flag & IOSKIP ? "<<-" : "<<", shf);
+ shf_puts("<<", shf);
+ if (flag & IOSKIP)
+ shf_putc('-', shf);
break;
case IOCAT:
shf_puts(">>", shf);
break;
case IOWRITE:
- shf_puts(flag & IOCLOB ? ">|" : ">", shf);
+ shf_putc('>', shf);
+ if (flag & IOCLOB)
+ shf_putc('|', shf);
break;
case IORDWR:
shf_puts("<>", shf);
if (type == IOHERE) {
if (iop->delim)
wdvarput(shf, iop->delim, 0, WDS_TPUTS);
- if (iop->flag & IOHERESTR)
+ if (flag & IOHERESTR)
shf_putc(' ', shf);
- } else if (iop->name)
- fptreef(shf, indent, (iop->flag & IONAMEXP) ? "%s " : "%S ",
- iop->name);
+ } else if (iop->name) {
+ if (flag & IONAMEXP)
+ print_value_quoted(shf, iop->name);
+ else
+ wdvarput(shf, iop->name, 0, WDS_TPUTS);
+ shf_putc(' ', shf);
+ }
prevent_semicolon = false;
}
shf_puts(cs, shf);
break;
case FUNSUB:
- shf_puts("${ ", shf);
+ c = ' ';
+ if (0)
+ /* FALLTHROUGH */
+ case VALSUB:
+ c = '|';
+ shf_putc('$', shf);
+ shf_putc('{', shf);
+ shf_putc(c, shf);
cs = ";}";
goto pSUB;
case EXPRSUB:
break;
case 'R':
/* I/O redirection */
- pioact(shf, indent, va_arg(va, struct ioword *));
+ pioact(shf, va_arg(va, struct ioword *));
break;
default:
shf_putc(c, shf);
break;
case COMSUB:
case FUNSUB:
+ case VALSUB:
case EXPRSUB:
while (*wp++ != 0)
;
char *cp, *buf;
size_t n;
- buf = alloc(sz + 8, ATEMP);
- snptreef(buf, sz + 8, "%T", t);
+ buf = alloc(sz + 16, ATEMP);
+ snptreef(buf, sz + 16, "%T", t);
cp = buf;
vist_loop:
if (UTFMODE && (n = utf_mbtowc(&c, cp)) != (size_t)-1) {
if (--sz == 0 || (c = (unsigned char)(*cp++)) == 0)
/* NUL or not enough free space */
goto vist_out;
- if ((c & 0x60) == 0 || (c & 0x7F) == 0x7F) {
+ if (ISCTRL(c & 0x7F)) {
/* C0 or C1 control character or DEL */
if (--sz == 0)
/* not enough free space for two chars */
goto vist_out;
*dst++ = (c & 0x80) ? '$' : '^';
- c = (c & 0x7F) ^ 0x40;
+ c = UNCTRL(c & 0x7F);
} else if (UTFMODE && c > 0x7F) {
/* better not try to display broken multibyte chars */
+ /* also go easy on the Unicode: no U+FFFD here */
c = '?';
}
*dst++ = c;
void
dumpchar(struct shf *shf, int c)
{
- if (((c & 0x60) == 0) || ((c & 0x7F) == 0x7F)) {
+ if (ISCTRL(c & 0x7F)) {
/* C0 or C1 control character or DEL */
shf_putc((c & 0x80) ? '$' : '^', shf);
- c = (c & 0x7F) ^ 0x40;
+ c = UNCTRL(c & 0x7F);
}
shf_putc(c, shf);
}
case FUNSUB:
shf_puts("FUNSUB<", shf);
goto dumpsub;
+ case VALSUB:
+ shf_puts("VALSUB<", shf);
+ goto dumpsub;
case EXPRSUB:
shf_puts("EXPRSUB<", shf);
goto dumpsub;
shf_puts("{IOACT", shf);
while ((iop = *ioact++) != NULL) {
- int type = iop->flag & IOTYPE;
+ unsigned short type = iop->ioflag & IOTYPE;
#define DT(x) case x: shf_puts(#x, shf); break;
-#define DB(x) if (iop->flag & x) shf_puts("|" #x, shf);
+#define DB(x) if (iop->ioflag & x) shf_puts("|" #x, shf);
shf_putc(';', shf);
switch (type) {
DB(IOBASH)
DB(IOHERESTR)
DB(IONDELIM)
- shf_fprintf(shf, ",unit=%d", iop->unit);
+ shf_fprintf(shf, ",unit=%d", (int)iop->unit);
if (iop->delim) {
shf_puts(",delim<", shf);
dumpwdvar(shf, iop->delim);
shf_putc('>', shf);
}
if (iop->name) {
- if (iop->flag & IONAMEXP) {
+ if (iop->ioflag & IONAMEXP) {
shf_puts(",name=", shf);
print_value_quoted(shf, iop->name);
} else {