<> <> <> DIRECTORY AMModel USING [MostRecentNamedContext, RootContext, Section, Source], AMModelBridge USING [FrameFromContext], AMViewerOps USING [ReportProc, SourceFromTV], AMTypes USING [TV], BasicTime USING [FromPupTime], BcdDefs USING [NullVersion, VersionStamp], Commander USING [CommandProc, Handle, Register], FileViewerOps USING [OpenSource], IO USING [EndOfStream, GetTokenRope, IDProc, Put, PutRope, RIS, STREAM, time], List USING [Assoc], ProcessProps USING [GetPropList], Rope USING [Concat, Fetch, Flatten, Index, Match, ROPE, Run, Size, Substr], VersionMap USING [Length, Map, MapList, Range, RangeList, RangeToEntry, ShortNameToRanges], VersionMapDefaults USING [GetMapList], WorldVM USING [LocalWorld, World]; VersionMapCommandsImpl: CEDAR MONITOR IMPORTS AMModel, AMModelBridge, AMViewerOps, BasicTime, Commander, FileViewerOps, List, IO, ProcessProps, Rope, VersionMap, VersionMapDefaults, WorldVM SHARES VersionMap = BEGIN OPEN AMViewerOps, FileViewerOps; <> Section: TYPE = AMModel.Section; Source: TYPE = AMModel.Source; SourceFileList: TYPE = LIST OF SourceFileEntry; SourceFileEntry: TYPE = RECORD[map: VersionMap.Map, name: ROPE, stamp: VersionStamp]; Map: TYPE = VersionMap.Map; MapList: TYPE = VersionMap.MapList; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; TV: TYPE = AMTypes.TV; VersionStamp: TYPE = BcdDefs.VersionStamp; NullVersion: VersionStamp = BcdDefs.NullVersion; World: TYPE = WorldVM.World; <> <<[name: ROPE, desiredVersion: VersionStamp _ NullVersion]>> <> <> <> <> <> < 0 THEN version _ [0, 0, BasicTime.ToPupTime[created]];>> <> <<};>> < CONTINUE];>> <<}; >> <<>> FindSource: PROC [short: ROPE, mapList: MapList _ NIL, firstOnly: BOOL _ FALSE] RETURNS [SourceFileList _ NIL] = TRUSTED { size: INT _ short.Size[]; match: BOOL _ short.Index[0, "*"] # size; hasDot: BOOL _ short.Index[0, "."] # size; rangeList: VersionMap.RangeList _ NIL; head,tail: SourceFileList _ NIL; shortShort: ROPE _ NIL; IF size = 0 THEN RETURN; IF match THEN { shortShort _ Rope.Flatten[short, 0, short.Index[0, "*"]]; IF shortShort.Size[] = 0 THEN RETURN; } ELSE { IF NOT hasDot THEN { short _ short.Concat[".mesa"]; size _ short.Size[]; }; }; IF mapList = NIL THEN mapList _ VersionMapDefaults.GetMapList[$Source]; rangeList _ VersionMap.ShortNameToRanges[mapList, short]; WHILE rangeList # NIL DO range: VersionMap.Range _ rangeList.first; map: Map = range.map; rangeList _ rangeList.rest; IF NOT match THEN { WHILE range.len # 0 DO new: SourceFileList; fullName: ROPE; stamp: VersionStamp; [fullName, stamp, range] _ VersionMap.RangeToEntry[range]; new _ LIST[[map: range.map, name: fullName, stamp: stamp]]; IF tail = NIL THEN head _ new ELSE tail.rest _ new; tail _ new; ENDLOOP; } ELSE { entries: CARDINAL = VersionMap.Length[map]; shortShortLen: INT = Rope.Size[shortShort]; IF range.first >= entries THEN LOOP; range.len _ entries - range.first; WHILE range.len # 0 DO fullName: ROPE; stamp: VersionStamp; thisShort: ROPE; [fullName, stamp, range] _ VersionMap.RangeToEntry[range]; thisShort _ ShortName[fullName]; IF Rope.Run[shortShort, 0, thisShort, 0, FALSE] # shortShortLen THEN EXIT; IF Rope.Match[short, thisShort, FALSE] THEN { new: SourceFileList _ LIST[[map: range.map, name: fullName, stamp: stamp]]; IF tail = NIL THEN head _ new ELSE tail.rest _ new; tail _ new; }; ENDLOOP; }; ENDLOOP; RETURN [head]; }; <> <> <> <> <> <> <> <> <> <> <> <<}; >> <> <<};>> <<>> ShortName: PROC [r: ROPE] RETURNS [ROPE] = { <> <> first: INT _ 0; last: INT _ r.Size[]; FOR i: INT DECREASING IN [0..last) DO c: CHAR _ r.Fetch[i]; SELECT c FROM '>, '/ => {first _ i+1; EXIT}; '! => last _ i ENDCASE; ENDLOOP; RETURN [r.Substr[first, last - first]] }; OpenCommand: Commander.CommandProc = TRUSTED { <<[cmd: Handle]>> <<=> [in, out, err: STREAM, commandLine,command: ROPE, propertyList: List.AList]>> st: IO.STREAM _ cmd.out; dir: ROPE _ NIL; each: PROC [r: ROPE] = TRUSTED { inStream: IO.STREAM _ IO.RIS[r]; DO sfl: SourceFileList _ NIL; r _ IO.GetTokenRope[inStream, IO.IDProc ! IO.EndOfStream => EXIT].token; IF r.Size[] = 0 THEN RETURN; sfl _ RemoveDuplicates[FindSource[r, NIL, FALSE]]; IF sfl = NIL THEN { st.PutRope["Sorry, '"]; st.PutRope[r]; st.PutRope["' is not in the current Cedar release.\n"]; LOOP}; IF sfl.rest # NIL THEN { st.PutRope["Sorry, multiple versions for '"]; st.PutRope[r]; st.PutRope["':"]; WHILE sfl # NIL DO st.PutRope["\n "]; st.PutRope[sfl.first.name]; st.PutRope["\n "]; st.Put[IO.time[BasicTime.FromPupTime[sfl.first.stamp.time]]]; sfl _ sfl.rest; ENDLOOP; st.PutRope["\n"]; LOOP}; OpenSource[sfl.first.name, 0, 0, GetOutStream[]]; -- OpenViewerFromEntry[sfl.first]; st.PutRope["\n"]; ENDLOOP; }; each[cmd.commandLine]; }; OpenGlobalCommand: Commander.CommandProc = TRUSTED { <<[cmd: Handle]>> <<=> [in, out, err: STREAM, commandLine,command: ROPE, propertyList: List.AList]>> st: IO.STREAM _ cmd.out; dir: ROPE _ NIL; each: PROC [r: ROPE] = TRUSTED { inStream: IO.STREAM _ IO.RIS[r]; gf: TV _ NIL; DO fileName: ROPE _ NIL; r _ IO.GetTokenRope[inStream, IO.IDProc ! IO.EndOfStream => EXIT].token; IF r.Size[] = 0 THEN RETURN; gf _ AMModelBridge.FrameFromContext [AMModel.MostRecentNamedContext [name: r, context: AMModel.RootContext[WorldVM.LocalWorld[]]]]; IF gf = NIL THEN { st.PutRope[r]; st.PutRope[" can not be found.\n"]; LOOP; }; fileName _ SourceFromTV[gf, ClarkKent].name; IF fileName # NIL THEN { OpenSource[fileName, 0, 0, GetOutStream[]]; st.PutRope["\n"]; }; ENDLOOP; }; each[cmd.commandLine]; }; GetOutStream: PROC RETURNS[s: IO.STREAM _ NIL] = TRUSTED { WITH List.Assoc[$CommanderHandle, ProcessProps.GetPropList[]] SELECT FROM cmd: Commander.Handle => s _ cmd.out; ENDCASE; }; ClarkKent: AMViewerOps.ReportProc = TRUSTED { <<[msg: ROPE, severity: Severity]>> <<=> [in, out, err: STREAM, commandLine,command: ROPE, propertyList: List.AList]>> WITH List.Assoc[$CommanderHandle, ProcessProps.GetPropList[]] SELECT FROM cmd: Commander.Handle => { st: IO.STREAM _ cmd.out; st.PutRope[msg]; }; ENDCASE; }; RemoveDuplicates: PROC [sfl: SourceFileList] RETURNS [new: SourceFileList _ NIL] = { IF sfl # NIL THEN { entry: SourceFileEntry _ sfl.first; thisStamp: VersionStamp _ entry.stamp; each: SourceFileList _ sfl.rest _ RemoveDuplicates[sfl.rest]; lag: SourceFileList _ new _ sfl; WHILE each # NIL DO next: SourceFileList _ each.rest; IF each.first.stamp = thisStamp THEN lag.rest _ next ELSE lag _ each; each _ next; ENDLOOP; }; }; FindCommand: Commander.CommandProc = TRUSTED { <<[cmd: Handle]>> <<=> [in, out, err: STREAM, commandLine,command: ROPE, propertyList: List.AList]>> st: IO.STREAM _ cmd.out; each: PROC [r: ROPE] = TRUSTED { inStream: IO.STREAM _ IO.RIS[r]; DO sfl: SourceFileList _ NIL; r _ IO.GetTokenRope[inStream, IO.IDProc ! IO.EndOfStream => EXIT].token; IF r.Size[] = 0 THEN RETURN; sfl _ RemoveDuplicates[FindSource[r, NIL, FALSE]]; IF sfl = NIL THEN { st.PutRope["Sorry, '"]; st.PutRope[r]; st.PutRope["' is not in the current Cedar release.\n"]; LOOP}; st.PutRope[r]; st.PutRope[" =>\n"]; sfl _ FindSource[r, NIL, FALSE]; IF sfl = NIL THEN { st.PutRope["Sorry, '"]; st.PutRope[r]; st.PutRope["' is not in the current Cedar release.\n"]; LOOP}; WHILE sfl # NIL DO st.PutRope[" "]; st.PutRope[sfl.first.name]; st.PutRope["\n "]; st.Put[IO.time[BasicTime.FromPupTime[sfl.first.stamp.time]]]; st.PutRope["\n"]; sfl _ sfl.rest; ENDLOOP; ENDLOOP; }; each[cmd.commandLine]; }; Init: PROC = TRUSTED { Commander.Register [ "openr", OpenCommand, "Opens viewers on Cedar release source files given the short names (.mesa extension is the default). If a short name has multiple long names associated with it, the alternatives are listed, and no viewer is opened for that name. No spelling correction is performed."]; Commander.Register [ "openG", OpenGlobalCommand, "Opens source for named global frame."]; Commander.Register [ "findr", FindCommand, "Finds Cedar release source file names given the short names (.mesa extension is the default). No spelling correction is performed."]; }; Init[]; END.