-- Grapevine: Lily: misc input/output procedures

-- [Juniper]<Grapevine>Lily>LilySend.mesa

-- Andrew Birrell   4-Jan-82 15:27:32

DIRECTORY
Ascii,
GlassDefs	USING[ Handle, StringType ],
LilyIODefs	USING[ Confirmation ],
LogDefs		USING[ WriteLine, WriteLogEntry ],
MailParse	USING[ endOfInput ],
String		USING[ AppendDecimal, AppendString];

LilyIO: PROGRAM
IMPORTS LogDefs, String
EXPORTS LilyIODefs =

BEGIN

AppendFromInput: PUBLIC PROC[str: GlassDefs.Handle,
                             firstChar: CHARACTER,
                             write: PROC[CHARACTER],
                             unwrite: PROC RETURNS[CHARACTER],
                             type: GlassDefs.StringType]
                     RETURNS[end: CHARACTER] =
   BEGIN
   OPEN str;
   dummy: CHARACTER = '*; --used for echo if type = pwd--
   MyUnwrite: PROCEDURE =
      BEGIN
      prev: CHARACTER = unwrite[];
      IF prev # MailParse.endOfInput
      THEN BEGIN
           WriteChar['\];
           WriteChar[IF type = pwd THEN dummy ELSE prev];
           END;
      END;
   ClearWord: PROCEDURE =
      BEGIN
      state: { alpha, other } ← other;
      DO prev: CHARACTER = unwrite[];
         SELECT prev FROM
           MailParse.endOfInput => EXIT;
           IN ['a..'z], IN ['A..'Z], IN ['0..'9] => state ← alpha;
         ENDCASE => IF state # other THEN { write[prev]; EXIT };
         WriteChar['\];
         WriteChar[IF type = pwd THEN dummy ELSE prev];
      ENDLOOP;
      END;
   end ← firstChar;
   DO SELECT end FROM
         Ascii.ControlA, Ascii.BS => MyUnwrite[];
         Ascii.ControlW => ClearWord[];
         Ascii.ControlR => {WriteString["↑R"L]; WriteChar[Ascii.CR]; EXIT};
      ENDCASE =>
        BEGIN
        SELECT end FROM
          Ascii.SP => IF type # line AND type # any THEN EXIT;
          Ascii.CR => IF type # any THEN EXIT;
          Ascii.ESC, Ascii.DEL => EXIT;
        ENDCASE => NULL;
        write[end]; WriteChar[end];
        END;
      end ← ReadChar[];
   ENDLOOP;
   END;

Confirm: PUBLIC PROC[ str: GlassDefs.Handle]
             RETURNS[ answer: LilyIODefs.Confirmation ] =
   BEGIN
   OPEN str;
   DO WriteString[" [Confirm] "L];
      SELECT ReadChar[] FROM
        'y, 'Y, Ascii.SP, Ascii.CR => { answer ← yes; EXIT };
        'n, 'N =>                     { answer ← no; EXIT };
        Ascii.DEL =>                  { answer ← del; EXIT };
      ENDCASE =>
        WriteChar['?];
   ENDLOOP;
   WriteString[SELECT answer FROM
                 yes =>   "yes ... "L,
                 no =>    "no"L,
               ENDCASE => "XXX"L];
   SendNow[];
   END;

Type: PUBLIC PROC[str: GlassDefs.Handle,
                  readChar: PROC RETURNS[ CHARACTER ],
                  lastChar: CHARACTER] =
   BEGIN
   str.WriteChar[Ascii.CR];
   DO c: CHARACTER = readChar[]; IF c = lastChar THEN EXIT;
      IF str.DelTyped[] THEN EXIT;
      str.WriteChar[c];
   ENDLOOP;
   END;

LogAction: PUBLIC PROC[n: CARDINAL, action: STRING] =
   BEGIN
   log: STRING = [128];
   IF n = 0 THEN RETURN;
   String.AppendString[log, "Lily: connection #"L];
   String.AppendDecimal[log, n];
   String.AppendString[log, ": "L];
   String.AppendString[log, action];
   LogDefs.WriteLine[log]; LogDefs.WriteLogEntry[log];
   END;

END.