|
|
1.1 root 1: #include <stdio.h>
2: #include "ts.h"
3:
4: #define HSIZE 307
5: #define ALSIZE 2040
6:
7: static struct obj **objhash, *cobj = 0, *lastobj;
8: static struct ref **refhash;
9: static struct group **grouphash, *group0;
10: struct ref *undefrefs = 0, *defedrefs = 0;
11: struct group *cgroup = 0; /* current group */
12: struct obj *obj0 = 0; /* special null object */
13:
14: unsigned lasthash = 0, ngroup = 0, nrefc = 0;
15: int nextseq;
16:
17: char *malloc(), *strcpy();
18: extern char *progname;
19: extern int cyclep, verbose, verify;
20:
21: init(){
22: int i;
23:
24: objhash = (struct obj **) malloc(HSIZE*sizeof(struct obj *));
25: refhash = (struct ref **) malloc(HSIZE*sizeof(struct ref *));
26: grouphash = (struct group **) malloc(HSIZE*sizeof(struct group *));
27: if (!objhash || !refhash || !grouphash)
28: scream("initial mallocs fail\n","");
29: for (i = 0; i < HSIZE; i++)
30: { objhash[i] = 0; refhash[i] = 0; grouphash[i] = 0;}
31: cgroup = 0;
32: newgroup("");
33: group0 = cgroup;
34: newobj("",1);
35: obj0 = cobj;
36: }
37:
38: unsigned
39: hash(s)
40: unsigned char *s;
41: {
42: unsigned x = 0;
43: unsigned char c;
44:
45: while(c = *s++) x = (x<<1) + c;
46: return x % HSIZE;
47: }
48:
49: char *
50: newstruct(n)
51: unsigned n;
52: {
53: static char *next = 0, *last = 0;
54: char *s;
55:
56: if (next + n > last) {
57: next = malloc(ALSIZE);
58: if (!next) scream("malloc fails in newstruct\n","");
59: last = next + ALSIZE;
60: }
61: s = next;
62: next += n;
63: return s;
64: }
65:
66: char *
67: newstring(s)
68: char *s;
69: {
70: static char *next = 0, *last = 0;
71: char *s1;
72: unsigned n, strlen();
73:
74: n = strlen(s) + 1;
75: if (next + n > last) {
76: next = malloc(ALSIZE);
77: if (!next) scream("malloc fails in newstring\n","");
78: last = next + ALSIZE;
79: }
80: s1 = next;
81: next += n;
82: strcpy(s1,s);
83: return s1;
84: }
85:
86: newgroup(s)
87: char *s;
88: {
89: struct group *g, *gnext = 0, *gprev;
90:
91: cobj = 0;
92: gprev = (struct group *) &grouphash[hash(s)];
93: g = gprev->next;
94: for(;; gprev = g, g = g->next) {
95: if (!g) {
96: g = (struct group *)
97: newstruct(sizeof(struct group));
98: g->name = newstring(s);
99: g->next = 0;
100: g->gseq = ngroup++;
101: gprev->next = g;
102: break;
103: }
104: if (!strcmp(s,g->name)) break;
105: }
106: cgroup = g;
107: }
108:
109: struct ref *
110: lookup(s,add)
111: char *s;
112: int add;
113: {
114: struct ref *h, *hprev;
115:
116: hprev = (struct ref *) &refhash[lasthash = hash(s)];
117: h = hprev->next;
118: while(h) {
119: if (!strcmp(h->name,s)) return h;
120: hprev = h;
121: h = h->next;
122: }
123: if (add) {
124: h = (struct ref *) newstruct(sizeof(struct ref));
125: hprev->next = h;
126: h->next = 0;
127: h->name = cobj && !strcmp(cobj->name,s) ? cobj->name : newstring(s);
128: h->robj = 0;
129: }
130: return h;
131: }
132:
133: newobj(s,dup)
134: char *s;
135: int dup;
136: {
137: struct obj *h, *hnext = 0, *hprev, *o;
138: struct ref *r1;
139:
140: hprev = (struct obj *) &objhash[hash(s)];
141: h = hprev->next;
142: while(h) {
143: if (!strcmp(h->name,s) && h->ogroup == cgroup) {
144: if (dup || h == obj0) { cobj = h; return; }
145: if (verbose) {
146: fprintf(stderr, "duplicate %s", s);
147: if (*cgroup->name) fprintf(stderr, " in %s", cgroup->name);
148: fputs(" ignored\n", stderr);
149: }
150: cobj = 0;
151: return;
152: }
153: hprev = h;
154: h = h->next;
155: }
156: cobj = o = (struct obj *) newstruct(sizeof(struct obj));
157: hprev->next = o;
158: o->next = hnext;
159: r1 = lookup(s,0);
160: o->name = r1 ? r1->name : newstring(s);
161: o->ogroup = cgroup;
162: o->seq = o->iptr = o->jct = 0;
163: }
164:
165: defobjref(s,dup)
166: char *s;
167: int dup;
168: {
169: rdefobjref(lookup(s,1), s, dup);
170: }
171:
172: rdefobjref(r,s,dup)
173: struct ref *r;
174: char *s;
175: int dup;
176: {
177: struct obj *o;
178:
179: if (o = r->robj) {
180: newobj(s,dup);
181: if (!dup || o->ogroup != cgroup) dupmsg(0,r,s);
182: }
183: else {
184: r->robj = cobj = o = (struct obj *) newstruct(sizeof(struct obj));
185: o->next = objhash[lasthash];
186: objhash[lasthash] = o;
187: o->name = r->name;
188: o->ogroup = cgroup;
189: o->seq = o->iptr = o->jct = 0;
190: }
191: }
192:
193: dupmsg(oprt,r,s)
194: int oprt;
195: struct ref *r;
196: char *s;
197: {
198: struct obj *o = r->robj;
199: char *in;
200:
201: if (verbose && o != obj0) {
202: fprintf(stderr, "def of %s", s);
203: if (oprt && strcmp(s,cobj->name)) {
204: fprintf(stderr, " in %s", cobj->name);
205: in = "of";
206: }
207: else in = "in";
208: if (*cgroup->name) fprintf(stderr, " %s lib %s", in, cgroup->name);
209: else in = "of";
210: fprintf(stderr, " ignored; first defined in %s", o->name);
211: if (*(s = o->ogroup->name)) fprintf(stderr, " of lib %s", s);
212: putc('\n', stderr);
213: }
214: }
215:
216:
217: newref(s)
218: char *s;
219: { newrefr(lookup(s,1)); }
220:
221: newrefr(r)
222: struct ref *r;
223: {
224: struct refc rc;
225: struct obj *o1;
226: unsigned i;
227:
228: if (!cobj) return;
229: if (verify && r->robj && cobj != obj0) {
230: fputs(cobj->name, stderr);
231: if (cgroup != group0) fprintf(stderr, " of %s", cgroup->name);
232: fprintf(stderr, " needs %s\n", r->name);
233: }
234: rc.rcnext = cobj->iptr;
235: rc.rcref = r;
236: o1 = rc.rcref->robj;
237: if (o1 != cobj && o1 != obj0) { /* discard self references */
238: /* and refs to null object */
239: i = cobj->iptr = ++nrefc;
240: refstore(i, &rc);
241: }
242: }
243:
244: defref(s)
245: char *s;
246: { defrefr(lookup(s,1), s); }
247:
248: defrefr(r,s)
249: struct ref *r;
250: char *s;
251: {
252: if (!cobj) return;
253: if (r->robj) dupmsg(1,r,s);
254: else r->robj = cobj;
255: }
256:
257: struct obj *
258: ts0()
259: {
260: int i;
261: struct obj *firstobj, *o, *onext;
262: struct ref *r, *rnext;
263:
264: /* chain objects together */
265:
266: firstobj = 0;
267: for (i = 0; i < HSIZE; i++) {
268: for(o = objhash[i]; o; o = onext) {
269: onext = o->next;
270: o->next = firstobj;
271: firstobj = o;
272: }
273: }
274:
275: /* chain undefined refs together */
276:
277: defedrefs = undefrefs = 0;
278: for (i = 0; i < HSIZE; i++) {
279: for (r = refhash[i]; r; r = rnext) {
280: rnext = r->next;
281: if (!r->robj) { r->next = undefrefs; undefrefs = r; }
282: else { r->next = defedrefs; defedrefs = r; }
283: }
284: }
285:
286: free((char *) grouphash);
287: free((char *) refhash);
288: free((char *) objhash);
289: return firstobj;
290: }
291:
292: struct obj *
293: ts(all)
294: {
295: int i, i0, k;
296: unsigned j;
297: struct obj *firstobj, *o, *o1, *onext, *oprev, **ready, **rs;
298: struct refc rc;
299:
300: firstobj = ts0();
301:
302: /* do depth-first search (to break cycles) */
303:
304: nextseq = 1;
305: for (o = firstobj; o; o = o->next)
306: if (!o->seq && (all || o->ogroup == group0)) dfs(1,o);
307:
308: /* discard unreached objects */
309:
310: if (!all) {
311: oprev = (struct obj *) &firstobj;
312: for (o = firstobj; o; o = o->next)
313: if (o->seq) { oprev->next = o; oprev = o; }
314: oprev->next = 0;
315: }
316:
317: /* set up for funny breadth-first search */
318:
319: ready = (struct obj **) malloc(ngroup * sizeof(struct obj *));
320: if (!ready) scream("malloc of ready list fails\n","");
321:
322: obj0->jct = 0; /* force initial inclusion of obj0 */
323: for (i = 0; i < ngroup; i++) ready[i] = 0;
324: for (o = firstobj; o; o = onext) {
325: onext = o->next;
326: if (!o->jct) {
327: rs = ready + o->ogroup->gseq;
328: o->next = *rs;
329: *rs = o;
330: }
331: }
332: firstobj = lastobj = 0;
333: i = i0 = 0;
334: for(;;) {
335: if (!(o = ready[i])) {
336: i = i0;
337: while(!(o = ready[i]))
338: if (++i >= ngroup) {
339: if (lastobj) lastobj->next = 0;
340: return firstobj;
341: }
342: i0 = i;
343: }
344: ready[i] = o->next;
345: if (!lastobj) firstobj = o;
346: else lastobj->next = o;
347: lastobj = o;
348: for (j = o->iptr; j; ) {
349: reffetch(j, &rc);
350: j = rc.rcnext;
351: if (j >= nrefc) { j -= nrefc; continue; }
352: o1 = rc.rcref->robj;
353: if (!o1) continue;
354: if (!--o1->jct) {
355: k = o1->ogroup->gseq;
356: o1->next = ready[k];
357: ready[k] = o1;
358: if (i0 > k) i0 = k;
359: }
360: }
361: }
362: }
363:
364: dfs(level, o)
365: int level;
366: struct obj *o;
367: {
368: struct refc rc;
369: struct obj *o1;
370: int level0, s;
371: static int cycle = 0;
372: unsigned i, nextrc;
373:
374: o->seq = -level;
375: level0 = -(level + 1);
376: for (i = o->iptr; i; i = nextrc) {
377: reffetch(i, &rc);
378: nextrc = rc.rcnext;
379: o1 = rc.rcref->robj;
380: if (!o1 || o == o1 || o1 == obj0) continue;
381: s = o1->seq;
382: if (s >= 0) {
383: o1->jct++;
384: if (s > 0) continue; /* cross link */
385: s = dfs(level+1, o1);
386: }
387: else { /* back link */
388: if (cyclep && !cycle) {
389: fprintf(stderr, "%s: cycle...\n", progname);
390: cycle = 1;
391: }
392: rc.rcnext += nrefc;
393: refstore(i, &rc);
394: }
395: if (level0 < s) level0 = s;
396: }
397: o->seq = nextseq;
398: level = -level;
399: if (level <= level0 && cyclep) {
400: fprintf(stderr, "%s\n", o->name);
401: if (level == level0) { cycle = 0; putc('\n',stderr); }
402: else cycle = 1;
403: }
404: if (level > level0 || level == -1) { nextseq++; level0 = level; }
405: return level0;
406: }
407:
408: scream(s, s1)
409: char *s, *s1;
410: {
411: fprintf(stderr, "%s: ", progname);
412: fprintf(stderr, s, s1);
413: exit(1);
414: }
415:
416: undef(s,infile)
417: char *s;
418: FILE *infile;
419: {
420: newgroup("");
421: newobj("", 1);
422: newref(s);
423: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.