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

199 lines
3.1 KiB
C

//
// revtree.c
//
// two routines for printing out ascii reverse 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 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;
}