| pcmd.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
| git clone git://git.suckless.org/9base | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| pcmd.c (2681B) | |
| --- | |
| 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 switch(t->type){ | |
| 25 default: pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2); | |
| 26 break; | |
| 27 case '$': pfmt(f, "$%t", c0); | |
| 28 break; | |
| 29 case '"': pfmt(f, "$\"%t", c0); | |
| 30 break; | |
| 31 case '&': pfmt(f, "%t&", c0); | |
| 32 break; | |
| 33 case '^': pfmt(f, "%t^%t", c0, c1); | |
| 34 break; | |
| 35 case '`': pfmt(f, "`%t", c0); | |
| 36 break; | |
| 37 case ANDAND: pfmt(f, "%t && %t", c0, c1); | |
| 38 break; | |
| 39 case BANG: pfmt(f, "! %t", c0); | |
| 40 break; | |
| 41 case BRACE: pfmt(f, "{%t}", c0); | |
| 42 break; | |
| 43 case COUNT: pfmt(f, "$#%t", c0); | |
| 44 break; | |
| 45 case FN: pfmt(f, "fn %t %t", c0, c1); | |
| 46 break; | |
| 47 case IF: pfmt(f, "if%t%t", c0, c1); | |
| 48 break; | |
| 49 case NOT: pfmt(f, "if not %t", c0); | |
| 50 break; | |
| 51 case OROR: pfmt(f, "%t || %t", c0, c1); | |
| 52 break; | |
| 53 case PCMD: | |
| 54 case PAREN: pfmt(f, "(%t)", c0); | |
| 55 break; | |
| 56 case SUB: pfmt(f, "$%t(%t)", c0, c1); | |
| 57 break; | |
| 58 case SIMPLE: pfmt(f, "%t", c0); | |
| 59 break; | |
| 60 case SUBSHELL: pfmt(f, "@ %t", c0); | |
| 61 break; | |
| 62 case SWITCH: pfmt(f, "switch %t %t", c0, c1); | |
| 63 break; | |
| 64 case TWIDDLE: pfmt(f, "~ %t %t", c0, c1); | |
| 65 break; | |
| 66 case WHILE: pfmt(f, "while %t%t", c0, c1); | |
| 67 break; | |
| 68 case ARGLIST: | |
| 69 if(c0==0) | |
| 70 pfmt(f, "%t", c1); | |
| 71 else if(c1==0) | |
| 72 pfmt(f, "%t", c0); | |
| 73 else | |
| 74 pfmt(f, "%t %t", c0, c1); | |
| 75 break; | |
| 76 case ';': | |
| 77 if(c0){ | |
| 78 if(c1) | |
| 79 pfmt(f, "%t%c%t", c0, nl, c1); | |
| 80 else pfmt(f, "%t", c0); | |
| 81 } | |
| 82 else pfmt(f, "%t", c1); | |
| 83 break; | |
| 84 case WORDS: | |
| 85 if(c0) | |
| 86 pfmt(f, "%t ", c0); | |
| 87 pfmt(f, "%t", c1); | |
| 88 break; | |
| 89 case FOR: | |
| 90 pfmt(f, "for(%t", c0); | |
| 91 if(c1) | |
| 92 pfmt(f, " in %t", c1); | |
| 93 pfmt(f, ")%t", c2); | |
| 94 break; | |
| 95 case WORD: | |
| 96 if(t->quoted) | |
| 97 pfmt(f, "%Q", t->str); | |
| 98 else pdeglob(f, t->str); | |
| 99 break; | |
| 100 case DUP: | |
| 101 if(t->rtype==DUPFD) | |
| 102 pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1… | |
| 103 else | |
| 104 pfmt(f, ">[%d=]", t->fd0); | |
| 105 pfmt(f, "%t", c1); | |
| 106 break; | |
| 107 case PIPEFD: | |
| 108 case REDIR: | |
| 109 switch(t->rtype){ | |
| 110 case HERE: | |
| 111 pchr(f, '<'); | |
| 112 case READ: | |
| 113 case RDWR: | |
| 114 pchr(f, '<'); | |
| 115 if(t->rtype==RDWR) | |
| 116 pchr(f, '>'); | |
| 117 if(t->fd0!=0) | |
| 118 pfmt(f, "[%d]", t->fd0); | |
| 119 break; | |
| 120 case APPEND: | |
| 121 pchr(f, '>'); | |
| 122 case WRITE: | |
| 123 pchr(f, '>'); | |
| 124 if(t->fd0!=1) | |
| 125 pfmt(f, "[%d]", t->fd0); | |
| 126 break; | |
| 127 } | |
| 128 pfmt(f, "%t", c0); | |
| 129 if(c1) | |
| 130 pfmt(f, " %t", c1); | |
| 131 break; | |
| 132 case '=': | |
| 133 pfmt(f, "%t=%t", c0, c1); | |
| 134 if(c2) | |
| 135 pfmt(f, " %t", c2); | |
| 136 break; | |
| 137 case PIPE: | |
| 138 pfmt(f, "%t|", c0); | |
| 139 if(t->fd1==0){ | |
| 140 if(t->fd0!=1) | |
| 141 pfmt(f, "[%d]", t->fd0); | |
| 142 } | |
| 143 else pfmt(f, "[%d=%d]", t->fd0, t->fd1); | |
| 144 pfmt(f, "%t", c1); | |
| 145 break; | |
| 146 } | |
| 147 } |