199 lines
3.1 KiB
C
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;
|
||
|
}
|