1# 2# Output routines. 3# 4 5# 6# Echo list of strings. 7# 8echo(e: ref Env, s: list of string) 9{ 10 out := e.outfile(); 11 if (out == nil) 12 return; 13 out.putc('+'); 14 for (t := s; t != nil; t = tl t) { 15 out.putc(' '); 16 out.puts(hd t); 17 } 18 out.putc('\n'); 19 out.close(); 20} 21 22# 23# Return text representation of Word/Item/Cmd. 24# 25 26Word.word(w: self ref Word, d: string): string 27{ 28 if (w == nil) 29 return nil; 30 if (d != nil) 31 return d + w.text; 32 if (w.flags & Wquoted) 33 return enquote(w.text); 34 return w.text; 35} 36 37Item.text(i: self ref Item): string 38{ 39 if (i == nil) 40 return nil; 41 case i.op { 42 Icaret => 43 return i.left.text() + " ^ " + i.right.text(); 44 Iicaret => 45 return i.left.text() + i.right.text(); 46 Idollarq => 47 return i.word.word("$\""); 48 Idollar or Imatch => 49 return i.word.word("$"); 50 Iword => 51 return i.word.word(nil); 52 Iexpr => 53 return "(" + i.cmd.text() + ")"; 54 Ibackq => 55 return "`" + group(i.cmd); 56 Iquote => 57 return "\"" + group(i.cmd); 58 Iinpipe => 59 return "<" + group(i.cmd); 60 Ioutpipe => 61 return ">" + group(i.cmd); 62 * => 63 return "?" + string i.op; 64 } 65} 66 67words(l: list of ref Item): string 68{ 69 s: string; 70 while (l != nil) { 71 if (s == nil) 72 s = (hd l).text(); 73 else 74 s = s + " " + (hd l).text(); 75 l = tl l; 76 } 77 return s; 78} 79 80redir(s: string, c: ref Cmd): string 81{ 82 if (c == nil) 83 return s; 84 for (l := c.redirs; l != nil; l = tl l) { 85 r := hd l; 86 s = s + " " + rdsymbs[r.op] + " " + r.word.text(); 87 } 88 return s; 89} 90 91cmd2in(c: ref Cmd, s: string): string 92{ 93 return c.left.text() + " " + s + " " + c.right.text(); 94} 95 96group(c: ref Cmd): string 97{ 98 if (c == nil) 99 return "{ }"; 100 return redir("{ " + c.text() + " }", c); 101} 102 103sequence(c: ref Cmd): string 104{ 105 s: string; 106 do { 107 r := c.right; 108 t := ";"; 109 if (r.op == Casync) { 110 r = r.left; 111 t = "&"; 112 } 113 if (s == nil) 114 s = r.text() + t; 115 else 116 s = r.text() + t + " " + s; 117 c = c.left; 118 } while (c != nil); 119 return s; 120} 121 122Cmd.text(c: self ref Cmd): string 123{ 124 if (c == nil) 125 return nil; 126 case c.op { 127 Csimple => 128 return redir(words(c.words), c); 129 Cseq => 130 return sequence(c); 131 Cfor => 132 return "for (" + c.item.text() + " in " + words(c.words) + ") " + c.left.text(); 133 Cif => 134 return "if (" + c.left.text() +") " + c.right.text(); 135 Celse => 136 return c.left.text() +" else " + c.right.text(); 137 Cwhile => 138 return "while (" + c.left.text() +") " + c.right.text(); 139 Ccase => 140 return redir("case " + c.left.text() + " { " + c.right.text() + "}", c); 141 Ccases => 142 s := c.left.text(); 143 if (s[len s - 1] != '&') 144 return s + "; " + c.right.text(); 145 return s + " " + c.right.text(); 146 Cmatched => 147 return cmd2in(c, "=>"); 148 Cdefeq => 149 return c.item.text() + " := " + words(c.words); 150 Ceq => 151 return c.item.text() + " = " + words(c.words); 152 Cfn => 153 return "fn " + c.item.text() + " " + group(c.left); 154 Crescue => 155 return "rescue " + c.item.text() + " " + group(c.left); 156 Casync => 157 return c.left.text() + "&"; 158 Cgroup => 159 return group(c.left); 160 Clistgroup => 161 return ":" + group(c.left); 162 Csubgroup => 163 return "@" + group(c.left); 164 Cnop => 165 return nil; 166 Cword => 167 return c.item.text(); 168 Ccaret => 169 return cmd2in(c, "^"); 170 Chd => 171 return "hd " + c.left.text(); 172 Clen => 173 return "len " + c.left.text(); 174 Cnot => 175 return "!" + c.left.text(); 176 Ctl => 177 return "tl " + c.left.text(); 178 Ccons => 179 return cmd2in(c, "::"); 180 Ceqeq => 181 return cmd2in(c, "=="); 182 Cnoteq => 183 return cmd2in(c, "!="); 184 Cmatch => 185 return cmd2in(c, "~"); 186 Cpipe => 187 return cmd2in(c, "|"); 188 Cdepend => 189 return words(c.words) + " : " + words(c.left.words) + " " + c.left.text(); 190 Crule => 191 return c.item.text() + " :~ " + c.left.item.text() + " " + c.left.text(); 192 * => 193 if (c.op >= Cprivate) 194 return "Priv+" + string (c.op - Cprivate); 195 else 196 return "?" + string c.op; 197 } 198 return nil; 199} 200