<<>> <> <> <> DIRECTORY Convert, IO, PFS, Rope, VersionMap2, VersionMap2Pretty; VersionMap2PrettyImpl: CEDAR PROGRAM IMPORTS Convert, IO, PFS, Rope, VersionMap2 EXPORTS VersionMap2Pretty = BEGIN OPEN VersionMap2, VersionMap2Pretty; FormatName: PUBLIC PROC [name: Name] RETURNS [ROPE] ~ { IF name=nullName THEN RETURN ["*"]; RETURN [PFS.RopeFromPath[name]]}; ParseName: PUBLIC PROC [r: ROPE] RETURNS [Name] ~ { IF r.Equal["*"] THEN RETURN [nullName]; RETURN [PFS.PathFromRope[r]]}; FormatCreated: PUBLIC PROC [c: Created] RETURNS [r: ROPE] ~ { IF c=nullCreated THEN RETURN ["*"]; r _ Convert.RopeFromTime[from: c.egmt.gmt, end: seconds, useAMPM: FALSE]; IF c.egmt.usecs#0 THEN { sep: INT ~ r.FindBackward[" "]; r _ r.Replace[start: sep, len: 0, with: IO.PutFR1[".%06d", [cardinal[c.egmt.usecs]]]]}; IF c.host # [0, 0] THEN r _ IO.PutFR["%g at [%g, %g]", [rope[r]], [cardinal[c.host.a]], [cardinal[c.host.b]] ]; RETURN}; ParseCreated: PUBLIC PROC [r: ROPE] RETURNS [c: Created _ nullCreated] ~ { ENABLE Convert.Error => GOTO Err; dotpos: INT ~ r.Find["."]; IF r.Equal["*"] THEN RETURN [nullCreated]; IF dotpos > 0 THEN { sep: INT ~ r.Index[s2: " ", pos1: dotpos]; usr: ROPE ~ r.Substr[start: dotpos+1, len: sep-(dotpos+1)]; IF sep >= r.Length THEN GOTO Err; c.egmt.usecs _ Convert.CardFromRope[usr]; r _ r.Replace[start: dotpos, len: sep-dotpos, with: NIL]}; {atpos: INT ~ r.Find[" at ["]; IF atpos > 0 THEN { commapos: INT ~ r.Index[atpos, ","]; closepos: INT ~ r.Index[commapos, "]"]; IF closepos >= r.Length[] THEN GOTO Err; c.host.a _ Convert.CardFromRope[r.Substr[atpos+5, commapos-(atpos+5)]]; c.host.b _ Convert.CardFromRope[r.Substr[commapos+1, closepos-(commapos+1)]]; r _ r.Substr[len: atpos]}; c.egmt.gmt _ Convert.TimeFromRope[r]; RETURN}; EXITS Err => ERROR Error[[client, $CreatedSyntaxError, IO.PutFR1["\"%q\" does not follow created syntax", [rope[r]]], r]]}; FormatStamp: PUBLIC PROC [s: VersionStamp] RETURNS [r: ROPE] ~ { IF s=nullStamp THEN RETURN ["*"]; r _ IO.PutFR["%08x%08x", [cardinal[s[0]]], [cardinal[s[1]]] ]; RETURN}; ParseStamp: PUBLIC PROC [r: ROPE] RETURNS [s: VersionStamp _ nullStamp] ~ { IF r.Equal["*"] THEN RETURN [nullStamp]; IF r.Length[] # 16 THEN ERROR Error[[client, $StampSyntaxError, IO.PutFR1["\"%q\" does not follow version stamp syntax", [rope[r]]], r]]; {ENABLE Convert.Error => ERROR Error[[client, $StampSyntaxError, IO.PutFR1["\"%q\" does not follow version stamp syntax", [rope[r]]], r]]; s[0] _ Convert.CardFromRope[r.Substr[len: 8], 16]; s[1] _ Convert.CardFromRope[r.Substr[start: 8], 16]; RETURN}}; FormatTuple: PUBLIC PROC [t: VersionTuple] RETURNS [ROPE] ~ { RETURN Rope.Cat[FormatName[t.name], " of ", FormatCreated[t.created], " ver ", FormatStamp[t.stamp] ]}; ParseTuple: PUBLIC PROC [r: ROPE] RETURNS [t: VersionTuple _ nullTuple] ~ { verpos: INT ~ r.FindBackward[" ver "]; IF verpos < 0 THEN ERROR Error[[client, $TupleSyntaxError, IO.PutFR1["\"%q\" does not follow version tuple syntax ( of ver )", [rope[r]]], r]]; {ofpos: INT ~ r.FindBackward[" of ", verpos]; IF ofpos <= 0 THEN ERROR Error[[client, $TupleSyntaxError, IO.PutFR1["\"%q\" does not follow version tuple syntax ( of ver )", [rope[r]]], r]]; t.name _ ParseName[r.Substr[len: ofpos]]; t.created _ ParseCreated[r.Substr[start: ofpos+4, len: verpos-(ofpos+4)]]; t.stamp _ ParseStamp[r.Substr[start: verpos+5]]; RETURN}}; ListMap: PUBLIC PROC [map: Map, to: IO.STREAM, inOrder: BOOL, filters: MapList _ NIL] ~ {FactoredListMap[map, to, inOrder, PatternFactorMapList[filters]]}; FactoredListMap: PUBLIC PROC [map: Map, to: IO.STREAM, inOrder: BOOL, pfml: PatternFactoredMapList _ []] ~ { ListTuple: PROC [t: VersionTuple] RETURNS [BOOL] ~ { to.PutRope[FormatTuple[t]]; to.PutRope["\n"]; RETURN [FALSE]}; IF map.FactoredScan[ListTuple, inOrder, pfml].found THEN ERROR; RETURN}; END.