ComputeClientDebuggingImpl.mesa
Client side of the interface implementation.
Last Edited by: Bob Hagmann, November 5, 1985 12:54:23 pm PST
Copyright © 1984 by Xerox Corporation. All rights reserved.
DIRECTORY
Ascii,
ComputeClientInternal,
ComputeServerDebugger,
ComputeServerDebuggerRpcControl,
EditedStream,
FileViewerOps,
IO,
MBQueue,
Menus,
Process,
PupDefs,
PupErrors,
PupStream,
Rope,
RPC,
UserCredentials,
ViewerIO,
ViewerOps,
ViewerClasses,
VM;
ComputeClientDebuggingImpl: CEDAR MONITOR
IMPORTS ComputeClientInternal, ComputeServerDebuggerRpcControl, EditedStream, FileViewerOps, IO, MBQueue, Menus, Process, PupErrors, PupStream, Rope, RPC, --TiogaOps,-- UserCredentials, ViewerIO, ViewerOps
EXPORTS ComputeServerDebugger
= BEGIN
Declarations
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
debuggerStreamState: TYPE = {normal, sawCR, sawAmper, sawDigit, sawFirstSpace, sawBackArrow, stuffable};
debugItem: TYPE = REF debugObject;
debugObject: TYPE = RECORD [
alive: BOOLTRUE,
menuHitQueue: MBQueue.Queue ← MBQueue.Create[],
viewer: ViewerClasses.Viewer ← NIL,
state: debuggerStreamState ← normal,
viewerInStream: STREAM,
viewerOutStream: STREAM,
inOutPupStream: STREAM
];
Debugging
OpenDebugStream: PUBLIC PROC [listenerPupAddress: PupDefs.PupAddress, newListenerPupAddress: PupDefs.PupAddress, name: ROPE, serverMachine: ROPE] RETURNS [byteStreamOK: BOOLTRUE] = {
inOutPupStream: STREAMNIL;
found: BOOL;
found ← ComputeClientInternal.MatchPupAddress[listenerPupAddress].found;
IF found THEN {
currentViewer: ViewerClasses.Viewer ← NIL;
debugInfo: debugItem ← NIL;
viewerInStream, viewerOutStream: STREAM;
inOutPupStream ← PupStream.PupByteStreamCreate[remote: newListenerPupAddress, ticks: PupStream.SecondsToTocks[1] ! PupStream.StreamClosing => CONTINUE;] ;
IF inOutPupStream # NIL THEN {
title: ROPENIL;
IF serverMachine # NIL THEN title ← Rope.Cat["[", serverMachine, "] "];
currentViewer ← ViewerOps.CreateViewer[flavor: $Typescript, info: [iconic: FALSE, name: Rope.Cat["REMOTE ", title, name]]];
[viewerInStream, viewerOutStream] ← ViewerIO.CreateViewerStreams[name: NIL, viewer: currentViewer];
debugInfo ← NEW[debugObject ← [viewer: currentViewer, viewerInStream: viewerInStream, viewerOutStream: viewerOutStream, inOutPupStream: inOutPupStream]];
CreateInterpreterMenu[debugInfo];
TRUSTED {
Process.Detach[FORK CopyPupToViewerStream[debugInfo]];
Process.Detach[FORK CopyViewerToPupStream[debugInfo]];
};
}
ELSE byteStreamOK ← FALSE;
}
ELSE byteStreamOK ← FALSE;
};
OpenSourceViewer: PUBLIC PROC [listenerPupAddress: PupDefs.PupAddress, name: ROPE, index: INT ] = {
found: BOOL;
found ← ComputeClientInternal.MatchPupAddress[listenerPupAddress].found;
IF found THEN {
FileViewerOps.OpenSource[fileName: name, index: index, feedBack: NIL];
};
};
CopyPupToViewerStream: PROC [debugInfo: debugItem] = {
WHILE debugInfo.alive DO
IF debugInfo.inOutPupStream.CharsAvail[] > 0 THEN{
char: CHAR;
char ← debugInfo.inOutPupStream.GetChar[ ! IO.EndOfStream => {EXIT;}];
SELECT char FROM
'\n => debugInfo.state ← sawCR;
'& => debugInfo.state ← sawAmper ;
IN ['0..'9] => IF debugInfo.state = sawAmper OR debugInfo.state = sawDigit
THEN debugInfo.state ← sawDigit ELSE debugInfo.state ← normal;
' => IF debugInfo.state = sawDigit
THEN debugInfo.state ← sawFirstSpace
ELSE {
IF debugInfo.state = sawBackArrow THEN debugInfo.state ← stuffable ELSE debugInfo.state ← normal;
};
'← => IF debugInfo.state = sawFirstSpace THEN debugInfo.state ← sawBackArrow
ELSE debugInfo.state ← normal;
ENDCASE => debugInfo.state ← normal;
debugInfo.viewerOutStream.PutChar[char];
}
ELSE Process.Pause[4];
ENDLOOP;
debugInfo.alive ← FALSE;
};
CopyViewerToPupStream: PROC [debugInfo: debugItem] = {
stuffToFlush: BOOLFALSE;
WHILE debugInfo.alive DO
IF debugInfo.viewerInStream.CharsAvail[ ! IO.Error => EXIT ] > 0 THEN {
char: CHAR;
char ← debugInfo.viewerInStream.GetChar[ !
IO.EndOfStream => {EXIT;};
EditedStream.Rubout => {
char ← Ascii.DEL;
};
];
debugInfo.inOutPupStream.PutChar[char];
stuffToFlush ← TRUE;
}
ELSE {
IF stuffToFlush THEN debugInfo.inOutPupStream.Flush[] ELSE Process.Pause[4];
stuffToFlush ← FALSE;
};
ENDLOOP;
debugInfo.alive ← FALSE;
PupStream.SendMark[debugInfo.inOutPupStream, 26B ! PupErrors.StreamClosing => CONTINUE;];
debugInfo.inOutPupStream.Close[! IO.Error => CONTINUE;] ;
};
CreateInterpreterMenu: PROC[debugInfo: debugItem] = {
menu: Menus.Menu ← debugInfo.viewer.menu;
InsME: PROC[line: NAT, name: ROPE, proc: Menus.MenuProc] = {
Menus.InsertMenuEntry
[menu: menu,
line: line,
entry: MBQueue.CreateMenuEntry
[q: debugInfo.menuHitQueue, name: name, proc: proc, clientData: debugInfo]];
};
InsME[line: 0, name: "STOP!", proc: StopHit];
InsME[line: 0, name: "SetBreak", proc: SetBreakHit];
InsME[line: 0, name: "ClearBreak(s)", proc: ClearBreakHit];
InsME[line: 0, name: "ListBreaks", proc: ListBreaksHit];
InsME[line: 1, name: "WalkStack", proc: WalkStackHit];
InsME[line: 1, name: "ShowFrame", proc: ShowFrameHit];
InsME[line: 1, name: "Proceed", proc: ProceedHit];
InsME[line: 1, name: "Abort", proc: AbortHit];
InsME[line: 1, name: "Source", proc: SourceHit];
ChangeLines[debugInfo.viewer, 2];
};
ChangeLines: PROC[v: ViewerClasses.Viewer, nLines: NAT] = {
Menus.ChangeNumberOfLines[v.menu, nLines];
ViewerOps.EstablishViewerPosition[v, v.wx, v.wy, v.ww, v.wh];
flushes viewer cache STOPGAP 'till a viewers bug is fixed
ViewerOps.PaintViewer[v, all];
};
WalkStackHit: Menus.MenuProc = TRUSTED {
[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]
debugInfo: debugItem = NARROW[clientData, debugItem];
StuffIt[debugInfo,
  Rope.Cat[" ---- &WalkStack[nFrames: ",
SELECT mouseButton FROM red => "1", yellow => "-1000", blue => "-1"
  ENDCASE => ERROR,
  ", h: &H]\n"]];
};
ShowFrameHit: Menus.MenuProc = TRUSTED {
[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]
debugInfo: debugItem = NARROW[clientData, debugItem];
StuffIt[debugInfo, " ---- &ShowFrame[h: &H]\n"];
};
ProceedHit: Menus.MenuProc = TRUSTED {
[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]
debugInfo: debugItem = NARROW[clientData, debugItem];
StuffIt[debugInfo, " ---- &PROCEED[h: &H]\n"];
};
AbortHit: Menus.MenuProc = TRUSTED {
[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]
debugInfo: debugItem = NARROW[clientData, debugItem];
StuffIt[debugInfo, " ---- &ABORT[h: &H]\n"];
};
SourceHit: Menus.MenuProc = TRUSTED {
[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]
debugInfo: debugItem = NARROW[clientData, debugItem];
StuffIt[debugInfo, " ---- &Source[h: &H]\n"];
};
StuffIt: ENTRY PROC[debugInfo: debugItem, rope: ROPE] = {
ENABLE UNWIND => NULL;
debugInfo.inOutPupStream.Reset[];
IF Rope.IsEmpty[rope] THEN RETURN;
UNTIL debugInfo.state = stuffable DO Process.Pause[5]; ENDLOOP;
IF TiogaOps.GetSelection[].viewer = debugInfo.viewer.ts THEN TiogaOps.SelectPoint[viewer: debugInfo.viewer, caret: TiogaOps.LastLocWithin[TiogaOps.ViewerDoc[debugInfo.viewer]]];
debugInfo.viewerOutStream.PutRope[rope];
debugInfo.inOutPupStream.PutRope[rope];
debugInfo.inOutPupStream.Flush[];
};
Initialization
name, password: ROPE;
[name, password] ← UserCredentials.Get[];
ComputeServerDebuggerRpcControl.ExportInterface[
interfaceName: [ type: "ComputeServerDebugger.summoner", instance: ComputeClientInternal.myNetAddressRope, version: [1,1]],
user: name,
password: RPC.MakeKey[password]
];
END.
Bob Hagmann June 7, 1985 1:54:20 pm PDT
changes to: ComputeServerDebuggerRpcControl