DIRECTORY Ascii, ComputeClientInternal, ComputeServerCallbacks, ComputeServerCallbacksRpcControl, EditedStream, FileViewerOps, IO, MBQueue, Menus, Process, Pup USING [Address], PupStream USING [Create, SendMark, StreamClosing, waitForever], Rope, RPC, UserCredentials, ViewerIO, ViewerOps, ViewerClasses, VM; ComputeClientDebuggingImpl: CEDAR MONITOR IMPORTS ComputeClientInternal, EditedStream, FileViewerOps, IO, MBQueue, Menus, Process, PupStream, Rope, --TiogaOps,-- UserCredentials, ViewerIO, ViewerOps EXPORTS ComputeServerCallbacks = BEGIN 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: BOOL _ TRUE, menuHitQueue: MBQueue.Queue _ MBQueue.Create[], viewer: ViewerClasses.Viewer _ NIL, state: debuggerStreamState _ normal, viewerInStream: STREAM, viewerOutStream: STREAM, inOutPupStream: STREAM ]; OpenDebugStream: PUBLIC PROC [listenerPupAddress: Pup.Address, newListenerPupAddress: Pup.Address, name: ROPE, serverMachine: ROPE] RETURNS [byteStreamOK: BOOL _ TRUE] = { inOutPupStream: STREAM _ NIL; found: BOOL; found _ ComputeClientInternal.MatchPupAddress[listenerPupAddress].found; IF found THEN { currentViewer: ViewerClasses.Viewer _ NIL; debugInfo: debugItem _ NIL; viewerInStream, viewerOutStream: STREAM; inOutPupStream _ PupStream.Create[remote: newListenerPupAddress, getTimeout: 1000, putTimeout: PupStream.waitForever ! PupStream.StreamClosing => CONTINUE;] ; IF inOutPupStream # NIL THEN { title: ROPE _ NIL; 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: Pup.Address, 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: BOOL _ FALSE; 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 ! PupStream.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: 1, name: "WalkStack", proc: WalkStackHit]; InsME[line: 1, name: "ShowFrame", proc: ShowFrameHit]; 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]; ViewerOps.PaintViewer[v, all]; }; WalkStackHit: Menus.MenuProc = TRUSTED { 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 { debugInfo: debugItem = NARROW[clientData, debugItem]; StuffIt[debugInfo, " ---- &ShowFrame[h: &H]\n"]; }; AbortHit: Menus.MenuProc = TRUSTED { debugInfo: debugItem = NARROW[clientData, debugItem]; StuffIt[debugInfo, " ---- &ABORT[h: &H]\n"]; }; SourceHit: Menus.MenuProc = TRUSTED { debugInfo: debugItem = NARROW[clientData, debugItem]; StuffIt[debugInfo, " ---- &Source[h: &H]\n"]; }; StuffIt: ENTRY PROC[debugInfo: debugItem, rope: ROPE] = { ENABLE UNWIND => NULL; IF Rope.IsEmpty[rope] THEN RETURN; UNTIL debugInfo.state = stuffable DO Process.Pause[5]; ENDLOOP; debugInfo.viewerOutStream.PutRope[rope]; debugInfo.inOutPupStream.PutRope[rope]; debugInfo.inOutPupStream.Flush[]; }; name, password: ROPE; [name, password] _ UserCredentials.Get[]; END.  ComputeClientDebuggingImpl.mesa Client side of the interface implementation. Last Edited by: Bob Hagmann, April 18, 1986 12:29:49 pm PST Hal Murray, March 22, 1986 10:48:48 pm PST Copyright c 1984 by Xerox Corporation. All rights reserved. Declarations Debugging 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: "Proceed", proc: ProceedHit]; flushes viewer cache STOPGAP 'till a viewers bug is fixed [parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL] [parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL] ProceedHit: Menus.MenuProc = TRUSTED { [parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL] debugInfo: debugItem = NARROW[clientData, debugItem]; StuffIt[debugInfo, " ---- &PROCEED[h: &H]\n"]; }; [parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL] [parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL] debugInfo.inOutPupStream.Reset[]; IF TiogaOps.GetSelection[].viewer = debugInfo.viewer.ts THEN TiogaOps.SelectPoint[viewer: debugInfo.viewer, caret: TiogaOps.LastLocWithin[TiogaOps.ViewerDoc[debugInfo.viewer]]]; Initialization Bob Hagmann June 7, 1985 1:54:20 pm PDT changes to: ComputeServerDebuggerRpcControl Bob Hagmann April 18, 1986 10:30:35 am PST ComputeServerDebugger moved into ComputeServerCallbacks ΚΠ– "Cedar" style˜headšœ™Ibodyšœ,™,L™;code™*Jšœ Οmœ1™