// // revtree.c // // two routines for printing out ascii reverse call tree's // #include #include #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 "hungary.h" #include "bsc.h" #include "bscsup.h" // forward declarations static BOOL FUsedInst(IINST iinst); static VOID dRevTree(IINST iinst, WORD cuby); // static variables static BYTE *UbyBits = NULL; static WORD cNest = 0; VOID BSC_API RevTreeInst (IINST iinst) // emit the call tree starting from the given inst // { WORD iinstMac; int igrp; iinstMac = IinstMac(); // allocate memory for bit array UbyBits = LpvAllocCb((WORD)(iinstMac/8 + 1)); // no memory -- no call tree if (!UbyBits) return; igrp = iinstMac/8+1; while (--igrp>=0) UbyBits[igrp] = 0; cNest = 0; dRevTree(iinst, 1); FreeLpv(UbyBits); } static VOID dRevTree (IINST iinst, WORD cuby) // emit the call tree starting from the given inst // // there are many block variables to keep the stack to a minimum... { { ISYM isym; { ATR atr; TYP typ; InstInfo(iinst, &isym, &typ, &atr); if (typ > INST_TYP_LABEL) return; } { WORD i; cNest++; for (i = cNest; i; i--) BSCPrintf ("| "); } if (cuby > 1) BSCPrintf ("%s[%d]", LszNameFrSym (isym), cuby); else BSCPrintf ("%s", LszNameFrSym (isym)); } if (FUsedInst(iinst)) { BSCPrintf ("...\n"); cNest--; return; } BSCPrintf ("\n"); { IUBY iuby, iubyMac; IINST iinstUby; UbyRangeOfInst(iinst, &iuby, &iubyMac); for (; iuby < iubyMac; iuby++) { UbyInfo(iuby, &iinstUby, &cuby); dRevTree (iinstUby, cuby); } } cNest--; } BOOL BSC_API FRevTreeLsz(LSZ lszName) // print out a call tree based on the given name // { IMOD imod; ISYM isym; cNest = 0; if (!lszName) return FALSE; { IINST iinstMac; int igrp; iinstMac = IinstMac(); // allocate memory for bit array UbyBits = LpvAllocCb((WORD)(iinstMac/8 + 1)); // no memory -- no call tree if (!UbyBits) return FALSE; igrp = iinstMac/8+1; while (--igrp >= 0) UbyBits[igrp] = 0; } if ((imod = ImodFrLsz (lszName)) != imodNil) { IMS ims, imsMac; MsRangeOfMod(imod, &ims, &imsMac); BSCPrintf ("%s\n", LszNameFrMod (imod)); for ( ; ims < imsMac ; ims++) dRevTree (IinstOfIms(ims), 1); FreeLpv(UbyBits); return TRUE; } if ((isym = IsymFrLsz (lszName)) != isymNil) { IINST iinst, iinstMac; BSCPrintf ("%s\n", LszNameFrSym (isym)); InstRangeOfSym(isym, &iinst, &iinstMac); for (; iinst < iinstMac; iinst++) dRevTree (iinst, 1); FreeLpv(UbyBits); return TRUE; } FreeLpv(UbyBits); return FALSE; } static BOOL FUsedInst(IINST iinst) // return the status bit for this iinst and set it true // { WORD igrp; BOOL fOut; WORD mask; igrp = iinst / 8; mask = (1 << (iinst % 8)); fOut = !!(UbyBits[igrp] & mask); UbyBits[igrp] |= mask; return fOut; }