1 #include "rc.h" 2 #include "io.h" 3 #include "fns.h" 4 char nl='\n'; /* change to semicolon for bourne-proofing */ 5 #define c0 t->child[0] 6 #define c1 t->child[1] 7 #define c2 t->child[2] 8 9 void 10 pdeglob(io *f, char *s) 11 { 12 while(*s){ 13 if(*s==GLOB) 14 s++; 15 pchr(f, *s++); 16 } 17 } 18 19 void 20 pcmd(io *f, tree *t) 21 { 22 if(t==0) 23 return; 24 assert(f != nil); 25 switch(t->type){ 26 default: pfmt(f, "bad cmd %d %p %p %p", t->type, c0, c1, c2); 27 break; 28 case '$': pfmt(f, "$%t", c0); 29 break; 30 case '"': pfmt(f, "$\"%t", c0); 31 break; 32 case '&': pfmt(f, "%t&", c0); 33 break; 34 case '^': pfmt(f, "%t^%t", c0, c1); 35 break; 36 case '`': pfmt(f, "`%t", c0); 37 break; 38 case ANDAND: pfmt(f, "%t && %t", c0, c1); 39 break; 40 case BANG: pfmt(f, "! %t", c0); 41 break; 42 case BRACE: pfmt(f, "{%t}", c0); 43 break; 44 case COUNT: pfmt(f, "$#%t", c0); 45 break; 46 case FN: pfmt(f, "fn %t %t", c0, c1); 47 break; 48 case IF: pfmt(f, "if%t%t", c0, c1); 49 break; 50 case NOT: pfmt(f, "if not %t", c0); 51 break; 52 case OROR: pfmt(f, "%t || %t", c0, c1); 53 break; 54 case PCMD: 55 case PAREN: pfmt(f, "(%t)", c0); 56 break; 57 case SUB: pfmt(f, "$%t(%t)", c0, c1); 58 break; 59 case SIMPLE: pfmt(f, "%t", c0); 60 break; 61 case SUBSHELL: pfmt(f, "@ %t", c0); 62 break; 63 case SWITCH: pfmt(f, "switch %t %t", c0, c1); 64 break; 65 case TWIDDLE: pfmt(f, "~ %t %t", c0, c1); 66 break; 67 case WHILE: pfmt(f, "while %t%t", c0, c1); 68 break; 69 case ARGLIST: 70 if(c0==0) 71 pfmt(f, "%t", c1); 72 else if(c1==0) 73 pfmt(f, "%t", c0); 74 else 75 pfmt(f, "%t %t", c0, c1); 76 break; 77 case ';': 78 if(c0){ 79 if(c1) 80 pfmt(f, "%t%c%t", c0, nl, c1); 81 else pfmt(f, "%t", c0); 82 } 83 else pfmt(f, "%t", c1); 84 break; 85 case WORDS: 86 if(c0) 87 pfmt(f, "%t ", c0); 88 pfmt(f, "%t", c1); 89 break; 90 case FOR: 91 pfmt(f, "for(%t", c0); 92 if(c1) 93 pfmt(f, " in %t", c1); 94 pfmt(f, ")%t", c2); 95 break; 96 case WORD: 97 if(t->quoted) 98 pfmt(f, "%Q", t->str); 99 else pdeglob(f, t->str); 100 break; 101 case DUP: 102 if(t->rtype==DUPFD) 103 pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */ 104 else 105 pfmt(f, ">[%d=]", t->fd0); 106 pfmt(f, "%t", c1); 107 break; 108 case PIPEFD: 109 case REDIR: 110 switch(t->rtype){ 111 case HERE: 112 pchr(f, '<'); 113 case READ: 114 case RDWR: 115 pchr(f, '<'); 116 if(t->rtype==RDWR) 117 pchr(f, '>'); 118 if(t->fd0!=0) 119 pfmt(f, "[%d]", t->fd0); 120 break; 121 case APPEND: 122 pchr(f, '>'); 123 case WRITE: 124 pchr(f, '>'); 125 if(t->fd0!=1) 126 pfmt(f, "[%d]", t->fd0); 127 break; 128 } 129 pfmt(f, "%t", c0); 130 if(c1) 131 pfmt(f, " %t", c1); 132 break; 133 case '=': 134 pfmt(f, "%t=%t", c0, c1); 135 if(c2) 136 pfmt(f, " %t", c2); 137 break; 138 case PIPE: 139 pfmt(f, "%t|", c0); 140 if(t->fd1==0){ 141 if(t->fd0!=1) 142 pfmt(f, "[%d]", t->fd0); 143 } 144 else pfmt(f, "[%d=%d]", t->fd0, t->fd1); 145 pfmt(f, "%t", c1); 146 break; 147 } 148 } 149