-- 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.