TSRemoteServerImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bob Hagmann, August 7, 1985 10:08:06 am PDT
Rick Beach, June 3, 1985 2:48:01 pm PDT
DIRECTORY
Atom USING [DottedPairNode],
Basics USING [UnsafeBlock],
BasicTime USING [earliestGMT, GetClockPulses, GMT, Now, Period, Pulses, PulsesToMicroseconds],
Commander USING [CommandProc],
ComputeServerServer USING [Register],
Convert USING [RopeFromInt, RopeFromReal],
FS USING [ComponentPositions, Error, ExpandName, GetName, OpenFileFromStream, StreamOpen],
IO USING [CharsAvail, GetChar, PutChar, PutRope, SetLength, STREAM, UnsafePutBlock],
NodeStyle USING [Ref],
ProcessProps USING [AddPropList],
PutGet USING [FromFile],
Rope USING [Cat, Concat, Equal, Fetch, Index, Length, ROPE, Substr],
SafeStorage USING [ReclaimCollectibleObjects],
SirPress USING [CursorObject, CursorObjectRec, CursorProc],
TEditInput USING [FreeTree],
TextNode USING [LastLocWithin, LocNumber, Ref],
TSJaMPageBuilder USING [RunPageBuilder],
TSObject USING [ItemList],
TSOutput USING [Close, Handle],
TSOutputPress USING [CreateWithCursor],
TSTranslate USING [FontNotFound, ProgressProc, TreeToVlist],
TSViewer USING [Tool, ToolRec],
UserProfile USING [Boolean],
ViewerTools USING [SetContents];
TSRemoteServerImpl: CEDAR MONITOR
IMPORTS BasicTime, ComputeServerServer, Convert, FS, IO, ProcessProps, PutGet, Rope, SafeStorage, TEditInput, TextNode, TSOutput, TSOutputPress, TSJaMPageBuilder, TSTranslate, UserProfile, ViewerTools
= BEGIN OPEN TSViewer;
ROPE: TYPE = Rope.ROPE;
cursorData: TYPE = REF cursorDataObject;
cursorDataObject: TYPE = RECORD [
out: IO.STREAMNIL,
lastSendTime: BasicTime.GMT ← BasicTime.earliestGMT,
lastPulse: BasicTime.Pulses ← 0
];
ShowMessage: ENTRY PROCEDURE [out: IO.STREAM, prefix: CHAR, msg: ROPE] = {
ENABLE UNWIND => NULL;
out.PutChar[prefix];
out.PutRope[msg];
out.PutChar['$];
};
CreateOutputHandle: PROCEDURE [tool: Tool, node: TextNode.Ref,
cursorObject: SirPress.CursorObject]
RETURNS
[outputHandle: TSOutput.Handle] = {
stream: IO.STREAMFS.StreamOpen[GetPressName[tool], $create];
inputLength: INT ← TextNode.LocNumber[TextNode.LastLocWithin[node], 0];
stream.SetLength[MIN[1024, inputLength+inputLength-inputLength/3]];
tool.pressName ← FS.GetName[FS.OpenFileFromStream[stream]].fullFName;
IF node=NIL THEN ERROR;
outputHandle ← TSOutputPress.CreateWithCursor[
stream: stream,
documentName: tool.currentName,
cursorObject: cursorObject
];
};
GetPressName: PROCEDURE [tool: Tool] RETURNS [pressName: ROPE] = {
nameLen: INT ← 0;
cp: FS.ComponentPositions; dirOmitted: BOOL;
[tool.currentName, cp, dirOmitted] ← FS.ExpandName[tool.currentName];
IF tool.currentName.Substr[cp.ext.start, cp.ext.length].Equal["Tioga", FALSE] THEN
pressName ← tool.currentName.Substr[cp.base.start, cp.base.length]
ELSE pressName ← tool.currentName.Substr[cp.base.start, cp.ext.start+cp.ext.length-cp.base.start];
IF tool.singleOutputFile THEN pressName ← pressName.Concat[".etc"];
pressName ← pressName.Concat[".press"];
IF cp.server.length = 0 THEN {
pressName ← tool.currentName.Substr[0, cp.base.start].Concat[pressName];
};
IF tool.tempPress THEN pressName ← pressName.Concat["$"];
IF pressName.Equal[tool.pressName] THEN {
ViewerTools.SetContents[tool.serverMsg, ""]
}
};
CursorProc: ENTRY SirPress.CursorProc = CHECKED {
ENABLE UNWIND => NULL;
cursor: cursorData = NARROW[clientData];
out: IO.STREAM = cursor.out;
block: Basics.UnsafeBlock;
now: BasicTime.GMT = BasicTime.Now[];
nowPulse: BasicTime.Pulses = BasicTime.GetClockPulses[];
IF bits = NIL OR BasicTime.Period[cursor.lastSendTime, now] > 0 OR BasicTime.PulsesToMicroseconds[nowPulse - cursor.lastPulse] > 200000 THEN {
cursor.lastSendTime ← now;
cursor.lastPulse ← nowPulse;
IF bits = NIL THEN out.PutRope["c$"]
ELSE {
out.PutChar['b];
block ← [LOOPHOLE[bits], 0, 32];
out.UnsafePutBlock[block];
out.PutChar['$];
};
};
};
RemoteTSetterProc: Commander.CommandProc = {
tool: Tool ← NEW[ToolRec ← [tempPress: UserProfile.Boolean["Hardcopy.TemporaryPressFiles"], stop: FALSE]];
aborted: BOOL;
lastProgressReported: REAL ← -2.0;
IsAborted: PROC RETURNS [BOOL] = {
IF cmd.in.CharsAvail[] > 0 THEN {
inChar: CHAR ;
inChar ← cmd.in.GetChar[];
IF inChar = 's THEN tool.stop ← TRUE;
};
RETURN[tool.stop];
};
ProgressProc: ENTRY TSTranslate.ProgressProc = {
ENABLE UNWIND => NULL;
IF progress > lastProgressReported + 1.0 THEN {
realString: ROPE ← Rope.Cat["p", Convert.RopeFromReal[from: progress, precision: 3, useE: FALSE], "$"];
lastProgressReported ← progress;
cmd.out.PutRope[realString];
IF cmd.in.CharsAvail[] > 0 THEN {
inChar: CHAR ;
inChar ← cmd.in.GetChar[];
IF inChar = 's THEN tool.stop ← TRUE;
};
IF tool.stop THEN ERROR ABORTED;
};
};
galley: TSObject.ItemList;
style: NodeStyle.Ref;
outputHandle: TSOutput.Handle ← NIL;
names: ROPE ← cmd.commandLine;
IF names.Substr[0, 3].Equal["-t "] THEN {
tool.tempPress ← TRUE;
names ← names.Substr[3];
}
ELSE tool.tempPress ← FALSE;
WHILE names.Length[] > 0 AND ~tool.stop DO
ENABLE TSTranslate.FontNotFound => {
msg ← Rope.Cat["Unable to find font ", fontName, "; position including comment nodes = ", Convert.RopeFromInt[location]];
tool.stop ← TRUE;
GOTO Quit
};
errorMsg: ROPENIL;
end: INT;
node: TextNode.Ref;
IF names.Fetch[0] = ' THEN {
names ← names.Substr[1];
LOOP;
};
end ← names.Index[0," "];
tool.currentName ← names.Substr[0, end];
names ← names.Substr[end];
node ← PutGet.FromFile[tool.currentName !
FS.Error => {errorMsg ← error.explanation; CONTINUE}];
IF errorMsg = NIL THEN {
cursor: cursorData ← NEW[cursorDataObject];
cursor.out ← cmd.out;
cursor.lastPulse ← BasicTime.GetClockPulses[];
IF outputHandle = NIL THEN
outputHandle ← CreateOutputHandle[tool, node,
NEW[SirPress.CursorObjectRec ← [cursorProc: CursorProc, clientData: cursor]]];
ShowMessage[cmd.out, 'm, Rope.Concat[IF tool.singleOutputFile THEN "Typesetting member " ELSE "Typesetting ", tool.currentName]];
{
FormatFile: PROC ~ {
[galley, style] ← TSTranslate.TreeToVlist[node, ProgressProc];
aborted ← TSJaMPageBuilder.RunPageBuilder[
galley: galley,
style: style,
output: outputHandle,
abortCheckProc: IsAborted,
documentName: tool.currentName
! ABORTED => { aborted ← TRUE; }]
};
wd: Rope.ROPE ← ExtractWorkingDirectory[tool.currentName];
ProcessProps.AddPropList[propList: LIST[NEW[Atom.DottedPairNode ← [$WorkingDirectory, wd]]], inner: FormatFile];
};
tool.stop ← tool.stop OR aborted;
TEditInput.FreeTree[node];
SafeStorage.ReclaimCollectibleObjects[];
}
ELSE ShowMessage[cmd.out, 'e, errorMsg];
ENDLOOP;
IF outputHandle # NIL THEN outputHandle.Close;
EXITS Quit => {}
};
ExtractWorkingDirectory: PROC [fileName: Rope.ROPE] RETURNS [wd: Rope.ROPE]~ {
fullFName: Rope.ROPE;
cp: FS.ComponentPositions;
[fullFName, cp] ← FS.ExpandName[fileName];
wd ← Rope.Substr[fullFName, 0, cp.base.start];
};
ComputeServerServer.Register[
key: "RemoteTSetter",
proc: RemoteTSetterProc
];
END.
Bob Hagmann May 20, 1985 2:26:28 pm PDT
changes to: DIRECTORY, IMPORTS, GetPressName, RemoteTSetterProc, ComputeServerServer, CreateOutputHandle
Rick Beach, June 3, 1985 2:19:57 pm PDT
changes to: RemoteTSetterProc to establish a working directory while formatting a file, ExtractWorkingDirectory added to determine the working directory from a formatted file, GetPressName, IsAborted (local of RemoteTSetterProc), ProgressProc (local of RemoteTSetterProc)
Bob Hagmann August 7, 1985 10:08:06 am PDT
added unwind nulls
changes to: ShowMessage, CursorProc, ProgressProc (local of RemoteTSetterProc)