]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/8l/list.c
mothra: fix alt display resizing, filter control characters in panel entries, use...
[plan9front.git] / sys / src / cmd / 8l / list.c
1 #include        "l.h"
2
3 void
4 listinit(void)
5 {
6
7         fmtinstall('R', Rconv);
8         fmtinstall('A', Aconv);
9         fmtinstall('D', Dconv);
10         fmtinstall('S', Sconv);
11         fmtinstall('P', Pconv);
12 }
13
14 static  Prog    *bigP;
15
16 int
17 Pconv(Fmt *fp)
18 {
19         char str[STRINGSZ];
20         Prog *p;
21
22         p = va_arg(fp->args, Prog*);
23         bigP = p;
24         switch(p->as) {
25         case ATEXT:
26                 if(p->from.scale) {
27                         sprint(str, "(%ld)      %A      %D,%d,%D",
28                                 p->line, p->as, &p->from, p->from.scale, &p->to);
29                         break;
30                 }
31         default:
32                 sprint(str, "(%ld)      %A      %D,%D",
33                         p->line, p->as, &p->from, &p->to);
34                 break;
35         case ADATA:
36         case AINIT:
37         case ADYNT:
38                 sprint(str, "(%ld)      %A      %D/%d,%D",
39                         p->line, p->as, &p->from, p->from.scale, &p->to);
40                 break;
41         }
42         bigP = P;
43         return fmtstrcpy(fp, str);
44 }
45
46 int
47 Aconv(Fmt *fp)
48 {
49         int i;
50
51         i = va_arg(fp->args, int);
52         return fmtstrcpy(fp, anames[i]);
53 }
54
55 int
56 Dconv(Fmt *fp)
57 {
58         char str[40], s[20];
59         Adr *a;
60         int i;
61
62         a = va_arg(fp->args, Adr*);
63         i = a->type;
64         if(i >= D_INDIR) {
65                 if(a->offset)
66                         sprint(str, "%ld(%R)", a->offset, i-D_INDIR);
67                 else
68                         sprint(str, "(%R)", i-D_INDIR);
69                 goto brk;
70         }
71         switch(i) {
72
73         default:
74                 sprint(str, "%R", i);
75                 break;
76
77         case D_NONE:
78                 str[0] = 0;
79                 break;
80
81         case D_BRANCH:
82                 if(bigP != P && bigP->pcond != P)
83                         if(a->sym != S)
84                                 sprint(str, "%lux+%s", bigP->pcond->pc,
85                                         a->sym->name);
86                         else
87                                 sprint(str, "%lux", bigP->pcond->pc);
88                 else
89                         sprint(str, "%ld(PC)", a->offset);
90                 break;
91
92         case D_EXTERN:
93                 sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
94                 break;
95
96         case D_STATIC:
97                 sprint(str, "%s<%d>+%ld(SB)", a->sym->name,
98                         a->sym->version, a->offset);
99                 break;
100
101         case D_AUTO:
102                 sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
103                 break;
104
105         case D_PARAM:
106                 if(a->sym)
107                         sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
108                 else
109                         sprint(str, "%ld(FP)", a->offset);
110                 break;
111
112         case D_CONST:
113                 sprint(str, "$%ld", a->offset);
114                 break;
115
116         case D_FCONST:
117                 sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
118                 break;
119
120         case D_SCONST:
121                 sprint(str, "$\"%S\"", a->scon);
122                 break;
123
124         case D_ADDR:
125                 a->type = a->index;
126                 a->index = D_NONE;
127                 sprint(str, "$%D", a);
128                 a->index = a->type;
129                 a->type = D_ADDR;
130                 goto conv;
131         }
132 brk:
133         if(a->index != D_NONE) {
134                 sprint(s, "(%R*%d)", a->index, a->scale);
135                 strcat(str, s);
136         }
137 conv:
138         return fmtstrcpy(fp, str);
139 }
140
141 char*   regstr[] =
142 {
143         "AL",           /* [D_AL] */
144         "CL",
145         "DL",
146         "BL",
147         "AH",
148         "CH",
149         "DH",
150         "BH",
151
152         "AX",           /* [D_AX] */
153         "CX",
154         "DX",
155         "BX",
156         "SP",
157         "BP",
158         "SI",
159         "DI",
160
161         "F0",           /* [D_F0] */
162         "F1",
163         "F2",
164         "F3",
165         "F4",
166         "F5",
167         "F6",
168         "F7",
169
170         "CS",           /* [D_CS] */
171         "SS",
172         "DS",
173         "ES",
174         "FS",
175         "GS",
176
177         "GDTR",         /* [D_GDTR] */
178         "IDTR",         /* [D_IDTR] */
179         "LDTR",         /* [D_LDTR] */
180         "MSW",          /* [D_MSW] */
181         "TASK",         /* [D_TASK] */
182
183         "CR0",          /* [D_CR] */
184         "CR1",
185         "CR2",
186         "CR3",
187         "CR4",
188         "CR5",
189         "CR6",
190         "CR7",
191
192         "DR0",          /* [D_DR] */
193         "DR1",
194         "DR2",
195         "DR3",
196         "DR4",
197         "DR5",
198         "DR6",
199         "DR7",
200
201         "TR0",          /* [D_TR] */
202         "TR1",
203         "TR2",
204         "TR3",
205         "TR4",
206         "TR5",
207         "TR6",
208         "TR7",
209
210         "NONE",         /* [D_NONE] */
211 };
212
213 int
214 Rconv(Fmt *fp)
215 {
216         char str[20];
217         int r;
218
219         r = va_arg(fp->args, int);
220         if(r >= D_AL && r <= D_NONE)
221                 sprint(str, "%s", regstr[r-D_AL]);
222         else
223                 sprint(str, "gok(%d)", r);
224
225         return fmtstrcpy(fp, str);
226 }
227
228 int
229 Sconv(Fmt *fp)
230 {
231         int i, c;
232         char str[30], *p, *a;
233
234         a = va_arg(fp->args, char*);
235         p = str;
236         for(i=0; i<sizeof(double); i++) {
237                 c = a[i] & 0xff;
238                 if(c >= 'a' && c <= 'z' ||
239                    c >= 'A' && c <= 'Z' ||
240                    c >= '0' && c <= '9') {
241                         *p++ = c;
242                         continue;
243                 }
244                 *p++ = '\\';
245                 switch(c) {
246                 default:
247                         if(c < 040 || c >= 0177)
248                                 break;  /* not portable */
249                         p[-1] = c;
250                         continue;
251                 case 0:
252                         *p++ = 'z';
253                         continue;
254                 case '\\':
255                 case '"':
256                         *p++ = c;
257                         continue;
258                 case '\n':
259                         *p++ = 'n';
260                         continue;
261                 case '\t':
262                         *p++ = 't';
263                         continue;
264                 }
265                 *p++ = (c>>6) + '0';
266                 *p++ = ((c>>3) & 7) + '0';
267                 *p++ = (c & 7) + '0';
268         }
269         *p = 0;
270         return fmtstrcpy(fp, str);
271 }
272
273 void
274 diag(char *fmt, ...)
275 {
276         char buf[STRINGSZ], *tn;
277         va_list arg;
278
279         tn = "??none??";
280         if(curtext != P && curtext->from.sym != S)
281                 tn = curtext->from.sym->name;
282         va_start(arg, fmt);
283         vseprint(buf, buf+sizeof(buf), fmt, arg);
284         va_end(arg);
285         print("%s: %s\n", tn, buf);
286
287         nerrors++;
288         if(nerrors > 20 && !debug['A']) {
289                 print("too many errors\n");
290                 errorexit();
291         }
292 }