|
|
1.1 root 1: #include "cem.h"
2: #define STD_OBJ 1
3: #include "stdobj.h"
4: #include "symbol.h"
5: #include "type.h"
6:
7: /*
8: * Type table routines.
9: */
10:
11: extern char *strchr();
12:
13: /*
14: * Comparison routines. "Identical type" equivalence.
15: * We believe file modtimes unless we are told to doubt.
16: */
17:
18: static int
19: cmp_enum(p, q)
20: type *p;
21: type *q;
22: {
23: register e_data *e;
24: register e_data *f;
25: register e_elt *g;
26: register e_elt *h;
27: register int i;
28:
29: e = p->d.e;
30: f = q->d.e;
31:
32: if (modtimes && e->e_line == f->e_line && match_times(e->e_file, f->e_file))
33: return 0;
34:
35: if (e->e_name != f->e_name)
36: {
37: if (e->e_name == NULL)
38: return -f->e_name->sy_index;
39: else if (f->e_name == NULL)
40: return e->e_name->sy_index;
41: else
42: return e->e_name->sy_index - f->e_name->sy_index;
43: }
44:
45: if ((i = e->e_low - f->e_low) != 0 || (i = e->e_high - f->e_high) != 0)
46: return i;
47:
48: g = e->e_list;
49: h = f->e_list;
50:
51: while (g != NULL)
52: {
53: if (h == NULL)
54: return -1;
55:
56: if (g->e_name != h->e_name)
57: return g->e_name->sy_index - h->e_name->sy_index;
58:
59: if ((i = g->e_value - h->e_value) != 0)
60: return i;
61:
62: g = g->e_next;
63: h = h->e_next;
64: }
65:
66: if (h != NULL)
67: return 1;
68:
69: return 0;
70: }
71:
72: static int
73: cmp_struct(p, q)
74: type *p;
75: type *q;
76: {
77: register s_data *e;
78: register s_data *f;
79: register s_elt *g;
80: register s_elt *h;
81: register int i;
82:
83: e = p->d.s;
84: f = q->d.s;
85:
86: if (modtimes && e->s_line == f->s_line && match_times(e->s_file, f->s_file))
87: return 0;
88:
89: if (e->s_name != f->s_name)
90: {
91: if (e->s_name == NULL)
92: return -f->s_name->sy_index;
93: else if (f->s_name == NULL)
94: return e->s_name->sy_index;
95: else
96: return e->s_name->sy_index - f->s_name->sy_index;
97: }
98:
99: if ((i = e->s_size - f->s_size) != 0)
100: return i;
101:
102: g = e->s_list;
103: h = f->s_list;
104:
105: while (g != NULL)
106: {
107: if (h == NULL)
108: return -1;
109:
110: if (g->s_name != h->s_name)
111: return g->s_name->sy_index - h->s_name->sy_index;
112:
113: if (g->s_type != h->s_type)
114: return g->s_type->t_index - h->s_type->t_index;
115:
116: g = g->s_next;
117: h = h->s_next;
118: }
119:
120: if (h != NULL)
121: return 1;
122:
123: return 0;
124: }
125:
126: static int
127: cmp_union(p, q)
128: type *p;
129: type *q;
130: {
131: register u_data *e;
132: register u_data *f;
133: register u_elt *g;
134: register u_elt *h;
135: register int i;
136:
137: e = p->d.u;
138: f = q->d.u;
139:
140: if (modtimes && e->u_line == f->u_line && match_times(e->u_file, f->u_file))
141: return 0;
142:
143: if (e->u_name != f->u_name)
144: {
145: if (e->u_name == NULL)
146: return -f->u_name->sy_index;
147: else if (f->u_name == NULL)
148: return e->u_name->sy_index;
149: else
150: return e->u_name->sy_index - f->u_name->sy_index;
151: }
152:
153: if ((i = e->u_size - f->u_size) != 0)
154: return i;
155:
156: g = e->u_list;
157: h = f->u_list;
158:
159: while (g != NULL)
160: {
161: if (h == NULL)
162: return -1;
163:
164: if (g->u_name != h->u_name)
165: return g->u_name->sy_index - h->u_name->sy_index;
166:
167: if (g->u_type != h->u_type)
168: return g->u_type->t_index - h->u_type->t_index;
169:
170: g = g->u_next;
171: h = h->u_next;
172: }
173:
174: if (h != NULL)
175: return 1;
176:
177: return 0;
178: }
179:
180: /*
181: * We win a lot by trusting the file/modtime linenumber
182: * of a struct/unions declaration.
183: */
184: #define THASHSZ 37
185: #define TPRIME0 7
186: #define TPRIME1 31
187:
188: /*
189: * Type hashing by filename/modtime and line number.
190: */
191: static type *
192: type_hash(h0, h1, t)
193: long h0;
194: long h1;
195: type *t;
196: {
197: typedef struct thash thash;
198:
199: struct thash
200: {
201: long h0;
202: long h1;
203: type *t;
204: thash *next;
205: };
206:
207: register long i;
208: register thash *p;
209: static thash *thasht[THASHSZ];
210:
211: i = TPRIME0 * h0 + TPRIME1 * h1;
212:
213: if (i < 0)
214: i = -i;
215:
216: i %= THASHSZ;
217:
218: for (p = thasht[i]; p != NULL; p = p->next)
219: {
220: if (p->h0 == h0 && p->h1 == h1)
221: return p->t;
222:
223: }
224:
225: if (t == NULL)
226: return NULL;
227:
228: p = talloc(thash);
229: p->h0 = h0;
230: p->h1 = h1;
231: p->t = t;
232: p->next = thasht[i];
233: thasht[i] = p;
234: return t;
235: }
236:
237: /*
238: * Lookup a type hashing by filename/modtime and line number.
239: */
240: type *
241: lookup_hash(s, l)
242: symbol *s;
243: long l;
244: {
245: if (modtimes && strchr(s->sy_name, TIME_SEP) != NULL)
246: return type_hash(s->sy_index, l, (type *)NULL);
247: else
248: return NULL;
249: }
250:
251: /*
252: * Enter a type hashing by filename/modtime and line number.
253: */
254: void
255: enter_hash(s, l, t)
256: symbol *s;
257: long l;
258: type *t;
259: {
260: if (modtimes && strchr(s->sy_name, TIME_SEP) != NULL)
261: type_hash(s->sy_index, l, t);
262: }
263:
264: /*
265: * Type table manager. Pass it a type and it will return you the
266: * (strongly) equivalent type that characterises it. i.e. it
267: * 'interns' a type. Type comparison is then pointer comparison.
268: */
269: type *
270: find_type(t)
271: register type *t;
272: {
273: typedef struct ttnode ttnode;
274:
275: struct ttnode
276: {
277: type *tt_type;
278: ttnode *tt_left;
279: ttnode *tt_right;
280: };
281:
282: register type *p;
283: register type *q;
284: register int i;
285: register ttnode **n;
286: register ttnode *tt;
287:
288: static ttnode *type_table[(int)t_types];
289:
290: n = &type_table[(int)t->t_type];
291:
292: while (*n != NULL)
293: {
294: p = t;
295: q = (*n)->tt_type;
296:
297: if ((i = ((int)p->t_type) - ((int)q->t_type)) == 0)
298: {
299: switch (p->t_type)
300: {
301: case t_arrayof:
302: if ((i = p->d.dim - q->d.dim) == 0)
303: i = p->t_subtype->t_index - q->t_subtype->t_index;
304:
305: break;
306:
307: case t_basetype:
308: i = p->d.mask - q->d.mask;
309: break;
310:
311: case t_bitfield:
312: if ((i = p->d.size - q->d.size) == 0)
313: i = p->t_subtype->t_index - q->t_subtype->t_index;
314:
315: break;
316:
317: case t_dimless:
318: case t_ftnreturning:
319: case t_ptrto:
320: i = p->t_subtype->t_index - q->t_subtype->t_index;
321: break;
322:
323: case t_enum:
324: i = cmp_enum(p, q);
325: break;
326:
327: case t_structof:
328: i = cmp_struct(p, q);
329: break;
330:
331: case t_unionof:
332: i = cmp_union(p, q);
333: break;
334:
335: default:
336: fprintf(stderr, "%s: find_type - bad type\n", my_name);
337: exit(1);
338: }
339:
340: if (i == 0)
341: {
342: delete_type(t);
343: return (*n)->tt_type;
344: }
345: }
346:
347: n = i < 0 ? &((*n)->tt_left) : &((*n)->tt_right);
348: }
349:
350: switch (t->t_type)
351: {
352: case t_structof:
353: enter_hash(t->d.s->s_file, t->d.s->s_line, t);
354: break;
355:
356: case t_unionof:
357: enter_hash(t->d.u->u_file, t->d.u->u_line, t);
358: }
359:
360: tt = talloc(ttnode);
361: *n = tt;
362: tt->tt_type = t;
363: tt->tt_left = NULL;
364: tt->tt_right = NULL;
365: t->t_index = new_type_index++;
366: return t;
367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.