CompilerClientCommandImpl.mesa
Copyright © 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
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 ROPENIL;
CompilerCondition: CONDITION;
Compile: SAFE PROC [cmd: Commander.Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL] ~ TRUSTED {
Moved here from global frame by Spreitzer August 29, 1985:
parms: REF CompilerOps.Transaction = NEW[CompilerOps.Transaction];
sourceName, objectName, errorName, rootName, wDir: Rope.ROPENIL;
sourceStream, objectStream, errorStream: IO.STREAMNIL;
useLog: BOOL;  -- use compiler.log for error reporting
makeNewLog: BOOL ← TRUE;
destroyLogOnSuccess: BOOL;
createIconic: BOOL;
blinkIfIconic: BOOL;
viewSeparateLogs: BOOL;
userAbort: BOOLFALSE; -- set by ^DEL, STOP
errors, warnings: BOOLFALSE;
someNonSuccess: BOOLFALSE;
remoteMsg: Rope.ROPENIL;
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: BOOLFALSE;
started: BOOLFALSE;
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 {
errorName = NIL iff useLog OR no errors or warnings, under normal circumstances
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: BOOLFALSE;
innerAppendRopeToLog: ENTRY SAFE PROC = CHECKED {
ENABLE UNWIND => NULL;
DO
openFailed: BOOLFALSE;
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[];
};
get some parameters from the user's profile
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;
do the compilation
BEGIN ENABLE UNWIND => Cleanup[];
switchDefaults ← DefaultSwitches[];
wDir ← FileNames.CurrentWorkingDirectory[];
DO
first: BOOL;
args, results: CommandUtil.PairList;
switches: Rope.ROPENIL;
localPause: BOOL;
sense: BOOL;
{ -- start scope for EXITS
cmdLine: Rope.ROPENIL;
originalSourceName: Rope.ROPENIL;
parms.switches ← switchDefaults;
parms.switches['p] ← FALSE;
IF complex
THEN
[sourceName, args, results, switches] ← CommandUtil.Parse[cmdStream
! CommandUtil.Failed => GOTO badSyntax]
ELSE {
use a simple syntax for the command line
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;
main line code
sourceName ← FileNames.GetShortName[sourceName];
IF complex THEN {
first: BOOLTRUE;
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: BOOLFALSE;
success: ComputeServerClient.RemoteSuccess ← false;
serverInstance: Rope.ROPENIL;
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: BOOLFALSE;
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: ROPENIL;
runError: BOOLFALSE;
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;
};
};
Here after completion of subcommand
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;
Here after completion of all subcommands
END; -- end catch phrase to release the resource and reset the process priority
Cleanup[];
};
rollback
RollbackRecovery: Booting.RollbackProc = CHECKED {
directoriesToUseExistingLog ← NIL;
};
new log for compiler
NewCompilerLog: ENTRY SAFE PROC [cmd: Commander.Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL] = 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;
};
compiler inquiries
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
]]};
START HERE
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 "];
}.
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)