InitialCommandsA.mesa
Last editted: April 14, 1983 12:16 pm by L. Stewart
Last editted: April 19, 1983 3:10 pm by Paul Rovner
DIRECTORY
AMBridge USING [TVForReferent],
CedarVersion USING [major, minor, patch],
Commander,
Directory USING [Lookup],
ExecOps USING [Outcome],
Feedback
USING [BeginItemProc, CreateProc, DestroyProc, FinishItemProc, NoteProgressProc,
Procs],
File USING [Capability],
IO USING [STREAM, string, rope, time, int, RIS, PutF, PutRope, PutTV, PutText, Put, UserAbort, ResetUserAbort, UserAborted, GetInt, NewLine],
List USING [CompareProc, Sort],
Loader USING [Start, Instantiate],
Process USING [Priority, GetPriority, SetPriority, priorityBackground],
Resource USING [Acquire, Release, AbortProc],
Rope USING [Compare, Concat, IsEmpty, Length, ROPE, ToRefText, Cat],
Runtime USING [GetBuildTime, IsBound],
TemporarySpecialExecOps USING [BindUsingFeedback, CompileUsingFeedback],
TiogaMenuOps USING [Open],
UECP USING [Argv, Parse],
UserCredentials USING [GetUserCredentials],
UserProfile USING [Boolean, Token],
ViewerClasses USING [Viewer],
ViewerOps USING [CreateViewer];
InitialCommandsA: CEDAR PROGRAM
IMPORTS AMBridge, CedarVersion, Commander, Directory, IO, List, Loader, Process, Resource, Rope, Runtime, TemporarySpecialExecOps, TiogaMenuOps, UserProfile, UECP, UserCredentials, ViewerOps =
BEGIN
compilerSwitches, binderSwitches: Rope.ROPE ← NIL;
destroyLogOnSuccess: BOOL ← FALSE;
connecting concrete and opaque types
abortProc: Resource.AbortProc = TRUSTED{
PROC [data: REF ANY] RETURNS[abort: BOOL];
in: IO.STREAM = NARROW[data, IO.STREAM];
abort ← in.UserAbort[];
IF abort THEN in.ResetUserAbort[];
};
Bind:
PROC[args: Rope.
ROPE, in, out:
IO.
STREAM]
RETURNS[outCome: ExecOps.Outcome] =
TRUSTED {
priority: Process.Priority = Process.GetPriority[];
success: BOOL ← FALSE;
otherOwner: Rope.ROPE ← NIL;
aborted: BOOL ← FALSE;
BCreate: Feedback.CreateProc = {RETURN[NIL]};
BDestroy: Feedback.DestroyProc = {
out.Put[IO.string[trailer] ! IO.UserAborted => {aborted ← TRUE; CONTINUE}]};
BBeginItem: Feedback.BeginItemProc = {
out.Put[IO.string[item] ! IO.UserAborted => {aborted ← TRUE; CONTINUE}]};
BFinishItem: Feedback.FinishItemProc = {
out.PutF[" %g\n", IO.string[trailer] ! IO.UserAborted => {aborted ← TRUE; CONTINUE}]};
BNoteProgress: Feedback.NoteProgressProc = {
out.PutRope[" ." ! IO.UserAborted => {aborted ← TRUE; CONTINUE}];
IF aborted
OR in.UserAbort[]
THEN {
in.ResetUserAbort[];
ERROR IO.UserAborted;
};
};
binderProcs: Feedback.Procs ← [BCreate, BDestroy, BBeginItem, BNoteProgress, BFinishItem];
[success, otherOwner] ← Resource.Acquire[resource: $Binder,
owner: "Commander",
waitForIt: FALSE];
IF NOT success
THEN {
out.PutRope[Rope.Cat["Waiting for ", otherOwner, " to finish..."]];
[success, ] ← Resource.Acquire
[resource: $Binder,
owner: "Commander",
waitForIt: TRUE,
abortProc: abortProc,
abortProcData: in
];
IF
NOT success
THEN {
out.PutRope["ABORTED\n"];
RETURN;
} ELSE out.PutRope["proceeding\n"];
};
BEGIN ENABLE UNWIND => {Process.SetPriority[priority]; [] ← Resource.Release[$Binder]};
cmdText: REF StringBody;
cmd: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTER;
IF ~Runtime.IsBound[TemporarySpecialExecOps.BindUsingFeedback]
THEN {
ENABLE ANY => {out.PutText["Failed\n"]; GOTO Errors};
out.PutText["Loading and Starting Binder.bcd...\n"];
Loader.Start[Loader.Instantiate[Directory.Lookup["Binder.bcd"], 1, TRUE].cm];
};
cmdText ← LOOPHOLE[Rope.ToRefText[Rope.Concat[binderSwitches, args]], REF StringBody];
cmd ← LOOPHOLE[@(cmdText.text)];
Process.SetPriority[Process.priorityBackground];
outCome ← TemporarySpecialExecOps.BindUsingFeedback[cmd, @binderProcs];
EXITS
Errors => outCome ← errors;
END; -- ENABLE UNWIND
Process.SetPriority[priority];
[] ← Resource.Release[$Binder];
}; -- end Bind
Compile:
PROC[args: Rope.
ROPE, in, out:
IO.
STREAM]
RETURNS[outCome: ExecOps.Outcome] =
TRUSTED {
priority: Process.Priority = Process.GetPriority[];
success: BOOL ← FALSE;
otherOwner: Rope.ROPE ← NIL;
aborted: BOOL ← FALSE;
CCreate: Feedback.CreateProc = {RETURN[NIL]};
CDestroy: Feedback.DestroyProc = {
out.Put[IO.string[trailer] ! IO.UserAborted => {aborted ← TRUE; CONTINUE}]};
CBeginItem: Feedback.BeginItemProc = {
out.Put[IO.string[item] ! IO.UserAborted => {aborted ← TRUE; CONTINUE}]};
CFinishItem: Feedback.FinishItemProc = {
out.PutF[" %g\n", IO.string[trailer] ! IO.UserAborted => {aborted ← TRUE; CONTINUE}]};
CNoteProgress: Feedback.NoteProgressProc = {
out.PutRope[" ." ! IO.UserAborted => {aborted ← TRUE; CONTINUE}];
IF aborted
OR in.UserAbort[]
THEN {
in.ResetUserAbort[];
ERROR IO.UserAborted;
};
};
compilerProcs: Feedback.Procs ← [CCreate, CDestroy, CBeginItem, CNoteProgress, CFinishItem];
[success, otherOwner] ← Resource.Acquire[resource: $Compiler,
owner: "Commander",
waitForIt: FALSE];
IF NOT success
THEN {
out.PutRope[Rope.Cat["Waiting for ", otherOwner, " to finish..."]];
[success, ] ← Resource.Acquire
[resource: $Compiler,
owner: "Commander",
waitForIt: TRUE,
abortProc: abortProc,
abortProcData: in
];
IF
NOT success
THEN {
out.PutRope["ABORTED\n"];
RETURN;
} ELSE out.PutRope["proceeding\n"];
};
BEGIN ENABLE UNWIND => {Process.SetPriority[priority]; [] ← Resource.Release[$Compiler]};
cmdText: REF StringBody;
cmd: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTER;
IF ~Runtime.IsBound[TemporarySpecialExecOps.CompileUsingFeedback]
THEN {
ENABLE ANY => {out.PutText["Failed\n"]; GOTO Errors};
out.PutText["Loading and Starting Compiler.bcd...\n"];
Loader.Start[Loader.Instantiate[Directory.Lookup["Compiler.bcd"], 1, TRUE].cm];
};
cmdText ← LOOPHOLE[Rope.ToRefText[Rope.Concat[compilerSwitches, args]], REF StringBody];
cmd ← LOOPHOLE[@(cmdText.text)];
Process.SetPriority[Process.priorityBackground];
outCome ← TemporarySpecialExecOps.CompileUsingFeedback[cmd, @compilerProcs];
EXITS
Errors => outCome ← errors;
END; -- ENABLE UNWIND
Process.SetPriority[priority];
[] ← Resource.Release[$Compiler];
}; -- end Compile
PrintResult:
PROC [result: ExecOps.Outcome, out:
IO.
STREAM] = {
SELECT result
FROM
warnings => out.PutRope[". . . warnings\n"];
errors => out.PutRope[". . . errors\n"];
errorsAndWarnings => out.PutRope[". . . errorsAndWarnings\n"];
aborted => out.PutRope[". . . aborted\n"]
ENDCASE;
MyCompile: Commander.CommandProc = {
PrintResult[result: Compile[args: cmd.commandLine, in: cmd.in, out: cmd.out], out: cmd.out];
};
MyBind: Commander.CommandProc = {
PrintResult[result: Bind[args: cmd.commandLine, in: cmd.in, out: cmd.out], out: cmd.out];
};
SetDefaultSwitches: Commander.CommandProc =
{
SetDefaultSwitchesInternal[];
IF compilerSwitches.Length[] > 0 THEN cmd.out.PutF["Compiler Switches now %g\n", IO.rope[compilerSwitches]]
ELSE cmd.out.PutRope["No compiler switches,\n"];
IF binderSwitches.Length[] > 0 THEN cmd.out.PutF["Binder Switches now %g\n", IO.rope[binderSwitches]]
ELSE cmd.out.PutRope["No binder switches,\n"];
};
SetDefaultSwitchesInternal:
PROC = {
compilerSwitches ← UserProfile.Token["Compiler.Switches"];
IF UserProfile.Boolean["Compiler.SeparateLogs", FALSE] THEN compilerSwitches ← Rope.Concat["/-g", compilerSwitches];
binderSwitches ← UserProfile.Token["Binder.Switches"];
destroyLogOnSuccess ← UserProfile.Boolean["Compiler.DestroyLogOnSuccess", TRUE];
};
Date: Commander.CommandProc = {
cmd.out.PutF[" %t\n", IO.time[]];
};
User: Commander.CommandProc = {
user: Rope.ROPE ← UserCredentials.GetUserCredentials[].name;
IF user.Length[] = 0 THEN user ← "NIL";
cmd.out.PutF["User: %g\n", IO.rope[user]];
};
Version: Commander.CommandProc = {
cmd.out.PutF["Cedar %g.%g", IO.int[CedarVersion.major], IO.int[CedarVersion.minor]];
IF CedarVersion.patch # 0 THEN cmd.out.PutF[".%g", IO.int[CedarVersion.patch]];
cmd.out.PutF[" of %t\n", IO.time[Runtime.GetBuildTime[]]];
};
Properties: Commander.CommandProc =
TRUSTED {
argStream: IO.STREAM ← IO.RIS[cmd.commandLine];
depth, width: INT;
depth ← argStream.GetInt[ !
ANY => {
depth ← 4;
CONTINUE;
}];
width ← argStream.GetInt[ !
ANY => {
width ← 32;
CONTINUE;
}];
cmd.out.PutRope["propertyList = "];
cmd.out.PutTV[tv: AMBridge.TVForReferent[NEW[REF ANY ← cmd.propertyList]], depth: depth, width: width];
cmd.out.NewLine[];
};
ECell: TYPE = RECORD [name, doc: Rope.ROPE];
EnumerateCommands: Commander.CommandProc = {
el: LIST OF REF ANY;
eCell: REF ECell;
EProc:
PROC[name: Rope.
ROPE, proc: Commander.CommandProc, doc: Rope.
ROPE]
RETURNS[stop:
BOOL] = {
IF proc # NIL THEN el ← CONS[NEW[ECell ← [name: name, doc: doc]], el];
RETURN[FALSE];
};
MyCompare: List.CompareProc = {
a, b: REF ECell;
a ← NARROW[ref1];
b ← NARROW[ref2];
RETURN[Rope.Compare[a.name, b.name]];
};
cmd.out.PutRope["Registered commands:\n"];
[] ← Commander.Enumerate[EProc];
el ← List.Sort[list: el, compareProc: MyCompare];
WHILE el #
NIL
DO
eCell ← NARROW[el.first];
cmd.out.PutF["%-20g %g\n", IO.rope[eCell.name], IO.rope[eCell.doc]];
el ← el.rest;
ENDLOOP;
};
Alias: Commander.CommandProc = {
argv: UECP.Argv ← UECP.Parse[cmd.commandLine];
oldProc: Commander.CommandProc;
doc: Rope.ROPE;
IF argv.argc > 2
THEN {
[proc: oldProc, doc: doc] ← Commander.Lookup[argv[2]];
IF oldProc # NIL THEN Commander.Register[key: argv[1], proc: oldProc, doc: doc]
ELSE cmd.out.PutF["Alias: %g not found\n", IO.rope[argv[2]]];
}
ELSE cmd.out.PutRope["Usage: Alias newname oldname\n"];
};
Unregister: Commander.CommandProc = {
argv: UECP.Argv ← UECP.Parse[cmd.commandLine];
IF argv.argc = 2
THEN {
IF Commander.Lookup[argv[1]].proc # NIL THEN Commander.Register[key: argv[1], proc: NIL, doc: NIL]
ELSE cmd.out.PutF["Unregister: %g not found\n", IO.rope[argv[1]]];
}
ELSE cmd.out.PutRope["Usage: Unregister commandname\n"];
};
SetProperty: Commander.CommandProc = {
argv: UECP.Argv ← UECP.Parse[cmd.commandLine];
IF argv.argc # 3 THEN cmd.out.PutRope["Usage: SetProperty key value\n"]
ELSE [] ← Commander.PutProperty[key: argv[1], val: argv[2], aList: cmd.propertyList];
};
Open: Commander.CommandProc = {
argv: UECP.Argv ← UECP.Parse[cmd.commandLine];
IF argv.argc # 2
THEN {
cmd.out.PutRope["Usage: Open filename\n"];
RETURN;
};
OpenViewer[argv[1], FALSE, cmd.out];
};
New: Commander.CommandProc = {
OpenViewer[NIL, TRUE, cmd.out];
};
Comment: Commander.CommandProc = {
};
OpenViewer:
PROC [name: Rope.
ROPE, newViewer:
BOOLEAN ←
FALSE, out:
IO.
STREAM] = {
viewer: ViewerClasses.Viewer;
IF newViewer
THEN viewer ← ViewerOps.CreateViewer[flavor: $Text, info: [name:
IF Rope.IsEmpty[name]
THEN "No Name"
ELSE name,
file: name, iconic: FALSE]]
ELSE viewer ← TiogaMenuOps.Open[name]; -- workaround
IF viewer = NIL THEN out.PutF["\tViewer file not found: %g\n", IO.rope[name]]
ELSE out.PutF["\tCreated Viewer: %g\n", IO.rope[viewer.name]];
};
Init:
PROC = {
SetDefaultSwitchesInternal[];
Commander.Register[key: "Compile", proc: MyCompile, doc: "Compile programs"];
Commander.Register[key: "Bind", proc: MyBind, doc: "Bind configurations"];
Commander.Register[key: "SetCompilerSwitchesFromProfile", proc: SetDefaultSwitches, doc: "Read compiler and binder switches from user profile"];
Commander.Register[key: "Date", proc: Date, doc: "Print date and time"];
Commander.Register[key: "User", proc: User, doc: "Print name of logged in user"];
Commander.Register[key: "Version", proc: Version, doc: "Print Cedar version number"];
Commander.Register[key: "GetProperties", proc: Properties, doc: "Display command tool property list"];
Commander.Register[key: "Alias", proc: Alias, doc: "Alias newName oldName - Attach a new name to an existing command"];
Commander.Register[key: "?", proc: EnumerateCommands, doc: "List registered commands"];
Commander.Register[key: "SetProperty", proc: SetProperty, doc: "SetProperty propertyName value - change or add to the command tool property list"];
Commander.Register[key: "Open", proc: Open, doc: "Open fileName - open a viewer"];
Commander.Register[key: "New", proc: New, doc: "Open an empty viewer"];
Commander.Register[key: "Unregister", proc: Unregister, doc: "Unregister a command"];
Commander.Register[key: "/", proc: Comment, doc: "Comment"];
Commander.Register[key: "-", proc: Comment, doc: "Comment"];
};
Init[];
END.
March 27, 1983 3:27 pm, Stewart, Created
April 3, 1983 12:56 pm, Stewart, combined CompileAndBindImpl.mesa