DIRECTORY Ascii, BridgeFTPOps USING [StoreFile, RetrieveFile], BridgeSubmit USING [TransferProc, Register], BridgeDriver, CedarProcess, Commander, RemoteAlgebra, FS, FSExtras, FSBackdoor, IO, Rope, SymTab USING [Ref, Create, Fetch, Store, Delete], TerminalIO, UserCredentials, TiogaMenuOps, ThisMachine; RemoteAlgebraImpl: CEDAR MONITOR IMPORTS Ascii, BridgeDriver, CedarProcess, FS, FSExtras, FSBackdoor, IO, Rope, UserCredentials, ThisMachine, BridgeFTPOps, BridgeSubmit, SymTab, TerminalIO EXPORTS RemoteAlgebra ~ BEGIN ROPE: TYPE = Rope.ROPE; waitingProcess: CedarProcess.Process; stop: BOOL _ FALSE; criterion: ROPE _ "*.SUM!*"; globalOutputStream: IO.STREAM; lock: BOOLEAN _ FALSE; AlgebraCmd: Commander.CommandProc ~ { fileName: ROPE _ NIL; ropeStream: IO.STREAM _ IO.RIS[cmd.commandLine]; IF lock THEN { msg _ "\nWait for the previous Remote Algebra to finish !\nJob not sent.\n"; RETURN; }; lock _ TRUE; fileName _ FSExpandFromStream[ropeStream]; msg _ ExecuteRemoteAlgebra[fileName]; IF msg#NIL THEN lock _ FALSE; -- n.b. releases the lock if error from BridgeDriver.StartSession }; ExecuteRemoteAlgebra: PUBLIC PROC [fileName: ROPE] RETURNS [errmsg: ROPE] ~ { magicString: ROPE _ "RBatch\ncd /user/csl/arnon; csh .login; cd /user/csl/arnon/Sturgis; /user/csl/arnon/Sturgis/algebra "; name, password, machine, algebraCmd: ROPE; [name, password] _ UserCredentials.Get[]; name _ Rope.Substr[name, 0, Rope.Index[name, 0, "."]]; -- get rid of the ".pa" name _ Rope.Translate[base: name, translator: MyLower]; machine _ Rope.Cat[ThisMachine.Name[], " "]; algebraCmd _ Rope.Cat[magicString, machine, PrepareFFName[fileName] ]; errmsg _ BridgeDriver.StartSession["vaxc", name, password, algebraCmd]; }; MyLower: Rope.TranslatorType ~ {RETURN[Ascii.Lower[old]]}; StartWatching: PUBLIC PROC ~ { IF waitingProcess=NIL OR CedarProcess.GetStatus[waitingProcess]#busy THEN waitingProcess _ CedarProcess.Fork[WaitForListings, criterion]; }; FSExpandFromStream: PROC [s: IO.STREAM] RETURNS [fullFName: ROPE] ~ { fName: ROPE; index: INT; fName _ IO.GetTokenRope[s, IO.IDProc ! IO.EndOfStream => CONTINUE].token; index _ Rope.Find[fName, ".inData", 0, FALSE]; IF index#-1 THEN fName _ Rope.Substr[fName, 0, index]; -- toss ".inData" if present fullFName _ FS.ExpandName[fName].fullFName; }; StripExtension: PROC [inName: ROPE, extension: ROPE] RETURNS [fName: ROPE] ~ { index: INT; index _ Rope.Find[inName, extension, 0, FALSE]; IF index#-1 THEN fName _ Rope.Substr[inName, 0, index]; -- toss extension if present }; PrepareFFName: PROC [fullFName: ROPE] RETURNS [arg: ROPE] ~ { arg _ Rope.Cat["\"", fullFName, "\" "]; }; WaitForListings: CedarProcess.ForkableProc ~ { matchCriterion: ROPE _ NARROW[data]; event: REF READONLY FSBackdoor.CreateEvent _ NIL; UNTIL stop DO event _ FSBackdoor.NextCreateEvent[event]; IF Rope.Match[pattern: matchCriterion, object: event.fName, case: FALSE] THEN { globalOutputStream _ FS.StreamOpen[event.fName, $read]; lock _ FALSE; }; ENDLOOP; }; msgStream: IO.STREAM _ TerminalIO.TOS[]; keyTable: SymTab.Ref _ SymTab.Create[]; Key: TYPE = REF KeyRec; KeyRec: TYPE = RECORD [ msg: ROPE, locked: BOOL _ TRUE, unlocked: CONDITION ]; Waiting: PUBLIC ERROR = CODE; SAC2PolynomialBinaryOp: PUBLIC PROC [varSeq, firstArg, secondArg: ROPE] RETURNS [result: IO.STREAM] ~ { errmsg: ROPE; intialScript: ROPE _ RopeFromFile["SACScript"]; fileName: ROPE _ "SACIn"; outputFileName: ROPE; out: IO.STREAM _ FS.StreamOpen[fileName: fileName, accessOptions: $create, wDir: FSExtras.GetWDir[] ]; -- also could use CommandTool.FileNames interface; in any event, FSExtras.GetWDir seems to just be returning /// as WD, i.e. trivial effect. Probably result of call not coming from a Commander.CommandProc finalScript: ROPE _ intialScript; position: INT _ -1; position _ Rope.Find[finalScript, "#v"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#v"], with: varSeq]; position _ Rope.Find[finalScript, "#1"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#1"], with: firstArg]; position _ Rope.Find[finalScript, "#2"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#2"], with: secondArg]; out.PutRope[finalScript]; out.Close[]; [outputFileName, errmsg] _ DoRemoteAlgebra["SAC"]; IF errmsg#NIL THEN ERROR Waiting; globalOutputStream _ FS.StreamOpen[outputFileName, $read]; RETURN[globalOutputStream]; }; Store: BridgeSubmit.TransferProc ~ { localName : ROPE _ Rope.Cat[wDir, id, "In"]; remoteDir: ROPE _ RopeFromFile[Rope.Cat[id, "Directory"] ]; remoteName: ROPE _ Rope.Cat[remoteDir, id, "In"]; msg _ BridgeFTPOps.StoreFile[s, remoteName, localName, msgStream]; IF msg#NIL THEN { OK[id, msg]; RETURN[msg]}; }; Retrieve: BridgeSubmit.TransferProc ~ { localName : ROPE _ Rope.Cat[wDir, id, "Out"]; remoteDir: ROPE _ RopeFromFile[Rope.Cat[id, "Directory"] ]; remoteName: ROPE _ Rope.Cat[remoteDir, id, "Out"]; msg _ BridgeFTPOps.RetrieveFile[s, remoteName, localName, msgStream]; IF msg#NIL THEN { OK[id, msg]; RETURN[msg]}; OK[id, NIL]; }; RopeFromFile: PROC [filename: ROPE] RETURNS [ROPE] ~ { stream: IO.STREAM _ FS.StreamOpen[filename, $read]; rope: ROPE _ ""; c: CHAR _ stream.GetChar[]; -- toss first newline WHILE NOT stream.EndOf[] DO c _ stream.GetChar[]; IF ~stream.EndOf[] THEN rope _ rope.Cat[Rope.FromChar[c] ]; ENDLOOP; -- toss last newline RETURN[rope]; }; DoRemoteAlgebra: PUBLIC PROC [id: ROPE, waitUntilDone: BOOLEAN _ TRUE] RETURNS [outputFileName: ROPE, msg: ROPE] ~ { line: ROPE _ RopeFromFile[Rope.Cat[id, "Line"] ]; wDir: ROPE _ FSExtras.GetWDir[]; key: Key _ GetKey[id]; outputFileName _ Rope.Cat[wDir, id, "Out"]; IF key=NIL THEN RETURN[outputFileName, Rope.Cat["Remotealgebra -> The rope: '", id, "' is already in use"]]; msg _ BridgeSubmit.Register[id, line, wDir, Store, Retrieve]; IF msg=NIL AND waitUntilDone THEN msg _ WaitForOk[key]; RETURN[outputFileName, msg]; }; GetKey: PROC [id: ROPE] RETURNS[key: Key] ~ { IF SymTab.Fetch[keyTable, id].found THEN RETURN [NIL]; key _ NEW[KeyRec]; [] _ SymTab.Store[keyTable, id, key]; }; WaitForOk: ENTRY PROC [key: Key] RETURNS [msg: ROPE] ~ { ENABLE UNWIND => NULL; WHILE key.locked DO WAIT key.unlocked ENDLOOP; RETURN [key.msg]; }; OK: PROC [id, msg: ROPE] ~ { key: Key _ NARROW[SymTab.Fetch[keyTable, id].val]; IF key=NIL THEN RETURN; [] _ SymTab.Delete[keyTable, id]; key.msg _ msg; Unlock[key]; }; Unlock: ENTRY PROC [key: Key] ~ { ENABLE UNWIND => NULL; key.locked _ FALSE; BROADCAST key.unlocked; }; TerminalIO.PutRope["Begin TerminalIO\n"]; END. ŠRemoteAlgebraImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Christian Le Cocq April 29, 1987 5:58:45 pm PDT Last Edited by: Ross March 20, 1987 5:23:14 pm PST Arnon May 13, 1987 8:21:50 am PDT See: [cyan]EcadOps>EcadOps.mesa [cyan]EcadOps>EcadOpsImpl.mesa [Cyan]SpiceOps>SpiceCDCmds.mesa IMPORTS Ascii, BridgeDriver, CedarProcess, Commander, FS, FSBackdoor, IO, Rope, UserCredentials, TiogaMenuOps, ThisMachine Command Procs PROC [cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL] fullCIFFName, fullRulesFName, cellName: ROPE; fullRulesFName _ FSExpandFromStream[ropeStream]; cellName _ IO.GetTokenRope[ropeStream, IO.IDProc ! IO.EndOfStream => CONTINUE].token; name, password, machine, algebraCmd, CIFFName, RulesFName: ROPE; CIFFName _ PrepareFFName[fullCIFFName]; RulesFName _ PrepareFFName[fullRulesFName]; algebraCmd _ Rope.Cat[magicString, machine, CIFFName, RulesFName, cellName]; SAC2PolynomialBinaryOp: PUBLIC PROC [varSeq, firstArg, secondArg: ROPE] RETURNS [result: IO.STREAM] ~ { errmsg: ROPE; name, password, machine, algebraCmd: ROPE; magicString: ROPE _ "RBatch\ncd /user/csl/arnon; csh .login; cd /user/csl/arnon/INTRPTR; /user/csl/arnon/INTRPTR/RunInterpreter "; intialScript: ROPE _ "V \n #v \n E \n #1 $ \n E \n #2 $ \n G 1 2 \n W \n L 3 \n \n H \n Q \n"; fileName: ROPE _ "SacPolyBinaryOp.inData"; out: IO.STREAM _ FS.StreamOpen[fileName: fileName, accessOptions: $create,wDir: FSExtras.GetWDir[] ]; -- also could use CommandTool.FileNames interface; in any event, FSExtras.GetWDir seems to just be returning /// as WD, i.e. trivial effect. Probably result of call not coming from a Commander.CommandProc fullFName: ROPE _ FS.ExpandName[fileName].fullFName; finalScript: ROPE _ intialScript; position: INT _ -1; position _ Rope.Find[finalScript, "#v"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#v"], with: varSeq]; position _ Rope.Find[finalScript, "#1"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#1"], with: firstArg]; position _ Rope.Find[finalScript, "#2"]; finalScript _ Rope.Replace[base: finalScript, start: position, len: Rope.Length["#2"], with: secondArg]; out.PutRope[finalScript]; out.Close[]; [name, password] _ UserCredentials.Get[]; name _ Rope.Substr[name, 0, Rope.Index[name, 0, "."]]; -- get rid of the ".pa" name _ Rope.Translate[base: name, translator: MyLower]; machine _ Rope.Cat[ThisMachine.Name[], " "]; fullFName _ StripExtension[fullFName, ".inData"]; algebraCmd _ Rope.Cat[magicString, machine, PrepareFFName[fullFName] ]; UNTIL lock=FALSE DO ENDLOOP; -- wait until previous request finishes lock _ TRUE; errmsg _ BridgeDriver.StartSession["vaxc", name, password, algebraCmd]; IF errmsg#NIL THEN { lock _ FALSE; -- n.b. releases the lock if error from BridgeDriver.StartSession RETURN[NIL]; }; UNTIL lock=FALSE DO ENDLOOP; -- wait RETURN[globalOutputStream]; }; Internal Utilities fullFName _ FS.ExpandName[fName].fullFName; PROC [data: REF] RETURNS [results: REF _ NIL] IF Rope.Match[pattern: matchCriterion, object: event.fName, case: FALSE] THEN { viewer: TiogaMenuOps.Viewer _ TiogaMenuOps.Open[event.fName]; lock _ FALSE; }; New Stuff PROC [id, wDir: ROPE, s: IO.STREAM] RETURNS [msg: ROPE] PROC [id, wDir: ROPE, s: IO.STREAM] RETURNS [msg: ROPE] id is expected to be flavorRope, e.g. "Reduce", "SAC", "SMP" Initialization Commander.Register[key: "RemoteAlgebra", proc: AlgebraCmd, doc: "RemoteAlgebra CIFfileName rulesFileName TopLevelCellName\nSends CIF to Dracula"]; Commander.Register[key: "RemoteAlgebra", proc: AlgebraCmd, doc: "RemoteAlgebra dataFile\nSends Algebra to Vax"]; StartWatching[]; Κ ‰˜šœ™Jšœ<™