/* * BSCdump - Browser Data Base (.BSC) Dumper * (C) 1988 By Microsoft * * */ #include #include #define LINT_ARGS #if defined(OS2) #define INCL_NOCOMMON #define INCL_DOSPROCESS #define INCL_DOSSEMAPHORES #define INCL_DOSFILEMGR #define INCL_DOSERRORS #define INCL_DOSMISC #include #else #include #endif #include #include "bscdump.h" #include "version.h" #include "hungary.h" #include "bsc.h" #include "bscsup.h" #include "sbrvers.h" // this is gross but I don't know where these are supposed to come from // #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #if defined (DEBUG) char fDEBUG = FALSE; #endif char *psymbol = NULL; char *OutlineFileName = NULL; char far * fname; extern char *strdup(); void DumpRefsLsz(LSZ); void DumpDefsLsz(LSZ); void ListRdds(MBF); main (argc, argv) int argc; char *argv[]; { unsigned char Cont; unsigned char fCalltree = FALSE; unsigned char fSymRefs = FALSE; unsigned char fSymDefs = FALSE; unsigned char fRevtree = FALSE; unsigned char fDumpStats = FALSE; unsigned char fRedundant = FALSE; MBF mbf = mbfNil, mbfRef = mbfNil, mbfRdd = mbfNil; char *s; --argc; ++argv; while (argc && ((**argv == '-') || (**argv == '-'))) { Cont = TRUE; while (Cont && *++*argv) switch (**argv) { case 'o': s = *argv+1; while (*s) { switch (*s) { case 'F': mbf |= mbfFuncs; break; case 'M': mbf |= mbfMacros; break; case 'V': mbf |= mbfVars; break; case 'T': mbf |= mbfTypes; break; } s++; } if (mbf == mbfNil) mbf = mbfAll; if (--argc == 0) Usage(); OutlineFileName = *++argv; Cont = FALSE; break; case 'l': s = *argv+1; while (*s) { switch (*s) { case 'F': mbfRef |= mbfFuncs; break; case 'M': mbfRef |= mbfMacros; break; case 'V': mbfRef |= mbfVars; break; case 'T': mbfRef |= mbfTypes; break; } s++; } if (mbfRef == mbfNil) mbfRef = mbfAll; Cont = FALSE; break; case 'u': s = *argv+1; while (*s) { switch (*s) { case 'F': mbfRdd |= mbfFuncs; break; case 'M': mbfRdd |= mbfMacros; break; case 'V': mbfRdd |= mbfVars; break; case 'T': mbfRdd |= mbfTypes; break; } s++; } if (mbfRdd == mbfNil) mbfRdd = mbfAll; Cont = FALSE; break; case 't': if (--argc == 0) Usage(); psymbol = *++argv; fCalltree = TRUE; Cont = FALSE; break; case 'r': if (--argc == 0) Usage(); psymbol = *++argv; fSymRefs = TRUE; Cont = FALSE; break; case 'd': if (--argc == 0) Usage(); psymbol = *++argv; fSymDefs = TRUE; Cont = FALSE; break; case 'b': if (--argc == 0) Usage(); psymbol = *++argv; fRevtree = TRUE; Cont = FALSE; break; case 's': fDumpStats = TRUE; break; default: Usage(); break; } --argc; ++argv; } if (argc < 1) { Usage(); } fname = strdup(*argv++); if (!FOpenBSC(fname)) { BSCPrintf("BSCdump: cannot open database %s\n", fname); exit(4); } if (fDumpStats) StatsBSC(); else if (fCalltree) FCallTreeLsz(psymbol); else if (fSymRefs) DumpRefsLsz(psymbol); else if (fSymDefs) DumpDefsLsz(psymbol); else if (fRevtree) FRevTreeLsz(psymbol); else if (OutlineFileName) FOutlineModuleLsz(OutlineFileName, mbf); else if (mbfRef) ListRefs(mbfRef); else if (mbfRdd) ListRdds(mbfRdd); else DumpBSC(); CloseBSC(); free (fname); } Usage() { BSCPrintf("Microsoft (R) BSCdump Utility "); BSCPrintf(VERS(rmj, rmm, rup)); BSCPrintf(CPYRIGHT); BSCPrintf("Usage: bscdump [options] file.bsc\n\n"); BSCPrintf(" -o[FVMT] outline\n"); BSCPrintf(" -l[FVMT] List References\n"); BSCPrintf(" -u[FVMT] List Redundant definitions\n"); BSCPrintf(" -t Calltree \n"); BSCPrintf(" -b Backwards Calltree \n"); BSCPrintf(" -s Emit BSC stats\n"); BSCPrintf(" -r List all references to symbol\n"); BSCPrintf(" -d List all definitions of symbol\n"); exit(1); } void DumpDefsLsz(LSZ lszSym) { ISYM isym; IINST iinst, iinstMac; IDEF idef, idefMac; LSZ lsz; WORD line; isym = IsymFrLsz(lszSym); if (isym == isymNil) { BSCPrintf("unknown symbol %s\n", lszSym); return; } InstRangeOfSym(isym, &iinst, &iinstMac); for (;iinst < iinstMac; iinst++) { DefRangeOfInst(iinst, &idef, &idefMac); for ( ; idef < idefMac; idef++) { DefInfo(idef, &lsz, &line); BSCPrintf("%s %d\n", lsz, line); } } } void DumpRefsLsz(LSZ lszSym) { ISYM isym; IINST iinst, iinstMac; IREF iref, irefMac; LSZ lsz; WORD line; isym = IsymFrLsz(lszSym); if (isym == isymNil) { BSCPrintf("unknown symbol %s\n", lszSym); return; } InstRangeOfSym(isym, &iinst, &iinstMac); for (;iinst < iinstMac; iinst++) { RefRangeOfInst(iinst, &iref, &irefMac); for ( ; iref < irefMac; iref++) { RefInfo(iref, &lsz, &line); BSCPrintf("%s %d\n", lsz, line); } } } void ListRdds(MBF mbf) { ISYM isym, isymMac, isymname; IINST iinst, iinstMac; IUBY iubyFirst, iubyLast; LSZ lszsymname; TYP iinsttyp; ATR iinstattr; isymMac = IsymMac(); for (isym = 0 ; isym < isymMac ; isym++) { lszsymname = LszNameFrSym(isym); InstRangeOfSym(isym,&iinst,&iinstMac); for ( ; iinst < iinstMac ; iinst++) { UbyRangeOfInst(iinst,&iubyFirst,&iubyLast); if (iubyFirst == iubyLast) { InstInfo(iinst,&isymname, &iinsttyp, &iinstattr); // iinstattr &= INST_TYPMASK; if (iinsttyp <= INST_TYP_LABEL && !!(mbf & mbfFuncs)) BSCPrintf("Function not called : %s\n",lszsymname); else if ((iinsttyp <= INST_TYP_VARIABLE || iinsttyp >= INST_TYP_SEGMENT ) && !!(mbf & mbfVars)) BSCPrintf("Variable not used : %s\n",lszsymname); else if (iinsttyp <= INST_TYP_MACRO && !!(mbf & mbfMacros)) BSCPrintf("Macro not referenced : %s\n",lszsymname); else if (!!(mbf & mbfTypes)) BSCPrintf("Type not referenced : %s\n",lszsymname); } } } }