<> <> DIRECTORY AMModel, BcdDefs, Commander, CommandTool, FS, IO, ListerUtils, Rope, TimeStamp, VersionOf, VM; VersionOfImpl: CEDAR PROGRAM IMPORTS AMModel, Commander, CommandTool, FS, IO, ListerUtils, Rope, VM EXPORTS VersionOf = BEGIN OPEN VersionOf; NamedContexts: PUBLIC PROC [name: ROPE, context: --worldRoot or model--Context _ NIL--means root of this world--] RETURNS [contexts: ContextList] = TRUSTED { Collect: PROC [c: Context] RETURNS [stop: BOOL] = CHECKED { contexts _ CONS[c, contexts]; stop _ FALSE; }; IF context = NIL THEN context _ AMModel.RootContext[]; contexts _ NIL; [] _ AMModel.NamedContexts[name, context, Collect]; name _ name; }; GetVersions: PUBLIC PROC [name: ROPE, context: --worldRoot or model--Context _ NIL--means root of this world--] RETURNS [versions: VersionStampList] = TRUSTED { Collect: UNSAFE PROC [c: Context] RETURNS [stop: BOOL] = { versions _ CONS[AMModel.SectionVersion[AMModel.ContextSection[c]], versions]; stop _ FALSE; }; IF context = NIL THEN context _ AMModel.RootContext[]; versions _ NIL; [] _ AMModel.NamedContexts[name, context, Collect]; name _ name; }; VersionOfBcd: PUBLIC PROC [fileName: ROPE] RETURNS [version: VersionStamp] = TRUSTED { bcd: ListerUtils.RefBCD = ListerUtils.ReadBcd[fileName]; version _ IF bcd = NIL OR bcd.versionIdent # BcdDefs.VersionID THEN TimeStamp.Null ELSE bcd.version; }; VersionOfCmd: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- = TRUSTED { context: Context = AMModel.RootContext[]; FOR name: ROPE _ CommandTool.NextArgument[cmd], CommandTool.NextArgument[cmd] WHILE name # NIL DO IF Rope.Find[s1: name, s2: ".BCD", case: FALSE] # -1 THEN { ENABLE UNWIND => cmd.err.PutRope["OK! OK! I give up!\n"]; version: VersionStamp = VersionOfBcd[name !FS.Error => {cmd.err.PutF["FS.Error[%g, %g]\n", [atom[error.code]], [rope[error.explanation]]]; LOOP}]; fullFileName: ROPE = FS.FileInfo[name].fullFName; cmd.out.PutRope[fullFileName]; cmd.out.PutRope[""]; ListerUtils.PrintVersion[version, cmd.out]; cmd.out.PutRope["\n"]; } ELSE { Report: UNSAFE PROC [c: Context] RETURNS [stop: BOOL] = { first: BOOL _ TRUE; FOR c _ c, AMModel.ParentContext[c] WHILE AMModel.ContextClass[c] # world DO section: AMModel.Section = AMModel.ContextSection[c]; version: VersionStamp = AMModel.SectionVersion[section]; IF first THEN first _ FALSE ELSE cmd.out.PutRope[" in "]; cmd.out.PutRope[ContextName[c]]; cmd.out.PutRope[""]; ListerUtils.PrintVersion[version, cmd.out]; ENDLOOP; cmd.out.PutRope["\n"]; stop _ FALSE; }; [] _ AMModel.NamedContexts[name, context, Report]; }; ENDLOOP; }; ContextName: PROC [c: Context] RETURNS [name: ROPE] = TRUSTED { name _ NIL; name _ AMModel.ContextName[c !VM.AddressFault => --as of this writing, there is a bug that makes this error happen sometimes, and the line below is a workaround--CONTINUE]; IF name = NIL THEN name _ AMModel.SectionName[AMModel.ContextSection[c]]; }; Commander.Register[key: "VersionOf", proc: VersionOfCmd, doc: "Report version stamp of loaded program or BCD"]; END.