windows-nt/Source/XPSP1/NT/sdktools/mep/browser/bsc/calltree.c
2020-09-26 16:20:57 +08:00

214 lines
3.3 KiB
C

//
// calltree.c
//
// two routines for printing out ascii call tree's
//
#include <stdio.h>
#include <string.h>
#if defined(OS2)
#define INCL_NOCOMMON
#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#define INCL_DOSFILEMGR
#define INCL_DOSERRORS
#define INCL_DOSMISC
#include <os2.h>
#else
#include <windows.h>
#endif
#include <dos.h>
#include "hungary.h"
#include "bsc.h"
#include "bscsup.h"
// forward declarations
static BOOL FUsedInst(IINST iinst);
static VOID dCallTree(IINST iinst, WORD cuse);
// static variables
static BYTE *UseBits = NULL;
static WORD cNest = 0;
VOID BSC_API
CallTreeInst (IINST iinst)
// emit the call tree starting from the given inst
//
{
WORD iinstMac;
int igrp;
iinstMac = IinstMac();
// allocate memory for bit array
UseBits = LpvAllocCb((WORD)(iinstMac/8 + 1));
// no memory -- no call tree
if (!UseBits) return;
igrp = iinstMac/8+1;
while (--igrp>=0)
UseBits[igrp] = 0;
cNest = 0;
dCallTree(iinst, 1);
FreeLpv(UseBits);
}
static VOID
dCallTree (IINST iinst, WORD cuse)
// emit the call tree starting from the given inst
//
// there are many block variables to keep the stack to a minimum...
{
{
ISYM isym;
{
TYP typ;
ATR atr;
InstInfo(iinst, &isym, &typ, &atr);
if (typ > INST_TYP_LABEL)
return;
}
{
WORD i;
cNest++;
for (i = cNest; i; i--) BSCPrintf ("| ");
}
if (cuse > 1)
BSCPrintf ("%s[%d]", LszNameFrSym (isym), cuse);
else
BSCPrintf ("%s", LszNameFrSym (isym));
}
{
IDEF idef, idefMac;
LSZ lsz;
WORD w;
DefRangeOfInst(iinst, &idef, &idefMac);
DefInfo(idef, &lsz, &w);
if (strcmp("<Unknown>", lsz) == 0) {
BSCPrintf ("?\n");
cNest--;
return;
}
}
if (FUsedInst(iinst)) {
BSCPrintf ("...\n");
cNest--;
return;
}
BSCPrintf ("\n");
{
IUSE iuse, iuseMac;
IINST iinstUse;
UseRangeOfInst(iinst, &iuse, &iuseMac);
for (; iuse < iuseMac; iuse++) {
UseInfo(iuse, &iinstUse, &cuse);
dCallTree (iinstUse, cuse);
}
}
cNest--;
}
BOOL BSC_API
FCallTreeLsz(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
UseBits = LpvAllocCb((WORD)(iinstMac/8 + 1));
// no memory -- no call tree
if (!UseBits) return FALSE;
igrp = iinstMac/8+1;
while (--igrp >= 0)
UseBits[igrp] = 0;
}
if ((imod = ImodFrLsz (lszName)) != imodNil) {
IMS ims, imsMac;
MsRangeOfMod(imod, &ims, &imsMac);
BSCPrintf ("%s\n", LszNameFrMod (imod));
for ( ; ims < imsMac ; ims++)
dCallTree (IinstOfIms(ims), 1);
FreeLpv(UseBits);
return TRUE;
}
if ((isym = IsymFrLsz (lszName)) != isymNil) {
IINST iinst, iinstMac;
BSCPrintf ("%s\n", LszNameFrSym (isym));
InstRangeOfSym(isym, &iinst, &iinstMac);
for (; iinst < iinstMac; iinst++)
dCallTree (iinst, 1);
FreeLpv(UseBits);
return TRUE;
}
FreeLpv(UseBits);
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 = !!(UseBits[igrp] & mask);
UseBits[igrp] |= mask;
return fOut;
}