<> <> <> DIRECTORY Alloc: TYPE USING [Create, Chunkify, Destroy, Failure, Reset, TableInfo], Ascii: TYPE USING [Lower], BasicTime: TYPE USING [GMT, Now, Period], BcdBindDefs: TYPE USING [RelocHandle], BcdComData: TYPE USING [ aborted, bcdName, binderVersion, codeName, commandArgs, copyCode, copySymbols, currentName, debug, errors, errorStream, logStream, nConfigs, nErrors, nExports, nImports, nModules, nPages, nWarnings, objectStamp, op, outputFile, outputFti, rootName, sourceName, sourceStream, sourceVersion, symbolName, table, textIndex, warnings, zone], BcdControlDefs: TYPE USING [ BindRoot, BuildSemanticEntries, LoadRoot, WriteBcd, PrintBcd, PrintRelocations, PrintSemanticEntries, PrintTree], BcdDefs: TYPE USING [ BinderNTables, httype, MTNull, NullName, sstype, treetype, VersionStamp], BcdErrorDefs: TYPE USING [Finalize, GetModule, GetSti, Initialize], BcdFileDefs: TYPE USING [BuildFileTable, EraseFileTable], BcdLiterals: TYPE USING [Initialize, Finalize, SealLiterals], BcdParseData: TYPE, BcdUtilDefs: TYPE USING [EnterFile, Init, Reset], Commander: TYPE USING [Handle, Register], CommandUtil: TYPE USING [Echo, Failed, GetNthPair, ListLength, PairList, Parse, SetExtension], DebuggerSwap: TYPE USING [CallDebugger], FileIO: TYPE USING [StreamFromOpenFile], FS: TYPE USING [Close, Delete, EnumerateForInfo, Error, InfoProc, nullOpenFile, Open, OpenFile], HashOps: TYPE USING [Finalize, Initialize], IO: TYPE USING [char, Close, CR, CreateProcsStream, CreateRefStreamProcs, int, Put, PutChar, PutRope, rope, SetLength, STREAM, StreamProcs, time, UserAbort], OSMiscOps: TYPE USING [ BcdCreateTime, DeleteFile, FindFile, --ImageId,-- MergeStamps, TimeToStamp], P1: TYPE USING [InstallParseTable, Parse], PrincOpsUtils: TYPE USING [CodeBase], Rope: TYPE USING [Equal, Fetch, Find, Flatten, Length, ROPE, Substr], Symbols: TYPE USING [stNull], Tree: TYPE USING [Link], TreeOps: TYPE USING [PopTree, Finalize, Initialize], UnsafeStorage: TYPE USING [FreeUZone, NewUZone]; BcdControl: PROGRAM IMPORTS Alloc, Ascii, BasicTime, BcdControlDefs, BcdErrorDefs, BcdFileDefs, BcdLiterals, BcdParseData, BcdUtilDefs, Commander, CommandUtil, DebuggerSwap, FileIO, FS, HashOps, IO, OSMiscOps, P1, PrincOpsUtils, Rope, TreeOps, UnsafeStorage, data: BcdComData = { EquivalentRope: PROC [s1, s2: Rope.ROPE] RETURNS [BOOL] ~ { RETURN [Rope.Equal[s1, s2, FALSE]]}; <> log: IO.STREAM _ NIL; logFile: FS.OpenFile _ FS.nullOpenFile; SetLogStream: PROC ~ { IF logFile = FS.nullOpenFile THEN logFile _ OSMiscOps.FindFile["Binder.Log", $write]; log _ FileIO.StreamFromOpenFile[logFile]; IO.SetLength[log, 0]}; LogRope: PROC [s: Rope.ROPE] ~ {IO.PutRope[log, s]}; LogChar: PROC [c: CHAR] ~ {IO.PutChar[log, c]}; LogNumber: PROC [n: INTEGER] ~ {IO.Put[log, IO.int[n]]}; renamedOutput: BOOL _ FALSE; RepeatCommand: PROC [s: IO.STREAM] ~ { OPEN IO; PutRope[s, "\nBinding "]; PutRope[s, data.sourceName]; IF renamedOutput THEN {PutRope[s, ", BCD to "]; PutRope[s, data.bcdName]}; IF data.copyCode THEN { PutRope[s, ", code to "]; PutRope[s, IF data.codeName = NIL THEN "BCD" ELSE data.codeName]}; IF data.copySymbols THEN { PutRope[s, ", symbols to "]; PutRope[s, IF data.symbolName = NIL THEN "BCD" ELSE data.symbolName]}; PutChar[s, '\n]}; <> errorName: Rope.ROPE _ NIL; errorFile: FS.OpenFile _ FS.nullOpenFile; errorStream: IO.STREAM _ NIL; errorStreamProcs: REF IO.StreamProcs _ NIL; SetErrorName: PROC ~ { IF errorName = NIL THEN { errorName _ CommandUtil.SetExtension[data.rootName, "errlog"]}}; DummyErrorStream: PROC [ putProc: SAFE PROC[self: IO.STREAM, char: CHAR]] RETURNS [IO.STREAM] ~ { IF errorStreamProcs = NIL THEN errorStreamProcs _ IO.CreateRefStreamProcs[putChar~putProc]; RETURN [IO.CreateProcsStream[errorStreamProcs, NIL]]}; OpenErrorStream: PROC ~ { IF errorName = NIL THEN SetErrorName[]; IF errorFile = FS.nullOpenFile THEN errorFile _ OSMiscOps.FindFile[errorName, $write]; errorStream _ FileIO.StreamFromOpenFile[errorFile]; IO.SetLength[errorStream, 0]; WriteHerald[errorStream, errorName]; RepeatCommand[errorStream]}; CloseErrorStream: PROC ~ INLINE {IF data.errorStream # NIL THEN ErrorDestroy[]}; ErrorPut: SAFE PROC[self: IO.STREAM, char: CHAR] ~ TRUSTED { IF errorStream = NIL THEN OpenErrorStream[]; errorStream.PutChar[char]}; ErrorDestroy: PROC ~ { IF errorFile # FS.nullOpenFile AND errorStream # NIL THEN { IO.Close[errorStream]; errorStream _ NIL}}; WriteHerald: PROC [stream: IO.STREAM, id: Rope.ROPE] ~ { stream.Put[IO.rope["Cedar 3.x Binder of "], IO.time[OSMiscOps.BcdCreateTime[]]]; <> <> IF id.Length[] # 0 THEN stream.Put[IO.rope[id], IO.rope[" -- "]]; stream.Put[IO.time[], IO.char['\n]]}; Logger: PROC [proc: PROC [log: IO.STREAM]] = { proc[data.errorStream]}; <> sourceFile, bcdFile: FS.OpenFile _ FS.nullOpenFile; GetRoot: PROC [s: Rope.ROPE] RETURNS[Rope.ROPE] ~ { dotIndex: INT _ Rope.Find[s, "."]; IF dotIndex > -1 THEN s _ Rope.Substr[s, 0, dotIndex]; RETURN[s]}; <> StandardDefaults: PACKED ARRAY CHAR ['a..'z] OF BOOL ~ [ FALSE, -- A Copy all (code and symbols) FALSE, -- B Unused TRUE , -- C Copy code FALSE, -- D Call debugger error FALSE, -- E Unused FALSE, -- F Unused TRUE , -- G TRUE => errlog goes to binder.log, FALSE => use root.errlog FALSE, -- H Unused FALSE, -- I Unused FALSE, -- J Unused FALSE, -- K Unused FALSE, -- L Unused FALSE, -- M Unused FALSE, -- N Unused FALSE, -- O Unused FALSE, -- P Pause after config with errors FALSE, -- Q Unused FALSE, -- R Unused FALSE, -- S Copy symbols FALSE, -- T Unused FALSE, -- U Unused FALSE, -- V Unused FALSE, -- W Pause after config with warnings FALSE, -- X Copy compressed symbols (not implemented) FALSE, -- Y Unused FALSE -- Z Unused ]; <> Bind: SAFE PROC [cmd: Commander.Handle] ~ TRUSTED { results: CommandUtil.PairList; switches: Rope.ROPE; key, value: Rope.ROPE; anyErrors, anyWarnings: BOOL _ FALSE; localPause: BOOL; defaultSwitches: PACKED ARRAY CHAR ['a..'z] OF BOOL _ StandardDefaults; defaultDebugPass: CARDINAL _ CARDINAL.LAST; localSwitches: PACKED ARRAY CHAR ['a..'z] OF BOOL; debugPass: CARDINAL; IF cmd = NIL THEN ERROR; <> <> <> <<>> SetLogStream[]; WriteHerald[log, NIL]; data.op _ $bind; data.zone _ UnsafeStorage.NewUZone[]; data.table _ NIL; <
> DO { Initialize: PROC ~ { weights: ARRAY [0..BcdDefs.BinderNTables) OF Alloc.TableInfo _ [ -- empirical (SDD) [4], [2], [10], [4], [5], [4], [4], [4], [2], [1], [4], [4], [4], [2], [4], [2], [4], [5], [1], [1]]; RepeatCommand[log]; data.errors _ data.warnings _ FALSE; data.nErrors _ data.nWarnings _ 0; data.textIndex _ 0; data.currentName _ BcdDefs.NullName; IF data.table = NIL THEN { data.table _ Alloc.Create[weights~DESCRIPTOR[weights]]; (data.table).Chunkify[BcdDefs.treetype]} ELSE (data.table).Reset[]; HashOps.Initialize[data.table, BcdDefs.httype, BcdDefs.sstype]; TreeOps.Initialize[data.table, data.zone]; BcdUtilDefs.Init[data.table]; BcdLiterals.Initialize[data.table, data.zone]; BcdErrorDefs.Initialize[]; errorStream _ NIL}; Finalize: PROC ~ { TreeOps.Finalize[]; HashOps.Finalize[]; BcdErrorDefs.Finalize[]; BcdLiterals.Finalize[]; BcdUtilDefs.Reset[]; (data.table).Reset[]; anyErrors _ data.errors OR anyErrors; anyWarnings _ data.warnings OR anyWarnings; IF data.aborted THEN LogRope["Binding aborted\n"] ELSE IF data.errors THEN LogRope["Errors detected; BCD not written\n"] ELSE { IF data.nConfigs > 1 THEN { LogNumber[data.nConfigs]; LogRope[" configs, "]}; LogNumber[data.nModules]; LogRope[" modules, "]; LogNumber[data.nImports]; LogRope[" imports, "]; LogNumber[data.nExports]; LogRope[" exports, "]; LogNumber[data.nPages]; LogRope[" pages, "]; LogNumber[BasicTime.Period[BasicTime.Now[], startTime]]; LogRope[" seconds\n"]}; IF errorStream # NIL THEN { LogRope["See "]; LogRope[data.rootName]; LogRope[".errlog\n"]}; IF log # data.errorStream THEN CloseErrorStream[]; IF errorName = NIL THEN {SetErrorName[]; OSMiscOps.DeleteFile[errorName]}; IO.Close[data.sourceStream]; IF sourceFile # FS.nullOpenFile THEN {FS.Close[sourceFile]; sourceFile _ FS.nullOpenFile}; IF bcdFile # FS.nullOpenFile THEN {FS.Close[bcdFile]; bcdFile _ FS.nullOpenFile}; IF data.nErrors # 0 OR data.aborted THEN FS.Delete[data.bcdName ! FS.Error => TRUSTED {CONTINUE}]; data.outputFile _ FS.nullOpenFile; <> <> <