-- DebugImpl.Mesa
-- Last edited by Lewis on 2-Apr-81 10:14:37
-- Last edited by Levin on July 6, 1982 3:42 pm
DIRECTORY
Alloc USING [AddNotify, DropNotify, Handle, Notifier],
BcdDefs USING [
CTIndex, CTNull, CTRecord, EVIndex, EVNull, FTIndex, FTNull, FTRecord, FTSelf,
MTIndex, MTRecord, Namee, NameRecord, NTIndex, NTRecord, NullName,
PackedString, SGIndex, SGRecord, VersionID, VersionStamp],
CodePackProcs USING [ModuleIndex],
CharIO USING [
CR, NumberFormat, TAB, PutChar, PutDecimal, PutNumber, PutOctal,
PutString],
Debug,
PackagerDefs USING [
globalData, packsstype, packsttype, packmdtype, packtreetype,
packctreetype],
ProcessingOrder USING [Enumerate],
SemanticEntry USING [STIndex],
SourceBcd USING [
bcdBases, bcdHeader, bcdLimits, configTreeRoot, CTreeIndex,
NullCTreeIndex, EnumerateModules, EnumerateModulesInConfig,
EnumerateConfigs],
Strings USING [SubString, SubStringDescriptor],
SymTabDefs USING [HTIndex, HTNull],
SymTabOps USING [SubStringForHash],
Table USING [Base, Limit],
Time USING [Append, Packed, Unpack],
Tree: FROM "PackTree" USING [Index, Link, Map, NodeName, NullIndex, root],
TreeOps: FROM "PackTreeOps" USING [UpdateTree];
DebugImpl: PROGRAM
IMPORTS Alloc, CharIO, PackagerDefs, SourceBcd, SymTabOps, Time,
Tree, TreeOps, ProcessingOrder
EXPORTS Debug =
BEGIN OPEN PackagerDefs;
SubString: TYPE = Strings.SubString;
table: Alloc.Handle ← NIL;
-- Initialization and Finalization
Initialize: PUBLIC PROC =
{table ← PackagerDefs.globalData.ownTable;
table.AddNotify[UpdateBases]};
Finalize: PUBLIC PROC =
{table.DropNotify[UpdateBases];
table ← NIL};
stb, tb, mdb, ctreeb: Table.Base;
pssb: LONG POINTER TO BcdDefs.PackedString;
UpdateBases: Alloc.Notifier =
BEGIN
pssb ← base[PackagerDefs.packsstype]; -- packed string table
tb ← base[PackagerDefs.packtreetype]; -- parse tree table
stb ← base[PackagerDefs.packsttype]; -- semantic entry table
ctreeb ← base[PackagerDefs.packctreetype]; -- config tree table
mdb ← base[PackagerDefs.packmdtype]; -- code pack module table
END;
-- Utility Writes
WriteChar: PROC [c: CHARACTER] = {CharIO.PutChar[globalData.errorStream, c]};
WriteString: PROC [s: STRING] = {CharIO.PutString[globalData.errorStream, s]};
WriteSubString: PROC [ss: SubString] =
BEGIN
i: CARDINAL;
FOR i IN [ss.offset..ss.offset+ss.length)
DO WriteChar[ss.base[i]] ENDLOOP;
END;
WriteTime: PROC [t: Time.Packed] =
BEGIN
s: STRING ← [20];
Time.Append[s, Time.Unpack[t]];
WriteString[s];
END;
WriteCR: PROC = INLINE {WriteChar[CharIO.CR]};
Indent: PROC [n: CARDINAL] =
BEGIN
THROUGH [1..n/8] DO WriteChar[CharIO.TAB] ENDLOOP;
THROUGH [1..n MOD 8] DO WriteChar[' ] ENDLOOP;
END;
Tab: PROC [n: CARDINAL] = {WriteCR[]; Indent[n]};
-- Annotated printing
WriteDecimal: PROC [id: STRING, n: INTEGER] =
BEGIN
IF id # NIL THEN WriteString[id];
CharIO.PutDecimal[PackagerDefs.globalData.errorStream, n];
END;
WriteOctal: PROC [id: STRING, n: UNSPECIFIED] =
BEGIN
IF id # NIL THEN WriteString[id];
CharIO.PutOctal[PackagerDefs.globalData.errorStream, n];
END;
WriteIndex: PROC [id: STRING, index: UNSPECIFIED] =
BEGIN
IF id # NIL THEN WriteString[id];
PrintIndex[index];
END;
-- Utility Prints
PrintMachine: PROC [stamp: BcdDefs.VersionStamp] =
BEGIN
octal: CharIO.NumberFormat = [8,FALSE,FALSE,1];
CharIO.PutNumber[PackagerDefs.globalData.errorStream, stamp.net, octal];
WriteChar['#];
CharIO.PutNumber[PackagerDefs.globalData.errorStream, stamp.host, octal];
WriteChar['#];
END;
PrintFileName: PROC [fti: BcdDefs.FTIndex] =
BEGIN OPEN BcdDefs;
SELECT fti FROM
FTNull => WriteString["(null)"L];
FTSelf => WriteString["(self)"L];
ENDCASE => WriteName[SourceBcd.bcdBases.ftb[fti].name];
END;
PrintFileVersion: PROC [fti: BcdDefs.FTIndex] =
BEGIN OPEN SourceBcd.bcdBases.ftb[fti];
WriteChar['(];
IF version.time = 0 THEN WriteString ["Null Version"L]
ELSE
BEGIN
WriteTime[LOOPHOLE[version.time]];
WriteChar[' ]; PrintMachine[version];
END;
WriteChar[')];
END;
PrintIndex: PROC [index: UNSPECIFIED] =
BEGIN
WriteChar['[];
IF index = Table.Limit-1
THEN WriteString["Null"L]
ELSE CharIO.PutDecimal[PackagerDefs.globalData.errorStream, index];
WriteChar[']];
END;
WriteNameFromTable: PROC [n: BcdDefs.Namee] =
BEGIN OPEN BcdDefs;
nti: NTIndex ← FIRST[NTIndex];
UNTIL nti = SourceBcd.bcdLimits.nt DO
IF SourceBcd.bcdBases.ntb[nti].item = n THEN
BEGIN
WriteName[SourceBcd.bcdBases.ntb[nti].name]; EXIT;
END;
nti ← nti + SIZE[NTRecord];
ENDLOOP;
END;
-- ********************** Parse Tree Printing **********************
PrintTree: PUBLIC PROC =
BEGIN
WriteCR[]; WriteCR[]; WriteString["--Parse Tree--"L]; WriteCR[];
PrintSubTree[Tree.root, 0]; WriteCR[]; WriteCR[];
END;
PrintSubTree: PROC [t: Tree.Link, nBlanks: CARDINAL] =
BEGIN OPEN Tree;
Printer: Tree.Map =
BEGIN
node: Tree.Index;
Tab[nBlanks];
WITH s: t SELECT FROM
hash => WriteHTI[s.index];
symbol => WriteSymbol[s.index];
procs => WriteCodePackProcs[s.index];
subtree =>
BEGIN node ← s.index;
IF node = Tree.NullIndex
THEN WriteString["<empty>"L]
ELSE
BEGIN OPEN tb[node];
WriteNodeName[name]; PrintIndex[node];
WriteOctal[", source["L, info]; WriteChar[']];
SELECT name FROM
allComp, compItems, exceptItems, exceptPacks,
itemsExceptPacks, exceptPacksItems, mainProcs =>
BEGIN
WriteString[", cp"L]; PrintIndex[cp];
WriteString[", seg"L]; PrintIndex[seg];
END;
ENDCASE;
IF attr1 THEN SELECT name FROM
codePack, unnamedCodePack, discardCodePack =>
WriteString[", except MAIN"L];
ENDCASE;
IF attr2 THEN SELECT name FROM
codeSeg, codePack, unnamedCodePack, merge, mergeFP,
discardCodePack =>
WriteString[", superceded"L];
ENDCASE;
IF attr3 THEN SELECT name FROM
codeSeg, codePack, unnamedCodePack, merge, mergeFP,
discardCodePack =>
WriteString[", placed"L];
ENDCASE;
nBlanks ← nBlanks + 2;
[] ← TreeOps.UpdateTree[s, Printer];
nBlanks ← nBlanks - 2;
END;
END;
ENDCASE;
RETURN [t]
END;
[] ← Printer[t];
END;
WriteHTI: PROC [hti: SymTabDefs.HTIndex] =
BEGIN
ss: Strings.SubString = @desc;
desc: Strings.SubStringDescriptor;
IF hti = SymTabDefs.HTNull
THEN WriteString["(anonymous)"L]
ELSE {SymTabOps.SubStringForHash[ss, hti]; WriteSubString[ss]};
END;
WriteNodeName: PROC [n: Tree.NodeName] =
BEGIN
NodePrintName: ARRAY Tree.NodeName OF STRING = [
"list"L,
"code segment"L, "code pack"L, "unnamed code pack"L,
"discard code pack"L, "frame pack"L,
"merge segment"L, "merge frame pack"L,
"allComp"L, "compItems"L, "exceptItems"L, "exceptPacks"L,
"itemsExceptPacks"L, "exceptPacks&Items"L, "main procs"L,
"component", "MAIN",
"none"L];
WriteString[NodePrintName[n]];
END;
WriteSymbol: PROC [sym: SemanticEntry.STIndex] =
BEGIN
WriteIndex["symbol"L, sym];
WriteChar[' ]; WriteHTI[stb[sym].hti];
WriteIndex[", parse tree"L, stb[sym].treeNode];
WITH stb[sym] SELECT FROM
unknown => WriteString[" <unknown>"L];
config =>
BEGIN
WriteIndex[", config: cti"L, cti];
WriteIndex[", cNode"L, cNode];
END;
module =>
BEGIN
WriteIndex[", module: mti"L, mti];
WriteIndex[", mNode"L, mNode];
END;
segment =>
WriteString[", segment"L];
codePack =>
WriteString[", code pack"L];
framePack =>
WriteString[", frame pack"L];
ENDCASE;
END;
WriteCodePackProcs: PROC [mi: CodePackProcs.ModuleIndex] =
BEGIN
WriteIndex["code pack procs"L, mi];
END;
-- ********************** Source Bcd Table Printing **********************
PrintSourceBcd: PUBLIC PROC =
BEGIN
WriteCR[]; WriteCR[]; WriteString["--Source Bcd--"L]; WriteCR[];
PrintHeader[];
WriteString["Configurations:"L];
SourceBcd.EnumerateConfigs[PrintConfig];
WriteCR[]; WriteCR[]; WriteString["Modules:"L];
SourceBcd.EnumerateModules[PrintModule];
WriteCR[];
PrintFiles[];
END;
PrintHeader: PROC =
BEGIN OPEN bcd: SourceBcd.bcdHeader;
WriteString[" Configured "L];
WriteTime[LOOPHOLE[bcd.version.time]];
IF bcd.source # BcdDefs.NullName THEN
BEGIN WriteString[" from "L]; WriteName[bcd.source]; END;
WriteString[" by "L];
PrintMachine[bcd.version];
IF bcd.versionIdent # BcdDefs.VersionID THEN
WriteDecimal[" Obsolete VersionID = "L, bcd.versionIdent];
WriteCR[];
WriteString[" Configured by "L];
WriteTime[LOOPHOLE[bcd.creator.time]];
WriteChar[' ];
PrintMachine[bcd.creator];
WriteCR[];
WriteString[" "L];
IF ~bcd.definitions THEN WriteChar['~];
WriteString["definitions, "L];
IF ~bcd.repackaged THEN WriteChar['~];
WriteString["repackaged, "L];
IF ~bcd.tableCompiled THEN WriteChar['~];
WriteString["tableCompiled"L];
WriteCR[]; WriteCR[];
WriteDecimal[" Configurations: "L, bcd.nConfigs];
WriteDecimal[", Modules: "L, bcd.nModules];
WriteDecimal[", Imports: "L, bcd.nImports];
WriteDecimal[", Exports: "L, bcd.nExports];
WriteDecimal[", Dummy: "L, bcd.firstdummy];
WriteDecimal[", #Dummies: "L, bcd.nDummies];
WriteCR[]; WriteCR[];
END;
PrintConfig: PROC [cti: BcdDefs.CTIndex] RETURNS [stop: BOOLEAN] =
BEGIN OPEN BcdDefs;
config: LONG POINTER TO BcdDefs.CTRecord = @SourceBcd.bcdBases.ctb[cti];
i: CARDINAL;
Tab[2];
WriteName[config.name]; PrintIndex[cti];
IF config.namedInstance THEN
{WriteString[", instance: "L]; WriteNameFromTable[[config[cti]]]};
WriteString[", file: "L]; PrintFileName[config.file];
PrintIndex[config.file];
IF config.config # CTNull THEN
BEGIN WriteString[", parent: "L];
WriteName[SourceBcd.bcdBases.ctb[config.config].name];
PrintIndex[config.config];
END;
IF config.nControls # 0 THEN
BEGIN
WriteString[", controls:"L];
FOR i IN [0..config.nControls) DO
IF i MOD 6 = 0 THEN Tab[6] ELSE WriteChar[' ];
WITH item: config.controls[i] SELECT FROM
module => WriteName[SourceBcd.bcdBases.mtb[item.mti].name];
config => WriteName[SourceBcd.bcdBases.ctb[item.cti].name];
ENDCASE;
PrintIndex[config.controls[i]];
IF i+1 # config.nControls THEN WriteChar[',];
ENDLOOP;
END;
RETURN[FALSE];
END;
PrintModule: PROC [mti: BcdDefs.MTIndex] RETURNS [stop: BOOLEAN] =
BEGIN OPEN BcdDefs;
module: LONG POINTER TO BcdDefs.MTRecord = @SourceBcd.bcdBases.mtb[mti];
Tab[2];
WriteName[module.name]; PrintIndex[mti];
IF module.namedInstance THEN
{WriteString[", instance: "L]; WriteNameFromTable[[module[mti]]]};
WriteString[", file: "L];
PrintFileName[module.file]; PrintIndex[module.file];
IF module.config # CTNull THEN
BEGIN
WriteString[", config: "L];
WriteName[SourceBcd.bcdBases.ctb[module.config].name];
PrintIndex[module.config];
END;
Tab[4];
WriteDecimal["framesize: "L, module.framesize];
WriteDecimal[", gfi: "L, module.gfi];
WriteDecimal[", ngfi: "L, module.ngfi];
WriteString[", links: "L];
WriteString[IF module.linkLoc=frame THEN "frame"L ELSE "code"L];
Tab[4];
WriteString["code: "L]; PrintSegment[module.code.sgi];
WriteOctal[", offset: "L, module.code.offset];
WriteOctal[", length: "L, module.code.length];
IF module.code.linkspace THEN WriteString [", space available for links"L];
Tab[4];
WriteString["symbols: "L]; PrintSegment[module.sseg];
IF module.variables # EVNull THEN
{Tab[4]; WriteIndex["variables: "L, module.variables]};
Tab[4];
WriteDecimal["number of links: "L, NLinks[module]];
Tab[4];
IF ~module.altoCode THEN WriteChar['~];
WriteString["altoCode, "L];
IF ~module.packageable THEN WriteChar['~];
WriteString["packageable, "L];
IF ~module.tableCompiled THEN WriteChar['~];
WriteString["tableCompiled, "L];
IF ~module.residentFrame THEN WriteChar['~];
WriteString["residentFrame"L];
RETURN[FALSE];
END;
NLinks: PROC [module: LONG POINTER TO BcdDefs.MTRecord]
RETURNS [nLinks: [0..Table.Limit)] =
BEGIN
WITH mth: module SELECT FROM
direct => RETURN[mth.length];
indirect => RETURN[SourceBcd.bcdBases.lfb[mth.links].length];
multiple => RETURN[SourceBcd.bcdBases.lfb[mth.links].length];
ENDCASE;
END;
PrintSegment: PROC [sgi: BcdDefs.SGIndex] =
BEGIN
sd: LONG POINTER TO BcdDefs.SGRecord = @SourceBcd.bcdBases.sgb[sgi];
PrintFileName[sd.file]; PrintIndex[sgi];
WriteDecimal[", [base: "L, sd.base]; WriteDecimal[", pages: "L, sd.pages];
IF sd.extraPages # 0 THEN WriteDecimal["+"L, sd.extraPages];
WriteChar[']];
END;
PrintFiles: PROC =
BEGIN OPEN BcdDefs;
fti: FTIndex ← FIRST[FTIndex];
WriteCR[]; WriteString["Files:"L];
UNTIL fti = SourceBcd.bcdLimits.ft DO
PrintFile[fti];
fti ← fti + SIZE[FTRecord]
ENDLOOP;
WriteCR[];
END;
PrintFile: PROC [fti: BcdDefs.FTIndex] =
BEGIN OPEN SourceBcd.bcdBases.ftb[fti];
Tab[2];
SELECT fti FROM
BcdDefs.FTNull => WriteString["(null)"];
BcdDefs.FTSelf => WriteString["(self)"];
ENDCASE =>
BEGIN
WriteName[name]; PrintIndex[fti];
WriteString[", version: "L]; PrintFileVersion[fti];
END;
END;
WriteName: PROC [n: BcdDefs.NameRecord] =
BEGIN
ssd: Strings.SubStringDescriptor ← [
base: @SourceBcd.bcdBases.ssb.string,
offset: n,
length: SourceBcd.bcdBases.ssb.size[n]];
WriteSubString[@ssd];
END;
-- ********************** Configuration Tree Printing **********************
PrintConfigTree: PUBLIC PROC =
BEGIN OPEN SourceBcd;
WriteCR[]; WriteCR[]; WriteString["--Configuration Tree--"L]; WriteCR[];
IF configTreeRoot = NullCTreeIndex THEN WriteString[" <Empty>"L]
ELSE {WriteSubConfigTree[configTreeRoot, 0]; WriteCR[]};
WriteCR[];
END;
WriteSubConfigTree: PROC [root: SourceBcd.CTreeIndex, nBlanks: CARDINAL] =
BEGIN OPEN SourceBcd, node: ctreeb[root];
son: CTreeIndex;
Tab[nBlanks];
WITH node SELECT FROM
instance => {WriteName[instanceName]; WriteChar[':]};
ENDCASE;
WriteName[node.prototypeName]; PrintIndex[root];
WriteChar[' ];
IF ~node.anotherNodeWSameProtoName THEN WriteChar['~];
WriteString["pNameTwice"L];
WITH node.index SELECT FROM
module => WriteIndex[", module"L, mti];
config => WriteIndex[", config"L, cti];
ENDCASE;
WriteIndex[", Link: i"L, node.instanceLink];
WriteIndex[", p"L, node.prototypeLink];
WriteIndex[", Prev: i"L, node.instancePrev];
WriteIndex[", p"L, node.prototypePrev];
IF node.firstSon # NullCTreeIndex THEN
BEGIN
nBlanks ← nBlanks + 2;
FOR son ← node.firstSon, ctreeb[son].brother UNTIL son = NullCTreeIndex DO
WriteSubConfigTree[son, nBlanks];
ENDLOOP;
nBlanks ← nBlanks - 2;
END;
END;
-- ******************** Processing Order Printing ********************
PrintProcessingOrder: PUBLIC PROC =
BEGIN
WriteCR[]; WriteCR[]; WriteString["--Processing Order--"L]; WriteCR[];
SourceBcd.EnumerateModulesInConfig[
kind: prototype,
configTreeNode: SourceBcd.configTreeRoot,
userProc: PrintOneModulesOrder];
WriteCR[];
END;
PrintOneModulesOrder: PROC [mti: BcdDefs.MTIndex] RETURNS [stop: BOOLEAN] =
BEGIN
printCount: CARDINAL ← 0;
PrintOneCDNode: PROC [cdNode: Tree.Index] RETURNS [stop: BOOLEAN] =
BEGIN -- print one component description node to be processed for mti
IF (printCount ← printCount+1) > 10 THEN
{WriteCR[]; WriteString[" "L]; printCount ← 1}
ELSE WriteString[" "L];
PrintIndex[cdNode];
RETURN[FALSE];
END;
Tab[0];
WriteName[SourceBcd.bcdBases.mtb[mti].name];
PrintIndex[mti]; WriteString[": "L];
ProcessingOrder.Enumerate[mti, PrintOneCDNode];
RETURN[FALSE];
END;
END.