-- /ivy/binding/hickory/hickoryUtilImpl.mesa -- last edited by: Binding, July 21, 1984 9:22:40 am PDT PDT PDT DIRECTORY BasicTime USING [GMT, earliestGMT, latestGMT, nullGMT], Commander USING [CommandProc, Register], Convert USING [ IntFromRope, RopeFromLiteral], FS USING [ StreamOpen, Error], Hickory USING [ EventTuple, EventList, RepetitionType, RestoreEvents, EnterEvent, DestroyDataBase, Options, NoOptions, All], HickorySupport USING [ DisplayFailureMessage], IO USING[PutRope, STREAM, SkipWhitespace, GetLineRope, EndOfStream, GetIndex, Close, PutF, PutFR, int, rope, TokenKind, GetCedarTokenRope, GetRopeLiteral, PeekChar, GetChar, EndOf, GetTokenRope, RIS], MessageWindow USING [ Append, Blink], RememberDefs USING [ ParameterClass], Rope USING[ROPE, Equal], Tempus USING [defaultTime, MakeRope, Packed, Parse, Unintelligible] ; HickoryUtilImpl: CEDAR PROGRAM IMPORTS BasicTime, Commander, Convert, FS, Hickory, HickorySupport, IO, MessageWindow, Rope, Tempus SHARES HickorySupport = BEGIN GetFileName: PROC [ cmdLine: Rope.ROPE] RETURNS [ fn: Rope.ROPE] = BEGIN fn _ "RememberEvents.txt"; -- default IF cmdLine # NIL AND NOT Rope.Equal[ cmdLine, "\n"] THEN BEGIN st: IO.STREAM _ IO.RIS[ cmdLine]; [] _ IO.SkipWhitespace[ st]; fn _ IO.GetTokenRope[ st ! IO.EndOfStream => CONTINUE].token; IF Rope.Equal[ fn, "\n"] THEN fn _ "RememberEvents.txt"; END; RETURN[ fn]; END; -- GetFileName TxtToDB: PROC [ cmdLine: Rope.ROPE] = BEGIN <> fileStream: IO.STREAM _ NIL; fileName: Rope.ROPE _ GetFileName[ cmdLine]; evList: Hickory.EventList _ NIL; error: BOOLEAN _ FALSE; BEGIN -- establish EXIT scope fileStream _ FS.StreamOpen[ fileName, $read ! FS.Error => CONTINUE]; IF fileStream = NIL THEN GOTO noRememberFile; evList _ NIL; DO evTime: Rope.ROPE; ev: Hickory.EventTuple; [] _ IO.SkipWhitespace[ fileStream]; evTime _ IO.GetLineRope[ fileStream ! IO.EndOfStream => EXIT]; ev.EventTime _ LOOPHOLE[ Tempus.Parse[ evTime ! Tempus.Unintelligible => GOTO badTimeFormat].time]; DO r: Rope.ROPE; class: RememberDefs.ParameterClass; par: Hickory.RepetitionType; time: Rope.ROPE; [class, r, error] _ ReadParameter[ fileStream]; IF error THEN GOTO formatError; SELECT class FROM repeat => BEGIN [ par, time] _ GetRepeatTypes[ r]; ev.RepeatType _ par; ev.RepeatTime _ time; END; until => IF Rope.Equal[ r, "", FALSE] THEN ev.RepeatUntil _ LOOPHOLE[ BasicTime.nullGMT] ELSE ev.RepeatUntil _ LOOPHOLE[ Tempus.Parse[ r].time]; duration => ev.Duration _ Convert.IntFromRope[ r]; getSeriousAfter => ev.NagTime _ Convert.IntFromRope[ r]; leadTime => ev.LeadTime _ Convert.IntFromRope[ r]; startTime => GOTO ambiguousStartTime; text => IF Rope.Equal[ r, "", FALSE] THEN ev.Text _ NIL ELSE ev.Text _ r; message => IF Rope.Equal[ r, "", FALSE] THEN ev.Message _ NIL ELSE ev.Message _ r; iconFlavor => IF Rope.Equal[ r, "", FALSE] THEN ev.IconFlavor _ NIL ELSE ev.IconFlavor _ r; iconLabel => IF Rope.Equal[ r, "", FALSE] THEN ev.IconLabel _ NIL ELSE ev.IconLabel _ r; place => IF Rope.Equal[ r, "", FALSE] THEN ev.Place _ NIL ELSE ev.Place _ r; keepUntil => IF Rope.Equal[ r, "", FALSE] THEN ev.KeepUntil _ LOOPHOLE[ BasicTime.nullGMT] ELSE ev.KeepUntil _ LOOPHOLE[ Tempus.Parse[ r].time]; ENDCASE; IF class = text THEN EXIT; -- text must come last! ENDLOOP; evList _ CONS[ ev, evList]; ENDLOOP; IO.Close[ fileStream]; FOR l: LIST OF Hickory.EventTuple _ evList, l.rest UNTIL l = NIL DO [] _ Hickory.EnterEvent[ l.first]; ENDLOOP; EXITS noRememberFile => BEGIN MessageWindow.Append[ "Could not find RememberEvents.txt", TRUE]; MessageWindow.Blink[]; END; badTimeFormat => HickorySupport.DisplayFailureMessage[ "HickoryUtilImpl.TxtToDB", IO.PutFR[ "Bad Time format for an event time in text file at or near position: %d", IO.int[ IO.GetIndex[ fileStream]]]]; formatError => NULL; ambiguousStartTime => HickorySupport.DisplayFailureMessage[ "HickoryUtilImpl.TxtToDB", IO.PutFR[ "Event start time specified twice in text file at or near position: %d\n", IO.int[ IO.GetIndex[ fileStream]]]]; END; END; -- TxtToDB GetRepeatTypes: PROCEDURE [ r: Rope.ROPE] RETURNS [ par: Hickory.RepetitionType _ None, time: Rope.ROPE _ NIL] = BEGIN IF Rope.Equal[ "Hourly", r, FALSE] THEN RETURN[ par: Hourly] ELSE IF Rope.Equal[ "Daily", r, FALSE] THEN RETURN[ par: Daily] ELSE IF Rope.Equal[ "Weekly", r, FALSE] THEN RETURN[ par: Weekly] ELSE IF Rope.Equal[ "Weekdays", r, FALSE] THEN RETURN[ par: Weekdays] ELSE IF Rope.Equal[ "Monthly", r, FALSE] THEN RETURN[ par: Monthly] ELSE IF Rope.Equal[ "Yearly", r, FALSE] THEN RETURN[ par: Yearly] ELSE RETURN[ par: Complicated, time: r]; END; -- GetRepeatTypes ReadParameter: PROC[stream: IO.STREAM] RETURNS[parameterClass: RememberDefs.ParameterClass _ text, value: Rope.ROPE _ NIL, error: BOOLEAN _ FALSE] = { ENABLE { IO.EndOfStream => BEGIN HickorySupport.DisplayFailureMessage["HickoryUtilImpl.ReadParameter", "Unexpected EOF"]; GOTO Error; END; }; key: Rope.ROPE; kind: IO.TokenKind; [kind, value, ] _ IO.GetCedarTokenRope[stream]; SELECT kind FROM tokenROPE => RETURN[text, Convert.RopeFromLiteral[value]]; tokenID => key _ value; tokenSINGLE => { -- e.g. , ; etc. left over on line. [parameterClass, value] _ ReadParameter[stream]; RETURN; }; ENDCASE => BEGIN HickorySupport.DisplayFailureMessage["HickoryUtilImpl.ReadParameter", "Unexpected Cedar Token Kind!"]; GOTO Error; END; [] _ IO.SkipWhitespace[stream]; IF NOT stream.EndOf[] AND stream.PeekChar[] = ': THEN [] _ stream.GetChar[]; SELECT TRUE FROM Rope.Equal[s1: key, s2: "REPEAT", case: FALSE] => parameterClass _ repeat; Rope.Equal[s1: key, s2: "DURATION", case: FALSE] => parameterClass _ duration; Rope.Equal[s1: key, s2: "GETSERIOUSAFTER", case: FALSE], Rope.Equal[s1: key, s2: "NAGTIME", case: FALSE] => parameterClass _ getSeriousAfter; Rope.Equal[s1: key, s2: "UNTIL", case: FALSE] => parameterClass _ until; Rope.Equal[s1: key, s2: "LEADTIME", case: FALSE] => parameterClass _ leadTime; Rope.Equal[s1: key, s2: "TIME", case: FALSE] => parameterClass _ startTime; Rope.Equal[s1: key, s2: "TEXT", case: FALSE] => parameterClass _ text; Rope.Equal[s1: key, s2: "ICONFLAVOR", case: FALSE] => parameterClass _ iconFlavor; Rope.Equal[s1: key, s2: "ICONLABEL", case: FALSE] => parameterClass _ iconLabel; Rope.Equal[s1: key, s2: "ICONLABELTYPE", case: FALSE] => parameterClass _ iconLabelType; Rope.Equal[s1: key, s2: "MESSAGE", case: FALSE] => parameterClass _ message; Rope.Equal[ s1: key, s2: "PLACE", case: FALSE] => parameterClass _ place; Rope.Equal[ s1: key, s2: "KEEPUNTIL", case: FALSE] => parameterClass _ keepUntil; ENDCASE => HickorySupport.DisplayFailureMessage[ "HickoryUtilImpl.ReadParameter", "Bad format for parameter keyword"]; [] _ IO.SkipWhitespace[stream]; IF stream.EndOf[] THEN value _ NIL ELSE IF stream.PeekChar[] = '" THEN value _ IO.GetRopeLiteral[stream] ELSE value _ IO.GetTokenRope[stream].token; RETURN; EXITS Error => error _ TRUE; }; DBToTxt: PROC [ cmdLine: Rope.ROPE] = BEGIN <> evList: LIST OF Hickory.EventTuple; out: IO.STREAM _ NIL; options: Hickory.Options _ Hickory.NoOptions; fileName: Rope.ROPE _ GetFileName[ cmdLine]; out _ FS.StreamOpen[fileName: fileName, accessOptions: $create, keep: 2 ! FS.Error => BEGIN MessageWindow.Append[IO.PutFR[ "FS Error trying to open%g", IO.rope[ fileName]], TRUE]; MessageWindow.Blink[]; CONTINUE; END ]; IF out = NIL THEN RETURN; options[ Hickory.All] _ TRUE; evList _ Hickory.RestoreEvents[ BasicTime.earliestGMT, BasicTime.latestGMT, options]; -- the entire data base FOR l: LIST OF Hickory.EventTuple _ evList, l.rest UNTIL l = NIL DO DumpEvent[ l.first, out]; ENDLOOP; IO.Close[ out]; END; -- DBToText DumpEvent: PROC [event: Hickory.EventTuple, stream: IO.STREAM] = BEGIN IO.PutF[ stream, "%g\n", IO.rope[ Tempus.MakeRope[ time: LOOPHOLE[ event.EventTime], includeDayOfWeek: TRUE]]]; IF event.RepeatType # None THEN BEGIN IO.PutRope[ stream, "Repeat: "]; IF event.RepeatType # Complicated THEN -- no need to fiddle around with time SELECT event.RepeatType FROM Hourly => IO.PutRope[ stream, "Hourly\n"]; Daily => IO.PutRope[ stream, "Daily\n"]; Weekdays => IO.PutRope[ stream, "Weekdays\n"]; Weekly => IO.PutRope[ stream, "Weekly\n"]; Monthly => IO.PutRope[ stream, "Monthly\n"]; Yearly => IO.PutRope[ stream, "Yearly\n"]; ENDCASE ELSE IO.PutF[ stream, "%g\n", IO.rope[ event.RepeatTime]]; IF event.RepeatUntil # BasicTime.nullGMT THEN IO.PutF[ stream, "Until: \"%g\"\n", IO.rope[ Tempus.MakeRope[ time: LOOPHOLE[ event.RepeatUntil], includeDayOfWeek: FALSE]]]; END; IF event.Duration # 0 THEN IO.PutF[ stream, "Duration: %d\n", IO.int[ event.Duration]]; IF event.LeadTime # 0 THEN IO.PutF[ stream, "LeadTime: %d\n", IO.int[ event.LeadTime]]; IF event.NagTime # 0 THEN IO.PutF[ stream, "NagTime: %d\n", IO.int[ event.NagTime]]; IF event.IconFlavor # NIL THEN IO.PutF[ stream, "IconFlavor: \"%g\"\n", IO.rope[ event.IconFlavor]]; IF event.IconLabel # NIL THEN IO.PutF[ stream, "IconLabel: \"%q\"\n", IO.rope[event.IconLabel]]; IF event.Message # NIL THEN IO.PutF[ stream, "Message: \"%q\"\n", IO.rope[event.Message]]; IF event.Place # NIL THEN IO.PutF[ stream, "Place: \"%g\"\n", IO.rope[ event.Place]]; IF event.KeepUntil # BasicTime.nullGMT THEN IO.PutF[ stream, "KeepUntil: \"%g\"\n", IO.rope[ Tempus.MakeRope[ time: LOOPHOLE[ event.KeepUntil]]]]; IO.PutF[ stream, "\"%q\"\n\n", IO.rope[event.Text]]; -- MUST be last END; -- DumpEvent DumpHickory: Commander.CommandProc = BEGIN DBToTxt[ cmd.commandLine]; END; CreateHickory: Commander.CommandProc = BEGIN TxtToDB[ cmd.commandLine]; END; DestroyHickory: Commander.CommandProc = TRUSTED BEGIN Hickory.DestroyDataBase[]; END; Commander.Register["DumpHickory", DumpHickory, "DumpHickory : dumps the entire data base onto RememberEvents.txt{cr})"]; Commander.Register["CreateHickory", CreateHickory, "CreateHickory : reads RememberEvents.txt and updates database{cr})"]; Commander.Register["DestroyHickory", DestroyHickory, "DestroyHickory: destroys the remember data base!{cr})"]; END.