EcadOpsImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Christian Le Cocq November 20, 1987 10:24:44 am PST
Last Edited by: Ross March 20, 1987 5:23:14 pm PST
DIRECTORY
BridgeFTPOps USING [StoreFile, RetrieveFile],
BridgeSubmit USING [TransferProc, Register],
Commander,
CommandTool,
EcadOps,
FS,
FSExtras,
IO,
Rope,
SymTab,
TerminalIO;
EcadOpsImpl: CEDAR MONITOR
IMPORTS BridgeFTPOps, BridgeSubmit, Commander, CommandTool, FS, FSExtras, IO, Rope, SymTab, TerminalIO
EXPORTS EcadOps
~ BEGIN
ROPE: TYPE = Rope.ROPE;
Key: TYPE = REF KeyRec;
KeyRec: TYPE = RECORD [
msg: ROPENIL,
locked: BOOLTRUE,
unlocked: CONDITION
];
cmdDoc: ROPE ← " TopLevelCellName rulesFileName \nSends CIF to Dracula";
host: ROPE ← "Palain";
userName: ROPENIL;
passWord: ROPENIL;
remoteDir: ROPE ← "/palain/guest/ecad/spool/";
ecadCmd: ROPE ← "/palain/ecad/bin/dracula ";
defaultRulesName: ROPE ← "VTI";
cifExt: ROPE ← ".cif";
logExt: ROPE ← ".drc.log";
errorsExt: ROPE ← ".errors.cif";
logFile: ROPE ← "DRCLOG.SUM"; --highly flexible name
startText: ROPE ← "(LINE SEGMENTS)";
stopText: ROPE ← "PRIMARY CELL :";
noError: PUBLIC ROPE ← "No Errors !!!";
lock: BOOLEANFALSE;
keyTable: SymTab.Ref ← SymTab.Create[];
msgStream: IO.STREAM ← TerminalIO.TOS[];
Command Proc
ECADCmd: Commander.CommandProc ~ {
PROC [cmd: Handle] RETURNS [result: REFNIL, msg: ROPENIL]
topCellName, rulesFName: ROPE;
args: CommandTool.ArgumentVector = CommandTool.Parse[cmd
! CommandTool.Failed => {msg ← errorMsg; GO TO fail};
];
nArgs: NAT = args.argc;
IF nArgs<2 THEN GO TO fail;
topCellName ← args[1];
rulesFName ← IF nArgs>2 THEN args[2] ELSE defaultRulesName;
IF lock THEN {
msg ← "\nWait for the previous DRC to finish !\nJob not sent.\n";
GO TO fail;
};
lock ← TRUE;
msg ← ExecuteRemoteECAD[topCellName, rulesFName];
IF msg#NIL AND msg#noError THEN GO TO fail;
EXITS fail => result ← $Failed;
};
ExecuteRemoteECAD: PUBLIC PROC [topCellName, rules: ROPE] RETURNS [errmsg: ROPE] ~ {
cmd: ROPE;
wDir: ROPE ← FSExtras.GetWDir[];
[] ← SymTab.Store[keyTable, topCellName, NEW[KeyRec]];
lock ← TRUE;
cmd ← Rope.Cat[ecadCmd, topCellName, " ", rules];
errmsg ← BridgeSubmit.Register[host, topCellName, cmd, wDir, Store, Retrieve, userName, passWord, remoteDir];
IF errmsg#NIL THEN lock ← FALSE;
};
I/Os
Store: BridgeSubmit.TransferProc ~ {
PROC [host, id, wDir: ROPE, s: IO.STREAM] RETURNS [msg: ROPE]
localName : ROPE ← Rope.Cat[wDir, id, cifExt];
remoteName: ROPE ← Rope.Cat[remoteDir, id, cifExt];
msg ← BridgeFTPOps.StoreFile[s, remoteName, localName, msgStream];
IF msg # NIL THEN { Ok[id, msg]; RETURN[msg]};
};
Retrieve: BridgeSubmit.TransferProc ~ {
PROC [host, id, wDir: ROPE, s: IO.STREAM] RETURNS [msg: ROPE]
localName : ROPE ← Rope.Cat[wDir, id, logExt];
remoteName: ROPE ← Rope.Cat[remoteDir, logFile];
msg ← BridgeFTPOps.RetrieveFile[s, remoteName, localName, msgStream];
lock ← FALSE;
IF msg # NIL THEN { Ok[id, msg]; RETURN[msg]};
IF CheckForErrors[localName, msgStream] THEN {
localName ← Rope.Cat[wDir, id, errorsExt];
remoteName ← Rope.Cat[remoteDir, id, errorsExt];
msg ← BridgeFTPOps.RetrieveFile[s, remoteName, localName, msgStream];
}
ELSE msg ← noError;
Ok[id, msg]
};
CheckForErrors: PROC [logName: Rope.ROPE, outStream: IO.STREAM] RETURNS [hasErrors: BOOLEANFALSE] ~ {
l: Rope.ROPE ← NIL;
logFile: IO.STREAM;
logFile ← FS.StreamOpen[logName, read];
UNTIL Rope.Find[s1: l, s2: startText]#-1 DO
l ← IO.GetLineRope[logFile];
ENDLOOP;
[] ← IO.SkipWhitespace[logFile];
l ← IO.GetLineRope[logFile];
UNTIL Rope.Find[s1: l, s2: stopText]#-1 DO
hasErrors ← TRUE;
IO.PutRope[outStream, Rope.Cat[l, "\n"]];
[] ← IO.SkipWhitespace[logFile];
l ← IO.GetLineRope[logFile];
ENDLOOP;
};
Monitoring
WaitForOk: PUBLIC ENTRY PROC[id: ROPE] RETURNS[msg: ROPE]~ {
ENABLE UNWIND => NULL;
key: Key ← NARROW[SymTab.Fetch[keyTable, id].val];
WHILE key.locked DO WAIT key.unlocked ENDLOOP;
RETURN [key.msg];
};
Unlock: ENTRY PROC [key: Key] ~ {
ENABLE UNWIND => NULL;
key.locked ← FALSE;
BROADCAST key.unlocked;
};
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];
};
Initialization
Commander.Register[key: "EcadOps", proc: ECADCmd, doc: cmdDoc];
TerminalIO.PutRope["EcadOps loaded\n"];
END.