github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/8c/list.c (about) 1 // Inferno utils/8c/list.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/8c/list.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 #define EXTERN 32 #include "gc.h" 33 34 void 35 listinit(void) 36 { 37 38 fmtinstall('A', Aconv); 39 fmtinstall('B', Bconv); 40 fmtinstall('P', Pconv); 41 fmtinstall('S', Sconv); 42 fmtinstall('D', Dconv); 43 fmtinstall('R', Rconv); 44 } 45 46 int 47 Bconv(Fmt *fp) 48 { 49 char str[STRINGSZ], ss[STRINGSZ], *s; 50 Bits bits; 51 int i; 52 53 str[0] = 0; 54 bits = va_arg(fp->args, Bits); 55 while(bany(&bits)) { 56 i = bnum(bits); 57 if(str[0]) 58 strcat(str, " "); 59 if(var[i].sym == S) { 60 sprint(ss, "$%d", var[i].offset); 61 s = ss; 62 } else 63 s = var[i].sym->name; 64 if(strlen(str) + strlen(s) + 1 >= STRINGSZ) 65 break; 66 strcat(str, s); 67 bits.b[i/32] &= ~(1L << (i%32)); 68 } 69 return fmtstrcpy(fp, str); 70 } 71 72 int 73 Pconv(Fmt *fp) 74 { 75 char str[STRINGSZ]; 76 Prog *p; 77 78 p = va_arg(fp->args, Prog*); 79 switch(p->as) { 80 case ADATA: 81 sprint(str, "(%L) %A %D/%d,%D", 82 p->lineno, p->as, &p->from, p->from.scale, &p->to); 83 break; 84 85 case ATEXT: 86 if(p->from.scale) { 87 sprint(str, "(%L) %A %D,%d,%lD", 88 p->lineno, p->as, &p->from, p->from.scale, &p->to); 89 break; 90 } 91 sprint(str, "(%L) %A %D,%lD", 92 p->lineno, p->as, &p->from, &p->to); 93 break; 94 95 default: 96 sprint(str, "(%L) %A %D,%D", 97 p->lineno, p->as, &p->from, &p->to); 98 break; 99 } 100 return fmtstrcpy(fp, str); 101 } 102 103 int 104 Aconv(Fmt *fp) 105 { 106 int i; 107 108 i = va_arg(fp->args, int); 109 return fmtstrcpy(fp, anames[i]); 110 } 111 112 int 113 Dconv(Fmt *fp) 114 { 115 char str[STRINGSZ], s[STRINGSZ]; 116 Adr *a; 117 int i; 118 119 a = va_arg(fp->args, Adr*); 120 i = a->type; 121 122 if(fp->flags & FmtLong) { 123 if(i == D_CONST2) 124 sprint(str, "$%d-%d", a->offset, a->offset2); 125 else { 126 // ATEXT dst is not constant 127 sprint(str, "!!%D", a); 128 } 129 goto brk; 130 } 131 132 if(i >= D_INDIR) { 133 if(a->offset) 134 sprint(str, "%d(%R)", a->offset, i-D_INDIR); 135 else 136 sprint(str, "(%R)", i-D_INDIR); 137 goto brk; 138 } 139 switch(i) { 140 default: 141 if(a->offset) 142 sprint(str, "$%d,%R", a->offset, i); 143 else 144 sprint(str, "%R", i); 145 break; 146 147 case D_NONE: 148 str[0] = 0; 149 break; 150 151 case D_BRANCH: 152 sprint(str, "%d", a->offset); 153 break; 154 155 case D_EXTERN: 156 sprint(str, "%s+%d(SB)", a->sym->name, a->offset); 157 break; 158 159 case D_STATIC: 160 sprint(str, "%s<>+%d(SB)", a->sym->name, a->offset); 161 break; 162 163 case D_AUTO: 164 if(a->sym) 165 sprint(str, "%s+%d(SP)", a->sym->name, a->offset); 166 else 167 sprint(str, "%d(SP)", a->offset); 168 break; 169 170 case D_PARAM: 171 if(a->sym) 172 sprint(str, "%s+%d(FP)", a->sym->name, a->offset); 173 else 174 sprint(str, "%d(FP)", a->offset); 175 break; 176 177 case D_CONST: 178 sprint(str, "$%d", a->offset); 179 break; 180 181 case D_CONST2: 182 if(!(fp->flags & FmtLong)) { 183 // D_CONST2 outside of ATEXT should not happen 184 sprint(str, "!!$%d-%d", a->offset, a->offset2); 185 } 186 break; 187 188 case D_FCONST: 189 sprint(str, "$(%.17e)", a->dval); 190 break; 191 192 case D_SCONST: 193 sprint(str, "$\"%S\"", a->sval); 194 break; 195 196 case D_ADDR: 197 a->type = a->index; 198 a->index = D_NONE; 199 sprint(str, "$%D", a); 200 a->index = a->type; 201 a->type = D_ADDR; 202 goto conv; 203 } 204 brk: 205 if(a->index != D_NONE) { 206 sprint(s, "(%R*%d)", (int)a->index, (int)a->scale); 207 strcat(str, s); 208 } 209 conv: 210 return fmtstrcpy(fp, str); 211 } 212 213 char* regstr[] = 214 { 215 "AL", /* [D_AL] */ 216 "CL", 217 "DL", 218 "BL", 219 "AH", 220 "CH", 221 "DH", 222 "BH", 223 224 "AX", /* [D_AX] */ 225 "CX", 226 "DX", 227 "BX", 228 "SP", 229 "BP", 230 "SI", 231 "DI", 232 233 "F0", /* [D_F0] */ 234 "F1", 235 "F2", 236 "F3", 237 "F4", 238 "F5", 239 "F6", 240 "F7", 241 242 "CS", /* [D_CS] */ 243 "SS", 244 "DS", 245 "ES", 246 "FS", 247 "GS", 248 249 "GDTR", /* [D_GDTR] */ 250 "IDTR", /* [D_IDTR] */ 251 "LDTR", /* [D_LDTR] */ 252 "MSW", /* [D_MSW] */ 253 "TASK", /* [D_TASK] */ 254 255 "CR0", /* [D_CR] */ 256 "CR1", 257 "CR2", 258 "CR3", 259 "CR4", 260 "CR5", 261 "CR6", 262 "CR7", 263 264 "DR0", /* [D_DR] */ 265 "DR1", 266 "DR2", 267 "DR3", 268 "DR4", 269 "DR5", 270 "DR6", 271 "DR7", 272 273 "TR0", /* [D_TR] */ 274 "TR1", 275 "TR2", 276 "TR3", 277 "TR4", 278 "TR5", 279 "TR6", 280 "TR7", 281 282 "X0", /* [D_X0] */ 283 "X1", 284 "X2", 285 "X3", 286 "X4", 287 "X5", 288 "X6", 289 "X7", 290 291 "NONE", /* [D_NONE] */ 292 }; 293 294 int 295 Rconv(Fmt *fp) 296 { 297 char str[STRINGSZ]; 298 int r; 299 300 r = va_arg(fp->args, int); 301 if(r >= D_AL && r <= D_NONE) 302 sprint(str, "%s", regstr[r-D_AL]); 303 else 304 sprint(str, "gok(%d)", r); 305 306 return fmtstrcpy(fp, str); 307 } 308 309 int 310 Sconv(Fmt *fp) 311 { 312 int i, c; 313 char str[STRINGSZ], *p, *a; 314 315 a = va_arg(fp->args, char*); 316 p = str; 317 for(i=0; i<sizeof(double); i++) { 318 c = a[i] & 0xff; 319 if(c >= 'a' && c <= 'z' || 320 c >= 'A' && c <= 'Z' || 321 c >= '0' && c <= '9') { 322 *p++ = c; 323 continue; 324 } 325 *p++ = '\\'; 326 switch(c) { 327 default: 328 if(c < 040 || c >= 0177) 329 break; /* not portable */ 330 p[-1] = c; 331 continue; 332 case 0: 333 *p++ = 'z'; 334 continue; 335 case '\\': 336 case '"': 337 *p++ = c; 338 continue; 339 case '\n': 340 *p++ = 'n'; 341 continue; 342 case '\t': 343 *p++ = 't'; 344 continue; 345 } 346 *p++ = (c>>6) + '0'; 347 *p++ = ((c>>3) & 7) + '0'; 348 *p++ = (c & 7) + '0'; 349 } 350 *p = 0; 351 return fmtstrcpy(fp, str); 352 }