MobOrderCommands.mesa
Copyright Ó 1989, 1990, 1991 by Xerox Corporation. All rights reserved.
Michael Plass, December 2, 1991 1:56 pm PST
Willie-s, March 22, 1991 1:10 pm PST
DIRECTORY Atom, Rope, IO, CommanderOps, Commander, MobOrder, FS;
MobOrderCommands: CEDAR PROGRAM
IMPORTS Atom, Rope, IO, CommanderOps, Commander, MobOrder, FS
~ BEGIN OPEN MobOrder;
ROPE: TYPE = Rope.ROPE;
usageOrder: ROPE = "Deduce a load order from DFs and Mobs: MobOrder <DFName> ... -g <goal> ... -i <importer-goal> ... -x \"<exclusion-pattern>\"";
usageDependents: ROPE = "Deduce a dependents order from DFs and Mobs: MobDependents <DFName> ... -g <goal> ... ";
ExpandImportGoals: PROC [connections: LIST OF MobConnections, goals: LIST OF ROPE] RETURNS [LIST OF ROPE] = {
head: LIST OF ROPELIST[NIL];
last: LIST OF ROPE ← head;
UNTIL goals = NIL DO
IF Rope.Match[pattern: "-i*", object: goals.first, case: FALSE]
THEN {
goals ← goals.rest;
IF goals # NIL THEN {
last.rest ← FindImportGoals[connections, LIST[Atom.MakeAtom[goals.first]]];
UNTIL last.rest = NIL DO last ← last.rest ENDLOOP;
};
}
ELSE {
last ← last.rest ← LIST[goals.first];
};
goals ← goals.rest;
ENDLOOP;
RETURN [head.rest]
};
MakeLoadListWithImportGoals: PROC [dfNames: LIST OF ROPE, goals: LIST OF ROPE] RETURNS [LIST OF LIST OF ATOM] = {
connections: LIST OF MobConnections = GetMobsViaDFs[dfNames];
realGoals: LIST OF ROPE = ExpandImportGoals[connections, goals];
withGoals: LIST OF MobConnections = MarkGoals[connections, realGoals];
sorted: LIST OF LIST OF MobConnections = TopoSortConnections[withGoals];
namesOnly: LIST OF LIST OF ATOM = ExtractNames[sorted];
RETURN [namesOnly]
};
ExpandStars: PROC [list: LIST OF ROPE] RETURNS [LIST OF ROPE] = {
head: LIST OF ROPE ¬ LIST[NIL];
last: LIST OF ROPE ¬ head;
AddNamePattern: PROC [pattern: ROPE] = {
something: BOOL ¬ FALSE;
EachName: FS.NameProc = {
[fullFName: ROPE] RETURNS [continue: BOOL]
something ¬ TRUE;
last ¬ last.rest ¬ LIST[fullFName];
continue ¬ TRUE;
};
FS.EnumerateForNames[pattern: pattern, proc: EachName];
IF NOT something THEN ERROR FS.Error[error: [user, $nomatch, IO.PutFR1["\"%g\" matches no files.", [rope[pattern]]]]];
};
FOR tail: LIST OF ROPE ¬ list, tail.rest UNTIL tail = NIL DO
AddNamePattern[tail.first];
ENDLOOP;
RETURN [head.rest];
RETURN [list] -- no star patterns here, for now.
};
Command: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
goals: LIST OF ROPE ¬ CommanderOps.ParseToList[cmd: cmd].list;
dfNames: LIST OF ROPE ¬ ExpandStars[GetDFNames[]];
GetDFNames: PROC RETURNS [dfNames: LIST OF ROPE] = {
side-effect on goals
prev: LIST OF ROPE ¬ NIL;
dfNames ¬ goals;
WHILE goals # NIL DO
IF Rope.Equal[s1: "-g", s2: goals.first, case: FALSE] THEN {
IF prev # NIL THEN prev.rest ¬ NIL;
goals ¬ goals.rest;
EXIT;
};
prev ¬ goals;
goals ¬ goals.rest;
ENDLOOP;
};
ans: LIST OF LIST OF ATOM ¬ NIL;
IF dfNames = NIL OR goals = NIL THEN RETURN [result: $Failure, msg: cmd.procData.doc];
BEGIN ENABLE
{
MobOrder.BoundProgramNotKnown => {
IO.PutF[cmd.err, "-- Correct version of %g not in %g\n", [rope[Atom.GetPName[program.identifier]]], [rope[Atom.GetPName[configuration.identifier]]]];
RESUME;
};
MobOrder.BogusMob => {
IO.PutF1[cmd.err, "-- Mob error: %g\n", [rope[msg]]];
RESUME;
};
MobOrder.GoalNotFound => {
IO.PutF1[cmd.err, "-- Goal not found: %g\n", [rope[rope]]];
RESUME;
};
MobOrder.DuplicateExports => {
IO.PutF[cmd.err, "-- Duplicate exports to %g (%g)\n", [rope[Atom.GetPName[interfaceID.identifier]]], [rope[Atom.GetPName[moduleID.identifier]]]];
RESUME;
};
MobOrder.IncorrectVersionNumberInDF => {
IO.PutF[cmd.err, "-- Bad file version number %g => %g\n", [rope[fullFName]], [rope[Rope.Substr[realName, Rope.Index[s1: realName, s2: "!"]]]]];
RESUME;
};
};
SELECT cmd.procData.clientData FROM
$MobOrder => ans ¬ MakeLoadList[dfNames: dfNames, goals: goals];
$MobDependents => {
modules: LIST OF ATOM;
dependentDFNames: LIST OF ROPE;
[modules: modules, dependentDFNames: dependentDFNames] ¬ MakeDependentsList[dfNames: dfNames, roots: goals];
FOR tail: LIST OF ROPE ¬ dependentDFNames, tail.rest UNTIL tail = NIL DO
IO.PutRope[cmd.out, tail.first];
IF tail.rest # NIL THEN IO.PutRope[cmd.out, " "];
ENDLOOP;
IO.PutRope[cmd.out, "\n"];
ans ¬ LIST[modules];
};
ENDCASE => ERROR;
END;
FOR tail: LIST OF LIST OF ATOM ¬ ans, tail.rest UNTIL tail = NIL DO
FOR a: LIST OF ATOM ¬ tail.first, a.rest UNTIL a = NIL DO
id: ROPE = Atom.GetPName[a.first];
IO.PutRope[cmd.out, Rope.Substr[base: id, len: Rope.Index[s1: id, s2: "."]]];
IF a.rest # NIL THEN IO.PutRope[cmd.out, " "];
ENDLOOP;
IF tail.rest # NIL THEN IO.PutRope[cmd.out, "\t"];
ENDLOOP;
};
Commander.Register[key: "MobOrder", proc: Command, doc: usageOrder, clientData: $MobOrder];
Commander.Register[key: "MobDependents", proc: Command, doc: usageDependents, clientData: $MobDependents];
END.