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