]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/pickle.c
fix filetype detecton by suffix so that multiple dots dont confuse it. (thanks kvik)
[plan9front.git] / sys / src / cmd / cc / pickle.c
1 #include "cc.h"
2
3 static char *kwd[] =
4 {
5         "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn",
6         "$delete", "$do", "$else", "$eval", "$head", "$if",
7         "$local", "$loop", "$return", "$tail", "$then",
8         "$union", "$whatis", "$while",
9 };
10 static char picklestr[] = "\tbp = pickle(bp, ep, un, ";
11
12 static char*
13 pmap(char *s)
14 {
15         int i, bot, top, new;
16
17         bot = 0;
18         top = bot + nelem(kwd) - 1;
19         while(bot <= top){
20                 new = bot + (top - bot)/2;
21                 i = strcmp(kwd[new]+1, s);
22                 if(i == 0)
23                         return kwd[new];
24
25                 if(i < 0)
26                         bot = new + 1;
27                 else
28                         top = new - 1;
29         }
30         return s;
31 }
32
33 Sym*
34 picklesue(Type *t)
35 {
36         int h;
37         Sym *s;
38
39         if(t != T)
40         for(h=0; h<nelem(hash); h++)
41                 for(s = hash[h]; s != S; s = s->link)
42                         if(s->suetag && s->suetag->link == t)
43                                 return s;
44         return 0;
45 }
46
47 Sym*
48 picklefun(Type *t)
49 {
50         int h;
51         Sym *s;
52
53         for(h=0; h<nelem(hash); h++)
54                 for(s = hash[h]; s != S; s = s->link)
55                         if(s->type == t)
56                                 return s;
57         return 0;
58 }
59
60 char    picklechar[NTYPE];
61 Init    picklecinit[] =
62 {
63         TCHAR,          'C',    0,
64         TUCHAR,         'b',    0,
65         TSHORT,         'd',    0,
66         TUSHORT,                'u',    0,
67         TLONG,          'D',    0,
68         TULONG,         'U',    0,
69         TVLONG,         'V',    0,
70         TUVLONG,        'W',    0,
71         TFLOAT,         'f',    0,
72         TDOUBLE,                'F',    0,
73         TARRAY,         'a',    0,
74         TIND,           'X',    0,
75         -1,             0,      0,
76 };
77
78 static void
79 pickleinit(void)
80 {
81         Init *p;
82
83         for(p=picklecinit; p->code >= 0; p++)
84                 picklechar[p->code] = p->value;
85
86         picklechar[TINT] = picklechar[TLONG];
87         picklechar[TUINT] = picklechar[TULONG];
88         if(types[TINT]->width != types[TLONG]->width) {
89                 picklechar[TINT] = picklechar[TSHORT];
90                 picklechar[TUINT] = picklechar[TUSHORT];
91                 if(types[TINT]->width != types[TSHORT]->width)
92                         warn(Z, "picklemember int not long or short");
93         }
94         
95 }
96
97 void
98 picklemember(Type *t, long off)
99 {
100         Sym *s, *s1;
101         static int picklecharinit = 0;
102
103         if(picklecharinit == 0) {
104                 pickleinit();
105                 picklecharinit = 1;
106         }
107         s = t->sym;
108         switch(t->etype) {
109         default:
110                 Bprint(&outbuf, "       T%d\n", t->etype);
111                 break;
112
113         case TIND:
114                 if(s == S)
115                         Bprint(&outbuf,
116                                 "%s\"p\", (char*)addr+%ld+_i*%ld);\n",
117                                 picklestr, t->offset+off, t->width);
118                 else
119                         Bprint(&outbuf,
120                                 "%s\"p\", &addr->%s);\n",
121                                 picklestr, pmap(s->name));
122                 break;
123
124         case TINT:
125         case TUINT:
126         case TCHAR:
127         case TUCHAR:
128         case TSHORT:
129         case TUSHORT:
130         case TLONG:
131         case TULONG:
132         case TVLONG:
133         case TUVLONG:
134         case TFLOAT:
135         case TDOUBLE:
136                 if(s == S)
137                         Bprint(&outbuf, "%s\"%c\", (char*)addr+%ld+_i*%ld);\n",
138                                 picklestr, picklechar[t->etype], t->offset+off, t->width);
139                 else
140                         Bprint(&outbuf, "%s\"%c\", &addr->%s);\n",
141                                 picklestr, picklechar[t->etype], pmap(s->name));
142                 break;
143         case TARRAY:
144                 Bprint(&outbuf, "\tfor(_i = 0; _i < %ld; _i++) {\n\t",
145                         t->width/t->link->width);
146                 picklemember(t->link, t->offset+off);
147                 Bprint(&outbuf, "\t}\n\t_i = 0;\n\tUSED(_i);\n");
148                 break;
149
150         case TSTRUCT:
151         case TUNION:
152                 s1 = picklesue(t->link);
153                 if(s1 == S)
154                         break;
155                 if(s == S) {
156                         Bprint(&outbuf, "\tbp = pickle_%s(bp, ep, un, (%s*)((char*)addr+%ld+_i*%ld));\n",
157                                 pmap(s1->name), pmap(s1->name), t->offset+off, t->width);
158                 } else {
159                         Bprint(&outbuf, "\tbp = pickle_%s(bp, ep, un, &addr->%s);\n",
160                                 pmap(s1->name), pmap(s->name));
161                 }
162                 break;
163         }
164 }
165
166 void
167 pickletype(Type *t)
168 {
169         Sym *s;
170         Type *l;
171         Io *i;
172         int n;
173         char *an;
174
175         if(!debug['P'])
176                 return;
177         if(debug['P'] > 1) {
178                 n = 0;
179                 for(i=iostack; i; i=i->link)
180                         n++;
181                 if(n > 1)
182                         return;
183         }
184         s = picklesue(t->link);
185         if(s == S)
186                 return;
187         switch(t->etype) {
188         default:
189                 Bprint(&outbuf, "T%d\n", t->etype);
190                 return;
191
192         case TUNION:
193         case TSTRUCT:
194                 if(debug['s'])
195                         goto asmstr;
196                 an = pmap(s->name);
197
198                 Bprint(&outbuf, "uchar*\npickle_%s(uchar *bp, uchar *ep, int un, %s *addr)\n{\n\tint _i = 0;\n\n\tUSED(_i);\n", an, an);
199                 for(l = t->link; l != T; l = l->down)
200                         picklemember(l, 0);
201                 Bprint(&outbuf, "\treturn bp;\n}\n\n");
202                 break;
203         asmstr:
204                 if(s == S)
205                         break;
206                 for(l = t->link; l != T; l = l->down)
207                         if(l->sym != S)
208                                 Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
209                                         s->name,
210                                         l->sym->name,
211                                         l->offset);
212                 break;
213         }
214 }
215
216 void
217 picklevar(Sym *s)
218 {
219         int n;
220         Io *i;
221         Type *t;
222         Sym *s1, *s2;
223
224         if(!debug['P'] || debug['s'])
225                 return;
226         if(debug['P'] > 1) {
227                 n = 0;
228                 for(i=iostack; i; i=i->link)
229                         n++;
230                 if(n > 1)
231                         return;
232         }
233         t = s->type;
234         while(t && t->etype == TIND)
235                 t = t->link;
236         if(t == T)
237                 return;
238         if(t->etype == TENUM) {
239                 Bprint(&outbuf, "%s = ", pmap(s->name));
240                 if(!typefd[t->etype])
241                         Bprint(&outbuf, "%lld;\n", s->vconst);
242                 else
243                         Bprint(&outbuf, "%f\n;", s->fconst);
244                 return;
245         }
246         if(!typesu[t->etype])
247                 return;
248         s1 = picklesue(t->link);
249         if(s1 == S)
250                 return;
251         switch(s->class) {
252         case CAUTO:
253         case CPARAM:
254                 s2 = picklefun(thisfn);
255                 if(s2)
256                         Bprint(&outbuf, "complex %s %s:%s;\n",
257                                 pmap(s1->name), pmap(s2->name), pmap(s->name));
258                 break;
259         
260         case CSTATIC:
261         case CEXTERN:
262         case CGLOBL:
263         case CLOCAL:
264                 Bprint(&outbuf, "complex %s %s;\n",
265                         pmap(s1->name), pmap(s->name));
266                 break;
267         }
268 }