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 = { 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 = { 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. Z 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 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] }; [fullFName: ROPE] RETURNS [continue: BOOL] RETURN [list] -- no star patterns here, for now. [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] side-effect on goals Κ –(cedarcode) style•NewlineDelimiter ™šœ™Icodešœ Οeœ=™HK™+K™$K™—šΟk œ žœ%žœ˜@K˜—K˜KšΟnœž ˜Kšžœ4ž˜=šœžœžœ ˜K˜•StartOfExpansionL -- [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL]šžœžœžœ˜K˜—šœ žœ‚˜’K˜—šœžœ\˜qK˜—šŸœžœžœžœžœžœžœžœžœžœžœ™mKš œžœžœžœžœžœ™Kšœžœžœžœ™šžœ žœž™–6[pattern: ROPE, object: ROPE, case: BOOL _ TRUE]šžœ7žœ™?šžœ™Kšœ™šžœ žœžœ™Kšœ)žœ™KKšžœ žœžœžœ™2Kšœ™—Kšœ™—šžœ™Kšœžœ™%Kšœ™——Kšœ™Kšžœ™—Kšžœ ™Kšœ™K™—šŸœžœ žœžœžœ žœžœžœžœžœžœžœžœžœ™qKšœ žœžœ)™=Kšœ žœžœžœ)™@Kšœ žœžœ4™FKš œžœžœžœžœ1™HKš œ žœžœžœžœžœ™7Kšžœ ™K™K™—šŸ œžœžœžœžœžœžœžœžœ˜AKš œžœžœžœžœžœ˜Kšœžœžœžœ˜–. -- [fullFName: ROPE] RETURNS [continue: BOOL]šŸœžœ žœ˜(Kšœ žœžœ˜šŸœžœ ˜Kšœ*™*Kšœ žœ˜Kšœžœ ˜#Kšœ žœ˜Kšœ˜—Kšžœ5˜7K–[error: FS.ErrorDesc]š žœžœ žœžœžœžœ7˜vKšœ˜—š žœžœžœžœžœžœž˜Kšœ žœžœžœ˜2š Ÿ œžœžœ žœžœžœ˜4Kšœ™Kš œžœžœžœžœ˜K˜šžœ žœž˜–-[s1: ROPE, s2: ROPE, case: BOOL _ TRUE]šžœ-žœžœ˜[s1: ROPE, pos1: INT _ 0, s2: ROPE, case: BOOL _ TRUE]šžœŽ˜Kšžœ˜K˜—Kšœ˜—šžœž˜#K˜@šœ˜Kšœ žœžœžœ˜Kšœžœžœžœ˜K˜lš žœžœžœžœžœžœž˜HK–>[s1: ROPE, pos1: INT _ 0, s2: ROPE, case: BOOL _ TRUE]šžœ˜ Kšžœ žœžœžœ˜1Kšžœ˜—Kšžœ˜Kšœžœ ˜Kšœ˜—Kšžœžœ˜—Kšžœ˜—šžœžœžœžœžœžœžœžœž˜Cš žœžœžœžœžœžœž˜9Kšœžœ˜"K–>[s1: ROPE, pos1: INT _ 0, s2: ROPE, case: BOOL _ TRUE]šžœK˜MKšžœ žœžœžœ˜.Kšžœ˜—Kšžœ žœžœžœ˜2Kšžœ˜—K˜K˜—Kšœ[˜[Kšœj˜j—K˜Kšžœ˜—…— ¨