Basename:
PROC [in:
ROPE]
RETURNS [out:
ROPE] ~ {
parts: FS.ComponentPositions;
tmp: ROPE;
[tmp, parts, ] ¬ FS.ExpandName[in];
out ¬ Rope.Substr[base: tmp, start: parts.base.start, len: parts.base.length];
};
DeriveCmd:
PROC [spec: CourierProgram]
RETURNS [cmd:
ROPE] ~ {
formatOne:
ROPE ¬
IO.PutFR["%g%g%g",
IO.rope["Sirocco %g;"],
IO.rope["TiogaMesa %g; Sleep 1;"],
IO.rope["TiogaMesa %gInit; Sleep 1;"]
];
formatTwo:
ROPE ¬
IO.PutFR["%g%g%g%g%g",
IO.rope["%g"], -- first half
IO.rope["TiogaMesa %gAux; Sleep 1;"],
IO.rope["TiogaMesa %gAuxImpl; Sleep 1; "],
IO.rope["TiogaMesa %gClientImpl; Sleep 1; "],
IO.rope["TiogaMesa %gServerImpl; Sleep 1; "]
];
cmd ¬
IO.PutFR[
formatOne,
IO.rope[GetSwitches[spec.resultPrefix]],
IO.rope[Basename[spec.filename]],
IO.rope[spec.interface],
IO.rope[spec.interface]
];
cmd ¬
IO.PutFR[
formatTwo,
IO.rope[cmd],
IO.rope[spec.interface],
IO.rope[spec.interface],
IO.rope[spec.interface],
IO.rope[spec.interface]
];
};
DeriveFrom:
PROC [spec: CourierProgram]
RETURNS [from: From] ~ {
from ¬ [mustHave: LIST[spec.sourceNode], optional: NIL];
FOR each: ReferencedProgramList ¬ spec.dependsUpon, each.rest
WHILE (each #
NIL)
DO
interface: ROPE ~ Rope.Cat[each.first.name, "P", each.first.pid, "V", each.first.vid];
table: ROPE ~ Rope.Cat[interface, ".Tables"];
from.mustHave ¬ CONS [ MakeDo.GetNode[table, MakeDo.fileClass], from.mustHave];
ENDLOOP;
};
GetDependsUpon:
PROC [spec:
IO.
STREAM]
RETURNS [list: ReferencedProgramList ¬
NIL] ~ {
ENABLE {
IO.EndOfStream => {
GOTO ParseError;
};
IO.Error => {
GOTO ParseError;
};
};
shiftBox: ARRAY DependsParse OF ROPE ¬ ALL[NIL];
skip: INT;
token: ROPE;
tokenKind: IO.TokenKind;
list ¬ CONS [NEW [ReferencedProgramObject], list];
DO
[tokenKind, token, skip] ¬ IO.GetCedarTokenRope[spec];
SELECT tokenKind
FROM
tokenID => {
IF ( Rope.Equal[token,
DEPENDS] )
THEN {
EXIT;
};
};
tokenSINGLE,
tokenDECIMAL,
tokenOCTAL,
tokenHEX,
tokenREAL,
tokenROPE,
tokenCHAR,
tokenATOM,
tokenDOUBLE,
tokenCOMMENT => {
NULL;
};
tokenERROR,
tokenEOF => {
RETURN [NIL];
};
ENDCASE;
ENDLOOP;
DO
[tokenKind, token, skip] ¬ IO.GetCedarTokenRope[spec];
SELECT tokenKind
FROM
tokenID,
tokenDECIMAL,
tokenSINGLE => {
IF ( Rope.Equal[token,
COMMA] )
THEN {
list.first.valid ¬ TRUE;
list.first.name ¬ shiftBox[name];
list.first.pid ¬ shiftBox[pid];
list.first.vid ¬ shiftBox[vid];
list ¬ CONS [NEW [ReferencedProgramObject], list];
};
IF ( Rope.Equal[token,
SEMI] )
THEN {
list.first.valid ¬ TRUE;
list.first.name ¬ shiftBox[name];
list.first.pid ¬ shiftBox[pid];
list.first.vid ¬ shiftBox[vid];
EXIT;
};
FOR i: DependsParse
IN [name .. version]
DO
shiftBox[i] ¬ shiftBox[SUCC[i]];
ENDLOOP;
shiftBox[vid] ¬ token;
};
tokenOCTAL,
tokenHEX,
tokenREAL,
tokenROPE,
tokenCHAR,
tokenATOM,
tokenDOUBLE,
tokenCOMMENT => {
NULL;
};
tokenERROR,
tokenEOF => {
list.first.valid ¬ FALSE;
};
ENDCASE;
ENDLOOP;
IF (list.first.valid = FALSE) THEN list ¬ list.rest;
RETURN [list];
EXITS
ParseError => { RETURN [NIL]; };
};
GetSwitches:
PROC [resultPrefix:
ROPE]
RETURNS [switches:
ROPE] ~ {
ss: IO.STREAM ¬ NIL;
ss ¬
FS.StreamOpen[Rope.Cat[resultPrefix, ".SiroccoSwitches"]
! FS.Error => CONTINUE
];
IF (ss = NIL) THEN RETURN [NIL];
[] ¬ ss.SkipWhitespace[];
IF (ss.EndOf[]) THEN RETURN [NIL];
switches ¬ ss.GetLineRope[];
IO.Close[ss];
};
GuessForSpec:
PROC [in:
ROPE]
RETURNS [list: CourierProgramList ¬
NIL] ~ {
ParseEachSpec:
PROC [fullFName:
ROPE]
RETURNS [continue:
BOOL ¬
TRUE] ~ {
ENABLE {
IO.EndOfStream => {
GOTO ParseError;
};
IO.Error => {
GOTO ParseError;
};
};
shiftBox: ARRAY ProgramParse OF ROPE ¬ ALL[NIL];
skip: INT;
spec: IO.STREAM ¬ NIL;
token: ROPE;
tokenKind: IO.TokenKind;
spec ¬
FS.StreamOpen[fullFName
! FS.Error => CONTINUE
];
IF (spec = NIL) THEN RETURN [TRUE];
list ¬ CONS [NEW [CourierProgramObject], list];
DO
[tokenKind, token, skip] ¬ IO.GetCedarTokenRope[spec];
SELECT tokenKind
FROM
tokenID,
tokenDECIMAL,
tokenSINGLE => {
IF ( Rope.Equal[token,
EQUAL] )
THEN {
list.first.found ¬ TRUE;
EXIT;
};
FOR i: ProgramParse
IN [name .. version]
DO
shiftBox[i] ¬ shiftBox[SUCC[i]];
ENDLOOP;
shiftBox[vid] ¬ token;
};
tokenOCTAL,
tokenHEX,
tokenREAL,
tokenROPE,
tokenCHAR,
tokenATOM,
tokenDOUBLE,
tokenCOMMENT => {
NULL;
};
tokenERROR,
tokenEOF => {
list.first.found ¬ FALSE;
};
ENDCASE;
ENDLOOP;
list.first.filename ¬ fullFName;
list.first.program ¬ shiftBox[name];
list.first.pid ¬ shiftBox[pid];
list.first.vid ¬ shiftBox[vid];
list.first.interface ¬ Rope.Cat[list.first.program, "P", list.first.pid, "V", list.first.vid];
IF (list.first.found = TRUE) THEN list.first.dependsUpon ¬ GetDependsUpon[spec];
IO.Close[spec];
RETURN [TRUE];
EXITS
ParseError => {
list ¬ list.rest;
RETURN [TRUE];
};
};
FS.EnumerateForNames[in, ParseEachSpec];
};
SiroccoFind:
PROC [resultName:
ROPE, finderData:
REF
ANY]
RETURNS [found:
BOOLEAN, sought: Node, makes, cmdFrom: NodeList, from: From, cmd:
ROPE, class: ActionClass, foundData:
REF
ANY] ~ {
Global State (EndsIn side effects)
discoveredSuffix: ROPE;
programLength: INT ¬ 0--only to prevent compiler warnings about uninitialized--;
interfaceName: ROPE;
spec: CourierProgram;
resultCP: FS.ComponentPositions;
resultFull: ROPE;
resultShort: ROPE;
basenameLength: INT;
specDetails: CourierProgram;
EndsIn:
PROC [word:
ROPE, suffix:
ROPE]
RETURNS [ans:
BOOL] ~ {
suffixLength: INT ~ suffix.Length[];
wordLength: INT ~ word.Length[];
tail: ROPE;
IF (suffixLength > wordLength) THEN RETURN [FALSE];
tail ¬ Rope.Substr[base: word, start: (wordLength - suffixLength), len: suffixLength];
IF (ans ¬ Rope.Equal[s1: suffix, s2: tail, case:
FALSE])
THEN {
programLength ¬ (wordLength - suffixLength);
discoveredSuffix ¬ suffix;
};
};
Tail:
PROC [suffix:
ROPE]
RETURNS [node: Node] ~ {
node ¬ MakeDo.GetNode[Rope.Cat[specDetails.resultPrefix, suffix], MakeDo.fileClass];
IF (Rope.Equal[suffix, discoveredSuffix]) THEN sought ¬ node;
};
sought ¬ NIL;
[resultFull, resultCP, ] ¬
FS.ExpandName[resultName
! FS.Error => {found ¬ FALSE; CONTINUE}
];
IF (
NOT found)
THEN
RETURN;
basenameLength ¬ (resultCP.ext.start + resultCP.ext.length) - resultCP.base.start;
resultShort ¬ Rope.Substr[base: resultFull, start: resultCP.base.start, len: basenameLength];
found ¬ EndsIn[resultShort, ".Tables"]
OR EndsIn[resultShort, ".Mesa"]
OR EndsIn[resultShort, "Init.Mesa"]
OR EndsIn[resultShort, "Aux.Mesa"]
OR EndsIn[resultShort, "AuxImpl.Mesa"]
OR EndsIn[resultShort, "ClientImpl.Mesa"]
OR EndsIn[resultShort, "ServerImpl.Mesa"];
IF (
NOT found)
THEN
RETURN;
interfaceName ¬ Rope.Substr[base: resultShort, start: 0, len: programLength];
specDetails ¬ Heuristic[interfaceName];
IF (specDetails =
NIL)
THEN {
found ¬ FALSE;
RETURN;
};
specDetails.resultPrefix ¬ Rope.Substr[base: resultFull, start: 0, len: resultCP.base.start];
specDetails.resultPrefix ¬ Rope.Concat[specDetails.resultPrefix, specDetails.interface];
specDetails.switchFile ¬ Rope.Cat[specDetails.resultPrefix, ".SiroccoSwitches"];
cmdFrom ¬
LIST[
specDetails.sourceNode ¬ MakeDo.GetNode[specDetails.filename, MakeDo.fileClass],
specDetails.switchesNode ¬ MakeDo.GetNode[specDetails.switchFile, MakeDo.fileClass]
];
foundData ¬ spec ¬ specDetails;
makes ¬
LIST[
Tail[".Tables"],
Tail[".Mesa"],
Tail["Init.Mesa"],
Tail["Aux.Mesa"],
Tail["AuxImpl.Mesa"],
Tail["ClientImpl.Mesa"],
Tail["ServerImpl.Mesa"]
];
IF (sought = NIL) THEN ERROR;
from ¬ DeriveFrom[spec];
class ¬ siroccoClass;
};