static void pioact(struct shf *shf, struct ioword *iop) { int flag = iop->flag; int type = flag & IOTYPE; int 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); switch (type) { case IOREAD: shf_putc('<', shf); break; case IOHERE: shf_puts("<<", shf); if (flag & IOSKIP) shf_putc('-', shf); break; case IOCAT: shf_puts(">>", shf); break; case IOWRITE: shf_putc('>', shf); if (flag & IOCLOB) shf_putc('|', shf); break; case IORDWR: shf_puts("<>", shf); break; case IODUP: shf_puts(flag & IORDUP ? "<&" : ">&", shf); break; } /* name/delim are NULL when printing syntax errors */ if (type == IOHERE) { if (iop->delim) wdvarput(shf, iop->delim, 0, WDS_TPUTS); if (iop->flag & IOHERESTR) shf_putc(' ', shf); } else if (iop->name) { if (iop->flag & IONAMEXP) print_value_quoted(shf, iop->name); else wdvarput(shf, iop->name, 0, WDS_TPUTS); shf_putc(' ', shf); } prevent_semicolon = false; }
/* variant of fputs for ptreef and wdstrip */ static const char * wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode) { int c; const char *cs; /*- * problems: * `...` -> $(...) * 'foo' -> "foo" * x${foo:-"hi"} -> x${foo:-hi} unless WDS_TPUTS * x${foo:-'hi'} -> x${foo:-hi} unless WDS_KEEPQ * could change encoding to: * OQUOTE ["'] ... CQUOTE ["'] * COMSUB [(`] ...\0 (handle $ ` \ and maybe " in `...` case) */ while (/* CONSTCOND */ 1) switch (*wp++) { case EOS: return (--wp); case ADELIM: case CHAR: c = *wp++; if ((opmode & WDS_MAGIC) && (ISMAGIC(c) || c == '[' || c == '!' || c == '-' || c == ']' || c == '*' || c == '?')) shf_putc(MAGIC, shf); shf_putc(c, shf); break; case QCHAR: { bool doq; c = *wp++; doq = (c == '"' || c == '`' || c == '$' || c == '\\'); if (opmode & WDS_TPUTS) { if (quotelevel == 0) doq = true; } else { if (!(opmode & WDS_KEEPQ)) doq = false; } if (doq) shf_putc('\\', shf); shf_putc(c, shf); break; } case COMSUB: shf_puts("$(", shf); cs = ")"; pSUB: while ((c = *wp++) != 0) shf_putc(c, shf); shf_puts(cs, shf); break; case FUNSUB: c = ' '; if (0) /* FALLTHROUGH */ case VALSUB: c = '|'; shf_putc('$', shf); shf_putc('{', shf); shf_putc(c, shf); cs = ";}"; goto pSUB; case EXPRSUB: shf_puts("$((", shf); cs = "))"; goto pSUB; case OQUOTE: if (opmode & WDS_TPUTS) { quotelevel++; shf_putc('"', shf); } break; case CQUOTE: if (opmode & WDS_TPUTS) { if (quotelevel) quotelevel--; shf_putc('"', shf); } break; case OSUBST: shf_putc('$', shf); if (*wp++ == '{') shf_putc('{', shf); while ((c = *wp++) != 0) shf_putc(c, shf); wp = wdvarput(shf, wp, 0, opmode); break; case CSUBST: if (*wp++ == '}') shf_putc('}', shf); return (wp); case OPAT: if (opmode & WDS_MAGIC) { shf_putc(MAGIC, shf); shf_putchar(*wp++ | 0x80, shf); } else { shf_putchar(*wp++, shf); shf_putc('(', shf); } break; case SPAT: c = '|'; if (0) case CPAT: c = /*(*/ ')'; if (opmode & WDS_MAGIC) shf_putc(MAGIC, shf); shf_putc(c, shf); break; } }
/* variant of fputs for ptreef and wdstrip */ static const char * wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode) { int c; const char *cs; /*- * problems: * `...` -> $(...) * 'foo' -> "foo" * x${foo:-"hi"} -> x${foo:-hi} unless WDS_TPUTS * x${foo:-'hi'} -> x${foo:-hi} * could change encoding to: * OQUOTE ["'] ... CQUOTE ["'] * COMSUB [(`] ...\0 (handle $ ` \ and maybe " in `...` case) */ while (/* CONSTCOND */ 1) switch (*wp++) { case EOS: return (--wp); case ADELIM: if (ord(*wp) == ORD(/*{*/ '}')) { ++wp; goto wdvarput_csubst; } /* FALLTHROUGH */ case CHAR: c = ord(*wp++); shf_putc(c, shf); break; case QCHAR: c = ord(*wp++); if (opmode & WDS_TPUTS) switch (c) { case ORD('\n'): if (quotelevel == 0) { c = ORD('\''); shf_putc(c, shf); shf_putc(ORD('\n'), shf); } break; default: if (quotelevel == 0) /* FALLTHROUGH */ case ORD('"'): case ORD('`'): case ORD('$'): case ORD('\\'): shf_putc(ORD('\\'), shf); break; } shf_putc(c, shf); break; case COMASUB: case COMSUB: shf_puts("$(", shf); cs = ")"; if (ord(*wp) == ORD('(' /*)*/)) shf_putc(' ', shf); pSUB: while ((c = *wp++) != 0) shf_putc(c, shf); shf_puts(cs, shf); break; case FUNASUB: case FUNSUB: c = ORD(' '); if (0) /* FALLTHROUGH */ case VALSUB: c = ORD('|'); shf_putc('$', shf); shf_putc('{', shf); shf_putc(c, shf); cs = ";}"; goto pSUB; case EXPRSUB: shf_puts("$((", shf); cs = "))"; goto pSUB; case OQUOTE: if (opmode & WDS_TPUTS) { quotelevel++; shf_putc('"', shf); } break; case CQUOTE: if (opmode & WDS_TPUTS) { if (quotelevel) quotelevel--; shf_putc('"', shf); } break; case OSUBST: shf_putc('$', shf); if (ord(*wp++) == ORD('{')) shf_putc('{', shf); while ((c = *wp++) != 0) shf_putc(c, shf); wp = wdvarput(shf, wp, 0, opmode); break; case CSUBST: if (ord(*wp++) == ORD('}')) { wdvarput_csubst: shf_putc('}', shf); } return (wp); case OPAT: shf_putchar(*wp++, shf); shf_putc('(', shf); break; case SPAT: c = ORD('|'); if (0) /* FALLTHROUGH */ case CPAT: c = ORD(/*(*/ ')'); shf_putc(c, shf); break; } }