OSDN Git Service

Upgrade to mksh 51.
[android-x86/external-mksh.git] / src / tree.c
index 8015a8d..c057559 100644 (file)
@@ -2,7 +2,7 @@
 
 /*-
  * 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 *);
@@ -69,7 +69,7 @@ ptree(struct op *t, int indent, struct shf *shf)
                    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;
                }
@@ -214,19 +214,19 @@ ptree(struct op *t, int indent, struct shf *shf)
                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;
                        }
@@ -244,31 +244,35 @@ ptree(struct op *t, int indent, struct shf *shf)
 }
 
 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);
@@ -281,11 +285,15 @@ pioact(struct shf *shf, int indent, struct ioword *iop)
        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;
 }
 
@@ -345,7 +353,14 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
                        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:
@@ -485,7 +500,7 @@ vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
                                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);
@@ -588,6 +603,7 @@ wdscan(const char *wp, int c)
                        break;
                case COMSUB:
                case FUNSUB:
+               case VALSUB:
                case EXPRSUB:
                        while (*wp++ != 0)
                                ;
@@ -745,8 +761,8 @@ vistree(char *dst, size_t sz, struct op *t)
        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) {
@@ -762,15 +778,16 @@ vistree(char *dst, size_t sz, struct op *t)
        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;
@@ -785,10 +802,10 @@ vistree(char *dst, size_t sz, struct op *t)
 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);
 }
@@ -830,6 +847,9 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
                case FUNSUB:
                        shf_puts("FUNSUB<", shf);
                        goto dumpsub;
+               case VALSUB:
+                       shf_puts("VALSUB<", shf);
+                       goto dumpsub;
                case EXPRSUB:
                        shf_puts("EXPRSUB<", shf);
                        goto dumpsub;
@@ -890,9 +910,9 @@ dumpioact(struct shf *shf, struct op *t)
 
        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) {
@@ -913,14 +933,14 @@ dumpioact(struct shf *shf, struct op *t)
                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 {