DIRECTORY ActionAreas USING [actionAreaIcon, RestoreSelection, inactiveActionAreaIcon], BBAction USING [Abort, Action, ActionId, TakeData], BBBreak USING [BreakEntry, BreakExit, BreakIndex], BBContext USING [Context, ContextForLocalFrame, GetContents], BBSafety USING [Mother], BBVForUserExec USING [ReportProc, Severity], BBVExtras USING [ShowBreakPoint, ClearActionBreakPoint, ClearSelectedBreakPoint, ClearAllBreaks, DisplayLocalFrame, ShowSource, WalkContext, ListBreaks, SetBreakFromPosition], Convert USING [ValueToRope], IO USING [CurrentPosition, SyntaxError, EndOfStream, Flush, GetInt, PutChar, PutF, PutRope, int, rope, ROPE, STREAM, TV, RIS, GetToken, IDProc, WhiteSpace], Menus USING [AppendMenuEntry, ClickProc, CreateEntry, GetLine, Menu, MenuEntry, SetLine], MessageWindow USING [Append, Blink, Clear], Process USING [Detach, Pause, MsecToTicks, Ticks], Rope USING [Equal, IsEmpty, Length, Cat, Concat], TiogaOps USING [Location, LocOffset, SelectionGrain, GetSelection, ViewerDoc], UserExec USING [HistoryEvent, RegisterCommand, CommandProc, ExecHandle, Expression, EvaluationFailed, CreateExpr, EvalExpr, Viewer, GetExecHandle, GetStreams, StuffIt, DoIt], UserExecPrivate USING [ActionAreaData, CaptionForExec, execMenu, ExecPrivateRecord, GoToSleep, execHandleList, GetPrivateStuff, tildas, secondMenuLine, ForAllSplitViewers, SplitViewerProc], ViewerClasses USING [Viewer], ViewerOps USING [PaintViewer, SetMenu, CloseViewer, DestroyViewer, FindViewer], ViewerTools USING [GetSelectedViewer, GetSelectionContents, SetSelection], WorldVM USING [World] ; ActionAreasOpsImpl: CEDAR PROGRAM IMPORTS ActionAreas, BBAction, BBBreak, BBContext, BBSafety, BBVExtras, Convert, IO, Menus, MessageWindow, Process, Rope, TiogaOps, UserExec, UserExecPrivate, ViewerOps, ViewerTools EXPORTS UserExec, UserExecPrivate = BEGIN OPEN IO; tildas: PUBLIC ROPE _ "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; ExecHandle: TYPE = UserExec.ExecHandle; Viewer: TYPE = UserExec.Viewer; ClickProc: TYPE = Menus.ClickProc; Action: TYPE = BBAction.Action; ExecPrivateRecord: PUBLIC TYPE = UserExecPrivate.ExecPrivateRecord; SetBreak: ClickProc = { viewer: Viewer _ NARROW[parent]; exec: ExecHandle = UserExec.GetExecHandle[viewer: viewer]; start: TiogaOps.Location; command: ROPE; private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; IF private.execState = suspended THEN { MessageWindow.Append["That exec is busy. Use another one.", TRUE]; MessageWindow.Blink[]; RETURN; }; [viewer, start] _ TiogaOps.GetSelection[]; IF viewer = NIL THEN {ReportExec[exec, "Make a selection.", fatal]; RETURN}; SELECT mouseButton FROM red => command _ "SetBreak"; yellow, blue => { sel: ROPE = ViewerTools.GetSelectionContents[]; IF mouseButton = yellow THEN command _ "BreakAtEntry" ELSE command _ "BreakAtExit"; IF Rope.Length[sel] > 1 THEN { command _ Rope.Cat[command, " ", sel]; viewer _ NIL; }; }; ENDCASE => ERROR; IF viewer # NIL THEN command _ Rope.Cat[command, " ", viewer.name, " ", Convert.ValueToRope[[signed[TiogaOps.LocOffset[loc1: [TiogaOps.ViewerDoc[viewer], 0], loc2: start, skipCommentNodes: TRUE]]]]]; IF private.execState = dormant THEN -- dormant, i.e. not waiting for input. must call direct, but have to fork because the command is not supposed to be executed under notifier TRUSTED {Process.Detach[FORK UserExec.DoIt[input: Rope.Concat[command, "\n"], exec: exec]]} ELSE MakeExecCommand[NARROW[parent], command, TRUE]; ViewerTools.SetSelection[exec.viewer]; }; ClearBreak: ClickProc = { viewer: Viewer = NARROW[parent]; exec: ExecHandle = UserExec.GetExecHandle[viewer: viewer]; private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; command: ROPE; command _ SELECT mouseButton FROM red => IF ViewerTools.GetSelectedViewer[] = viewer THEN "ClearActionBreak" ELSE "ClearSelectedBreak", yellow => "ClearActionBreak", blue => "ClearAllBreaks", ENDCASE => ERROR; IF private.execState = suspended THEN { MessageWindow.Append["That exec is busy. Use another one.", TRUE]; MessageWindow.Blink[]; } ELSE IF private.execState = dormant THEN -- dormant, i.e. not waiting for input. must call direct TRUSTED {Process.Detach[FORK UserExec.DoIt[input: Rope.Concat[command, "\n"], exec: exec]]} ELSE MakeExecCommand[NARROW[parent], command, TRUE]; }; Proceed: ClickProc -- PROC [parent: REF ANY, clientData: REF ANY, redButton: BOOL] -- = { MakeExecCommand[NARROW[parent], SELECT mouseButton FROM red => "Proceed", yellow => "Proceed Destroy", blue => "Proceed Close", ENDCASE => ERROR]; }; Abort: ClickProc -- PROC [parent: REF ANY, clientData: REF ANY, redButton: BOOL] -- = { viewer: Viewer = NARROW[parent]; exec: ExecHandle = UserExec.GetExecHandle[viewer: viewer]; AbortExec: PROC [exec: ExecHandle] = { private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; viewer: Viewer = exec.viewer; IF private.execState = suspended THEN { WaitTillReady: PROC [exec: ExecHandle] = { ticks: Process.Ticks = Process.MsecToTicks[100]; UNTIL private.eventState = readyForNext DO Process.Pause[ticks]; ENDLOOP; }; AbortExec[private.spawnedActionArea];-- abort the child first. WaitTillReady[exec]; -- wait until the abort gets noticed by this work area, since otherwise the "Abort" stuffed in the buffer would be cleared, and therefore never take place. }; MakeExecCommand[viewer, SELECT mouseButton FROM red => "Abort", yellow => "Abort Destroy", blue => "Abort Close", ENDCASE => ERROR]; }; IF exec = NIL THEN {ReportProc["Exec = NIL", fatal]; RETURN}; AbortExec[exec]; }; Source: ClickProc -- PROC [parent: REF ANY, clientData: REF ANY, redButton: BOOL] -- = { r: ROPE _ "Source"; IF control THEN r _ Rope.Concat[r, " global"]; MakeExecCommand[NARROW[parent], r, TRUE]; }; WalkStack: ClickProc -- PROC [parent: REF ANY, clientData: REF ANY, redButton: BOOL] -- = { MakeExecCommand[ NARROW[parent], SELECT mouseButton FROM red => "WalkStack", yellow => "WalkStack 0", blue => "WalkStack -1", ENDCASE => ERROR, TRUE]; }; ShowFrame: ClickProc -- [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] -- = { r: ROPE _ SELECT mouseButton FROM red => "ShowFrame", yellow => "ShowFrame args", blue => "ShowFrame args allVars", ENDCASE => ERROR; IF control THEN r _ Rope.Concat[r, " globals"]; MakeExecCommand[NARROW[parent], r, TRUE]; }; ListBreaks: ClickProc -- PROC [parent: REF ANY, clientData: REF ANY, redButton: BOOL] -- = { MakeExecCommand[NARROW[parent], "ListBreaks"]; }; MakeExecCommand: PROCEDURE [viewer: Viewer, command: ROPE, sameLine: BOOL _ FALSE] = { exec: ExecHandle = UserExec.GetExecHandle[viewer: viewer]; private: REF ExecPrivateRecord; IF exec = NIL THEN {ReportProc["Exec = NIL", fatal]; RETURN}; private _ UserExecPrivate.GetPrivateStuff[exec]; IF sameLine THEN { IF private.eventState = running THEN UserExec.StuffIt[exec, Rope.Cat["\021", command, "\t"]] -- workaround, because currently, changing a typescript look will not take effect until the typescript is waiting for a character, which means the notifier gets wedged until the event that is currently executing finishes ELSE UserExec.StuffIt[exec: exec, rope: NIL, list: LIST[NEW[INT _ ('S - 'A)], $ApplyTypeScriptLook, "\021", command, NEW[INT _ ('S - 'A)], $RemoveTypeScriptLook, "\t"]] } ELSE UserExec.StuffIt[exec, Rope.Cat["\021", command, "\n"]]; }; SetBreakCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { action: Action = GetAction[exec]; viewerName: ROPE; viewer: ViewerClasses.Viewer; position: INT _ -1; break: BBBreak.BreakIndex; Report: BBVForUserExec.ReportProc = { ReportExec[exec, msg, severity]; }; world: WorldVM.World; IF action # NIL THEN world _ action.event.world; MessageWindow.Clear[]; viewerName _ event.commandLineStream.GetToken[IO.WhiteSpace ! IO.EndOfStream => CONTINUE]; position _ event.commandLineStream.GetInt[ ! IO.EndOfStream => CONTINUE ]; viewer _ ViewerOps.FindViewer[viewerName]; IF viewer = NIL THEN Report["No such viewer", fatal] ELSE IF position = -1 THEN Report["No such location", fatal] ELSE break _ BBVExtras.SetBreakFromPosition[report: Report, viewer: viewer, position: position, world: world]; ShowBreakPoint[exec, break]; }; BreakAtEntryCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { BreakEntryOrExit[event: event, exec: exec, entry: TRUE]; }; BreakAtExitCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { BreakEntryOrExit[event: event, exec: exec, exit: TRUE]; }; BreakEntryOrExit: PROC [event: UserExec.HistoryEvent, exec: ExecHandle, entry: BOOL _ FALSE, exit: BOOL _ FALSE] = { action: Action = GetAction[exec]; break: BBBreak.BreakIndex; name: ROPE = IO.GetToken[event.commandLineStream, IO.IDProc]; position: INT _ -1; Report: BBVForUserExec.ReportProc = { ReportExec[exec, msg, severity]; }; world: WorldVM.World; IF NOT entry AND NOT exit THEN RETURN; IF action # NIL THEN world _ action.event.world; position _ event.commandLineStream.GetInt[ ! IO.EndOfStream => CONTINUE; ]; IF position # -1 THEN { viewer: ViewerClasses.Viewer = ViewerOps.FindViewer[name]; IF viewer = NIL THEN Report["No such viewer", fatal] ELSE break _ BBVExtras.SetBreakFromPosition[viewer: viewer, position: position, report: Report, world: world, entry: entry, exit: exit] } ELSE { inner: PROC = { IF exit THEN break _ BBBreak.BreakExit[expr.value]; IF entry THEN break _ BBBreak.BreakEntry[expr.value]; }; error: ROPE; expr: UserExec.Expression = UserExec.CreateExpr[name]; MessageWindow.Append[Rope.Cat["Evaluating ", name, "..."], TRUE]; [] _ UserExec.EvalExpr[expr: expr, exec: exec ! UserExec.EvaluationFailed => { error _ msg; CONTINUE }]; MessageWindow.Clear[]; IF error = NIL THEN error _ BBSafety.Mother[inner]; IF error # NIL THEN Report[error, fatal]; }; ShowBreakPoint[exec, break]; }; ShowBreakPoint: PROCEDURE [exec: UserExec.ExecHandle, break: BBBreak.BreakIndex] = { Report: BBVForUserExec.ReportProc = {ReportExec[exec, msg, severity]}; MessageWindow.Clear[]; BBVExtras.ShowBreakPoint[break, Report]; }; ClearBreakCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { Report: BBVForUserExec.ReportProc = {ReportExec[exec, msg, severity]}; action: Action = GetAction[exec]; IF ViewerTools.GetSelectedViewer[] = exec.viewer THEN -- selection is in the action area. clear the break associated with that area BBVExtras.ClearActionBreakPoint[GetAction[exec], Report] ELSE BBVExtras.ClearSelectedBreakPoint[IF action # NIL THEN action.event.world ELSE NIL, Report]; }; ClearActionBreakCommand: UserExec.CommandProc = { Report: BBVForUserExec.ReportProc = {ReportExec[exec, msg, severity]}; BBVExtras.ClearActionBreakPoint[GetAction[exec], Report]; }; ClearAllBreaksCommand: UserExec.CommandProc = { Report: BBVForUserExec.ReportProc = {ReportExec[exec, msg, severity]}; BBVExtras.ClearAllBreaks[Report]; }; ProceedCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { out: STREAM = UserExec.GetStreams[exec].out; action: Action = GetAction[exec]; r: ROPE; IF action = NIL THEN {out.PutF["*eNo action associated with this work area."]; RETURN}; -- user typed this to a work area no longer associated with an action. In future, this will simply be disabled via predicate associated with command. LeaveActionArea[exec: exec, abort: FALSE]; IF action.status = pendingOut THEN [] _ BBAction.TakeData[action] ELSE IF action.status = busy THEN NULL ELSE ERROR; r _ IO.GetToken[event.commandLineStream, IO.IDProc]; SELECT TRUE FROM Rope.Equal[r, "Destroy", FALSE] => ViewerOps.CloseViewer[exec.viewer]; Rope.Equal[r, "Close", FALSE] => ViewerOps.DestroyViewer[exec.viewer]; ENDCASE; ERROR UserExecPrivate.GoToSleep[]; }; AbortCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { out: STREAM = UserExec.GetStreams[exec].out; action: Action = GetAction[exec]; r: ROPE; IF action = NIL THEN {out.PutF["*eNo action associated with this work area."]; RETURN}; LeaveActionArea[exec: exec, abort: TRUE]; IF action.status = pendingOut THEN [] _ BBAction.Abort[action] ELSE IF action.status = dead THEN NULL ELSE ERROR; r _ IO.GetToken[event.commandLineStream, IO.IDProc]; SELECT TRUE FROM Rope.Equal[r, "Destroy", FALSE] => ViewerOps.CloseViewer[exec.viewer]; Rope.Equal[r, "Close", FALSE] => ViewerOps.DestroyViewer[exec.viewer]; ENDCASE; ERROR UserExecPrivate.GoToSleep[]; }; EndSessionCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { out: STREAM = UserExec.GetStreams[exec].out; action: Action = GetAction[exec]; IF action = NIL THEN {out.PutF["*eNo action associated with this work area."]; RETURN}; LeaveActionArea[exec: exec, abort: FALSE, booted: TRUE]; IF action.status = pendingOut THEN { [] _ BBAction.Abort[action]; ERROR UserExecPrivate.GoToSleep[]; } ELSE IF action.status = dead THEN NULL ELSE ERROR; }; LeaveActionArea: PUBLIC PROC [exec: ExecHandle, abort: BOOL, booted: BOOL _ FALSE] = { ENABLE UNWIND => NULL; viewer: Viewer = exec.viewer; private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; out: STREAM = IF booted THEN private.out ELSE UserExec.GetStreams[exec].out; parentExec: ExecHandle; parentsPrivate: REF ExecPrivateRecord; actionAreaData: REF UserExecPrivate.ActionAreaData = private.actionAreaData; action: Action = actionAreaData.action; msg: ROPE = IF abort THEN "aborted" ELSE "proceeded"; IF booted THEN out.PutF["*n*sEnd Of Session\n"] ELSE { out.PutF["*n*s%g Action #%d", rope[msg], int[action.id]]; IF actionAreaData.parentExec # NIL THEN { parentExec _ actionAreaData.parentExec; parentsPrivate _ UserExecPrivate.GetPrivateStuff[parentExec]; out.PutF[", returning to %g Area %g", rope[IF parentsPrivate.actionAreaData # NIL THEN "Action" ELSE "Work"], rope[parentsPrivate.id]]; }; }; out.PutF["*n%g\n", rope[UserExecPrivate.tildas]]; IO.Flush[out]; actionAreaData.action _ NIL; actionAreaData.aborted _ abort; actionAreaData.booted _ booted; private.process _ NIL; IF private.evalHead # NIL THEN { private.evalHead.context _ NIL; private.evalHead.globalContext _ NIL; }; {viewerProc: UserExecPrivate.SplitViewerProc = { Menus.SetLine[menu: viewer.menu, line: 1, entryList: NIL]; viewer.icon _ ActionAreas.inactiveActionAreaIcon; ViewerOps.PaintViewer[viewer, menu]; }; UserExecPrivate.ForAllSplitViewers[viewer, viewerProc]; }; [] _ UserExecPrivate.CaptionForExec[exec, TRUE]; IF booted THEN RETURN; IF parentsPrivate # NIL THEN { viewerProc: UserExecPrivate.SplitViewerProc = TRUSTED { IF parentsPrivate.actionAreaData # NIL THEN { viewer.icon _ ActionAreas.actionAreaIcon; Menus.SetLine[menu: viewer.menu, line: 1, entryList: UserExecPrivate.secondMenuLine]; ViewerOps.PaintViewer[viewer, menu]; } ELSE viewer.icon _ typescript; }; IF NOT abort THEN parentsPrivate.out.PutF["*mcontinuing*s\n"]; parentsPrivate.spawnedActionArea _ NIL; UserExecPrivate.ForAllSplitViewers[parentExec.viewer, viewerProc]; parentsPrivate.execState _ listening; [] _ UserExecPrivate.CaptionForExec[actionAreaData.parentExec, TRUE]; }; ActionAreas.RestoreSelection[exec]; }; SourceCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; commandLineStream: STREAM = IO.RIS[event.commandLine]; useGlobal: BOOL _ FALSE; ctx: BBContext.Context; tv, gfTV: TV; r: ROPE; comment, fatal, success: BOOL _ FALSE; Report: BBVForUserExec.ReportProc = { IF Rope.IsEmpty[msg] THEN RETURN; SELECT severity FROM comment => {IF comment THEN RETURN; comment _ TRUE}; fatal => {IF fatal THEN RETURN; fatal _ TRUE}; success => {IF success THEN RETURN; success _ TRUE}; ENDCASE => RETURN; ReportExec[exec, msg, severity]; }; UNTIL Rope.IsEmpty[r _ IO.GetToken[commandLineStream, IO.IDProc]] DO SELECT TRUE FROM Rope.Equal[r, "global", FALSE] => useGlobal _ TRUE; ENDCASE; ENDLOOP; MessageWindow.Clear[]; ctx _ IF private.evalHead.context # NIL THEN private.evalHead.context ELSE private.evalHead.globalContext; [, gfTV, tv] _ BBContext.GetContents[ctx]; IF tv = NIL OR useGlobal THEN tv _ gfTV; BBVExtras.ShowSource[tv, Report] }; WalkStackCommand: UserExec.CommandProc -- [exec: ExecHandle] RETURNS[ok: BOOLEAN _ TRUE] -- = { Report: BBVForUserExec.ReportProc = {ReportExec[exec, msg, severity]}; private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; commandLineStream: STREAM = event.commandLineStream; lf: TV; delta: INT _ 1; MessageWindow.Clear[]; delta _ commandLineStream.GetInt[! IO.SyntaxError => CONTINUE; IO.EndOfStream => CONTINUE ]; lf _ BBVExtras.WalkContext[private.actionAreaData.action, private.evalHead.context, delta, Report]; IF lf # NIL THEN { private.evalHead.context _ BBContext.ContextForLocalFrame[lf]; BBVExtras.DisplayLocalFrame[out: UserExec.GetStreams[exec].out, lf: lf, report: Report]; }; }; ShowFrameCommand: UserExec.CommandProc = { args, vars, allVars, globals, lfAndPc: BOOL _ FALSE; private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; commandLineStream: STREAM = event.commandLineStream; out: STREAM = UserExec.GetStreams[exec].out; r: ROPE; Report: BBVForUserExec.ReportProc = {ReportExec[exec, msg, severity]}; UNTIL Rope.IsEmpty[r _ IO.GetToken[commandLineStream, IO.IDProc]] DO SELECT TRUE FROM Rope.Equal[r, "args", FALSE] => args _ TRUE; Rope.Equal[r, "vars", FALSE] => {args _ TRUE; vars _ TRUE}; Rope.Equal[r, "allVars", FALSE] => {args _ TRUE; vars _ TRUE; allVars _ TRUE}; Rope.Equal[r, "globals", FALSE] => globals _ TRUE; Rope.Equal[r, "lfAndPc", FALSE] => lfAndPc _ TRUE; ENDCASE; ENDLOOP; MessageWindow.Clear[]; BBVExtras.DisplayLocalFrame[out: out, lf: BBContext.GetContents[private.evalHead.context].lf, report: Report, args: args, vars: vars, allVars: allVars, globals: globals, lfAndPc: lfAndPc]; }; ListBreaksCommand: UserExec.CommandProc = { BBVExtras.ListBreaks[UserExec.GetStreams[exec].out]; }; GetAction: PROC [exec: ExecHandle] RETURNS [Action] = INLINE { private: REF ExecPrivateRecord = UserExecPrivate.GetPrivateStuff[exec]; RETURN[IF private.actionAreaData # NIL THEN private.actionAreaData.action ELSE NIL]; }; ReportProc: BBVForUserExec.ReportProc -- [msg: ROPE, severity: Severity] -- = { MessageWindow.Append[msg]; IF severity = fatal THEN MessageWindow.Blink[]; }; ReportExec: PROC [exec: UserExec.ExecHandle, msg: ROPE, severity: BBVForUserExec.Severity, out: IO.STREAM _ NIL] = { ReportProc[msg, severity]; IF severity = comment THEN NULL ELSE IF exec # NIL THEN {out: STREAM = UserExec.GetStreams[exec].out; IF out.CurrentPosition[] # 0 THEN out.PutChar['\t]; out.PutF[ SELECT severity FROM success => "%g", warning => "*m%g*s", fatal => "*e%g*s", ENDCASE => ERROR, rope[msg] ]; } ELSE IF out # NIL THEN out.PutRope[msg] -- when outRopeStreams can be given font changes, can handle exec and out case the same. ELSE ReportProc[msg, severity]; }; secondMenuLine: PUBLIC Menus.MenuEntry; Init: PROCEDURE [] RETURNS [] = { execMenu: Menus.Menu = UserExecPrivate.execMenu; Menus.AppendMenuEntry[ menu: execMenu, entry: Menus.CreateEntry[name: "Proceed", proc: Proceed, documentation: "Proceed with action", fork: FALSE], line: 1 ]; Menus.AppendMenuEntry[ menu: execMenu, entry: Menus.CreateEntry[name: "Abort", proc: Abort, documentation: "Abort action", fork: FALSE], line: 1 ]; Menus.AppendMenuEntry[ menu: execMenu, entry: Menus.CreateEntry[name: "Source", proc: Source, documentation: "Show source for this context", fork: FALSE], line: 1 ]; Menus.AppendMenuEntry[ menu: execMenu, entry: Menus.CreateEntry[name: "WalkStack", proc: WalkStack, documentation: "Walk stack. Red button => advance one frame earlier on call stack, blue button => advance one frame later, yellow button => reset stack.", fork: FALSE], line: 1 ]; Menus.AppendMenuEntry[ menu: execMenu, entry: Menus.CreateEntry[name: "ShowFrame", proc: ShowFrame, documentation: "Display current frame for this context. Yellow button => with args, Blue button => args + allVars, CTRL => globals", fork: FALSE], line: 1 ]; secondMenuLine _ Menus.GetLine[menu: execMenu, line: 1]; Menus.AppendMenuEntry[ menu: execMenu, entry: Menus.CreateEntry[name: "Set", proc: SetBreak, documentation: "Set Break Point. Click red to at selected location, yellow at entry to indicated procedure, blue at exit.", fork: FALSE], line: 0]; Menus.AppendMenuEntry[ menu: execMenu, entry: Menus.CreateEntry[name: "Clear", proc: ClearBreak, documentation: "Clears current break Point. Blue Button means clear all break points.", fork: FALSE], line: 0 ]; FOR l: LIST OF ExecHandle _ UserExecPrivate.execHandleList, l.rest UNTIL l = NIL DO viewer: Viewer _ l.first.viewer; ViewerOps.SetMenu[viewer, execMenu]; ENDLOOP; }; Init[]; UserExec.RegisterCommand["Proceed", ProceedCommand, "Proceeds current action, if any."]; UserExec.RegisterCommand["Abort", AbortCommand, "Aborts current action, if any."]; UserExec.RegisterCommand["EndSession", EndSessionCommand]; UserExec.RegisterCommand["SetBreak", SetBreakCommand, "Set break point.", "Sets break point at current feedback selection."]; UserExec.RegisterCommand["BreakAtEntry", BreakAtEntryCommand, "Set break point at entry to named procedure. Form is BreakAtEntry ."]; UserExec.RegisterCommand["BreakAtExit", BreakAtExitCommand, "Set break point at exit to named procedure. Form is BreakAtExit ."]; UserExec.RegisterCommand["ClearSelectedBreak", ClearBreakCommand, "Clears selected break point. If selection in action area, same as ClearActionBreak."]; UserExec.RegisterCommand["ClearActionBreak", ClearActionBreakCommand, "Clears break point associated with this action area."]; UserExec.RegisterCommand["ClearAllBreaks", ClearAllBreaksCommand, "Clears all break points."]; UserExec.RegisterCommand["ListBreaks", ListBreaksCommand, "Lists current breakpoints."]; UserExec.RegisterCommand["Source", SourceCommand, "Show source for this context.", "Show source for this context. Source global shows source for the global frame associated with the local context. If there is no local context, both Source and Source global shows source for the default global context."]; UserExec.RegisterCommand["WalkStack", WalkStackCommand, "Walk the Stack.", "Walk the Stack. WalkStack n, where n > 0 means advance n frames earlier in frame order. n < 0 means advance n frames later in frame order. WalkStack {cr} is equivalent to WalkStack 1. WalkStack 0 means reset stack to its original state upon entering the action area"]; UserExec.RegisterCommand["ShowFrame", ShowFrameCommand, "Displays the current frame.", "Displays the current frame. Form is ShowFrame ...options... where options can be one of:\nargs:\tinclude arguments,\nvars:\tinclude local variables for this block,\nallVars:\tinclude all local variables of frame, i.e. if this block is nested, show local variables of outer blocks as well,\nglobals:\tinclude globals for the current local frame,\nlfAndPc:\tshow local frame and pc as long cardinals."]; END. ActionAreasOpsImpl.mesa Warren Teitelman, April 20, 1983 11:04 am Types so can reference action, evalHead, etc. Menu buttons Corresponding exec commands Miscellaneous Initialization Menus.AppendMenuEntry[ menu: execMenu, entry: Menus.CreateEntry[name: "ListBreaks", proc: ListBreaks, documentation: "Lists current break Points."], line: 1]; -- if on first line, not enough room for yes and no buttons Edited on March 28, 1983 12:21 pm, by Teitelman break at exit/entry was not working for point selection. Also, died if evaluation caused an error changes to: DIRECTORY, SetBreak, Report (local of SetBreakCommand), SetBreakCommand, Report (local of BreakEntryOrExit), BreakEntryOrExit, inner (local of BreakEntryOrExit), UserExec, UserExec, DIRECTORY, SetBreak, Report (local of SetBreakCommand), SetBreakCommand, Report (local of BreakEntryOrExit), BreakEntryOrExit, inner (local of BreakEntryOrExit), UserExec, UserExec, END, SetBreak, LeaveActionArea, LeaveActionArea, viewerProc (local of LeaveActionArea), LeaveActionArea Edited on April 6, 1983 11:43 am, by Teitelman changes to: DIRECTORY, SetBreak, SetBreakCommand, BreakEntryOrExit, Report (local of BreakEntryOrExit), IMPORTS, SetBreak, SetBreak, SetBreak Edited on April 20, 1983 9:58 am, by Teitelman changes to: MakeExecCommand ส&– "Cedar" style˜J˜Jšฯc™Jšœ™)J˜šฯk ˜ Jšœ žœ<˜MJšœ žœ%˜3Jšœžœ%˜2Jšœ žœ.˜=Jšœ žœ ˜Jšœžœ˜,Jšœ žœ ˜ฏJšœžœ˜Jš žœžœ_žœžœžœžœ ˜œJšœžœN˜YJšœžœ˜+Jšœžœ%˜2Jšœžœ'˜1Jšœ žœ@˜NJšœ žœ ˜ฎJšœžœจ˜ฝJšœžœ ˜Jšœ žœ@˜OJšœ žœ9˜JJšœžœ˜šœ˜J˜——J˜Jšะblœžœžœ˜%J˜JšžœJžœg˜บJ˜Jšžœ˜"J˜Jšœžœžœžœ˜J˜Jšฯnœž œ-˜@head™Jš  œžœ˜'Jš œžœ˜Jš  œžœ˜#Jš œžœ˜š œžœžœ%˜CJ™'——šœ ™ š œ˜Jšœžœ ˜ Jšœ:˜:J˜Jšœ žœ˜Jšœ žœ;˜Gšžœžœ˜'Jšœ<žœ˜BJšœ˜Jšžœ˜J˜—Jšœ*˜*Jšžœ žœžœ0žœ˜Lšžœ ž˜Jšœž˜šœ˜Jšœžœ&˜/Jšžœžœ˜5Jšžœ˜šžœžœ˜Jšœ&˜&Jšœ žœ˜ J˜—Jšœ˜—Jšžœžœ˜—Jšžœ žœžœชžœ˜ศšžœžœŒ˜ฑJšžœžœ?˜[—Jšžœžœžœ˜4J˜&˜J˜——š  œ˜Jšœžœ ˜ Jšœ:˜:Jšœ žœ;˜GJšœ žœ˜šœ žœ ž˜!Jšœžœ*žœžœ˜fJšœ˜Jšœ˜Jšžœž˜—šžœžœ˜'Jšœ<žœ˜YJ˜—šžœžœ8˜bJšžœžœ?˜[—Jšžœžœžœ˜4˜J˜——š œ žBœž˜Zšœžœ žœ ž˜7Jšœ˜Jšœ˜Jšœ˜Jšžœžœ˜—J˜J˜—š œ žBœž˜XJšœžœ ˜ Jšœ:˜:š  œžœž˜'Jšœ žœ;˜GJšœ˜šžœž˜%šœ˜š  œžœž˜*J˜0šžœ#ž˜*Jšœ˜Jšžœ˜—J˜—Jšœ%˜>Jšœ›˜ฑJ˜——šœžœ ž˜/Jšœ˜Jšœ˜Jšœ˜Jšžœžœ˜—J˜—Jšžœžœžœ#žœ˜=J˜J˜J˜—š œ žBœž˜YJšœžœ ˜Jšžœ žœ˜.Jšœžœ žœ˜)J˜J˜—š  œ žBœž˜]šœ˜Jšžœ ˜šžœ ž˜Jšœ˜Jšœ˜Jšœ˜Jšžœžœ˜—Jšžœ˜—J˜J˜—•StartOfExpansion† -- [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE] -- š  œ ะck†œž˜Ÿšœžœžœ ž˜!Jšœ˜Jšœ˜Jšœ!˜!Jšžœž˜—Jšžœ žœ ˜/Jšœžœ žœ˜)J˜J˜—š  œ žBœ˜]Jšœžœ˜.J˜—J˜š  œž œžœ žœžœ˜VJšœ:˜:Jšœ žœ˜Jšžœžœžœ#žœ˜=Jšœ0˜0šžœ ž˜Jšžœžœ9ะbc ฯ˜นJšžœ$žœžœžœžœ6žœžœ,˜จJ˜—Jšžœ9˜=J˜——šœ™š œž4œž˜`Jšœ!˜!Jšœ žœ˜J˜Jšœ žœ˜Jšœ˜š œ˜%Jšœ ˜ Jšœ˜—J˜Jšžœ žœžœ˜0J˜Jšœ.žœžœžœ˜Z˜,Jšžœž˜J˜—J˜*Jšžœ žœžœ ˜4Jšžœžœžœ"˜Jšžœžœžœž˜&Jšžœžœ˜ Jšœžœ#žœ ˜5šž˜Jšœžœ(˜FJšœžœ*˜FJšž˜—Jšžœ˜"˜J˜——š œž4œž˜bJšœžœ!˜,J˜!Jšžœ žœžœ;žœ˜WJšœ#žœ žœ˜8šžœž˜$J˜Jšžœ˜"J˜—Jšžœžœžœž˜&Jšžœžœ˜ ˜J˜——š  œžœžœžœ žœžœ˜XJšžœžœž˜Jšœ˜Jšœ žœ;˜GJš œžœžœžœ žœ!˜NJ˜Jšœžœ˜&Jšœžœ9˜LJ˜'Jš œžœžœžœ žœ ˜5Jšžœžœ!˜/šžœ˜Jšœ9˜9šžœžœž˜)Jšœ'˜'Jšœ=˜=Jš œ+žœ!žœžœ žœ#˜‡J˜—J˜—Jšœ1˜1Jšžœ ˜Jšœžœ˜Jšœ˜Jšœ˜Jšœžœ˜šžœžœž˜ Jšœžœ˜Jšœ!žœ˜%Jšœ˜—šœ  œ%˜0Jšœ5žœ˜:J˜1J˜$J˜—Jšœ7˜7Jšœ˜Jšœ*žœ˜0Jšžœžœžœ˜šžœžœžœ˜ š  œ$žœ˜7šžœ!žœžœ˜-Jšœ)˜)JšœU˜UJ˜$J˜—Jšžœ˜J˜—Jšžœžœžœ-˜>Jšœ#žœ˜'JšœB˜BJ˜%Jšœ?žœ˜EJ˜—Jšœ#˜#˜J˜——š  œž4œ˜\Jšœ žœ;˜GJšœžœžœžœ˜6Jšœ žœžœ˜J˜Jšœ žœ˜ Jšœžœ˜Jšœžœžœ˜&š œ˜%Jšžœžœžœ˜!šžœ ž˜Jš œ žœ žœžœ žœ˜4Jš œ žœžœžœ žœ˜.Jš œ žœ žœžœ žœ˜4Jšž˜—Jšœ ˜ Jšœ˜—šžœ=ž˜Dšž˜Jšœžœžœ ž˜3Jšž˜—Jšžœ˜—Jšœ˜Jš œžœžœžœžœ"˜lJ˜*Jšžœžœžœ žœ ˜(Jšœ ˜ ˜J˜——š œž1œ˜`Jš œ@˜FJšœ žœ;˜GJšœžœ˜4Jšœžœ˜Jšœžœ˜J˜šœ"˜"Jšžœž ˜Jšžœž˜Jšœ˜—Jšœc˜cšžœžœž˜J˜>JšœX˜XJ˜—˜J˜——š œ˜+Jšœ'žœžœ˜4Jšœ žœ;˜GJšœžœ˜4Jšœžœ!˜,Jšœžœ˜Jš œ@˜Fšžœ=ž˜Dšž˜Jšœžœžœž˜,Jšœžœ žœ žœ˜;Jš œžœžœ žœ žœ ž˜NJšœžœžœ žœ˜2Jšœžœžœ ž˜2Jšž˜—Jšžœ˜—J˜Jšœผ˜ผ˜J˜——š œ˜+Jšœ4˜4J˜——šœ™š  œžœžœ ž˜>Jšœ žœ;˜GJš žœžœžœžœžœžœ˜TJšœ˜J˜—š  œž%œž˜PJ˜Jšžœžœ˜/J˜J˜—š   œžœ"žœ*žœžœžœ˜uJšœž˜Jšžœžœž˜šžœžœžœž˜Jšœžœ!˜-Jšžœžœ˜3šœ ˜ šžœ ž˜Jšœ˜Jšœ˜Jšœ˜Jšžœžœ˜—Jšœ ˜ Jšœ˜—J˜—Jš žœžœžœžœขT˜Jšžœ˜J˜——™Jš œžœ˜'š œž œžœ˜"J˜0˜J˜Jšœ^ฯbะbkœ˜lJ˜Jšœ˜—˜Jšœ˜JšœTฃคœ˜aJ˜J˜—˜J˜Jšœfฃคœ˜sJ˜Jšœ˜—˜J˜Jšœุฃคœ˜ๅJ˜Jšœ˜—˜J˜Jšœยฃคœ˜ฯJ˜Jšœ˜—™J™J™mJšœ ;™F—J˜8˜J˜Jšœฒฃคœ˜ฟJ˜ —˜J˜Jšœ’ฃคœ˜ŸJ˜Jšœ˜—š žœžœžœ5žœžœž˜SJšœ ˜ J˜$Jšžœ ˜—˜J˜——J˜J˜XJ˜RJ˜:J˜~J˜J˜‹Jšœ™˜™Jšœ~˜~J˜^J˜XJ˜ฐJ˜ุJ˜้J˜J˜—Jšžœ˜™/J™aJšœ ฯrœฅœฅœฅ1œฅœฅœฅQœฅ™฿—™.Jšœ ฅ>œฅ'™—J™J™J™J™™.Jšœ ฅ™—J™—…—Y๖t6