<<>> <> <> <> <> <<>> 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 ... -g ... -i ... -x \"\""; usageDependents: ROPE = "Deduce a dependents order from DFs and Mobs: MobDependents ... -g ... "; <> <> <> <> <> <> <> <> <> <> <<};>> <<}>> <> <> <<};>> <> <> <> <<};>> <<>> <> <> <> <> <> <> <> <<};>> <<>> 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]; <> }; 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] = { <> 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.