|
|
1.1 ! root 1: #include <a.out.h> ! 2: #include "symtab.pri" ! 3: #include "dtype.pri" ! 4: #include "symbol.h" ! 5: #include "stab.h" ! 6: #include "core.pub" ! 7: SRCFILE("bsdsymtab.c") ! 8: ! 9: char *strchr(char *, int); ! 10: char *memset(char *, int, int); ! 11: char *memcpy(char *, char *, int); ! 12: int nccdemangle(char **, char *); ! 13: void SymbolStats(); ! 14: ! 15: BsdSymTab::BsdSymTab(Core* c, int fd, SymTab *i, long r):(c, fd, i, r) ! 16: { ! 17: hdr = new exec; ! 18: bsdshare = 0; ! 19: } ! 20: ! 21: BsdSymTab::~BsdSymTab() ! 22: { ! 23: delete hdr; ! 24: if (bsdshare) ! 25: delete bsdshare; ! 26: } ! 27: ! 28: char *BsdSymTab::gethdr() ! 29: { ! 30: if( lseek( fd, 0L, 0 ) == -1 || !ReadOK(fd, (char*)hdr, sizeof *hdr) ) ! 31: return SysErr( "symbol table: " ); ! 32: _magic = hdr->a_magic; ! 33: // if( N_BADMAG(*hdr) || hdr->a_trsize || hdr->a_drsize ) ! 34: if( N_BADMAG(*hdr) ) ! 35: return "symbol table: not executable text"; ! 36: entries = hdr->a_syms/sizeof(nlist); ! 37: return 0; ! 38: } ! 39: ! 40: int BsdSymTab::endtext() ! 41: { ! 42: exec h = *hdr; ! 43: return N_DATADDR(h); ! 44: } ! 45: ! 46: Block *BsdSymTab::gatherfunc(Func *func) ! 47: { ! 48: register struct nlist *f, *n; ! 49: register Block *ablk, *lblk; ! 50: Var *arg = 0, *lcl = 0; ! 51: register Stmt *stmt = 0; ! 52: long bfun = func->begin, size = func->size, i; ! 53: char *so = func->source()->_text; ! 54: BsdType *bsd = func->source()->bsdp; ! 55: char *subtype; ! 56: ! 57: ++FunctionGathered; ! 58: SymbolStats(); ! 59: IF_LIVE( bfun < 0 || bfun+size > entries ) return 0; ! 60: if (size == 0) ! 61: return fakeblk(); ! 62: if( !(n = f = nlistvector(bfun,size+1)) ) return 0; ! 63: IF_LIVE( n->n_type != N_FUN ) return 0; ! 64: ablk = new Block( this, 0, 0, sf("%s().arg_blk",n->n_un.n_name) ); ! 65: lblk = new Block( this, ablk, 0, sf("%s().lcl_blk",n->n_un.n_name) ); ! 66: ablk->child = lblk; ! 67: for( i = 0; i < size; ++i, ++n ){ ! 68: switch( n->n_type ){ ! 69: case N_PSYM: ! 70: gathervar( n, &arg, ablk, U_ARG, bsd ); ! 71: break; ! 72: case N_LSYM: ! 73: subtype = strchr(n->n_un.n_name, ':'); ! 74: if (!subtype || *++subtype != '(') ! 75: break; ! 76: gathervar( n, &lcl, lblk, U_AUT, bsd ); ! 77: break; ! 78: case N_STSYM: ! 79: case N_LCSYM: ! 80: subtype = strchr(n->n_un.n_name, ':'); ! 81: if (!subtype || *++subtype != 'V') ! 82: break; ! 83: n->n_value += relocation; ! 84: gathervar( n, &lcl, lblk, U_STA, bsd ); ! 85: break; ! 86: case N_RSYM: ! 87: gathervar( n, &lcl, lblk, U_REG, bsd ); ! 88: break; ! 89: case N_FUN: ! 90: case N_SLINE: ! 91: n->n_value += relocation; ! 92: if( stmt ) { ! 93: if ( n->n_desc > stmt->lineno ) ! 94: func->lines.hi = n->n_desc; ! 95: stmt->range.hi = n->n_value; ! 96: } ! 97: stmt = new Stmt(this,lblk,stmt); ! 98: if( !ablk->stmt ) ablk->stmt = stmt; ! 99: stmt->lineno = n->n_desc; ! 100: stmt->range.lo = n->n_value; ! 101: if( !ablk->range.lo ) ! 102: ablk->range.lo = n->n_value; ! 103: ablk->range.hi = n->n_value; ! 104: break; ! 105: } ! 106: } ! 107: if( stmt ) ! 108: stmt->range.hi = n->n_value + relocation; ! 109: delete f; ! 110: uncfront( ablk->var, (char *)0 ); ! 111: uncfront( lblk->var, (char *)0 ); ! 112: return ablk; ! 113: } ! 114: ! 115: void BsdSymTab::gathervar( nlist *n, Var **v, Block *b, UDisc d, BsdType *bt ) ! 116: { ! 117: IF_LIVE( !v ) return; ! 118: if( *n->n_un.n_name == ' ') ! 119: return; ! 120: char *marker = strchr( n->n_un.n_name, ':'); ! 121: if (!marker) ! 122: marker = n->n_un.n_name + strlen(n->n_un.n_name); ! 123: else if (marker[1] == ':') { //Special Ncc symbol ! 124: marker = strchr( &marker[2], ':'); ! 125: if (!marker) { ! 126: marker = n->n_un.n_name + strlen(n->n_un.n_name); ! 127: while (*++marker == 0) ! 128: ; ! 129: marker--; ! 130: } ! 131: } ! 132: *marker++ = 0; ! 133: *v = new Var( this, b, *v, d, n->n_un.n_name ); ! 134: if( b && !b->var ) b->var = *v; ! 135: (*v)->range.lo = n->n_value; ! 136: (*v)->type = bt->gettype(marker); ! 137: } ! 138: ! 139: void BsdSymTab::gathervar( nlist *n, Var **v, Block *b, UDisc d) ! 140: { ! 141: DType dt; ! 142: ! 143: IF_LIVE( !v ) return; ! 144: *v = new Var( this, b, *v, d, n->n_un.n_name ); ! 145: if( b && !b->var ) b->var = *v; ! 146: (*v)->range.lo = n->n_value; ! 147: (*v)->type = dt; ! 148: (*v)->type.pcc = n->n_desc; ! 149: } ! 150: ! 151: char *BsdSymTab::gettbl() ! 152: { ! 153: base = new nlist[entries]; ! 154: symoff = (nlist*)N_SYMOFF(*hdr); ! 155: if( lseek(fd, (long)symoff, 0) == 1 ! 156: || !ReadOK(fd, (char*)base, hdr->a_syms) ! 157: || !ReadOK(fd, (char*)&strsize, 4) ){ ! 158: delete base; base = 0; ! 159: return SysErr( "symbol table: " ); ! 160: } ! 161: strings = new char[strsize]; ! 162: if( lseek( fd, -4, 1 ) == -1 || !ReadOK(fd, strings, strsize) ){ ! 163: delete strings; strings = 0; ! 164: delete base; base = 0; ! 165: return SysErr( "strings table: " ); ! 166: } ! 167: strcpy( strings, "???" ); /* zero string index */ ! 168: return 0; ! 169: } ! 170: ! 171: Source *BsdSymTab::tree() ! 172: { ! 173: register nlist *n, *base_entries; ! 174: Source *src = 0; ! 175: Func *func = 0; ! 176: Block *fake = fakeblk(); ! 177: Var *glb = 0, *fst = 0, *resolve; ! 178: // UType *u; ! 179: register long regstrings, inafunc = 0, inasrc = 0; ! 180: long lastline, funcstart = 0, lgfound = 0; ! 181: char *equal, *subtype; ! 182: BsdType *bsd = 0; ! 183: DType *t; ! 184: ! 185: if( _warn = gettbl() ) return 0; ! 186: base_entries = base+entries; ! 187: regstrings = (long) strings; ! 188: glb = globregs(_blk, _core->nregs() ); ! 189: bsdshare = new BsdTShare; ! 190: for( n = base; n < base_entries; ++n ){ ! 191: n->n_un.n_strx += (long) regstrings; ! 192: if( inasrc && n->n_un.n_name && (equal = strchr(n->n_un.n_name, '='))) ! 193: bsd->parsetype(equal, n->n_un.n_name); ! 194: switch( n->n_type ){ ! 195: case N_ABS|N_EXT: ! 196: if( n->n_un.n_name[0] != '_' ) break; /* ? */ ! 197: case N_BSS|N_EXT: ! 198: case N_DATA|N_EXT: ! 199: if( *n->n_un.n_name == '_' ) ++n->n_un.n_name; ! 200: nccdemangle(&n->n_un.n_name, (char *)0); ! 201: resolve = (Var*)idtosym(U_GLB, n->n_un.n_name, 0); ! 202: n->n_value += relocation; ! 203: if( resolve ){ ! 204: if( !resolve->range.lo ) ! 205: resolve->range.lo = n->n_value; ! 206: } else { ! 207: n->n_desc = LONG; ! 208: gathervar( n, &glb, _blk, U_GLB ); ! 209: break; ! 210: } ! 211: break; ! 212: case N_GSYM: ! 213: if( !inasrc ) break; ! 214: subtype = strchr(n->n_un.n_name, ':'); ! 215: if (!subtype) ! 216: break; ! 217: *subtype = 0; ! 218: nccdemangle(&n->n_un.n_name, (char *)0); ! 219: if( !idtosym(U_GLB, n->n_un.n_name, 0) ) ! 220: gathervar( n, &glb, _blk, U_GLB, bsd ); ! 221: break; ! 222: case N_LCSYM: ! 223: case N_STSYM: ! 224: if( !inasrc || !src || !src->blk ) break; ! 225: subtype = strchr(n->n_un.n_name, ':') + 1; ! 226: if (*subtype != 'S') ! 227: break; ! 228: n->n_value += relocation; ! 229: gathervar( n, &fst, src->blk, U_FST, bsd ); ! 230: break; ! 231: case N_SLINE: ! 232: lastline = n->n_desc; ! 233: if (funcstart) { ! 234: funcstart = 0; ! 235: func->lines.lo = lastline; ! 236: } ! 237: break; ! 238: case N_BINCL: // Include files for type indexing ! 239: bsd->addinclude(n->n_un.n_name, 1); ! 240: break; ! 241: case N_EXCL: ! 242: bsd->addinclude(n->n_un.n_name, 0); ! 243: break; ! 244: case N_SO: ! 245: if (inafunc) { ! 246: inafunc = 0; ! 247: func->lines.hi = lastline; ! 248: func->size = n-base - func->begin; ! 249: } ! 250: // Directory entry in 4.0? ! 251: if (n->n_un.n_name[strlen(n->n_un.n_name)-1] == '/') { ! 252: inasrc = 0; ! 253: break; ! 254: } ! 255: if (!strcmp(n->n_un.n_name, "libg.s")) { ! 256: lgfound = 1; ! 257: inasrc = 0; ! 258: break; ! 259: } ! 260: inasrc = 1; ! 261: src = new Source(this,src,n->n_un.n_name,0); ! 262: bsd = src->bsdp = new BsdType(src, bsdshare); ! 263: func = 0; ! 264: inafunc = 0; ! 265: fst = 0; ! 266: n += 12; // Through away type info ! 267: break; ! 268: case N_TEXT|N_EXT: ! 269: if( *n->n_un.n_name == '_' ) ++n->n_un.n_name; ! 270: nccdemangle(&n->n_un.n_name, (char *)0); ! 271: if( idtosym(U_FUNC, n->n_un.n_name, 0) ) break; ! 272: func = new Func(this,0,0,0,n->n_un.n_name); ! 273: func->range.lo = n->n_value + relocation; ! 274: func->_blk = fake; ! 275: t = new DType; ! 276: t->pcc = LONG; ! 277: func->type = t->incref(); ! 278: func->type.pcc = FTN; ! 279: break; ! 280: case N_FUN: ! 281: if (inafunc) { ! 282: inafunc = 0; ! 283: func->lines.hi = lastline; ! 284: func->size = n-base - func->begin; ! 285: } ! 286: if( !inasrc || !src ) break; ! 287: inafunc = 1; ! 288: ++FunctionStubs; ! 289: subtype = strchr(n->n_un.n_name, ':'); ! 290: *subtype++ = 0; ! 291: nccdemangle(&n->n_un.n_name, (char *)0); ! 292: func = new Func(this,src,func,n-base,n->n_un.n_name); ! 293: if( !src->child ) src->child = src->linefunc = func; ! 294: funcstart = 1; ! 295: func->range.lo = n->n_value + relocation; ! 296: t = new DType; ! 297: *t = bsd->gettype(subtype); ! 298: func->type = t->incref(); ! 299: func->type.pcc = FTN; ! 300: break; ! 301: } ! 302: } ! 303: while( src && src->lsib ) src = (Source*) src->lsib; ! 304: if( base ) { delete base; base = 0; } ! 305: if (!lgfound) ! 306: _warn = "should be linked with ld -g"; ! 307: return src; ! 308: } ! 309: ! 310: Var *BsdSymTab::gatherutype(UType *u) ! 311: { ! 312: Var *first = 0, *v = 0; ! 313: char *memname, *cp; ! 314: int file, offset; ! 315: int bitsize, bitoffset; ! 316: int isenum = (u->type.pcc == ENUMTY); ! 317: ! 318: memname = u->encode; ! 319: if (!memname) ! 320: return first; ! 321: ++UTypeGathered; ! 322: SymbolStats(); ! 323: while (*memname != ';') { ! 324: cp = strchr(memname, ':'); ! 325: *cp++ = 0; ! 326: if (isenum) { ! 327: v = new Var( this, 0, v, U_MOT, memname ); ! 328: v->range.lo = u->bsdp->toint(cp); ! 329: v->type.pcc = MOETY; ! 330: if( !first ) first = v; ! 331: memname = strchr(cp, ',') + 1; ! 332: continue; ! 333: } ! 334: u->bsdp->toindices(cp, file, offset); ! 335: cp = strchr(cp, ')') + 2; ! 336: bitoffset = u->bsdp->toint(cp); ! 337: cp = strchr(cp, ',') + 1; ! 338: bitsize = u->bsdp->toint(cp); ! 339: v = new Var( this, 0, v, U_MOT, memname ); ! 340: v->type = u->bsdp->gettype(file, offset); ! 341: if ((bitsize & 0x7) || (bitoffset & 0x7)) { ! 342: v->range.lo = ((bitoffset >> 5) << 5) + ! 343: 32 - bitsize - (bitoffset & 0x1f); ! 344: v->type.pcc = UBITS; ! 345: v->type.dim = bitsize; ! 346: } else ! 347: v->range.lo = bitoffset >> 3; ! 348: if( !first ) first = v; ! 349: memname = strchr(cp, ';') + 1; ! 350: } ! 351: uncfront(first, u->_text); ! 352: return first; ! 353: } ! 354: ! 355: nlist *BsdSymTab::nlistvector(long start, long size ) ! 356: { ! 357: struct nlist *n; ! 358: int i; ! 359: ! 360: lseek(fd, (long) (symoff + start), 0); ! 361: n = new nlist[size]; ! 362: IF_LIVE( !ReadOK(fd, (char*) n, size * sizeof *n) ){ ! 363: delete n; ! 364: return 0; ! 365: } ! 366: for( i = 0; i < size; ++i ) ! 367: n[i].n_un.n_strx += (long) strings; ! 368: return n; ! 369: } ! 370: ! 371: BsdTShare::BsdTShare() ! 372: { ! 373: } ! 374: ! 375: BsdTShare::~BsdTShare() ! 376: { ! 377: for(BsdTFile *f = file; f < &file[used]; f++) { ! 378: for (int i = 0; i < f->ntypes; i++) ! 379: delete f->type[i]; ! 380: delete f->type; ! 381: } ! 382: delete file; ! 383: } ! 384: ! 385: int BsdTShare::addfile(char *fname, int flag) ! 386: { ! 387: BsdTFile *f; ! 388: int i; ! 389: ! 390: if (used == nfiles) { // Grow the number of files ! 391: nfiles += 10; ! 392: f = new BsdTFile[nfiles]; ! 393: for (i = 0; i < used; i++) ! 394: f[i] = file[i]; ! 395: delete file; ! 396: file = f; ! 397: } ! 398: f = &file[used]; ! 399: f->fname = fname; // Initialize ! 400: f->ntypes = 20; ! 401: f->type = new DTypep[20]; ! 402: if (flag) { // add builtins ! 403: static int typeindex[] = { ! 404: 0, INT, CHAR, LONG, SHORT, UCHAR, USHORT, ! 405: ULONG, UNSIGNED, FLOAT, DOUBLE, INT, UNDEF ! 406: }; ! 407: for(i = 1; i < sizeof(typeindex)/sizeof(int); i++) { ! 408: f->type[i] = new DType; ! 409: f->type[i]->pcc = typeindex[i]; ! 410: } ! 411: } ! 412: return used++; ! 413: } ! 414: ! 415: int BsdTShare::findfile(char *fname) ! 416: { ! 417: for(BsdTFile *f = &file[used-1]; f >= file; f--) ! 418: if (!strcmp(f->fname, fname)) ! 419: return f - file; ! 420: return -1; ! 421: } ! 422: ! 423: DType *BsdTShare::findtype(int fnum, int offset) ! 424: { ! 425: if (offset >= file[fnum].ntypes) ! 426: return 0; ! 427: return file[fnum].type[offset]; ! 428: } ! 429: ! 430: char *BsdTShare::filename(int fnum) ! 431: { ! 432: return file[fnum].fname; ! 433: } ! 434: ! 435: void BsdTShare::entertype(int fnum, int offset, DTypep dp) ! 436: { ! 437: BsdTFile *f = &file[fnum]; ! 438: if (offset >= f->ntypes) { ! 439: int n = offset + 5; // Room to spare ! 440: DTypepar nda = new DTypep[n]; ! 441: for(int i = 0; i < f->ntypes; i++) ! 442: nda[i] = f->type[i]; ! 443: delete f->type; ! 444: f->type = nda; ! 445: f->ntypes = n; ! 446: } ! 447: f->type[offset] = dp; ! 448: } ! 449: ! 450: BsdType::BsdType(Source *sp, BsdTShare *sh) ! 451: { ! 452: share = sh; ! 453: src = sp; ! 454: utypeindex = 0; ! 455: nfiles = 10; ! 456: filemap = new int[nfiles]; ! 457: filemap[0] = share->addfile(src->text(), 1); ! 458: used = 1; ! 459: } ! 460: ! 461: BsdType::~BsdType() ! 462: { ! 463: delete filemap; ! 464: } ! 465: ! 466: void BsdType::addinclude(char *fname, int flg) ! 467: { ! 468: if (used == nfiles) { // More mapping space needed ! 469: nfiles += 10; ! 470: int *map = new int[nfiles]; ! 471: for(int i = 0; i < used; i++) ! 472: map[i] = filemap[i]; ! 473: delete filemap; ! 474: filemap = map; ! 475: } ! 476: if (flg) ! 477: filemap[used] = share->addfile(fname); ! 478: else ! 479: filemap[used] = share->findfile(fname); ! 480: used++; ! 481: } ! 482: ! 483: /* ! 484: * Parse the yucky '=' symbol table information ! 485: * Possiblities: ! 486: * (a,b)=(x,y) usually typedefs ! 487: * (a,b)=*(x,y) pointers ! 488: * (a,b)=f(x,y) functions ! 489: * (a,b)=ar(0,1);lo;hi;(x,y) arrays ! 490: * (a,b)=r(x,y);lo;hi; range - who cares! ! 491: * (a,b)=eN:size,...; enum encoding ! 492: * (a,b)=sSN:(x,y),off,size;...;; structure encoding ! 493: * (a,b)=uSN:(x,y),off,size;...;; union encoding ! 494: * (a,b)=x{esu}name: ptr to undefined utype ! 495: */ ! 496: void BsdType::parsetype(char *equalptr, char *name) ! 497: { ! 498: int file, offset; ! 499: int pfile, poffset; ! 500: struct DType *dp, *dp1; ! 501: int ssize; ! 502: char stype; ! 503: char sname[100], *utypename; ! 504: ! 505: char *nextequal = strchr(equalptr+1, '='); ! 506: if (nextequal) ! 507: parsetype (nextequal, name); ! 508: register char *tp = equalptr; ! 509: while (*--tp != '(') ! 510: ; ! 511: toindices(tp, file, offset); ! 512: register char *cp = equalptr + 1; ! 513: switch ( *cp ) { ! 514: case '(': ! 515: toindices(cp, pfile, poffset); ! 516: dp1 = share->findtype(pfile,poffset); ! 517: dp = new DType; ! 518: dp->pcc = dp1->pcc; ! 519: dp->dim = dp1->dim; ! 520: dp->univ = dp1->univ; ! 521: share->entertype(file, offset, dp); ! 522: cp = strchr(cp, ')') + 1; ! 523: break; ! 524: case '*': ! 525: toindices(++cp, pfile, poffset); ! 526: cp = strchr(cp, ')') + 1; ! 527: dp = new DType; ! 528: dp->univ = share->findtype(pfile,poffset); ! 529: if (!dp->univ) ! 530: dp->over = (pfile << 16) | poffset; ! 531: dp->pcc = PTR; ! 532: share->entertype(file, offset, dp); ! 533: break; ! 534: case 'f': ! 535: toindices(++cp, pfile, poffset); ! 536: cp = strchr(cp, ')') + 1; ! 537: dp = new DType; ! 538: dp->univ = share->findtype(pfile,poffset); ! 539: if (!dp->univ) ! 540: dp->over = (pfile << 16) | poffset; ! 541: dp->pcc = FTN; ! 542: share->entertype(file, offset, dp); ! 543: break; ! 544: case 'a': ! 545: cp = strchr(cp, ';') + 1; ! 546: cp = strchr(cp, ';') + 1; ! 547: dp = new DType; ! 548: dp->dim = toint(cp) + 1; ! 549: dp->pcc = ARY; ! 550: cp = strchr(cp, ';') + 1; ! 551: toindices(cp, pfile, poffset); ! 552: cp = strchr(cp, ')') + 1; ! 553: dp->univ = share->findtype(pfile,poffset); ! 554: if (!dp->univ) ! 555: dp->over = (pfile << 16) | poffset; ! 556: share->entertype(file, offset, dp); ! 557: break; ! 558: case 'r': ! 559: cp = strchr(cp, ';') + 1; ! 560: cp = strchr(cp, ';') + 1; ! 561: cp = strchr(cp, ';') + 1; ! 562: break; ! 563: case 'x': ! 564: stype = *++cp; ! 565: ssize = 0; ! 566: cp++; ! 567: for(char *to = utypename = sname; *cp != ':'; ) ! 568: *to++ = *cp++; ! 569: *to = 0; ! 570: cp++; ! 571: goto xentry; ! 572: case 's': ! 573: case 'u': ! 574: case 'e': ! 575: if (*--tp == 'T' || *tp == 't') { ! 576: *strchr(name, ':') = 0; ! 577: utypename = name; ! 578: } else { ! 579: sprintf(sname, "%s.%d", ! 580: basename(share->filename(file)), ! 581: offset); ! 582: utypename = sname; ! 583: } ! 584: stype = *cp++; ! 585: ssize = toint(cp); ! 586: if (stype == 'e') ! 587: ssize = 1; ! 588: xentry: ! 589: UType *u = (UType*) src->symtab->idtosym( ! 590: U_UTYPE, utypename, 0); ! 591: if( u ){ ! 592: if( u->range.lo < ssize ){ ! 593: if( u->encode ) ! 594: delete u->encode; ! 595: u->encode = toutypestr(cp, stype); ! 596: u->range.lo = ssize; ! 597: u->bsdp = this; ! 598: } else if (ssize) ! 599: delete toutypestr(cp, stype); ! 600: } else { ! 601: ++UTypeStubs; ! 602: if (utypename == sname) ! 603: utypename = sf("%s", sname); ! 604: u = new UType(src->symtab, ! 605: ssize ? toutypestr(cp, stype) : (char *)0, ! 606: utypename, this); ! 607: u->range.lo = ssize; ! 608: switch(stype) { ! 609: case 'e': ! 610: u->type.pcc = ENUMTY; ! 611: break; ! 612: case 's': ! 613: u->type.pcc = STRTY; ! 614: break; ! 615: case 'u': ! 616: u->type.pcc = UNIONTY; ! 617: break; ! 618: } ! 619: u->type.univ = u; ! 620: u->rsib = src->symtab->utype; ! 621: src->symtab->utype = u; ! 622: } ! 623: if (!share->findtype(file, offset)) { ! 624: dp = new DType; ! 625: dp->univ = u; ! 626: dp->pcc = u->type.pcc; ! 627: share->entertype(file, offset, dp); ! 628: } ! 629: break; ! 630: default: ! 631: break; ! 632: } ! 633: memset(equalptr, ' ', cp - equalptr); ! 634: } ! 635: ! 636: DType BsdType::gettype(char *string) ! 637: { ! 638: int file, offset; ! 639: string = strchr(string, '('); ! 640: toindices(string, file, offset); ! 641: return gettype(file, offset); ! 642: } ! 643: ! 644: DType BsdType::gettype(int fnum, int offset) ! 645: { ! 646: return chain(share->findtype(fnum, offset)); ! 647: } ! 648: ! 649: DType BsdType::chain(DType *dp) ! 650: { ! 651: DType d; ! 652: ! 653: if (!dp) { // Shouldn't happen - fix this if ever figure ! 654: d.pcc = INT; // out how the include file references are ! 655: return d; // shared. I give up .... ! 656: } ! 657: d.pcc = dp->pcc; ! 658: d.dim = dp->dim; ! 659: d.univ = dp->univ; ! 660: if( d.pcc & TMASK ){ ! 661: if (!dp->univ) ! 662: dp->univ = share->findtype(dp->over>>16, ! 663: dp->over&0xffff); ! 664: d.univ = new DType; ! 665: *(d.ref()) = chain(dp->ref()); ! 666: } ! 667: return d; ! 668: } ! 669: ! 670: void BsdType::toindices(char *cp, int &fnum, int &offset) ! 671: { ! 672: while (*cp++ != '(') ! 673: ; ! 674: fnum = filemap[toint(cp)]; ! 675: while (*cp++ != ',') ! 676: ; ! 677: offset = toint(cp); ! 678: } ! 679: ! 680: int BsdType::toint(char *cp) ! 681: { ! 682: int cnt = 0; ! 683: int sign = 1; ! 684: ! 685: if (*cp == '-') { ! 686: sign = -1; ! 687: cp++; ! 688: } ! 689: while (*cp >= '0' && *cp <= '9') ! 690: cnt = cnt * 10 + *cp++ - '0'; ! 691: return cnt * sign; ! 692: } ! 693: ! 694: char *BsdType::toutypestr(char *cp, int c) ! 695: { ! 696: char *bp; ! 697: int size; ! 698: char *cstart; ! 699: register char *to, *from; ! 700: ! 701: if (c == 'e') { ! 702: cstart = cp; ! 703: for(size = 0; ; cp++) { ! 704: if (*cp == '\\') { ! 705: *cp++ = ' '; ! 706: *cp = ' '; ! 707: } ! 708: if (*cp != ' ') ! 709: size++; ! 710: if (*cp == ';') /* Enum delimiter */ ! 711: break; ! 712: } ! 713: } else { ! 714: while (*cp >= '0' && *cp <= '9') ! 715: *cp++ = ' '; ! 716: cstart = cp; ! 717: for(size = 0; ; cp++) { ! 718: if (*cp == '\\') { ! 719: *cp++ = ' '; ! 720: *cp = ' '; ! 721: char *nextequal = strchr(cp+1, '='); ! 722: if (nextequal) ! 723: parsetype (nextequal, nextequal); ! 724: } ! 725: if (*cp != ' ') ! 726: size++; ! 727: if (*cp == ';' && *(cp-1) == ';') ! 728: break; ! 729: } ! 730: } ! 731: to = bp = new char[size + 1]; ! 732: from = cstart; ! 733: for (register i = size; size--; ) { ! 734: while (*from == ' ') ! 735: from++; ! 736: *to++ = *from; ! 737: *from++ = ' '; ! 738: } ! 739: *to = 0; ! 740: return bp; ! 741: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.