DIRECTORY Ascii USING [Lower], Booting USING [RegisterProcs, RollbackProc], Commander USING [CommandObject, Handle, Register], CommandTool USING [ArgumentVector, Failed, Parse, RegistrationDirectory, Run], CommandUtil USING [PairList, Failed, GetNth, GetRootName, ListLength, Parse, SetExtension], CompilerOps USING [LetterSwitches, StreamId, Transaction], ComputeServerClient USING [BestServerStats, RemoteSuccess, StartService], ComputeServerServer USING [Lookup, RegisteredProcHandle], FileNames USING [ConvertToSlashFormat, CurrentWorkingDirectory, GetShortName, ResolveRelativePath], FileParms USING [BindingProc], FileViewerOps USING [AttachErrorLog, ShowLog, RemoveErrorLog, WaitUntilSaved], FS USING [Delete, Error, ExpandName, nullOpenFile, OpenFile, StreamOpen], IO USING [Close, EndOfStream, GetTokenRope, IDProc, PutRope, RIS, STREAM], MessageWindow USING [Append, Blink, Clear], Process USING [GetPriority, InitializeCondition, MsecToTicks, Priority, SetPriority], PupDefs USING [GetHostName, GetPupAddress, PupAddress, PupNameTrouble], PupTypes USING [fillInSocketID], Rope USING [Cat, Concat, Fetch, Find, FromChar, Equal, IsEmpty, Length, ROPE, Substr], RopeFile USING [FromStream], SystemVersion USING [machineType], UserProfile USING [Boolean, Token]; CompilerClientCommandImpl: MONITOR IMPORTS Ascii, Booting, Commander, CommandTool, CommandUtil, ComputeServerClient, ComputeServerServer, FileNames, FileViewerOps, FS, IO, MessageWindow, Process, PupDefs, Rope, RopeFile, SystemVersion, UserProfile = { ROPE: TYPE = Rope.ROPE; Outcome: TYPE = {ok, warnings, errors, aborted}; standardDefaults: CompilerOps.LetterSwitches = DefaultSwitches[]; directoriesToUseExistingLog: LIST OF ROPE _ NIL; CompilerCondition: CONDITION; Compile: SAFE PROC [cmd: Commander.Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL] ~ TRUSTED { parms: REF CompilerOps.Transaction = NEW[CompilerOps.Transaction]; sourceName, objectName, errorName, rootName, wDir: Rope.ROPE _ NIL; sourceStream, objectStream, errorStream: IO.STREAM _ NIL; useLog: BOOL; -- use compiler.log for error reporting makeNewLog: BOOL _ TRUE; destroyLogOnSuccess: BOOL; createIconic: BOOL; blinkIfIconic: BOOL; viewSeparateLogs: BOOL; userAbort: BOOL _ FALSE; -- set by ^DEL, STOP errors, warnings: BOOL _ FALSE; someNonSuccess: BOOL _ FALSE; remoteMsg: Rope.ROPE _ NIL; priority: Process.Priority = Process.GetPriority[]; switchDefaults: CompilerOps.LetterSwitches; verboseComputeServer: BOOL; moduleCount: CARDINAL _ 0; complex: BOOL = SELECT cmd.procData.clientData FROM $Vanilla => FALSE, $Complex => TRUE, $RemoteVanilla => FALSE, ENDCASE => ERROR; preferRemote: BOOL = cmd.procData.clientData = $RemoteVanilla; compilerSwitches: Rope.ROPE _ UserProfile.Token["Compiler.Switches"]; cmdStream: IO.STREAM; filesInit: BOOL _ FALSE; started: BOOL _ FALSE; Cleanup: PROC = { Process.SetPriority[priority]; IF useLog THEN FileViewerOps.ShowLog[ fileName: FS.ExpandName["Compiler.log", wDir].fullFName, destroyIt: ~someNonSuccess AND destroyLogOnSuccess, createIconic: createIconic, blinkIfIconic: blinkIfIconic ]; }; Finalize: PROC [userAbort: BOOL] = { sourceFileName: Rope.ROPE; IF sourceName # NIL THEN { sourceFileName _ FS.ExpandName[sourceName, wDir].fullFName; IF Rope.Length[remoteMsg] > 3 THEN appendRopeToLog[Rope.Substr[remoteMsg, 3]]; IF useLog OR ~(errors OR warnings) THEN FileViewerOps.RemoveErrorLog[sourceFileName] -- removes ErrorLog button ELSE { FileViewerOps.ShowLog[fileName: sourceFileName, createIconic: createIconic, blinkIfIconic: blinkIfIconic]; IF viewSeparateLogs THEN { IF ~errorName.IsEmpty[] THEN FileViewerOps.ShowLog[fileName: errorName, createIconic: createIconic, blinkIfIconic: blinkIfIconic]; } ELSE FileViewerOps.AttachErrorLog[sourceFileName]; }; }; IF userAbort OR errors THEN { IF objectName # NIL THEN DO FS.Delete[name: objectName, wDir: wDir ! FS.Error => IF error.group = lock OR error.code = $unknownFile THEN EXIT]; ENDLOOP; }; IF errorName = NIL THEN { errlogFileName: Rope.ROPE _ CommandUtil.SetExtension[rootName, "errlog"]; DO FS.Delete[name: errlogFileName, wDir: wDir ! FS.Error => IF error.group = lock OR error.code = $unknownFile THEN EXIT]; ENDLOOP; }; }; appendRopeToLog: SAFE PROC [logEntry: ROPE] = CHECKED { slashWDir: ROPE _ FileNames.ConvertToSlashFormat[wDir]; tries: INT _ 0; consCurrentDirectory: BOOL _ FALSE; innerAppendRopeToLog: ENTRY SAFE PROC = CHECKED { ENABLE UNWIND => NULL; DO openFailed: BOOL _ FALSE; needNewLog: BOOL; log: IO.STREAM; oldLog: IO.STREAM; consCurrentDirectory _ FALSE; IF makeNewLog THEN { needNewLog _ TRUE; consCurrentDirectory _ TRUE; } ELSE { FOR l: LIST OF ROPE _ directoriesToUseExistingLog, l.rest UNTIL l = NIL DO IF Rope.Equal[l.first, slashWDir] THEN { needNewLog _ FALSE; EXIT; }; REPEAT FINISHED => { consCurrentDirectory _ TRUE; needNewLog _ TRUE; }; ENDLOOP; }; IF ~needNewLog THEN oldLog _ FS.StreamOpen[fileName: "Compiler.log", accessOptions: $read ! FS.Error => { IF error.group = lock THEN { openFailed _ TRUE; tries _ tries + 1; IF tries > 10 THEN { MessageWindow.Clear[]; MessageWindow.Append["Compiler lock failure after 10 retries for Compiler.log read"]; MessageWindow.Blink[]; }; CONTINUE; } ELSE CONTINUE; }; ]; IF openFailed THEN { IF tries > 10 THEN EXIT; WAIT CompilerCondition; LOOP; }; log _ FS.StreamOpen[fileName: "Compiler.log", accessOptions: $create ! FS.Error => { IF error.group = lock THEN { openFailed _ TRUE; tries _ tries + 1; IF tries > 10 THEN { MessageWindow.Clear[]; MessageWindow.Append["Compiler lock failure after 10 retries for Compiler.log create"]; MessageWindow.Blink[]; }; CONTINUE; }; }; ]; IF openFailed THEN { IF tries > 10 THEN EXIT; WAIT CompilerCondition; LOOP; }; IF ~needNewLog AND log # NIL THEN { log.PutRope[RopeFile.FromStream[oldLog]]; }; IF openFailed THEN { IF tries > 10 THEN EXIT; WAIT CompilerCondition; LOOP; }; log.PutRope[logEntry]; log.Close[]; IF consCurrentDirectory THEN directoriesToUseExistingLog _ CONS[slashWDir, directoriesToUseExistingLog]; EXIT; ENDLOOP; makeNewLog _ FALSE; NOTIFY CompilerCondition; }; innerAppendRopeToLog[]; }; verboseComputeServer _ UserProfile.Boolean["Compiler.VerboseComputeServer", FALSE]; destroyLogOnSuccess _ UserProfile.Boolean["Compiler.DestroyLogOnSuccess", TRUE]; createIconic _ UserProfile.Boolean["Compiler.IconicLogs", FALSE]; blinkIfIconic _ UserProfile.Boolean["Compiler.BlinkLogs", TRUE]; viewSeparateLogs _ UserProfile.Boolean["Compiler.ViewSeparateLogs", FALSE]; IF UserProfile.Boolean["Compiler.SeparateLogs", FALSE] THEN compilerSwitches _ Rope.Cat[compilerSwitches, "~g"]; IF compilerSwitches.Length[] # 0 THEN cmd.commandLine _ Rope.Cat[(IF complex THEN "/" ELSE "-"), compilerSwitches, " ", cmd.commandLine]; cmdStream _ IO.RIS[cmd.commandLine]; sourceName _ rootName _ objectName _ errorName _ NIL; parms.objectName _ NIL; BEGIN ENABLE UNWIND => Cleanup[]; switchDefaults _ DefaultSwitches[]; wDir _ FileNames.CurrentWorkingDirectory[]; DO first: BOOL; args, results: CommandUtil.PairList; switches: Rope.ROPE _ NIL; localPause: BOOL; sense: BOOL; { -- start scope for EXITS cmdLine: Rope.ROPE _ NIL; originalSourceName: Rope.ROPE _ NIL; parms.switches _ switchDefaults; parms.switches['p] _ FALSE; IF complex THEN [sourceName, args, results, switches] _ CommandUtil.Parse[cmdStream ! CommandUtil.Failed => GOTO badSyntax] ELSE { token: Rope.ROPE; token _ cmdStream.GetTokenRope[IO.IDProc ! IO.EndOfStream => EXIT].token; IF token.Length[] > 0 THEN SELECT token.Fetch[0] FROM '- => switches _ token.Substr[1, token.Length[]-1]; ENDCASE => sourceName _ token}; IF sourceName = NIL AND switches = NIL THEN EXIT; IF CommandUtil.ListLength[results] > 1 THEN GOTO badSemantics; IF sourceName = NIL THEN GOTO globalSwitches; originalSourceName _ sourceName; rootName _ CommandUtil.GetRootName[IF CommandUtil.ListLength[results] = 1 THEN CommandUtil.GetNth[results, 0] ELSE FileNames.GetShortName[sourceName]]; errorName _ CommandUtil.SetExtension[rootName, "errlog"]; IF switches # NIL THEN { sense _ TRUE; FOR i: INT IN [0..switches.Length[]) DO c: CHAR = switches.Fetch[i]; SELECT c FROM '-, '~ => {sense _ ~sense; LOOP}; IN ['a..'z], IN ['A..'Z] => parms.switches[Ascii.Lower[c]] _ sense; IN ['1..'5] => parms.debugPass _ c-'0; ENDCASE; sense _ TRUE; ENDLOOP; switches _ NIL; }; sourceName _ CommandUtil.SetExtension[sourceName, "mesa"]; FileViewerOps.WaitUntilSaved[ IF Rope.Find[sourceName, ">"] < 0 AND Rope.Find[sourceName, "/"] < 0 THEN FS.ExpandName[sourceName, wDir].fullFName ELSE sourceName, cmd.out ! ABORTED => {userAbort _ TRUE; GOTO truncateList}]; parms.source.locator _ FileNames.GetShortName[sourceName]; IF CommandUtil.ListLength[results] # 0 THEN { objectName _ CommandUtil.GetNth[list: results, n: 0, delete: TRUE]; results _ NIL; } ELSE objectName _ rootName; objectName _ CommandUtil.SetExtension[objectName, "bcd"]; parms.objectName _ objectName; parms.objectFile _ FS.nullOpenFile; moduleCount _ moduleCount + 1; first _ TRUE; makeNewLog _ ~parms.switches['h]; parms.switches['h] _ FALSE; -- set append or force new log FOR c: CHAR IN ['a..'z] DO sd: BOOL = (IF c = 'p THEN FALSE ELSE standardDefaults[c]); IF parms.switches[c] # sd THEN { IF first THEN {first _ FALSE; cmdLine _ IF complex THEN "/" ELSE "-"}; IF sd THEN cmdLine _ cmdLine.Concat["-"]; cmdLine _ cmdLine.Concat[Rope.FromChar[c]]; }; ENDLOOP; cmdLine _ cmdLine.Concat[" "]; useLog _ parms.switches['g]; parms.switches['g] _ FALSE; localPause _ parms.switches['p]; parms.switches['p] _ FALSE; sourceName _ FileNames.GetShortName[sourceName]; IF complex THEN { first: BOOL _ TRUE; cmdLine _ cmdLine.Cat[rootName, " _ ", originalSourceName, "["]; FOR p: CommandUtil.PairList _ args, p.rest UNTIL p=NIL DO IF ~first THEN cmdLine _ cmdLine.Concat[", "]; cmdLine _ cmdLine.Cat[p.first.key, ": ", p.first.val]; first _ FALSE; ENDLOOP; cmdLine _ cmdLine.Concat["]"]; } ELSE cmdLine _ cmdLine.Concat[sourceName]; { ENABLE UNWIND => Finalize[userAbort]; found: BOOL _ FALSE; success: ComputeServerClient.RemoteSuccess _ false; serverInstance: Rope.ROPE _ NIL; result _ $Blocked; remoteMsg _ NIL; WHILE result = $Blocked DO IF SystemVersion.machineType # dorado THEN { remSuccess: ComputeServerClient.RemoteSuccess; selfBest: BOOL; FigOfMerit: REAL; [success: remSuccess, selfIsBest: selfBest, FOM: FigOfMerit] _ ComputeServerClient.BestServerStats[]; IF remSuccess # true OR selfBest OR FigOfMerit > 0.5 THEN { result _ $TryLocal; EXIT; }; }; IF ~preferRemote THEN result _ $TryLocal; IF result # $TryLocal THEN { IF verboseComputeServer THEN cmd.out.PutRope[" -- Trying remote compile\n"]; IF complex THEN { [found: found, success: success, remoteMsg: remoteMsg, serverInstance: serverInstance] _ ComputeServerClient.StartService[service: "RemoteComplexCompiler", cmdLine: cmdLine, in: NIL, out: cmd.out, queueService: TRUE, timeToWait: 600]; } ELSE { [found: found, success: success, remoteMsg: remoteMsg, serverInstance: serverInstance] _ ComputeServerClient.StartService[service: "RemoteCompiler", cmdLine: cmdLine, in: NIL, out: cmd.out, queueService: TRUE, timeToWait: 600]; }; SELECT TRUE FROM ~found OR success = false OR success = cantImportController OR success = cantImportServer OR success = communicationFailure OR success = commandNotFound OR success = clientNotRunning => { IF verboseComputeServer THEN cmd.out.PutRope[" -- Remote compile did not work; do it locally\n"]; result _ $TryLocal; }; success = aborted => { userAbort _ TRUE; }; success = timeOut OR success = serverTooBusy => { IF verboseComputeServer THEN cmd.out.PutRope[Rope.Cat[" -- Remote compile ", (IF success = timeOut THEN "timed out queuing" ELSE "found a server that was too busy"), "; try again\n"]]; LOOP; }; found AND success = true => { printServerName: PROC = { badName: BOOL _ FALSE; serverName: ROPE _ serverInstance; address: PupDefs.PupAddress; address _ PupDefs.GetPupAddress[PupTypes.fillInSocketID, serverInstance ! PupDefs.PupNameTrouble => { badName _ TRUE; CONTINUE; }; ]; IF ~badName THEN serverName _ PupDefs.GetHostName[address]; IF ~serverName.IsEmpty[] THEN cmd.out.PutRope[Rope.Cat[" -- Compute Server used was ", serverName, "\n"]]; }; IF ~remoteMsg.IsEmpty[] THEN SELECT remoteMsg.Fetch[0] FROM 'F => { -- failure result _ $Failure; errors _ TRUE; warnings _ FALSE; IF verboseComputeServer THEN { printServerName[]; } ELSE { IF ~serverInstance.IsEmpty[] THEN cmd.out.PutRope[Rope.Cat[" Compute Server used was ", serverInstance, "\n"]]; }; }; 'W => { -- warnings result _ $Warning; errors _ FALSE; warnings _ TRUE; IF verboseComputeServer THEN printServerName[]; }; 'S => { -- success result _ $Success; errorName _ NIL; errors _ FALSE; warnings _ FALSE; IF verboseComputeServer THEN printServerName[]; }; 'A => { -- aborted result _ $Aborted; errors _ TRUE; warnings _ FALSE; userAbort _ TRUE; IF verboseComputeServer THEN printServerName[]; }; 'B => { -- blocked bestSuccess: ComputeServerClient.RemoteSuccess; selfIsBest: BOOL; bestFOM: REAL; result _ $Blocked; [success: bestSuccess, selfIsBest: selfIsBest, FOM: bestFOM] _ ComputeServerClient.BestServerStats[]; IF verboseComputeServer THEN { cmd.out.PutRope[" -- Server tried was already busy.\n"]; printServerName[]; }; }; ENDCASE; }; ENDCASE; }; ENDLOOP; IF result = $TryLocal THEN { commandName: ROPE = IF complex THEN "RemoteComplexCompiler" ELSE "RemoteCompiler"; lookupProcData: ComputeServerServer.RegisteredProcHandle; errMsg: ROPE _ NIL; runError: BOOL _ FALSE; lookupProcData _ ComputeServerServer.Lookup["RemoteCompiler", NIL]; IF verboseComputeServer THEN cmd.out.PutRope[" -- Trying to do the compile locally.\n"]; IF lookupProcData = NIL THEN { dir: ROPE; dir _ CommandTool.RegistrationDirectory[cmd]; IF verboseComputeServer THEN cmd.out.PutRope[Rope.Cat[" -- Trying to run CompilerServer.bcd from directory", dir, ".\n"]]; [errMsg: errMsg, error: runError] _ CommandTool.Run[bcdName: dir.Concat["CompilerServer.bcd"], runEvenIfAlreadyRun: FALSE, runEvenIfUnbound: FALSE]; lookupProcData _ ComputeServerServer.Lookup["RemoteCompiler", NIL]; }; IF lookupProcData = NIL THEN { -- try the standard place IF verboseComputeServer THEN cmd.out.PutRope[Rope.Cat[" -- Trying to run CompilerServer.bcd from directory ///Commands/\n"]]; [] _ CommandTool.Run[bcdName: "///Commands/CompilerServer.bcd", runEvenIfAlreadyRun: FALSE, runEvenIfUnbound: FALSE]; lookupProcData _ ComputeServerServer.Lookup["RemoteCompiler", NIL]; }; IF lookupProcData = NIL THEN { msg _ "Failed to start up compiler (CompilerServer.bcd) on the workstation.\n"; IF runError AND ~errMsg.IsEmpty[] THEN msg _ msg.Cat[" Error from Run is ", errMsg]; appendRopeToLog[Rope.Concat[" -- ", msg]]; result _ $Failure; } ELSE { myCmd: Commander.Handle; myCmd _ NEW[Commander.CommandObject _ [ in: cmd.in, out: cmd.out, err: cmd.err, commandLine: cmdLine, command: commandName, propertyList: cmd.propertyList, procData: cmd.procData ]]; result _ $Blocked; WHILE result = $Blocked DO [result: result, msg: remoteMsg] _ lookupProcData.commanderProcHandle.proc[myCmd]; IF ~remoteMsg.IsEmpty[] THEN SELECT remoteMsg.Fetch[0] FROM 'F => { -- failure result _ $Failure; errors _ TRUE; warnings _ FALSE; }; 'W => { -- warnings result _ $Warning; errors _ FALSE; warnings _ TRUE; }; 'S => { -- success result _ $Success; errorName _ NIL; errors _ FALSE; warnings _ FALSE; }; 'A => { -- aborted result _ $Aborted; errors _ TRUE; userAbort _ TRUE; warnings _ FALSE; }; 'B => { -- blocked result _ $Blocked; }; ENDCASE; ENDLOOP; }; }; }; -- end ENABLE UNWIND => Finalize[]; IF result # $Success THEN someNonSuccess _ TRUE; Finalize[userAbort]; EXITS globalSwitches => { objectName _ NIL; sense _ TRUE; FOR i: INT IN [0..switches.Length[]) DO c: CHAR = switches.Fetch[i]; SELECT c FROM '-, '~ => sense _ ~sense; IN ['a..'z] => {switchDefaults[c] _ sense; sense _ TRUE}; IN ['A..'Z] => { switchDefaults[VAL['a.ORD+(c.ORD-'A.ORD)]] _ sense; sense _ TRUE}; ENDCASE => EXIT; ENDLOOP; switches _ NIL; args _ NIL; }; badSemantics => { objectName _ NIL; errors _ TRUE; appendRopeToLog[" -- Illegal command"]; args _ NIL; }; }; sourceName _ rootName _ objectName _ errorName _ NIL; parms.objectName _ NIL; results _ NIL; IF userAbort THEN {appendRopeToLog["\n... command aborted\n"]; GOTO truncateList}; IF (errors OR warnings) AND localPause THEN GOTO truncateList; REPEAT badSyntax => {appendRopeToLog["\n-- Illegal syntax"]; errors _ TRUE}; truncateList => switchDefaults['p] _ TRUE; ENDLOOP; END; -- end catch phrase to release the resource and reset the process priority Cleanup[]; }; RollbackRecovery: Booting.RollbackProc = CHECKED { directoriesToUseExistingLog _ NIL; }; NewCompilerLog: ENTRY SAFE PROC [cmd: Commander.Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL] = CHECKED { ENABLE UNWIND => NULL; argv: CommandTool.ArgumentVector; dir: ROPE; prev: LIST OF ROPE; argv _ CommandTool.Parse[cmd ! CommandTool.Failed => { msg _ errorMsg; CONTINUE; }]; dir _ FileNames.ConvertToSlashFormat[IF argv.argc < 2 THEN FileNames.CurrentWorkingDirectory[] ELSE FileNames.ResolveRelativePath[argv[1]]]; FOR l: LIST OF ROPE _ directoriesToUseExistingLog, l.rest UNTIL l = NIL DO IF Rope.Equal[l.first, dir] THEN { IF l = directoriesToUseExistingLog THEN directoriesToUseExistingLog _ l.rest ELSE prev.rest _ l.rest; EXIT; }; prev _ l; ENDLOOP; }; DefaultSwitches: PROC RETURNS [CompilerOps.LetterSwitches] = { RETURN [[ TRUE , -- A Address fault for NIL checks TRUE , -- B Bounds checking TRUE , -- C compile for Cedar (special FORK) FALSE, -- D call Debugger on compiler error (FALSE => just log error) TRUE , -- E fixed (big Eval stack) TRUE , -- F Floating point microcode TRUE , -- G TRUE => log goes to compiler.log, FALSE => use foo.errlog FALSE, -- H TRUE => append to compiler.log, FALSE => write new compiler.log FALSE, -- I unused FALSE, -- J cross-Jumping optimization FALSE, -- K unused TRUE , -- L allocate space for code Links TRUE , -- M reference counting Microcode TRUE , -- N Nil pointer checking FALSE, -- O unused FALSE, -- P Pause after compilation with errors FALSE, -- Q unused FALSE, -- R unused TRUE , -- S Sort (by static frequency) global vars & entry indexes FALSE, -- T unused FALSE, -- U uninitialized variable checking FALSE, -- V unused TRUE , -- W log Warning messages FALSE, -- X unused FALSE, -- Y complain about KFCB TRUE -- Z FALSE => use old-style method to access ROPE & ATOM literals ]]}; Booting.RegisterProcs[r: RollbackRecovery]; Process.InitializeCondition[@CompilerCondition, Process.MsecToTicks[250]]; Commander.Register["Compile", Compile, "Compile {-switches} xxx* - A simple syntax for compiling a list of cedar modules. (See 'ComplexCompile' for another syntax). Some useful switches are: -b => bounds checking (default: TRUE -- don't turn this off unless you know what you are doing), -d => call debugger on compiler error (else just log error), -g => log goes to compiler.log (-~g => log goes to foo.errlog), -j => cross-jump (default: FALSE -- don't turn this on unless you know what you are doing), -n => nil checking (default: TRUE -- don't turn this off unless you know what you are doing), -u => check for uninitialized variables, -w => log warning messages (default: TRUE) Switches can be negated with '~' (i.e. '-~bj~n'). The complete list of switches is in CompilerSequencer.DefaultSwitches. The defaults can be set in your user profile with Compiler.Switches.", $Vanilla]; Commander.Register["RCompile", Compile, "RCompile {-switches} xxx* - Same switches as Compile, but this prefers remote compilation", $RemoteVanilla]; Commander.Register["ComplexCompile", Compile, "ComplexCompile /j-b-n BcdTreeOps _ ProtoTreeOps[Literals: BcdSymbols, Symbols: BcdSymbols, Tree: BcdTree] . . . - Allows a parameterized compilation. Switches are marked with '/ and negated with '-. (See 'Compile' for more on switches.)", $Complex]; Commander.Register["NewCompilerLog", NewCompilerLog, "NewCompilerLog [directory] - Start a new Compiler.log for compiles done in the current directory or the specified directory. Useful only when the compiles are done with the g switch on "]; }. tCompilerClientCommandImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Satterthwaite, October 21, 1985 5:52:55 pm PDT Maxwell, January 26, 1984 9:05:33 am PST Paul Rovner, December 4, 1983 11:57 am Spreitzer, August 29, 1985 2:13:50 pm PDT Russ Atkinson (RRA) April 3, 1985 4:02:43 pm PST Bob Hagmann April 15, 1986 11:52:43 am PST Moved here from global frame by Spreitzer August 29, 1985: errorName = NIL iff useLog OR no errors or warnings, under normal circumstances get some parameters from the user's profile do the compilation use a simple syntax for the command line main line code Here after completion of subcommand Here after completion of all subcommands rollback new log for compiler compiler inquiries START HERE Bob Hagmann March 21, 1986 2:06:37 pm PST Added "H" switch. Wrote NewCompilerLog and RollbackRecovery to support it. Bob Hagmann April 15, 1986 11:49:54 am PST removed extraneous code from appendRopeToLog changes to: appendRopeToLog (local of Compile) Bob Hagmann April 15, 1986 11:52:43 am PST changes to: DIRECTORY, CompilerClientCommandImpl, appendRopeToLog (local of Compile) Κγ˜codešœ™Kšœ Οmœ1™žœ ˜VKšœ žœ˜Kšœžœ˜"Kšœ žœ˜#K˜—šœž˜"KšžœzžœžœM˜ΤKšœ˜K˜—Kšžœžœžœ˜K˜Kšœ žœ#˜0K˜K˜AK˜Kš œžœžœžœžœ˜0K˜K˜K˜K˜šΟnœž œžœ žœžœ žœžœžœ˜i™:Kšœžœžœ˜BKšœ8žœžœ˜CKšœ)žœžœžœ˜9K™KšœžœΟc'˜6Kšœ ž œ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜—K˜Kšœ žœžœ ˜-Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜K˜3K˜+Kšœžœ˜Kšœ žœ˜Kšœ žœžœžœ žœžœžœžœ˜ƒKšœžœ,˜>K˜Kšœžœ*˜EKšœ žœžœ˜Kšœ žœžœ˜Kšœ žœžœ˜šŸœžœ˜K˜šžœžœ˜%Kšœ žœ,˜8Kšœžœ˜3Kšœ˜Kšœ˜Kšœ˜—K˜—šŸœžœ žœ˜$Kšœžœ˜šžœžœžœ˜Jšœ žœ@™OJšœžœ(˜;JšœN˜NJšžœžœ žœ ˜"Jšœžœ/ ˜Nšœžœ˜šœ0˜0Jšœ:˜:—šžœ˜šžœ˜Jšžœžœf˜‚J˜—Jšžœ.˜2—Jšœ˜—J˜—K˜šžœ žœžœ˜šžœžœž˜šž˜šžœ%˜'Kš œžœ žœžœžœžœ˜L—Kšžœ˜——K˜—šžœ žœžœ˜Kšœžœ1˜Jšž˜šžœ)˜+Kš œžœ žœžœžœžœ˜L—Kšžœ˜—K˜—K˜K˜—š Οbœžœžœ žœžœ˜7Kšœ žœ(˜7Kšœžœ˜Kšœžœžœ˜#š œžœžœžœžœ˜1Kšžœžœžœ˜šž˜Kšœ žœžœ˜Kšœ žœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœžœ˜šžœ žœ˜Kšœ žœ˜Kšœžœ˜K˜—šœžœ˜š žœžœžœžœ'žœžœž˜Jšžœ žœ˜(Kšœ žœ˜Kšžœ˜K˜—šžœžœ˜Kšœžœ˜Kšœ žœ˜K˜—Kšžœ˜—K˜—šžœ žœ žœ=žœ ˜išžœžœ˜Kšœ žœ˜K˜šžœ žœ˜Kšœ˜KšœU˜UKšœ˜K˜—Kšžœ˜ K˜—Kšœžœžœ˜Kšœ˜—Kšœ˜šžœ žœ˜Kšžœ žœžœ˜Kšžœ˜Kšžœ˜K˜—šœžœ?žœ ˜Tšžœžœ˜Kšœ žœ˜K˜šžœ žœ˜Kšœ˜KšœW˜WKšœ˜K˜—Kšžœ˜ K˜—Kšœ˜—Kšœ˜šžœ žœ˜Kšžœ žœžœ˜Kšžœ˜Kšžœ˜K˜—šžœ žœžœžœ˜#Kšœ)˜)Kšœ˜—šžœ žœ˜Kšžœ žœžœ˜Kšžœ˜Kšžœ˜K˜—Kšœ˜Kšœ ˜ Kšžœžœžœ)˜hKšžœ˜Kšžœ˜—Kšœ žœ˜Kšžœ˜K˜—Kšœ˜K˜—K˜K™+KšœLžœ˜SKšœJžœ˜PKšœ:žœ˜AKšœ:žœ˜@KšœDžœ˜Kšžœ.žœ˜7Kšžœ5˜9—šžœž˜%Kšœžœ žœžœ/˜c—Kšœ žœžœ˜$Kšœ1žœ˜5Kšœžœ˜K˜Kšœ™šžœžœžœ˜!K˜K˜#K˜K˜+K˜šž˜Kšœžœ˜ K˜$Kšœžœžœ˜Kšœ žœ˜Kšœžœ˜ K˜šœ ˜Jšœžœžœ˜Jšœžœžœ˜$K˜Kšœ ˜ Kšœžœ˜K˜šžœ˜ šž˜šœC˜CKšœžœ ˜'——šžœ˜Kšœ(™(Kšœ žœ˜Kšœžœ žœžœ˜Išžœžœžœž˜5K˜3Kšžœ˜———Kš žœžœžœ žœžœžœ˜1Kšžœ%žœžœ˜>Kšžœžœžœžœ˜-Kšœ ˜ šœ#žœ$˜IKšžœ˜#Kšžœ%˜)—Kšœ9˜9šžœ žœžœ˜Kšœžœ˜ šžœžœžœž˜'Kšœžœ˜šžœž˜ Kšœžœ˜!šžœ žœ ˜Kšœ'˜'—šžœ ˜Kšœ˜—Kšžœ˜—Kšœž˜ Kšžœ˜—Kšœ žœ˜Kšœ˜—K˜:šœ˜šžœ žœ ˜EKšžœžœ'˜.Kšžœ ˜—Kšœ žœžœžœ˜<—Kšœ:˜:K˜šžœ$˜&šžœ˜Kšœ=žœ˜CKšœ žœ˜Kšœ˜—Kšžœ˜—K˜9K˜Kšœžœ˜#K˜K˜K˜Kšœžœ˜ Kšœ8žœ ˜^šžœžœžœ ž˜Kš œžœžœžœžœžœ˜;šžœžœ˜ Kš žœžœ žœ žœ žœžœ˜FKšžœžœ˜)Kšœ+˜+Kšœ˜—Kšžœ˜—Kšœ˜Kšœ3žœ˜9Kšœ7žœ˜=K˜K™K˜0šžœ žœ˜Jšœžœžœ˜Jšœ@˜@šžœ(žœžœž˜9Jšžœžœ ˜.Jšœ6˜6Jšœžœ˜Jšžœ˜—Jšœ˜Jšœ˜—Jšœžœ&˜+šœžœžœ˜'K˜Jšœžœžœ˜Jšœ3˜3Jšœžœžœ˜ J˜J˜Jšœ˜Jšœ žœ˜J˜šžœž˜šžœ$žœ˜,Jšœ.˜.Jšœ žœ˜Jšœ žœ˜Jšœ,žœ6˜ešžœžœ žœž˜;Jšœ˜Jšžœ˜J˜—J˜—Jšžœžœ˜)šžœžœ˜Jšžœžœ0˜Lšžœ žœ˜Jšœ²žœžœ˜κJ˜—šœžœ˜Jšœ«žœžœ˜γJ˜—šžœžœž˜š œžœžœ žœžœ žœžœ ˜»JšžœžœE˜aJšœ˜J˜—šœ˜Jšœ žœ˜Jšœ˜—šœžœ˜1Jš žœžœ2žœžœžœ8˜ΈJšžœ˜J˜—šœžœ˜šœžœ˜Jšœ žœžœ˜Jšœ žœ˜"Jšœ˜šœe˜eJšœ žœ˜Jšžœ˜ Jšœ˜—Jšœ˜Jšžœ žœ+˜;JšžœžœM˜jJ˜—šžœžœžœž˜;šœ  ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜šžœžœ˜Jšœ˜J˜—šœžœ˜JšžœžœN˜oJ˜—J˜—šœ  ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜Jšžœžœ˜/J˜—šœ  ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜Jšœ žœ˜Jšžœžœ˜/J˜—šœ  ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜Jšœ žœ˜Jšžœžœ˜/J˜—šœ  ˜Jšœ/˜/Jšœ žœ˜Jšœ žœ˜Jšœ˜Jšœ/žœ3˜ešžœžœ˜Jšœ8˜8Jšœ˜J˜—J˜—Jšžœ˜—J˜—Jšžœ˜—J˜—Jšžœ˜—K˜šžœžœ˜Kš œ žœžœ žœžœ˜SKšœ9˜9Kšœžœžœ˜Kšœ žœžœ˜Kšœ>žœ˜CKšžœžœ<˜Xšžœžœžœ˜Kšœžœ˜ Kšœ-˜-Kšžœžœ^˜zKšœtžœžœ˜”Kšœ>žœ˜CK˜—šžœžœžœ ˜9Kšžœžœa˜}KšœUžœžœ˜uKšœ>žœ˜CK˜—šžœžœžœ˜KšœO˜OKšžœ žœžœ.˜TKšœ*˜*Kšœ˜K˜—šœžœ˜Kšœ˜šœžœ˜'Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ˜šžœž˜KšœR˜Ršžœžœžœž˜;šœ  ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜J˜—šœ  ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜J˜—šœ  ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜Jšœ žœ˜J˜—šœ  ˜Jšœ˜Jšœ žœ˜Jšœ žœ˜Jšœ žœ˜J˜—šœ  ˜Jšœ˜J˜—Jšžœ˜—Jšžœ˜—K˜K˜—K˜—Kšœ #˜'—Kšœ0˜0Kšœ˜K˜šž˜˜Kšœ žœ˜Kšœžœ˜ šžœžœžœž˜'Kšœžœ˜šžœž˜ K˜Kšžœ1žœ˜9šžœ˜Kš œžœžœžœžœžœ˜B—Kšžœžœ˜—Kšžœ˜—Kšœ žœ˜Kšœžœ˜ Kšœ˜—˜Kšœ žœ žœ˜ Kšœ'˜'Kšœžœ˜ Kšœ˜——Kšœ˜—K˜K™#Kšœ1žœ˜5Kšœžœ˜Kšœ žœ˜Kšžœ žœ/žœ˜SKš žœ žœ žœ žœžœ˜>K˜šž˜Kšœ?žœ˜EKšœ%žœ˜*—Kšžœ˜—K™(K˜Kšžœ J˜P—K˜ Kšœ˜—K™J™˜šΠbnœžœ˜3Kšœžœ˜"K˜——K™J™J™˜šŸœž œžœžœ žœžœ žœžœžœ˜uKšž œžœ˜Kšœ!˜!Kšœžœ˜ Kšœžœžœžœ˜JšœHžœ˜UKšœ%žœžœ%žœ)˜Œš žœžœžœžœ'žœžœž˜Jšžœžœ˜"Kšžœ!žœ&žœ˜eKšžœ˜K˜—Kšœ ˜ Kšžœ˜—K˜K˜——Jšœ™˜šŸœžœžœ!˜>šžœ˜ Kšžœ "˜)Kšžœ ˜Kšžœ &˜-Kšžœ ?˜FKšžœ ˜#Kšžœ ˜%Kšžœ ?˜FKšžœ E˜LKšžœ  ˜Kšžœ  ˜'Kšžœ  ˜Kšžœ #˜*Kšžœ "˜)Kšžœ ˜!Kšžœ  ˜Kšžœ )˜0Kšžœ  ˜Kšžœ  ˜Kšžœ <˜CKšžœ  ˜Kšžœ %˜,Kšžœ  ˜Kšžœ ˜!Kšžœ  ˜Kšžœ ˜ Kšžœ B˜IK˜K˜———K˜Kšœ ™ Kšœ+˜+KšœJ˜JKšœ‡˜‡Kšœ•˜•Kšœͺ˜ͺKšœσ˜σK˜K˜˜K˜—™)KšœK™K—™*KšœΟr™,Kšœ £œ™.—™*Kšœ £5œ™T—K™—…—NΊk