-- File: WalnutRetrieveParseImpl.mesa
-- Contents: Implementation of the parsing of text into MsgRecs
-- Last edit by:
-- Rick on: XXX
-- Willie-Sue on: September 9, 1983 4:10 pm
DIRECTORY
GVMailParse USING [endOfInput, ParseError, ParseHandle,
FinalizeParse, GetFieldBody, GetFieldName, InitializeParse],
Rope,
IO,
WalnutLog USING [MsgRec],
WalnutParse USING [MessageFieldIndex, MessageInfo, ParseStatus, messageParseArray],
WalnutRetrieve;
WalnutRetrieveParseImpl: CEDAR PROGRAM
IMPORTS
GVMailParse, IO, Rope, WalnutParse
EXPORTS
WalnutRetrieve =
BEGIN OPEN GVMailParse;
ROPE: TYPE = Rope.ROPE;
-- turn the strm into records
ParseMsgIntoFields: PUBLIC PROC[msg: WalnutLog.MsgRec, strm: IO.STREAM, msgLength: INT]
RETURNS[s: WalnutParse.ParseStatus, sPos, mPos: INT] =
BEGIN
mLF: WalnutParse.MessageInfo;
startPos: INT← strm.GetIndex[];
lastCharPos: INT← startPos + msgLength;
NextChar: PROC[] RETURNS [ch: CHAR] =
{ IF mPos > lastCharPos THEN ch← endOfInput
ELSE ch← strm.GetChar[ ! IO.EndOfStream => {ch← endOfInput; CONTINUE}];
mPos← mPos + 1;
};
SimpleField: PROC[index: WalnutParse.MessageFieldIndex, fieldBody: ROPE] =
BEGIN
SELECT index FROM
senderF => msg.inMsgSender← fieldBody;
replyToF, ccF, cF, bccF => NULL;
fromF => msg.from← fieldBody;
dateF => msg.date← fieldBody;
subjectF => msg.subject← fieldBody;
inReplyToF => msg.inReplyTo← fieldBody;
toF => msg.to← fieldBody;
voiceF => msg.voiceID← fieldBody;
ENDCASE => ERROR;
END;
CategoriesField: PROC[fB: ROPE] RETURNS [LIST OF ROPE] =
BEGIN
end: INT← fB.Length[];
p: INT← Rope.SkipOver[fB, 0, " \n"];
r: ROPE;
IF p # end THEN r← Rope.Substr[fB, p, end-p+1] ELSE {r← fB; p← 0};
IF (p← Rope.Find[fB, "',", p]) < 0 THEN RETURN[CONS[r, NIL]]
ELSE RETURN[CONS[r, CategoriesField[Rope.Substr[r, p+1, end-p]]]];
END;
pH: ParseHandle← InitializeParse[];
BEGIN
field: ROPE← NIL;
s← ok; -- good status
mPos← startPos;
DO
found, fieldNotRecognized: BOOL← TRUE;
sPos← mPos;
[field, found]← GetFieldName[pH, NextChar ! ParseError => GOTO parseErrorExit];
IF ~found THEN EXIT;
FOR i: WalnutParse.MessageFieldIndex IN WalnutParse.MessageFieldIndex DO
{ mLF← WalnutParse.messageParseArray[i];
IF Rope.Equal[mLF.name, field, FALSE] THEN -- ignore case
{ fieldNotRecognized← FALSE;
SELECT mLF.fType FROM
simpleRope, rNameList => SimpleField[i, GetFieldBody[pH, NextChar]];
rCatList => msg.categoriesList← CategoriesField[GetFieldBody[pH, NextChar]];
ENDCASE => ERROR;
};
};
ENDLOOP;
IF fieldNotRecognized THEN
[]← GetFieldBody[pH, NextChar, TRUE]; -- anything not recognized
ENDLOOP;
-- leaves strm positioned at the beginning of the body of the message
FinalizeParse[pH];
EXITS
parseErrorExit => { FinalizeParse[pH]; RETURN[syntaxError, sPos, mPos]};
END;
END;
END.