|
|
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.