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;
~
BEGIN
OPEN MobOrder;
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 ROPE ← LIST[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];