<> <> <> <> <<>> DIRECTORY Commander USING [CommandObject, Handle], CommandTool USING [CurrentWorkingDirectory, Run], ComputeServerClient USING [RemoteSuccess, StartService], ComputeServerServer USING [Lookup, RegisteredProcHandle], Convert USING [Error, RealFromRope], IO USING [CreateStream, CreateStreamProcs, EndOfStream, STREAM, StreamProcs], PieViewers USING [Set], Process USING [InitializeCondition, SecondsToTicks], PseudoCursors USING [Set], Rope USING [Cat, Concat, Fetch, FromChar, IsEmpty, Length, ROPE, Substr], TSFormat USING [], TSViewer USING [Tool], ViewerTools USING [SetContents]; TSRemoteFormatImpl: CEDAR MONITOR IMPORTS CommandTool, ComputeServerClient, ComputeServerServer, Convert, IO, PieViewers, Process, PseudoCursors, Rope, ViewerTools EXPORTS TSFormat = BEGIN OPEN TSViewer; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; outBufStreamData: TYPE = REF outBufStreamDataObject; ThirtyTwoChars: TYPE = PACKED ARRAY [0..32) OF CHAR; outBufStreamDataObject: TYPE = RECORD [ token: ROPE _ NIL, bits: REF ThirtyTwoChars _ NEW[ThirtyTwoChars], bitsIndex: INT _ 0, tool: Tool _ NIL, errMsg: ROPE _ NIL, eof: BOOL _ FALSE ]; inBufStreamData: TYPE = REF inBufStreamDataObject; inBufStreamDataObject: TYPE = RECORD [ token: ROPE _ NIL, charsAvail: CONDITION, eof: BOOL _ FALSE ]; inStreamProcs: REF IO.StreamProcs _ IO.CreateStreamProcs[ variety: $input, class: $TSetterIn, getChar: InBufGetChar, charsAvail: InCharsAvail ]; outStreamProcs: REF IO.StreamProcs _ IO.CreateStreamProcs[ variety: $output, class: $TSetterOut, putChar: OutBufPutChar ]; OutBufPutChar: PROC [self: STREAM, char: CHAR] = { data: outBufStreamData = NARROW[self.streamData]; IF data.token # NIL AND data.token.Fetch[0] = 'b THEN { data.bits[data.bitsIndex] _ char; data.bitsIndex _ data.bitsIndex + 1; IF data.bitsIndex = 32 THEN TRUSTED { PseudoCursors.Set[data.tool.miniDisplay, LOOPHOLE[data.bits]]; data.token _ NIL; data.bitsIndex _ 0; }; } ELSE { IF char # '$ THEN data.token _ data.token.Concat[Rope.FromChar[char]] ELSE { IF ~data.token.IsEmpty[] THEN { SELECT data.token.Fetch[0] FROM 'c => { PseudoCursors.Set[data.tool.miniDisplay, NIL]; }; 'p => { realRope: ROPE = data.token.Substr[1]; pieSize: REAL _ 0.0; pieSize _ Convert.RealFromRope[realRope ! Convert.Error => CONTINUE;]; PieViewers.Set[data.tool.pie, 100.0-pieSize]; }; 'm => { msg: ROPE = data.token.Substr[1]; ShowMessage[data.tool, msg]; }; 'e => { data.errMsg _ data.token; }; ENDCASE; }; data.token _ NIL; }; }; }; InCharsAvail: PROC [self: STREAM, wait: BOOL] RETURNS [INT] = { data: inBufStreamData = NARROW[self.streamData]; RETURN[data.token.Length[]]; }; InBufGetChar: ENTRY PROC [self: STREAM] RETURNS [ch: CHAR] = { ENABLE UNWIND => NULL; data: inBufStreamData = NARROW[self.streamData]; WHILE data.token.Length[] <= 0 AND ~ data.eof DO WAIT data.charsAvail ENDLOOP; IF data.eof THEN ERROR IO.EndOfStream[self]; ch _ data.token.Fetch[0]; data.token _ data.token.Substr[1]; }; BufferInChar: INTERNAL PROC [data: inBufStreamData, ch: CHAR] = { ENABLE UNWIND => NULL; data.token _ data.token.Concat[Rope.FromChar[ch]]; NOTIFY data.charsAvail; }; ShowMessage: PROCEDURE [tool: Tool, msg: ROPE] = { tool.messageLog _ msg _ tool.messageLog.Cat["\n", msg]; ViewerTools.SetContents[tool.messageBox, msg]; [] _ tool.messageBox.class.scroll[tool.messageBox, thumb, 100]; }; FormatOneOutputFile: PUBLIC PROCEDURE [tool: Tool, names: LIST OF ROPE] = { found: BOOL; success: ComputeServerClient.RemoteSuccess; remoteMsg: ROPE _ NIL; msg: ROPE _ NIL; nameList: ROPE _ NIL; inStream: IO.STREAM _ NIL; inData: inBufStreamData; outData: outBufStreamData; outStream: IO.STREAM _ NIL; stopProcess: PROCESS; tryRemote: BOOL _ tool.remoteState # localOnly; finished: BOOL _ FALSE; retries: INT _ 0; FOR n:LIST OF ROPE _ names, n.rest UNTIL n = NIL DO IF nameList = NIL THEN nameList _ n.first ELSE nameList _ Rope.Cat[nameList, " ", n.first]; ENDLOOP; IF tool.tempPress THEN nameList _ Rope.Concat["-t ", nameList]; <> <> <> WHILE tryRemote AND ~finished AND retries < 4 DO retries _ retries + 1; IF tool.stop THEN EXIT; inStream _ IO.CreateStream[streamProcs: inStreamProcs, streamData: inData _ NEW[inBufStreamDataObject _ []]]; outStream _ IO.CreateStream[streamProcs: outStreamProcs, streamData: outData _ NEW[outBufStreamDataObject _ [tool: tool]]]; stopProcess _ FORK StopProcess[inData, outData, tool]; [found: found, success: success, remoteMsg: remoteMsg] _ ComputeServerClient.StartService[service: "RemoteTSetter", cmdLine: nameList, in: inStream, out: outStream]; SELECT TRUE FROM ~found OR success = false OR success = cantImportController OR success = cantImportServer OR success = communicationFailure OR success = commandNotFound OR success = clientNotRunning => { tryRemote _ FALSE; }; success = aborted => { tool.stop _ TRUE; finished _ TRUE; }; success = timeOut OR success = serverTooBusy => { LOOP; }; found AND success = true => { finished _ TRUE; }; ENDCASE; SetDone[inData, outData]; TRUSTED {JOIN stopProcess;}; ENDLOOP; IF ~tryRemote THEN { lookupProcData: ComputeServerServer.RegisteredProcHandle; errMsg: ROPE _ NIL; runError: BOOL _ FALSE; IF tool.remoteState = remoteOnly THEN { ShowMessage[tool," Failed to perform remote TSet and remoteOnly is requested"]; } ELSE { lookupProcData _ ComputeServerServer.Lookup["RemoteTSetter", NIL]; IF lookupProcData = NIL THEN { [errMsg: errMsg, error: runError] _ CommandTool.Run[bcdName: runDir.Concat["RemoteTSetter.bcd"], runEvenIfAlreadyRun: FALSE, runEvenIfUnbound: FALSE]; lookupProcData _ ComputeServerServer.Lookup["RemoteTSetter", NIL]; }; IF lookupProcData = NIL THEN { ShowMessage[tool," Failed to start up RemoteTSetter.bcd on the workstation"]; } ELSE { result: REF ANY; myCmd: Commander.Handle; inStream _ IO.CreateStream[streamProcs: inStreamProcs, streamData: inData _ NEW[inBufStreamDataObject _ []]]; outStream _ IO.CreateStream[streamProcs: outStreamProcs, streamData: outData _ NEW[outBufStreamDataObject _ [tool: tool]]]; stopProcess _ FORK StopProcess[inData, outData, tool]; myCmd _ NEW[Commander.CommandObject _ [ in: inStream, out: outStream, err: outStream, commandLine: nameList , command: "RemoteTSetter ", propertyList: NIL, procData: NIL ]]; [result: result, msg: remoteMsg] _ lookupProcData.commanderProcHandle.proc[myCmd ! ABORTED => CONTINUE;]; IF result = $Failure AND remoteMsg.IsEmpty[] THEN remoteMsg _ "Failed to Run local TSetter"; SetDone[inData, outData]; TRUSTED {JOIN stopProcess;}; }; }; }; <> <> IF remoteMsg # NIL THEN ShowMessage[tool, remoteMsg]; IF NOT tool.debug THEN msg _ tool.pressName ELSE msg _ NIL; IF tool.stop THEN msg _ msg.Concat[" aborted"] ELSE msg _ msg.Concat[" completed"]; ShowMessage[tool, msg]; }; SetDone: ENTRY PROC[ inData: inBufStreamData, outData: outBufStreamData] = { ENABLE UNWIND => NULL; inData.eof _ TRUE; outData.eof _ TRUE; NOTIFY inData.charsAvail; }; StopProcess: PROC [ inData: inBufStreamData, outData: outBufStreamData, tool: Tool] = { TRUSTED {Process.InitializeCondition[@inData.charsAvail, Process.SecondsToTicks[1]];}; StopInner[inData, outData, tool]; }; StopInner: ENTRY PROC [ inData: inBufStreamData, outData: outBufStreamData, tool: Tool] = { ENABLE UNWIND => NULL; sentStop: BOOL _ FALSE; WHILE ~inData.eof DO WAIT inData.charsAvail; IF tool.stop AND ~sentStop THEN { BufferInChar[inData, 's]; sentStop _ TRUE; }; ENDLOOP; }; runDir: ROPE _ CommandTool.CurrentWorkingDirectory[]; END. << >> <> <> <> <> <> <> <> <> <<>>