xref: /inferno-os/utils/kc/list.c (revision 9dbf735d35c339c90deaed43fc0ae17f16c122f7)
1 #define EXTERN
2 #include "gc.h"
3 
4 void
5 listinit(void)
6 {
7 
8 	fmtinstall('A', Aconv);
9 	fmtinstall('P', Pconv);
10 	fmtinstall('S', Sconv);
11 	fmtinstall('N', Nconv);
12 	fmtinstall('D', Dconv);
13 	fmtinstall('B', Bconv);
14 }
15 
16 int
17 Bconv(Fmt *fp)
18 {
19 	char str[STRINGSZ], ss[STRINGSZ], *s;
20 	Bits bits;
21 	int i;
22 
23 	str[0] = 0;
24 	bits = va_arg(fp->args, Bits);
25 	while(bany(&bits)) {
26 		i = bnum(bits);
27 		if(str[0])
28 			strcat(str, " ");
29 		if(var[i].sym == S) {
30 			sprint(ss, "$%ld", var[i].offset);
31 			s = ss;
32 		} else
33 			s = var[i].sym->name;
34 		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
35 			break;
36 		strcat(str, s);
37 		bits.b[i/32] &= ~(1L << (i%32));
38 	}
39 	return fmtstrcpy(fp, str);
40 }
41 
42 int
43 Pconv(Fmt *fp)
44 {
45 	char str[STRINGSZ];
46 	Prog *p;
47 	int a;
48 
49 	p = va_arg(fp->args, Prog*);
50 	a = p->as;
51 	if(a == ADATA)
52 		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
53 	else
54 	if(p->as == ATEXT)
55 		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
56 	else
57 	if(p->reg == NREG)
58 		sprint(str, "	%A	%D,%D", a, &p->from, &p->to);
59 	else
60 	if(p->from.type != D_FREG)
61 		sprint(str, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
62 	else
63 		sprint(str, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
64 	return fmtstrcpy(fp, str);
65 }
66 
67 int
68 Aconv(Fmt *fp)
69 {
70 	char *s;
71 	int a;
72 
73 	a = va_arg(fp->args, int);
74 	s = "?";
75 	if(a >= AXXX && a <= AEND)
76 		s = anames[a];
77 	return fmtstrcpy(fp, s);
78 }
79 
80 int
81 Dconv(Fmt *fp)
82 {
83 	char str[STRINGSZ];
84 	Adr *a;
85 
86 	a = va_arg(fp->args, Adr*);
87 	switch(a->type) {
88 
89 	default:
90 		sprint(str, "GOK-type(%d)", a->type);
91 		break;
92 
93 	case D_NONE:
94 		str[0] = 0;
95 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
96 			sprint(str, "%N(R%d)(NONE)", a, a->reg);
97 		break;
98 
99 	case D_CONST:
100 		if(a->reg != NREG)
101 			sprint(str, "$%N(R%d)", a, a->reg);
102 		else
103 			sprint(str, "$%N", a);
104 		break;
105 
106 	case D_OREG:
107 		if(a->reg != NREG)
108 			sprint(str, "%N(R%d)", a, a->reg);
109 		else
110 			sprint(str, "%N", a);
111 		break;
112 
113 	case D_REG:
114 		sprint(str, "R%d", a->reg);
115 		if(a->name != D_NONE || a->sym != S)
116 			sprint(str, "%N(R%d)(REG)", a, a->reg);
117 		break;
118 
119 	case D_FREG:
120 		sprint(str, "F%d", a->reg);
121 		if(a->name != D_NONE || a->sym != S)
122 			sprint(str, "%N(F%d)(REG)", a, a->reg);
123 		break;
124 
125 	case D_CREG:
126 		sprint(str, "C%d", a->reg);
127 		if(a->name != D_NONE || a->sym != S)
128 			sprint(str, "%N(C%d)(REG)", a, a->reg);
129 		break;
130 
131 	case D_BRANCH:
132 		sprint(str, "%ld(PC)", a->offset-pc);
133 		break;
134 
135 	case D_FCONST:
136 		sprint(str, "$%.17e", a->dval);
137 		break;
138 
139 	case D_SCONST:
140 		sprint(str, "$\"%S\"", a->sval);
141 		break;
142 	}
143 	return fmtstrcpy(fp, str);
144 }
145 
146 int
147 Sconv(Fmt *fp)
148 {
149 	int i, c;
150 	char str[STRINGSZ], *p, *a;
151 
152 	a = va_arg(fp->args, char*);
153 	p = str;
154 	for(i=0; i<NSNAME; i++) {
155 		c = a[i] & 0xff;
156 		if(c >= 'a' && c <= 'z' ||
157 		   c >= 'A' && c <= 'Z' ||
158 		   c >= '0' && c <= '9' ||
159 		   c == ' ' || c == '%') {
160 			*p++ = c;
161 			continue;
162 		}
163 		*p++ = '\\';
164 		switch(c) {
165 		case 0:
166 			*p++ = 'z';
167 			continue;
168 		case '\\':
169 		case '"':
170 			*p++ = c;
171 			continue;
172 		case '\n':
173 			*p++ = 'n';
174 			continue;
175 		case '\t':
176 			*p++ = 't';
177 			continue;
178 		case '\r':
179 			*p++ = 'r';
180 			continue;
181 		case '\f':
182 			*p++ = 'f';
183 			continue;
184 		}
185 		*p++ = (c>>6) + '0';
186 		*p++ = ((c>>3) & 7) + '0';
187 		*p++ = (c & 7) + '0';
188 	}
189 	*p = 0;
190 	return fmtstrcpy(fp, str);
191 }
192 
193 int
194 Nconv(Fmt *fp)
195 {
196 	char str[STRINGSZ];
197 	Adr *a;
198 	Sym *s;
199 
200 	a = va_arg(fp->args, Adr*);
201 	s = a->sym;
202 	if(s == S) {
203 		sprint(str, "%ld", a->offset);
204 		goto out;
205 	}
206 	switch(a->name) {
207 	default:
208 		sprint(str, "GOK-name(%d)", a->name);
209 		break;
210 
211 	case D_EXTERN:
212 		sprint(str, "%s+%ld(SB)", s->name, a->offset);
213 		break;
214 
215 	case D_STATIC:
216 		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
217 		break;
218 
219 	case D_AUTO:
220 		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
221 		break;
222 
223 	case D_PARAM:
224 		sprint(str, "%s+%ld(FP)", s->name, a->offset);
225 		break;
226 	}
227 out:
228 	return fmtstrcpy(fp, str);
229 }
230