Last Edited by: teitelman, April 20, 1983 8:38 pm
DIRECTORY
Atom USING [GetPropFromList],
Commander USING [Handle, PutProperty],
CommandProcOps USING [CheckForAbort, Confirm],
Directory USING [Error, Lookup, ignore],
IO USING [PutF, Flush, ROPE, rope, STREAM, UserAbort, UserAborted],
IOMisc USING [AskUser],
List USING [DotCons],
MessageWindow USING [Append],
Resource USING [AbortProc, Acquire, Release],
Rope USING [Cat, Find, IsEmpty, Length , ROPE, Substr, ToRefText],
Runtime USING [IsBound],
Spell USING [AbortProc, ConfirmProc, Filter, GetMatchingFileList, GetMatchingList, GetTheFile, GetTheOne, InformProc, IsAPattern, Modes, SpellingGenerator, SpellingList],
UserExec USING [AskUser, HistoryEvent, ExecHandle, GetTheOne, GetTheFile, GetMatchingList, GetMatchingFileList],
UserExecPrivate USING [EventFailed]
;
CommandProcOpsImpl: CEDAR PROGRAM
IMPORTS IO, IOMisc, Atom, List, Commander, CommandProcOps, Rope, MessageWindow, Resource, UserExec, UserExecPrivate, Directory, Runtime, Spell
EXPORTS CommandProcOps
= BEGIN OPEN IO;
ExecHandle: TYPE = UserExec.ExecHandle;
HistoryEvent: TYPE = UserExec.HistoryEvent;
Aborting: UserAbort, UserAborted
AskUser: PUBLIC PROC [msg: ROPE, timeout: INT ← -1, defaultKey: ATOMNIL, handle: Commander.Handle ← NIL, keyList: LIST OF ATOMNIL] RETURNS[value: ATOM] = {
exec: UserExec.ExecHandle;
event: UserExec.HistoryEvent;
[exec, event] ← GetExecHandle[handle];
RETURN[
IF exec # NIL THEN UserExec.AskUser[msg: msg, timeout: timeout, defaultKey: defaultKey, exec: exec, keyList: keyList]
ELSE IOMisc.AskUser[msg: msg, timeout: timeout, defaultKey: defaultKey, in: handle.in, out: handle.out, keyList: keyList]];
};
AskUser
EventFailed: PUBLIC PROC [handle: Commander.Handle, msg: ROPE, offender: ROPENIL] = {
exec: UserExec.ExecHandle;
event: UserExec.HistoryEvent;
[exec, event] ← GetExecHandle[handle];
IF exec = NIL THEN handle.out.PutF["*n%g", rope[msg]]
ELSE UserExecPrivate.EventFailed[event, msg, offender]; -- this procedure should be in (will be moved to) the UserExec interface.
};
GetTheOne, GetTheFile, etc.
GetTheOne: PUBLIC PROCEDURE[
unknown: ROPE,
spellingList: Spell.SpellingList ← NIL,
generator: Spell.SpellingGenerator ← NIL,
handle: Commander.Handle ← NIL,
filter: Spell.Filter ← NIL,
modes: Spell.Modes ← NIL
]
RETURNS [correct: ROPENIL] = {
Abort: Spell.AbortProc = {
CommandProcOps.CheckForAbort[handle];
};
Confirm: Spell.ConfirmProc -- [msg: ROPE, timeout: INT, defaultConfirm: BOOL] RETURNS[yes: BOOL] -- = {
RETURN[
CommandProcOps.Confirm[msg: msg, timeout: timeout, defaultConfirm: defaultConfirm, handle: handle]
]
};
Inform: Spell.InformProc --[msg: ROPE] -- = {
IF handle # NIL THEN handle.out.PutF["*n%g\n", rope[msg]]
ELSE MessageWindow.Append[message: msg, clearFirst: TRUE];
};
exec: UserExec.ExecHandle;
event: UserExec.HistoryEvent;
TRUSTED {IF Rope.IsEmpty[unknown] OR NOT Runtime.IsBound[Spell.GetTheOne] THEN RETURN[NIL]};
[exec, event] ← GetExecHandle[handle];
IF exec # NIL THEN RETURN[UserExec.GetTheOne[unknown: unknown, spellingList: spellingList, generator: generator, event: event, exec: exec, filter: filter, modes: modes]];
RETURN[Spell.GetTheOne[unknown: unknown, spellingList: spellingList, generator: generator, filter: filter, abort: Abort, confirm: Confirm, inform: Inform, modes: modes]];
};
GetMatchingList: PUBLIC PROCEDURE[
unknown: ROPE,
spellingList: Spell.SpellingList ← NIL,
generator: Spell.SpellingGenerator ← NIL,
handle: Commander.Handle ← NIL,
filter: Spell.Filter ← NIL,
modes: Spell.Modes ← NIL
]
RETURNS [matching: LIST OF ROPENIL] = {
Abort: Spell.AbortProc = {
CommandProcOps.CheckForAbort[handle];
};
Confirm: Spell.ConfirmProc -- [msg: ROPE, timeout: INT, defaultConfirm: BOOL] RETURNS[yes: BOOL] -- = {
RETURN[
CommandProcOps.Confirm[msg: msg, timeout: timeout, defaultConfirm: defaultConfirm, handle: handle]
]
};
Inform: Spell.InformProc --[msg: ROPE] -- = {
IF handle # NIL THEN handle.out.PutF["*n%g\n", rope[msg]]
ELSE MessageWindow.Append[message: msg, clearFirst: TRUE];
};
exec: UserExec.ExecHandle;
event: UserExec.HistoryEvent;
TRUSTED {IF Rope.IsEmpty[unknown] OR NOT Runtime.IsBound[Spell.GetTheOne] THEN RETURN[NIL]};
[exec, event] ← GetExecHandle[handle];
IF exec # NIL THEN RETURN[UserExec.GetMatchingList[unknown: unknown, spellingList: spellingList, generator: generator, event: event, exec: exec, filter: filter, modes: modes]];
IF NOT Spell.IsAPattern[unknown] THEN {
val: ROPE ← GetTheOne[unknown: unknown, spellingList: spellingList, generator: generator, handle: handle, filter: filter, modes: modes];
IF val # NIL THEN RETURN[LIST[val]]
ELSE RETURN[NIL];
};
RETURN[Spell.GetMatchingList[pattern: unknown, spellingList: spellingList, generator: generator, filter: filter, abort: Abort, confirm: Confirm, inform: Inform, modes: modes]];
};
CheckForFile: PUBLIC PROC [file: ROPE] RETURNS [found: BOOLEAN] = TRUSTED { -- Directory
fName: LONG STRING;
fName ← LOOPHOLE[Rope.ToRefText[file]];
found ← TRUE;
IF Rope.Length[file] = 0 THEN RETURN[FALSE];
[] ← Directory.Lookup[fileName: fName, permissions: Directory.ignore
! Directory.Error =>
{found ← FALSE; CONTINUE}
];
};
GetExecHandle: PUBLIC PROC [handle: Commander.Handle] RETURNS [exec: UserExec.ExecHandle, event: UserExec.HistoryEvent] = {
IF handle = NIL THEN RETURN[NIL, NIL];
RETURN[
NARROW[Atom.GetPropFromList[propList: handle.propertyList, prop: $UserExec]],
NARROW[Atom.GetPropFromList[propList: handle.propertyList, prop: $HistoryEvent]]
];
};
PutProperty: PUBLIC PROCEDURE [handle: Commander.Handle, key: REF ANY, val: REF ANY, thisEventOnly: BOOLFALSE] = {
if thisEventOnly is TRUE, the property is added to the handle in such a fashion that it will NOT be seen for subsequent events. If FALSE, the property will be seen, i.e. is a permanent change.
IF thisEventOnly THEN handle.propertyList ← CONS[List.DotCons[key, val], handle.propertyList]
ELSE handle.propertyList ← Commander.PutProperty[key, val, handle.propertyList];
};
GetTheFile: PUBLIC PROC [
file: ROPE,
defaultExt: ROPENIL,
handle: Commander.Handle ← NIL,
modes: Spell.Modes ← NIL] RETURNS [name: ROPENIL] = {
exec: UserExec.ExecHandle;
event: UserExec.HistoryEvent;
i: INT;
TRUSTED {IF Rope.IsEmpty[file] OR NOT Runtime.IsBound[Spell.GetTheOne] THEN RETURN[NIL]};
[exec, event] ← GetExecHandle[handle];
IF exec # NIL THEN RETURN[UserExec.GetTheFile[file: file, defaultExt: defaultExt, event: event, exec: exec, modes: modes]];
{
IF (i ← Rope.Find[s1: file, s2: "/"]) # -1
THEN {
IF i # 0 THEN file ← Rope.Substr[base: file, len: i] -- ignore switches
ELSE IF Rope.Find[s1: file, s2: "/", pos1: 1] = -1 THEN GOTO FullPath
ELSE RETURN[NIL];
};
IF Rope.Find[file, "["] # -1 OR Rope.Find[file, "<"] # -1 THEN GOTO FullPath;
EXITS
FullPath => {
handle.out.PutF["*nFull path names not yet implemented"];
RETURN[NIL]
};
};
IF CheckForFile[file] THEN RETURN[file];
IF (i ← Rope.Find[file, "."]) = -1 AND Rope.Length[defaultExt] # 0 THEN name ← Rope.Cat[file, ".", defaultExt]
ELSE name ← file;
IF CheckForFile[name] THEN RETURN[name];
{
Abort: Spell.AbortProc = {
CommandProcOps.CheckForAbort[handle];
};
Confirm: Spell.ConfirmProc -- [msg: ROPE, timeout: INT, defaultConfirm: BOOL] RETURNS[yes: BOOL] -- = {
RETURN[
CommandProcOps.Confirm[msg: msg, timeout: timeout, defaultConfirm: defaultConfirm, handle: handle]
]
};
Inform: Spell.InformProc -- [msg: ROPE] -- = {
IF handle # NIL THEN handle.out.PutF["*n%g\n", rope[msg]]
ELSE MessageWindow.Append[message: msg, clearFirst: TRUE];
};
name ← Spell.GetTheFile[unknown: file, defaultExt: defaultExt, abort: Abort, confirm: Confirm, inform: Inform, modes: modes];
IF name # NIL THEN {
i: INT;
new: ROPE = IF (i ← Rope.Find[file, "."]) = -1 AND (i ← Rope.Find[name, "."]) # -1 THEN Rope.Substr[base: name, len: i] ELSE name; -- if original file did not have an extension and name does, strip it off for purposes of correcting history.
};
};
};
GetMatchingFileList: PUBLIC PROC [
file: ROPE,
defaultExt: ROPENIL,
handle: Commander.Handle ← NIL,
modes: Spell.Modes ← NIL] RETURNS [fileList: LIST OF ROPENIL] = {
exec: UserExec.ExecHandle;
event: UserExec.HistoryEvent;
TRUSTED {IF Rope.IsEmpty[file] OR NOT Runtime.IsBound[Spell.GetTheOne] THEN RETURN[NIL]};
[exec, event] ← GetExecHandle[handle];
IF exec # NIL THEN RETURN[UserExec.GetMatchingFileList[file: file, defaultExt: defaultExt, event: event, exec: exec, modes: modes]];
IF NOT Spell.IsAPattern[file] THEN {
val: ROPE = GetTheFile[file: file, defaultExt: defaultExt, handle: handle];
IF val # NIL THEN RETURN[LIST[val]]
ELSE RETURN[NIL];
};
{
Abort: Spell.AbortProc = {
CommandProcOps.CheckForAbort[handle];
};
Confirm: Spell.ConfirmProc -- [msg: ROPE, timeout: INT, defaultConfirm: BOOL] RETURNS[yes: BOOL] -- = {
RETURN[
CommandProcOps.Confirm[msg: msg, timeout: timeout, defaultConfirm: defaultConfirm, handle: handle]
]
};
Inform: Spell.InformProc --[msg: ROPE] -- = {
IF handle # NIL THEN handle.out.PutF["*n%g\n", rope[msg]]
ELSE MessageWindow.Append[message: msg, clearFirst: TRUE];
};
fileList ← Spell.GetMatchingFileList[unknown: file, defaultExt: defaultExt, abort: Abort, inform: Inform, confirm: Confirm, modes: modes];
};
};
AcquireResource
Acquire: PUBLIC PROC [
resource: REF ANY,
waitForIt: BOOLFALSE,
owner: Rope.ROPENIL,
handle: Commander.Handle
] RETURNS[success: BOOL, ownedBy: Rope.ROPE] = {
Calls through to Resource.Acquire with an appropraite abortProc. If waitForIt = TRUE, and the resource is busy, first prints a message informing user.
abort: Resource.AbortProc = {
RETURN[handle.in.UserAbort[]];
};
[success, ownedBy] ← Resource.Acquire[resource: resource, waitForIt: FALSE, owner: owner, abortProc: abort];
CommandProcOps.CheckForAbort[handle];
IF success THEN RETURN;
IF owner # NIL THEN {
handle.out.PutF["*n*mWaiting for %g to finish...", rope[ownedBy]];
handle.out.Flush[];
};
[success, ownedBy] ← Resource.Acquire[resource: resource, waitForIt: TRUE, owner: owner, abortProc: abort];
CommandProcOps.CheckForAbort[handle];
IF owner # NIL THEN {
handle.out.PutF["proceeding\n*s"];
handle.out.Flush[];
};
};
Release: PUBLIC PROC [resource: REF ANY] RETURNS[success: BOOL] = { RETURN[Resource.Release[resource]]};
same as Resource.Release.
END. -- of CommandProcOpsImpl