<> 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; <> AskUser: PUBLIC PROC [msg: ROPE, timeout: INT _ -1, defaultKey: ATOM _ NIL, handle: Commander.Handle _ NIL, keyList: LIST OF ATOM _ NIL] 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]]; }; <> EventFailed: PUBLIC PROC [handle: Commander.Handle, msg: ROPE, offender: ROPE _ NIL] = { 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: 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: ROPE _ 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]; }; 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 ROPE _ 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]; }; 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: BOOL _ FALSE] = { <> 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: ROPE _ NIL, handle: Commander.Handle _ NIL, modes: Spell.Modes _ NIL] RETURNS [name: ROPE _ NIL] = { 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: ROPE _ NIL, handle: Commander.Handle _ NIL, modes: Spell.Modes _ NIL] RETURNS [fileList: LIST OF ROPE _ NIL] = { 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]; }; }; <> Acquire: PUBLIC PROC [ resource: REF ANY, waitForIt: BOOL _ FALSE, owner: Rope.ROPE _ NIL, handle: Commander.Handle ] RETURNS[success: BOOL, ownedBy: Rope.ROPE] = { <> 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]]}; <> END. -- of CommandProcOpsImpl