-- PackListImpl.Mesa
-- Last edited by Lewis on 3-Jan-81 18:01:31
-- Last edited by Sweet on September 16, 1980 12:48 PM
-- Last edited by Levin on July 6, 1982 4:30 pm
DIRECTORY
Alloc USING [AddNotify, Bounds, DropNotify, Handle, Notifier],
BcdDefs USING [MTIndex, Namee, NameRecord, NTIndex, NTRecord],
CodePackProcs USING [
AnyProcs, EnumerateSegments, EnumerateCodePacks, EnumerateModules,
EnumerateProcs, ModuleIndex, SubStringForOPIndex],
CharIO USING [CR, PutChar, PutString],
FramePackModules USING [EnumerateFramePacks, EnumerateModules],
PackagerDefs USING [
globalData, packsstype, packsttype, packmdtype, packtreetype,
packctreetype],
PackEnviron USING [BcdStringHandle],
PackList,
PackageSymbols USING [OPIndex],
SourceBcd USING [
bcdBases, bcdLimits, CTreeIndex, IsTableCompiled, LookupName,
NullCTreeIndex],
Strings USING [String, SubString, SubStringDescriptor],
SymTabDefs USING [HTIndex, HTNull],
SymTabOps USING [SubStringForHash],
Table USING [Base],
Time USING [Append, Current, Packed, Unpack],
Tree: FROM "PackTree" USING [Index, Link, NodeName, NullIndex];
PackListImpl: PROGRAM
IMPORTS Alloc, CharIO, PackagerDefs, SourceBcd, SymTabOps, Time,
CodePackProcs, FramePackModules
EXPORTS PackList =
BEGIN OPEN PackagerDefs;
PackListError: ERROR = CODE;
SubString: TYPE = Strings.SubString;
SubStringDescriptor: TYPE = Strings.SubStringDescriptor;
-- ********************* Print code and frame packs *********************
Print: PUBLIC PROC =
BEGIN
table ← PackagerDefs.globalData.ownTable;
table.AddNotify[UpdateBases];
PrintHeading[];
PrintCodePackProcs[];
PrintFramePackModules[];
table.DropNotify[UpdateBases];
table ← NIL;
END;
table: Alloc.Handle ← NIL;
stb, tb, mdb, ctreeb: Table.Base;
pssb: PackEnviron.BcdStringHandle;
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;
PrintHeading: PROC =
BEGIN
WriteString["-- File "L]; WriteString[globalData.packListFileName];
WriteCR[];
WriteString["-- Created by Packager from "L];
WriteString[globalData.packName];
WriteString[" on "L];
WriteTime[Time.Current[]]; WriteCR[];
END;
-- ********************* Code Pack Procedure Printing *********************
PrintCodePackProcs: PROC =
{CodePackProcs.EnumerateSegments[PrintOneCodeSegment]};
PrintOneCodeSegment: PROC [segNode: Tree.Index] RETURNS [stop: BOOLEAN] =
BEGIN
IF segNode # Tree.NullIndex THEN
BEGIN
WriteCR[];
WITH tb[segNode].son[1] SELECT FROM
hash => WriteHTI[index];
ENDCASE;
WriteString[": SEGMENT ="L]; WriteCR[];
WriteString[" BEGIN"L]; WriteCR[];
CodePackProcs.EnumerateCodePacks[segNode, PrintOneCodePack];
WriteString[" END;"L]; WriteCR[];
END;
RETURN[FALSE];
END;
PrintOneCodePack: PROC [cpNode: Tree.Index] RETURNS [stop: BOOLEAN] =
BEGIN
IF cpNode # Tree.NullIndex THEN
BEGIN
WriteCR[];
WriteString[" "L];
WITH tb[cpNode].son[1] SELECT FROM
hash => WriteHTI[index];
ENDCASE;
IF tb[cpNode].name = discardCodePack THEN
WriteString[": DISCARD CODE PACK ="L]
ELSE WriteString[": CODE PACK ="L];
WriteCR[];
WriteString[" BEGIN"L]; WriteCR[];
CodePackProcs.EnumerateModules[cpNode, PrintOneCodePackModule];
WriteString[" END;"L]; WriteCR[];
END;
RETURN[FALSE];
END;
firstProc: BOOLEAN;
numProcsPrinted: CARDINAL;
PrintOneCodePackModule: PROC [
mti: BcdDefs.MTIndex, module: CodePackProcs.ModuleIndex]
RETURNS [stop: BOOLEAN] =
BEGIN
IF CodePackProcs.AnyProcs[module] THEN
BEGIN
WriteString[" "L];
PrintModulePrototypeName[mti];
WriteString["["L]; WriteCR[];
firstProc ← TRUE; numProcsPrinted ← 0;
WriteString[" "L];
CodePackProcs.EnumerateProcs[module, PrintCodePackProc];
WriteString["];"L]; WriteCR[];
END
ELSE IF SourceBcd.IsTableCompiled[mti] THEN
BEGIN
WriteString[" "L];
PrintModulePrototypeName[mti];
WriteString[";"L]; WriteCR[];
END;
RETURN[FALSE];
END;
PrintModulePrototypeName: PROC [module: BcdDefs.MTIndex] =
BEGIN
name: BcdDefs.NameRecord;
ctreeb: Table.Base;
firstNode, n: SourceBcd.CTreeIndex;
WriteQualifiedName: PROC [cNode: SourceBcd.CTreeIndex] =
BEGIN
IF ctreeb[cNode].father # SourceBcd.NullCTreeIndex THEN
{WriteQualifiedName[ctreeb[cNode].father]; WriteChar['.]};
WriteName[ctreeb[cNode].prototypeName];
END;
ctreeb ← table.Bounds[PackagerDefs.packctreetype].base;
name ← SourceBcd.bcdBases.mtb[module].name;
firstNode ← SourceBcd.LookupName[name, prototype];
IF firstNode = SourceBcd.NullCTreeIndex THEN ERROR PackListError;
IF ctreeb[firstNode].prototypePrev = SourceBcd.NullCTreeIndex THEN
WriteName[name]
ELSE
BEGIN -- name is not unique, so find and print correct qualified name
FOR n ← firstNode, ctreeb[n].prototypePrev
UNTIL n = SourceBcd.NullCTreeIndex DO
WITH ctreeb[n].index SELECT FROM
module => IF mti = module THEN {WriteQualifiedName[n]; RETURN};
ENDCASE;
ENDLOOP;
ERROR PackListError; -- could not find the module to print out
END;
END;
PrintCodePackProc: PROC [
opi: PackageSymbols.OPIndex] RETURNS [stop: BOOLEAN] =
BEGIN
procIdSS: Strings.SubString ← @procIdSSDesc;
procIdSSDesc: Strings.SubStringDescriptor;
IF ~firstProc THEN WriteString[", "L];
firstProc ← FALSE;
IF (numProcsPrinted ← numProcsPrinted+1) > 5 THEN
{WriteCR[]; WriteString[" "L]; numProcsPrinted ← 1};
CodePackProcs.SubStringForOPIndex[procIdSS, opi];
WriteSubString[procIdSS];
RETURN[FALSE];
END;
-- ********************* Frame Pack Module Printing *********************
PrintFramePackModules: PROC =
{FramePackModules.EnumerateFramePacks[PrintOneFramePack]};
PrintOneFramePack: PROC [fpNode: Tree.Index] RETURNS [stop: BOOLEAN] =
BEGIN
IF fpNode # Tree.NullIndex THEN
BEGIN
WriteCR[];
WITH tb[fpNode].son[1] SELECT FROM
hash => WriteHTI[index];
ENDCASE;
WriteString[": FRAME PACK ="L]; WriteCR[];
WriteString[" BEGIN"L]; WriteCR[];
FramePackModules.EnumerateModules[fpNode, PrintOneFramePackModule];
WriteString[" END;"L]; WriteCR[];
END;
RETURN[FALSE];
END;
PrintOneFramePackModule: PROC [mti: BcdDefs.MTIndex] RETURNS [stop: BOOLEAN] =
BEGIN
WriteString[" "L]; PrintModuleInstanceName[mti]; WriteChar[';];
WriteCR[];
RETURN[FALSE];
END;
PrintModuleInstanceName: PROC [module: BcdDefs.MTIndex] =
BEGIN
name: BcdDefs.NameRecord;
ctreeb: Table.Base;
firstNode, n: SourceBcd.CTreeIndex;
WriteQualifiedName: PROC [cNode: SourceBcd.CTreeIndex] =
BEGIN
IF ctreeb[cNode].father # SourceBcd.NullCTreeIndex THEN
{WriteQualifiedName[ctreeb[cNode].father]; WriteChar['.]};
WITH ctreeb[cNode] SELECT FROM
instance => WriteName[instanceName];
prototype => WriteName[prototypeName];
ENDCASE
END;
ctreeb ← table.Bounds[PackagerDefs.packctreetype].base;
name ← SourceBcd.bcdBases.mtb[module].name;
firstNode ← SourceBcd.LookupName[name, instance];
IF firstNode = SourceBcd.NullCTreeIndex THEN ERROR PackListError;
IF ctreeb[firstNode].instancePrev = SourceBcd.NullCTreeIndex THEN
WriteName[name]
ELSE
BEGIN -- name is not unique, so find and print correct qualified name
FOR n ← firstNode, ctreeb[n].instancePrev
UNTIL n = SourceBcd.NullCTreeIndex DO
WITH ctreeb[n].index SELECT FROM
module => IF mti = module THEN {WriteQualifiedName[n]; RETURN};
ENDCASE;
ENDLOOP;
ERROR PackListError; -- could not find the module to print out
END;
END;
-- ************************ Utility Writes ************************
WriteChar: PROC [c: CHARACTER] = INLINE
{CharIO.PutChar[globalData.packListStream, c]};
WriteString: PROC [s: Strings.String] = INLINE
{CharIO.PutString[globalData.packListStream, s]};
WriteSubString: PROC [ss: SubString] =
BEGIN
i: CARDINAL;
FOR i IN [ss.offset..ss.offset+ss.length)
DO WriteChar[ss.base[i]] ENDLOOP;
END;
WriteCR: PROC = INLINE {WriteChar[CharIO.CR]};
WriteTime: PROC [t: Time.Packed] =
BEGIN
s: STRING ← [20];
Time.Append[s, Time.Unpack[t]];
WriteString[s];
END;
WriteName: PROC [name: BcdDefs.NameRecord] =
BEGIN
nameSubStr: SubString ← @nameDesc;
nameDesc: SubStringDescriptor;
nameDesc ← SubStringDescriptor[base: @SourceBcd.bcdBases.ssb.string,
offset: name, length: SourceBcd.bcdBases.ssb.size[name]];
WriteSubString[nameSubStr];
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
{WriteName[SourceBcd.bcdBases.ntb[nti].name]; EXIT};
nti ← nti + SIZE[NTRecord];
ENDLOOP;
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;
END.