Edited by Teitelman on April 18, 1983 1:31 pm
userexecprivate is for internal communication between modules of userexec, and, in certain exceptional cases, for use by privileged clients. If you are using this interface, please let me (Teitelman) know about it.
it is subject to change without notice.
DIRECTORY
BBAction USING [Action],
BBEval USING [EvalHead],
BBInterp USING [Tree],
File USING [Capability, nullCapability],
IO USING [DeliverWhenProc],
Menus USING [Menu, MenuEntry],
Spell USING [Modes, SpellingGenerator],
TiogaOps USING [Location, SelectionGrain], -- for ActionAreaData. If this becomes a problem, can make ActionAreaData opaque.
TTY USING [Handle],
UserExec USING [HistoryEvent, HistoryList, MethodProc, CommandProc, TransformProc, ExecHandle, Expression, ROPE, STREAM, TV, Viewer],
WorldVM USING [World]
;
UserExecPrivate: CEDAR DEFINITIONS IMPORTS UserExec, File =
BEGIN OPEN UserExec;
Concrete types for opaque types in userexec
ExecPrivateRecord and related types
ExecPrivateRecord: TYPE = MONITORED RECORD[
historyList: HistoryList,
id: ROPE, -- i.e. A, B, ... Z, AA, AB, etc.
execState: GlobalExecState ← notListening,
eventState: LocalExecState ← readyForNext,
for dealing with the interpreter
evalMode: BOOLEANFALSE,
actionAreaData: REF ActionAreaData ← NIL,
spawnedActionArea: ExecHandle ← NIL,
evalHead: BBEval.EvalHead ← NIL,
the following relate to interactions with typein and output.
lastChar: CHARACTERNULL, -- lastcharacter output to (or echoed to) exec.out .used in UserExecImpl.DefaultDeliverWhen, e.g. to remember if a CR was preceded by a '.
dontPrompt: BOOLEANFALSE, -- for continuing an event, e.g. following ESC completion. What the user sees on the input line is accurate.
continuation: BOOLEANFALSE, 
eventNum: INT ← 1, -- the event number of the next event to be created. used to prompt the user. Also used in UserExecInterpImpl.TreatAsExpr and used in HistoryImpl.CreateEvent.
advice: LIST OF Advice ← NIL, -- list of expressions to be evaluated when userexecutive is again ready for input.
lastLine: ROPENIL, -- holds last input line. ExecProcessInput obtains the input from this field. Used in UserExecImpl.DefaultDeliverWhen to handle treatment of esc.
for compatibility with old Exec interface
execDotW: TTY.Handle, -- UserExecRegCmdsImpl.CallRegisteredProc sets Exec.w to this before calling a procedure registered through Exec.AppendCommand
process: UNSAFE PROCESS, -- initialized to Process.GetCurrent[] when exec handle is created. used by UserExecImpl.GetExecHandle to find out which exec the current process is under. Also used to determine the parent for a spawned action area.
following deals with problems of synchronizing input/output to exec where may have several events running simultaneously.
execOwner: UNSAFE PROCESSNIL, -- usually itself
execOwnerCount: INT ← 0, -- to permit clients to Acquire/Release Exec without having to worry about previously owned in same process.
in, out: STREAMNIL
];
GlobalExecState: TYPE = {notListening, listening, dormant, suspended, destroyed};
ExecState contains the global state of the exec. EventState describes its state with respect to the current event. There is some redundancy, in that if execState = destroyed, eventState could never be running. However, execState might be dormant or notListening and eventState could be running, e.g. if DoIt were called directly.
LocalExecState: TYPE = {readyForNext, receivingInput, running};
readyForNext means at prompt. receivingInput means user has already typed something.
ActionAreaData: TYPE = RECORD[
action: BBAction.Action ← NIL,
parentExec: ExecHandle ← NIL,
world: WorldVM.World ← NIL,
viewer: Viewer ← NIL,
fullMsg, abbrevMsg, iconMsg: ROPENIL,
aborted, booted: BOOLFALSE, -- when action = NIL, this says whether it was proceeded or aborted. Used in userexecimpl
tiogaDoc: BOOLTRUE,
restoreSelAfterEachEvent: BOOLFALSE,
start, end: TiogaOps.Location ← [NIL, 0],
level: TiogaOps.SelectionGrain ← char,
caretBefore: BOOL ← NULL,
pendingDelete: BOOL ← NULL
];
Advice: TYPE = REF AdviceRecord;
AdviceRecord: TYPE = RECORD[before, after: PROC[data: REF ANY], data: REF ANY];
Events and expressions
HistoryEventPrivateRecord: TYPE = RECORD[
eventNum: NAT,
value: TVNIL, -- move to userexec
state: EventState ← notFinishedYet,
offender: ROPENIL, -- set by EventFailed so that when event completes, can tell that it caused an error
showInput: BOOLEANFALSE, -- tells userexec to print the event it is about to execut
inCommandFile: BOOLEANFALSE, -- either cm or commands
inCMFile: BOOLEANFALSE -- true when inside of a CM file
];
ExpressionPrivateRecord: TYPE = RECORD[
tree: BBInterp.Tree ← NIL,
valueRope: ROPENIL,
goForIt: BOOLFALSE
];
EventState: TYPE = {notFinishedYet, causedAnError, aborted, completed};
EvalHead
EvalHeadData: TYPE = RECORD[
exec: UserExec.ExecHandle,
viewer: Viewer,
generators: REF GeneratorsRecord ← NIL, -- for use in correcting interpreter errors. need to be separate for each exec because can now do evaluation in many execs.
expr: Expression ← NIL,
defaultInterface: ROPENIL,
confirmMenuUp: BOOLFALSE
];
the type of the REF stored in BBEval.EvalHead.data. Used in various Help procedures. Included here so that can set defaultInterface field in UserExecInterpImpl
GeneratorsRecord: TYPE = RECORD[
typeElementGenerator: Spell.SpellingGenerator, -- used to generate elements in a type, e.g. record, globalframe, etc.
enumTypeGenerator: Spell.SpellingGenerator, -- used to generate the elements of an enumerated
subrangeGenerator: Spell.SpellingGenerator, -- used to generate the elements of a subrange type
frameGenerator: Spell.SpellingGenerator -- used to generate global framenames and interface names from cached list
];
Miscellaneous
MethodList: TYPE = LIST OF REF MethodRecord;
MethodRecord: TYPE = RECORD[
name: ROPENIL,
proc: MethodProc ← NIL,
doc: ROPENIL,
clientData: REF ANYNIL
];
CommandList: TYPE = LIST OF REF CommandRecord;
CommandRecord: TYPE = RECORD[
name: ROPENIL,
commandProc: UserExec.CommandProc ← NIL,
oldStyleProc: UNSAFE PROCEDURENIL, -- for registering with Exec interface
transformProc: UserExec.TransformProc ← NIL,
briefDocumentation, documentation: ROPENIL,
nameOfBCD: ROPENIL,
clientData: REF ANYNIL,
fromCatalogue: BOOLFALSE
];
ResponseRecord: TYPE = MONITORED RECORD[
hasResponded: BOOLEANFALSE, -- tells program waiting for response that the value in value is now valid. Reset to FALSE in UserExecImpl.ExecGetRope.
value: ATOMNIL,
keyList: LIST OF ATOMNIL,
menuCount: INT ← 0,
HasResponded: CONDITION
];
constants and variables
ExecDeliverWhen: IO.DeliverWhenProc;
w: TTY.Handle; -- exported to Exec. Included here so both UserExecImpl and UserExecRegCmdsImpl can set it.
commandString: LONG STRING; -- ditto.
commandGenerator: Spell.SpellingGenerator;
suitable for spelling correction and pattern matching on registered commands. 
defaultExec: ExecHandle;
execHandleList: LIST OF ExecHandle;
commandList: CommandList;
methodList: MethodList;
execMenu: Menus.Menu;
secondMenuLine: Menus.MenuEntry;
experimentalNewFeatures: BOOLEAN;
version: ROPE;
Zone: PRIVATE ZONE; -- prefixed zone.
tildas: ROPE; -- "~~~~...~~~~"
defaultDepth, defaultWidth: INT; -- controls printing of expressions.
signals
FileNotFound: SIGNAL [name: ROPE, defaultExt: ROPENIL] RETURNS [shouldBe: ROPE];
raised by runbcd
GoToSleep: ERROR; -- tells exec handle to go dormant and stop listening. Restart via StartExec.
HistoryError: ERROR [ec: HistoryErrorCode, msg: ROPENIL];
raised by UseCommand
HistoryErrorCode: TYPE = {UseWhat, UseForWhat, UseHuh, NotFound};
manipulating execHandles
DestroyExec: PROCEDURE [exec: ExecHandle];
CaptionForExec: PROC [exec: ExecHandle, paint: BOOLTRUE] RETURNS[caption: ROPE];
computes caption using name of exec, mode and default context, action area status etc.
GetPrivateStuff: PROC [exec: ExecHandle] RETURNS[REF ExecPrivateRecord];
checks to see if exec is NIL, or destroyed and raises InvalidExecHandle
GetExecFromStream: PROC [in: STREAM] RETURNS[UserExec.ExecHandle];
AcquireExec: PROC [exec: ExecHandle] RETURNS[newlyAcquired: BOOL];
ReleaseExec: PROC [exec: ExecHandle] RETURNS[released: BOOL];
AdviseExec: PROC [exec: ExecHandle, before, after: PROC[data: REF ANY], data: REF ANY];
CreateExecLogFile: PROC [exec: ExecHandle] RETURNS[stream: STREAM];
CloseExecLogFile: PROC [exec: ExecHandle];
processing events
EventFailed: PROC [event: HistoryEvent, msg: ROPE ← NIL, offender: ROPENIL];
CreateSubEvent: PROC [event: HistoryEvent, input: ROPE] RETURNS[subEvent: HistoryEvent];
creates a subevent to the current (sub)event, inheriting the relevant properties from the current event, e.g. eventNum, and attaches it to event.
StoreInSymTab: PROC [value: TV, event: HistoryEvent, exec: ExecHandle];
makes the & variable associated with event have as its value the indicated tv. For use for those commands which return a value, e.g. walkstack, showframe, etc. move to userexec
EvalEvent: PROC [event: HistoryEvent, exec: ExecHandle];
GetEvalHead: PROC [exec: ExecHandle, expr: Expression ← NIL, viewer: Viewer ← NIL] RETURNS [BBEval.EvalHead];
in case exec # NIL, evalhead is cached in exec, and GetEvalHead just fills in the expr parts of data field of the evalHead.
ExpandCommandLine: PROC [line: ROPE, modes: Spell.Modes ← NIL, event: HistoryEvent, exec: ExecHandle] RETURNS [ROPE];
modes used in expansion of *'s. Defaults to users profile settings, but overriden for things like ^X which should not have to be confirmed
GetRestOfStream: PROC [in: STREAM, includeLast: BOOLTRUE] RETURNS[ROPE];
Prompt: PROC [eventNum: INT, exec: ExecHandle];
prompts with &n and ← if appropriate. Computes a sticky addr for beginning of line and saves it on exec.
DoesUserMean: PROC [rope: ROPE, exec: ExecHandle, intro: ROPENIL -- defaults to "perhaps user means:" -- ];
prompts user, loads input stream, and otherwise sets things upto allow user to simply type cr.
ReadQuietly: PROC [rope: ROPE, exec: ExecHandle];
defined in UserExecRegCmdsImpl, called from UserExecRegCmdsImpl.DoesUserMean, UserExecMethodsImpl.ExpandControlX, Escape.
Miscellaneous
BlinkIcon: PROC [icon: Viewer, n: INT ← 10];
forks a process which blinks the icon every n seconds until the icon is either opened, destroyed, or some other viewer is selected.
LookupCommand: PROC [name: ROPE, event: HistoryEvent ← NIL, exec: ExecHandle ← NIL] RETURNS[fullName: ROPE];
name may be misspelled, or incomplete. If there is more than command that matches name, prints an ambiguous message to exec.
if event, exec = NIL, simply calls Commander.Lookup.
GetRegistrationData: PROC [name: ROPE] RETURNS[REF CommandRecord];
LookupCommands: PROC [name: ROPE, event: HistoryEvent, exec: ExecHandle] RETURNS[LIST OF REF CommandRecord];
does not print the ambiguous message.
ReleaseResources: PROC [process: UNSAFE PROCESS]; -- releases all resources held by this process
CallRegisteredProc: PROC [command: ROPE, event: HistoryEvent, exec: ExecHandle] RETURNS[handled: BOOLEANFALSE];
processes the command line and then invokes the registered procedure in appropriate way
Register: PROC [
name: ROPENIL,
proc: UserExec.CommandProc ← NIL,
oldStyleProc: UNSAFE PROCEDURENIL,
transformProc: UserExec.TransformProc ← NIL,
briefDoc, doc: ROPENIL,
nameOfBCD: ROPENIL,
clientData: REF ANYNIL,
fromCatalogue: BOOLFALSE
];
Private
The following procedures should not be of interest to any client of userexec, even a wizard. The only reason they appear in an interface is that they happen to be called from more than one module.
RunAndCall: UserExec.CommandProc;
defined in UserExecOpsImpl, also called from UserExecMethodsImpl by ImplicitRunAndCall
RunBCDFile: PROCEDURE[fileName: ROPE, fileCapability: File.Capability ← File.nullCapability, callDebuggerFirst: BOOLFALSE, out: STREAM] RETURNS[name: ROPE, error: ROPE];
defined in UserExecMiscImpl, called from UserExecRegCmdsImpl.CallRegisteredProc, and UserExecOpsImpl.Run, RunAndCall
RenameFile: PROCEDURE[oldName, newName: ROPE, out: STREAM] RETURNS[success: BOOL];
PrintDeclFromSource: PROC [target: ROPE, file: ROPE, exec: UserExec.ExecHandle] RETURNS [BOOLEAN];
defined in UserExecMiscImpl, called from DwimImpl.HelpWrongType (for INLINE), and UserExecMethodsImpl.Help. opens stream on file if exists, searches for target as a declaration, and if found, prints declaration to exec.out. If anything fails, returns FALSE. Stream on File is closed
ProcessProfile: PROC;
defined in ViewerExecOpsImpl, called from ViewerExecOpsImpl.WasProfileEdited, and from UserExecOpsImpl.LoginProc, Login
PrintCommand: PROCEDURE[name: ROPE, event: HistoryEvent, exec: ExecHandle] RETURNS[recognized: BOOLEAN];
defined in UserExecMethodsImpl, called from UserExecMethodsImpl.Help, also called from UserExecRegCmdsImpl.LookupCommand, prints explanation of name. Used by ? command. Returns FALSE if name not a command
UpdateFrameCache: PROC;
defined in DwimImpl. called from UserExecMiscImpl.LoadAndGo. called after run command executed.
RegisterCommanderStuff: PROCEDURE;
defined in UserExecRegCmdsImpl. called from UserExecMiscImpl.LoadAndGo. called after run command executed.
RopeFromCMFile: PROC [file: ROPE, event: HistoryEvent, exec: ExecHandle] RETURNS[contents: ROPE, name: ROPE];
defined in UserExecMiscImpl, called from UserExecRegCmdsImpl.ExpandCommandLine, and UserExecOpsImpl.CommandsFrom
tries RopeFromFile[fileName]. If fails, tries to add .commands and go again. If that fails, tries cm and go again. If that fails, raises FileNotFound to get correction. If that fails, prints message and raises abortthisevent. name is the name of the file that was finally used, and has @ stripped off.
StripComments: PROC [event: HistoryEvent, rope: ROPE] RETURNS [ROPE];
defined in UserExecMiscImpl, called from UserExecMiscImpl.DoIt, and also from UserExecRegCmdsImpl.ExpandCommandLine,
ExecOwner: PROC[exec: ExecHandle] RETURNS[UNSAFE PROCESS] = INLINE
{private: REF ExecPrivateRecord = GetPrivateStuff[exec]; RETURN[private.execOwner]};
To be moved to UserExec
ForAllSplitViewers: PROC [viewer: Viewer, proc: SplitViewerProc];
SplitViewerProc: TYPE = PROC[viewer: Viewer];
END. -- UserExecPrivate