-- PackControl.Mesa
-- Last edited by Lewis on 3-Apr-81 10:02:05
-- Last edited by Sweet on 6-Feb-81 14:28:01
-- Last edited by Levin on July 6, 1982 4:16 pm
DIRECTORY
Alloc USING [
Chunkify, Create, defaultChunkType, Destroy, Failure,
Overflow, Reset, TableInfo],
BcdDefs USING [VersionStamp],
CharIO USING [CR, PutChar, PutString, SP],
CodePackProcs USING [Determine, Destroy],
CommandUtil USING [
CommandObject, CommandPtr, CopyString, Failed, FreePairList, FreeString,
GetNthPair, ListLength, PairList, Parse, SetExtension],
Debug USING [
Initialize, Finalize, PrintConfigTree, PrintSourceBcd, PrintTree,
PrintProcessingOrder],
Exec USING [AddCommand, commandLine, CommandLine, w],
Inline USING [BITOR, BITXOR, HighByte, LowByte, LowHalf],
LongStorage USING [Node, String],
ModuleSymbols USING [Initialize, Finalize],
PackagerDefs USING [NullSourceIndex, PackagerDataRecord, PackagerNTables],
PackCode USING [ComputeCodePlacement, PackError, WriteBcdToFile, WriteCodeToBcdFile],
PackEnviron USING [Zero],
PackHeap USING [Initialize, Finalize],
ParseData,
P1: FROM "PackParseDefs" USING [Parse],
ProcessingOrder USING [Determine, Destroy],
ProcessorFace USING [processorID],
PackList USING [Print],
Runtime USING [CallDebugger, GetBcdTime, GetTableBase],
Segments USING [
Access, Address, DefaultVersion, DestroyFile, FHandle, FileNameProblem,
FileProblem, LockFile, NewFile, PageCount, Read, ReleaseFile,
UnlockFile, Write],
SemanticEntry USING [BuildSemanticEntries],
SourceBcd USING [
BuildConfigTree, DestroyConfigTree, Load, Unload, BadSourceBcd,
moduleCount],
Space USING [
Create, Delete, GetHandle, Handle, LongPointer, Map, PageFromLongPointer,
virtualMemory],
Stream USING [DeleteProcedure, Object, PutByteProcedure],
Streams USING [CreateStream, Destroy, GetTimes, Handle, NewStream, PutByte],
Strings USING [
AppendChar, AppendString, EquivalentSubString, String, SubStringDescriptor],
SymTabOps USING [Initialize, Finalize],
Time USING [Append, AppendCurrent, Current, Unpack],
TreeOps: FROM "PackTreeOps" USING [Initialize, Finalize],
TTY USING [PutChar, PutCR, PutDecimal, PutLongString, UserAbort],
UserTerminal USING [CursorArray, GetCursorPattern, SetCursorPattern];
PackControl: PROGRAM
IMPORTS
Alloc, CharIO, CommandUtil, CodePackProcs, Debug, Exec, Inline, LongStorage,
ModuleSymbols, PackCode, PackEnviron, PackHeap, ParseData, P1,
ProcessingOrder, ProcessorFace, PackList, Runtime, Segments, SemanticEntry,
SourceBcd, Space, Streams, Strings, SymTabOps, Time, TreeOps, TTY, UserTerminal
EXPORTS
PackagerDefs
SHARES
ProcessorFace =
BEGIN
CR: CHARACTER = CharIO.CR;
SP: CHARACTER = CharIO.SP;
EquivalentString: PROC [s1, s2: Strings.String] RETURNS [BOOLEAN] =
BEGIN
ssd1: Strings.SubStringDescriptor ← [base: s1, offset: 0, length: s1.length];
ssd2: Strings.SubStringDescriptor ← [base: s2, offset: 0, length: s2.length];
RETURN[ Strings.EquivalentSubString[@ssd1, @ssd2] ];
END;
GetNetAndHost: PROC RETURNS [net, host: CARDINAL] =
BEGIN
sum: UNSPECIFIED ←
Inline.BITXOR[
ProcessorFace.processorID.a,
Inline.BITXOR[
ProcessorFace.processorID.b,
ProcessorFace.processorID.c]];
net ← LOOPHOLE[Inline.HighByte[sum]];
host ← LOOPHOLE[Inline.LowByte[sum]];
END;
-- Cursor control
savedCursor: UserTerminal.CursorArray;
PackagerCursor: UserTerminal.CursorArray = -- package
[1670B, 1110B, 520B, 7776B, 14102B, 24102B, 47776B, 54102B,
64102B, 47776B, 50204B, 60410B, 77760B, 0, 0, 0];
SaveOriginalCursor: PROC =
BEGIN
savedCursor ← UserTerminal.GetCursorPattern[];
END;
DisplayPackagerCursor: PROC [pass: CARDINAL] =
BEGIN
cursor: UserTerminal.CursorArray ← PackagerCursor;
box: CARDINAL ← 60000B;
THROUGH [0..pass) DO
cursor[14] ← Inline.BITOR[cursor[14], box];
cursor[15] ← Inline.BITOR[cursor[15], box];
box ← box/8;
ENDLOOP;
UserTerminal.SetCursorPattern[cursor];
END;
RestoreOriginalCursor: PROC =
{UserTerminal.SetCursorPattern[savedCursor]};
-- Table storage management
tableSpace: Segments.Address ← NIL;
InitializeTables: PROC =
BEGIN
weights: ARRAY [0..PackagerDefs.PackagerNTables) OF Alloc.TableInfo ← [
[16, FALSE[32]], [2, FALSE[8]], [4, FALSE[12]], [1, FALSE[1]],
[2, FALSE[8]], [1, FALSE[1]], [4, FALSE[8]], [1, FALSE[2]],
[4, FALSE[12]], [1, FALSE[1]], [1, FALSE[1]], [1, FALSE[1]],
[1, FALSE[1]], [1, FALSE[1]], [1, FALSE[1]], [1, FALSE[1]],
[1, FALSE[1]], [12, FALSE[24]], [1, FALSE[1]], [1, FALSE[1]],
[8, FALSE[12]], [12, FALSE[24]], [12, FALSE[24]], [4, FALSE[8]],
[4, FALSE[8]], [12, FALSE[24]]];
IF globalData.ownTable = NIL THEN {
globalData.ownTable ← Alloc.Create[weights: DESCRIPTOR[weights]];
Alloc.Chunkify[h: globalData.ownTable, table: Alloc.defaultChunkType]}
ELSE Alloc.Reset[globalData.ownTable];
END;
ReleaseTables: PROC =
BEGIN
Alloc.Reset[globalData.ownTable];
END;
GetStorage: PROC [
pages: Segments.PageCount] RETURNS [base: Segments.Address] =
BEGIN
new: Space.Handle ← Space.Create[
size: pages, parent: Space.virtualMemory];
Space.Map[new];
base ← Space.LongPointer[new];
END;
FreeStorage: PROC [base: Segments.Address] =
{Space.Delete[Space.GetHandle[Space.PageFromLongPointer[base]]]};
-- Packager log
LogString: PROC [s: Strings.String] = {TTY.PutLongString[Exec.w, s]};
LogLine: PROC [s: Strings.String] = {LogString[s]; TTY.PutCR[Exec.w]};
LogChar: PROC [c: CHARACTER] = {TTY.PutChar[Exec.w, c]};
NewLine: PROC = INLINE {TTY.PutCR[Exec.w]};
LogDecimal: PROC [i: CARDINAL] = {TTY.PutDecimal[Exec.w, i]};
LogHerald: PROC =
BEGIN
t: STRING ← [20];
LogString["Cedar/Mesa Packager 7.0c of "L];
Time.Append[t, Time.Unpack[LOOPHOLE[globalData.packagerVersion.time]]];
t.length ← t.length - 3;
LogLine[t];
t.length ← 0; Time.AppendCurrent[t]; t.length ← t.length - 3;
LogLine[t];
END;
LogCommand: PROC =
BEGIN OPEN gd: globalData;
NewLine[];
LogString["Packaging "L]; LogString[gd.sourceBcdName];
LogString[" according to "L]; LogLine[gd.packName];
LogString["Output to "L]; LogLine[gd.outputBcdName];
IF listPacks THEN
BEGIN
LogString["Code and frame pack listing to "L];
LogLine[gd.packListFileName];
END;
IF gd.printMap THEN
BEGIN
LogString["Code and frame pack map to "L];
LogLine[gd.mapFileName];
END;
END;
-- Command gathering
args, results: CommandUtil.PairList;
switches: Strings.String;
globalPause, localPause, listPacks: BOOLEAN;
debugPass: CARDINAL;
execLine: Exec.CommandLine;
cmdObject: CommandUtil.CommandObject;
cmdChars: PACKED ARRAY [0..200) OF CHARACTER;
GetPackagingCommands: PROC RETURNS [cmd: CommandUtil.CommandPtr] =
BEGIN
c: CHARACTER;
startFound: BOOLEAN ← FALSE;
execLine ← Exec.commandLine;
cmdObject ← CommandUtil.CommandObject[pos: 0, len: 0, data: @cmdChars];
FOR j: CARDINAL IN [execLine.i .. execLine.s.length) DO
c ← execLine.s[j];
SELECT c FROM
CR => EXIT;
SP => -- ignore initial blanks
IF startFound THEN
{cmdChars[cmdObject.len] ← c; cmdObject.len ← cmdObject.len + 1};
ENDCASE =>
BEGIN
startFound ← TRUE;
cmdChars[cmdObject.len] ← c; cmdObject.len ← cmdObject.len + 1;
END;
ENDLOOP;
RETURN[@cmdObject];
END;
-- Error logging
errorFile: Segments.FHandle ← NIL;
errorStreamObject: Stream.Object;
errorStream: Streams.Handle ← NIL;
OpenErrorStream: PROC =
BEGIN
errorName: Strings.String ← CommandUtil.CopyString[
globalData.rootName, 2+("errlog"L).length];
nameCopy: STRING ← [40];
errorName ← CommandUtil.SetExtension[errorName, "errlog"L];
IF errorFile = NIL THEN {
nameCopy.length ← 0;
Strings.AppendString[to: nameCopy, from: errorName];
errorFile ← Segments.NewFile[nameCopy, Segments.Write];
Segments.LockFile[errorFile]};
errorStream ← Streams.CreateStream[errorFile, Segments.Write];
WriteHeraldToErrlog[errorName]; WriteCommandToErrlog[];
errorName ← CommandUtil.FreeString[errorName];
END;
WriteHeraldToErrlog: PROC [errorFileName: Strings.String] =
BEGIN
t: STRING ← [20];
CharIO.PutString[errorStream, "Cedar/Mesa Packager 7.0c of "L];
Time.Append[t, Time.Unpack[LOOPHOLE[globalData.packagerVersion.time]]];
t.length ← t.length - 3;
CharIO.PutString[errorStream, t]; CharIO.PutChar[errorStream, CR];
t.length ← 0;
Time.AppendCurrent[t];
t.length ← t.length - 3;
CharIO.PutString[errorStream, errorFileName];
CharIO.PutString[errorStream, " -- "L];
CharIO.PutString[errorStream, t]; CharIO.PutChar[errorStream, CR];
END;
WriteCommandToErrlog: PROC =
BEGIN OPEN gd: globalData;
CharIO.PutChar[errorStream, CR];
CharIO.PutString[errorStream, "Packaging "L]; CharIO.PutString[errorStream, gd.sourceBcdName];
CharIO.PutString[errorStream, " according to "L]; CharIO.PutString[errorStream, gd.packName];
CharIO.PutChar[errorStream, CR];
CharIO.PutString[errorStream, "Output to "L]; CharIO.PutString[errorStream, gd.outputBcdName];
CharIO.PutChar[errorStream, CR];
IF listPacks THEN
BEGIN
CharIO.PutString[errorStream, "Code and frame pack listing to "L];
CharIO.PutString[errorStream, gd.packListFileName];
CharIO.PutChar[errorStream, CR];
END;
IF gd.printMap THEN
BEGIN
CharIO.PutString[errorStream, "Code and frame pack map to "L];
CharIO.PutString[errorStream, gd.mapFileName];
CharIO.PutChar[errorStream, CR];
END;
CharIO.PutChar[errorStream, CR];
END;
CloseErrorStream: PROC =
BEGIN
IF errorFile # NIL THEN
BEGIN
Segments.UnlockFile[errorFile];
SELECT TRUE FROM
errorStream # NIL => {Streams.Destroy[errorStream]; errorStream ← NIL};
errorFile # NIL => Segments.DestroyFile[errorFile];
ENDCASE;
errorFile ← NIL;
END;
END;
ErrorPut: Stream.PutByteProcedure --[sH: Stream.Handle, byte: Stream.Byte]-- =
BEGIN
IF errorStream = NIL THEN OpenErrorStream[];
Streams.PutByte[errorStream, LOOPHOLE[byte, CARDINAL]];
END;
ErrorDestroy: Stream.DeleteProcedure --[sH: Stream.Handle]-- =
{CloseErrorStream[]};
packFile, packListFile, mapFile: Segments.FHandle ← NIL;
OpenFiles: PROC =
BEGIN OPEN gd: globalData;
packFile ← OpenOneFile[gd.packName, Segments.Read];
gd.sourceBcdFile ← OpenOneFile[gd.sourceBcdName, Segments.Read];
gd.outputBcdFile ← OpenOneFile[gd.outputBcdName, Segments.Write];
IF listPacks THEN
packListFile ← OpenOneFile[gd.packListFileName, Segments.Write];
IF gd.printMap THEN
mapFile ← OpenOneFile[gd.mapFileName, Segments.Write];
END;
OpenOneFile: PROC [
name: Strings.String, access: Segments.Access] RETURNS [file: Segments.FHandle] =
BEGIN
nameCopy: STRING ← [40];
Strings.AppendString[to: nameCopy, from: name];
file ← NIL;
file ← Segments.NewFile[nameCopy, access
! Segments.FileNameProblem[] => CONTINUE];
IF file # NIL THEN Segments.LockFile[file];
END;
SetRoot: PROC [root, s: Strings.String] =
BEGIN
root.length ← 0;
FOR i: CARDINAL IN [0..s.length) DO
IF s[i] = '. THEN EXIT;
Strings.AppendChar[root, s[i]];
ENDLOOP;
END;
SetFileName: PROC [fileName, extension: Strings.String] RETURNS [Strings.String] =
BEGIN
root: Strings.String = IF fileName # NIL
THEN fileName
ELSE CommandUtil.CopyString[globalData.rootName, 2+extension.length];
RETURN[CommandUtil.SetExtension[root, extension]];
END;
-- timing procedures
startTime: LONG CARDINAL;
TimeSince: PROC [start: LONG CARDINAL] RETURNS [elapsedTime: LONG CARDINAL] =
{RETURN[Time.Current[] - start]};
MarkStartTime: PROC = {startTime ← Time.Current[]};
PrintElapsedTime: PROC [legend: STRING] =
BEGIN
IF globalData.debug THEN
BEGIN
LogString[legend]; LogDecimal[Inline.LowHalf[TimeSince[startTime]]];
LogLine[" seconds"L];
END;
END;
-- #### THIS MAIN PROCEDURE IS CALLED TO DO PACKAGING ####
DoPackaging: PROC =
BEGIN
packCommands: CommandUtil.CommandPtr;
key, value: Strings.String;
abortRequested: BOOLEAN ← FALSE;
SaveOriginalCursor[];
DisplayPackagerCursor[0];
globalPause ← TRUE;
listPacks ← FALSE;
debugPass ← LAST[CARDINAL];
packCommands ← GetPackagingCommands[];
globalData.packagerVersion.time ← Runtime.GetBcdTime[];
globalData.packagerVersion.net ← globalData.packagerVersion.host ← 0;
[globalData.network, globalData.host] ← GetNetAndHost[];
BEGIN
ENABLE {
UNWIND =>
IF globalData.ownTable ~= NIL THEN {
Alloc.Destroy[globalData.ownTable]; globalData.ownTable ← NIL};
Alloc.Overflow => RESUME[8]};
-- MAIN LOOP --
LogHerald[];
DO -- until no more Packager commands
BEGIN
parsed, aborted: BOOLEAN;
packagerStartTime: LONG CARDINAL;
Initialize: PROC =
BEGIN
LogCommand[];
globalData.errors ← globalData.warnings ← aborted ← FALSE;
globalData.nErrors ← globalData.nWarnings ← 0;
globalData.textIndex ← PackagerDefs.NullSourceIndex;
PackHeap.Initialize[];
errorStream ← NIL;
END;
Finalize: PROC =
BEGIN
SymTabOps.Finalize[]; TreeOps.Finalize[]; PackHeap.Finalize[];
IF globalData.debug THEN Debug.Finalize[];
IF abortRequested THEN LogLine["Packaging aborted"L]
ELSE IF globalData.errors THEN LogLine["Errors detected; Bcd not written"L]
ELSE {
LogDecimal[Inline.LowHalf[TimeSince[packagerStartTime]]];
LogLine[" seconds"L]};
IF errorStream # NIL THEN
{LogString["See "L]; LogString[globalData.rootName]; LogLine[".errlog"L]};
CloseErrorStream[];
Streams.Destroy[globalData.packStream];
IF globalData.packListStream # NIL THEN
Streams.Destroy[globalData.packListStream];
IF globalData.mapStream # NIL THEN Streams.Destroy[globalData.mapStream];
IF globalData.outputBcdFile # NIL THEN
BEGIN
Segments.UnlockFile[globalData.outputBcdFile];
IF globalData.nErrors # 0 THEN Segments.DestroyFile[globalData.outputBcdFile
! Segments.FileProblem[] => CONTINUE]
ELSE Segments.ReleaseFile[globalData.outputBcdFile
! Segments.FileProblem[] => CONTINUE];
globalData.outputBcdFile ← NIL;
END;
IF globalData.sourceBcdFile # NIL THEN
BEGIN
Segments.UnlockFile[globalData.sourceBcdFile];
Segments.ReleaseFile[globalData.sourceBcdFile
! Segments.FileProblem[] => CONTINUE];
globalData.sourceBcdFile ← NIL;
END;
ReleaseTables[];
END;
globalData.rootName ← LongStorage.String[40];
globalData.packName ← globalData.sourceBcdName ← NIL;
globalData.outputBcdName ← globalData.packListFileName ← NIL;
globalData.mapFileName ← NIL;
globalData.debug ← FALSE; debugPass ← LAST[CARDINAL];
globalData.printMap ← listPacks ← FALSE;
localPause ← FALSE;
[globalData.packName, args, results, switches] ← CommandUtil.Parse[
s: packCommands,
opX: 2+("pack"L).length, resultX: 2+("list"L).length
! CommandUtil.Failed => GO TO BadCommandLineSyntax];
IF globalData.packName = NIL AND switches = NIL THEN EXIT; -- done packaging
IF globalData.packName = NIL THEN GO TO GlobalSwitches;
SetRoot[globalData.rootName, globalData.packName];
FOR i: CARDINAL IN [0..CommandUtil.ListLength[results]) DO
[key, value] ← CommandUtil.GetNthPair[list: results, n: i];
SELECT TRUE FROM
(key = NIL), EquivalentString[key, "output"L] =>
globalData.outputBcdName ← CommandUtil.CopyString[s: value, extra: (".bcd"L).length];
EquivalentString[key, "list"L] =>
BEGIN
listPacks ← TRUE;
globalData.packListFileName ← CommandUtil.CopyString[s: value, extra: (".list"L).length]; END;
EquivalentString[key, "map"L] =>
BEGIN
globalData.printMap ← TRUE;
globalData.mapFileName ← CommandUtil.CopyString[s: value, extra: (".map"L).length];
END;
ENDCASE => GO TO BadCommandLineSemantics;
ENDLOOP;
FOR i: CARDINAL IN [0..CommandUtil.ListLength[args]) DO
[key, value] ← CommandUtil.GetNthPair[list: args, n: i];
SELECT TRUE FROM
(key = NIL), EquivalentString[key, "input"L] =>
globalData.sourceBcdName ← CommandUtil.CopyString[s: value, extra: (".bcd"L).length];
ENDCASE => GO TO BadCommandLineSemantics;
ENDLOOP;
IF switches # NIL THEN
BEGIN
i: CARDINAL ← 0;
sense: BOOLEAN ← TRUE;
WHILE i < switches.length DO
c: CHARACTER = switches[i];
SELECT c FROM
'-, '~ => sense ← ~sense;
'l, 'L => {listPacks ← sense; sense ← TRUE};
'm, 'M => {globalData.printMap ← sense; sense ← TRUE};
'p, 'P => {localPause ← sense; sense ← TRUE};
'b, 'B => sense ← TRUE; -- no longer necessary
'd, 'D => {globalData.debug ← sense; sense ← TRUE};
'! => {Runtime.CallDebugger[NIL]; sense ← TRUE};
IN ['0..'5] => {debugPass ← c-'0; sense ← TRUE};
ENDCASE;
i ← i+1;
ENDLOOP;
switches ← CommandUtil.FreeString[switches];
END;
IF globalData.sourceBcdName = NIL THEN GOTO NoSourceBcdFileGiven;
globalData.packName ← SetFileName[globalData.packName, "pack"L];
globalData.sourceBcdName ← SetFileName[globalData.sourceBcdName, "bcd"L];
globalData.outputBcdName ← SetFileName[globalData.outputBcdName, "bcd"L];
IF listPacks THEN
globalData.packListFileName ← SetFileName[globalData.packListFileName, "list"L];
IF globalData.printMap THEN
globalData.mapFileName ← SetFileName[globalData.mapFileName, "map"L];
packagerStartTime ← Time.Current[];
DisplayPackagerCursor[1];
BEGIN
ENABLE
ANY => CONTINUE;
packFile ← errorFile ← packListFile ← mapFile ← NIL;
globalData.sourceBcdFile ← globalData.outputBcdFile ← NIL;
globalData.packStream ← globalData.packListStream ← NIL;
globalData.mapStream ← NIL;
OpenFiles[];
IF packFile = NIL THEN
BEGIN
IF globalData.outputBcdFile # NIL THEN
BEGIN
Segments.UnlockFile[globalData.outputBcdFile];
Segments.DestroyFile[globalData.outputBcdFile ! Segments.FileProblem[] => CONTINUE];
END;
GO TO CantFindPackFile;
END
ELSE
BEGIN
globalData.packStream ← Streams.CreateStream[packFile, Segments.Read];
globalData.packVersion ← BcdDefs.VersionStamp[
net: 0, host: 0, time: Streams.GetTimes[globalData.packStream].create];
Segments.UnlockFile[packFile]; packFile ← NIL;
END;
IF globalData.sourceBcdFile = NIL THEN GO TO CantFindSourceBcdFile;
IF listPacks THEN
BEGIN
IF packListFile = NIL THEN
BEGIN
nameCopy: STRING ← [40];
Strings.AppendString[to: nameCopy, from: globalData.packListFileName];
globalData.packListStream ← Streams.NewStream[nameCopy, Segments.Write];
END
ELSE globalData.packListStream ← Streams.CreateStream[packListFile, Segments.Write];
END;
IF globalData.printMap THEN
BEGIN
IF mapFile = NIL THEN
BEGIN
nameCopy: STRING ← [40];
Strings.AppendString[to: nameCopy, from: globalData.mapFileName];
globalData.mapStream ← Streams.NewStream[nameCopy, Segments.Write]
END
ELSE globalData.mapStream ← Streams.CreateStream[mapFile, Segments.Write];
END;
END;
globalData.logStream ← NIL;
errorFile ← NIL;
errorStream ← NIL;
errorStreamObject ← -- install private putByte and destroy procedures
Stream.Object[
options: NULL, getByte: NULL,
putByte: ErrorPut,
getWord: NULL, putWord: NULL, get: NULL, put: NULL,
setSST: NULL, sendAttention: NULL, waitAttention: NULL,
delete: ErrorDestroy];
globalData.errorStream ← @errorStreamObject;
Initialize[];
BEGIN
ENABLE
BEGIN
Alloc.Failure =>
BEGIN
globalData.errors ← TRUE;
IF ~globalData.debug THEN
BEGIN
LogLine["Storage Overflow"L];
GOTO StorageOverflow;
END;
END;
UNWIND => Finalize[];
END;
IF TTY.UserAbort[] THEN GO TO AbortPackaging;
InitializeTables[];
SourceBcd.Load[ ! SourceBcd.BadSourceBcd => GO TO InvalidSourceBcd];
IF globalData.debug THEN Debug.Initialize[];
SymTabOps.Initialize[]; TreeOps.Initialize[];
MarkStartTime[];
[complete: parsed, nErrors: globalData.nErrors] ← P1.Parse[
sourceStream: globalData.packStream,
messageStream: globalData.errorStream,
table: Runtime.GetTableBase[LOOPHOLE[ParseData]] ];
IF globalData.nErrors # 0 THEN globalData.errors ← TRUE;
PrintElapsedTime["Time to parse: "L];
IF debugPass <= 1 THEN Debug.PrintTree[];
IF ~parsed THEN GO TO ParseFailed;
IF TTY.UserAbort[] THEN GO TO AbortAfterParsing;
IF ~globalData.errors THEN
BEGIN
MarkStartTime[]; DisplayPackagerCursor[2];
SourceBcd.BuildConfigTree[];
SemanticEntry.BuildSemanticEntries[];
PrintElapsedTime["Time to decorate parse tree: "L];
IF debugPass <= 2 THEN
{Debug.PrintSourceBcd[]; Debug.PrintConfigTree[]; Debug.PrintTree[]};
IF TTY.UserAbort[] THEN GO TO AbortAfterBuildingSEs;
IF ~globalData.errors THEN
BEGIN
MarkStartTime[]; DisplayPackagerCursor[3];
ProcessingOrder.Determine[];
PrintElapsedTime["Time to determine processing order: "L];
IF debugPass <= 3 THEN Debug.PrintProcessingOrder[];
IF TTY.UserAbort[] THEN GO TO AbortAfterDeterminingPO;
ModuleSymbols.Initialize[SourceBcd.moduleCount];
IF ~globalData.errors THEN
BEGIN
MarkStartTime[];
CodePackProcs.Determine[];
PrintElapsedTime["Time to determine code pack procedures: "L];
IF TTY.UserAbort[] THEN GO TO AbortAfterDeterminingCPProcs;
IF ~globalData.errors THEN
BEGIN
IF listPacks THEN PackList.Print[];
MarkStartTime[]; DisplayPackagerCursor[4];
PackCode.ComputeCodePlacement[
! PackCode.PackError =>
IF reason = SegmentTooBig THEN GO TO dont];
PrintElapsedTime["Time to compute code placement: "L];
IF TTY.UserAbort[] THEN GO TO AbortAfterComputingCodePlacement;
MarkStartTime[]; DisplayPackagerCursor[5];
PackCode.WriteBcdToFile[]; PackCode.WriteCodeToBcdFile[];
PrintElapsedTime["Time to create Bcd and copy code: "L];
EXITS
dont => NULL;
END;
CodePackProcs.Destroy[];
END;
ModuleSymbols.Finalize[];
ProcessingOrder.Destroy[];
END;
SourceBcd.DestroyConfigTree[];
END;
SourceBcd.Unload[];
EXITS
StorageOverflow => NULL;
ParseFailed => globalData.errors ← aborted ← TRUE;
InvalidSourceBcd => globalData.errors ← aborted ← TRUE;
AbortPackaging => abortRequested ← TRUE;
AbortAfterParsing =>
{SourceBcd.Unload[]; abortRequested ← TRUE};
AbortAfterBuildingSEs =>
BEGIN
SourceBcd.DestroyConfigTree[]; SourceBcd.Unload[];
abortRequested ← TRUE;
END;
AbortAfterDeterminingPO =>
BEGIN
ProcessingOrder.Destroy[];
SourceBcd.DestroyConfigTree[]; SourceBcd.Unload[];
abortRequested ← TRUE;
END;
AbortAfterDeterminingCPProcs, AbortAfterComputingCodePlacement =>
BEGIN
CodePackProcs.Destroy[]; ModuleSymbols.Finalize[];
ProcessingOrder.Destroy[];
SourceBcd.DestroyConfigTree[]; SourceBcd.Unload[];
abortRequested ← TRUE;
END;
END;
Finalize[];
EXITS
NoSourceBcdFileGiven =>
BEGIN
LogChar[CR];
LogString["No source BCD file given"L]; LogChar[CR];
globalData.errors ← TRUE;
END;
CantFindPackFile =>
BEGIN
LogChar[CR];
LogString["Can't find "L]; LogString[globalData.packName];
LogChar[CR];
globalData.errors ← TRUE;
END;
CantFindSourceBcdFile =>
BEGIN
LogChar[CR];
LogString["Can't find "L]; LogString[globalData.sourceBcdName];
LogChar[CR];
globalData.errors ← TRUE;
END;
GlobalSwitches =>
BEGIN
sense: BOOLEAN;
results ← CommandUtil.FreePairList[results];
args ← CommandUtil.FreePairList[args];
sense ← TRUE;
FOR i: CARDINAL IN [0..switches.length) DO
c: CHARACTER = switches[i];
SELECT c FROM
'-, '~ => sense ← ~sense;
'! => Runtime.CallDebugger[NIL];
'b, 'B => sense ← TRUE; -- ignored
'p, 'P => {globalPause ← sense; sense ← TRUE};
ENDCASE => EXIT;
ENDLOOP;
switches ← CommandUtil.FreeString[switches];
END;
BadCommandLineSemantics =>
BEGIN
results ← CommandUtil.FreePairList[results];
args ← CommandUtil.FreePairList[args];
LogString[" -- Illegal Packager command"L];
globalData.errors ← TRUE;
END;
END;
globalData.packName ← CommandUtil.FreeString[globalData.packName];
globalData.sourceBcdName ← CommandUtil.FreeString[globalData.sourceBcdName];
globalData.outputBcdName ← CommandUtil.FreeString[globalData.outputBcdName];
IF listPacks THEN
globalData.packListFileName ← CommandUtil.FreeString[globalData.packListFileName];
IF globalData.printMap THEN
globalData.mapFileName ← CommandUtil.FreeString[globalData.mapFileName];
results ← CommandUtil.FreePairList[results];
args ← CommandUtil.FreePairList[args];
IF globalData.errors OR globalData.warnings THEN
BEGIN
IF localPause THEN {globalPause ← TRUE; EXIT};
END;
REPEAT
BadCommandLineSyntax =>
BEGIN
NewLine[];
LogString["-- Illegal Packager command syntax"L];
globalData.errors ← TRUE;
END;
ENDLOOP;
END;
IF globalData.ownTable ~= NIL THEN {
Alloc.Destroy[globalData.ownTable]; globalData.ownTable ← NIL};
RestoreOriginalCursor[];
END; -- of procedure DoPackaging
-- MAIN BODY CODE
globalData: PUBLIC LONG POINTER TO PackagerDefs.PackagerDataRecord;
InitializeSelf: PROC =
BEGIN
globalData ← LongStorage.Node[SIZE[PackagerDefs.PackagerDataRecord]];
PackEnviron.Zero[globalData, SIZE[PackagerDefs.PackagerDataRecord]];
Exec.AddCommand[name: "Packager.~"L, proc: DoPackaging];
END;
InitializeSelf[];
END.