-- MessageParse.mesa -- Edited by Brotz, March 26, 1982 1:27 PM DIRECTORY vmD: FROM "VirtualMgrDefs" USING [CharIndex, ComposedMessagePtr, VirtualMessagePtr]; MessageParse: DEFINITIONS = BEGIN -- This interface provides a fast, simplified message parser. The functions supplied here do -- not adhere to every nuance of the Arpa standard message header syntax. Instead, a -- simple subset of that standard is supported. In almost all cases, this parser is sufficient -- for field parsing, as long as complicated address fields are not used. -- As in the Arpa standard, a carriage return followed by a blank or tab character is -- considered to be white space and does not terminate a field body. The first character -- of a field name must immediately follow a carriage return (or be the first character in -- the message. After this first character, blanks and tabs are ignored until a colon is -- encountered. The de-blanked text from the first character until (but not including) -- the colon is considered the field name. Capitalization is irrelevent is field names. ParseFault: ERROR [error: ParseError]; -- Raised by GetNextWord and GetNextNumber due to the exceptional condition indicated -- by error. If raised with error = stringTooSmall, then the calling procedure may be -- RETRY'ed with a larger string. ParseError: TYPE = {stringTooSmall, illegalNumber}; FieldRec: TYPE = RECORD [name: STRING, bodyStart, bodyEnd: vmD.CharIndex, found: CARDINAL]; FieldRecPtr: TYPE = POINTER TO FieldRec; FieldRecDescriptor: TYPE = DESCRIPTOR FOR ARRAY OF FieldRec; ParseMessage: PROCEDURE [vm: vmD.VirtualMessagePtr, fields: FieldRecDescriptor]; -- The message in vm is scanned for field names matching the set of names given in fields. -- The number of times each field name is encountered in vm is set in the found field -- corresponding to that field name. For any field whose found number is greater than -- or equal to 1, the bodyStart field is set to the index of the first character following the -- field name's colon, and the bodyEnd field is set to the CharIndex of the first carriage -- return (or end of message) that terminates that field body. If found = 0, then bodyStart -- and bodyEnd are 0. vm is searched for fields from [0 .. MessageLength[vm]). FieldListRec: TYPE = RECORD [field: STRING, start, valueStart, valueEnd: vmD.CharIndex, next: FieldList]; FieldList: TYPE = POINTER TO FieldListRec; FieldListPtr: TYPE = POINTER TO FieldList; MakeFieldList: PROCEDURE [vm: vmD.VirtualMessagePtr] RETURNS [fieldList: FieldList]; -- Creates a complete list of fields contained in vm. The fields in the list are sorted by -- position in vm. FreeFieldList: PROCEDURE [fieldList: FieldList]; -- Frees all storage associated with fieldList. LocateField: PROCEDURE [fieldList: FieldList, name: STRING] RETURNS [field: FieldList, count: CARDINAL]; -- Searches fieldList for a FieldListRec matching name. Returns a pointer to the matched -- FieldListRec and a count of how many matches actually occur in the list. UpdateFieldList: PROCEDURE [fieldList: FieldList, delta: INTEGER]; -- Increments the CharIndex's in the Field List starting at fieldList by delta. This procedure -- should be used whenever editing causes modifications in field positions. ReplaceOrAppendField: PROCEDURE [cm: vmD.ComposedMessagePtr, fieldListPtr: MessageParse.FieldListPtr, field, value: STRING, insertAtBeginning: BOOLEAN _ FALSE]; DeleteField: PROCEDURE [cm: vmD.ComposedMessagePtr, fieldListPtr: MessageParse.FieldListPtr, name: STRING]; GetNumberFromField: PROCEDURE [vm: vmD.VirtualMessagePtr, fieldList: FieldList, s: STRING] RETURNS [value: CARDINAL]; GetStringFromField: PROCEDURE [vm: vmD.VirtualMessagePtr, fieldList: FieldList, field, value: STRING]; -- Returns in "value" the first word in the value portion of the "field" of "vm". GetWholeField: PROCEDURE [vm: vmD.VirtualMessagePtr, fieldList: FieldList, name, value: STRING]; GetNextWord: PROCEDURE [vm: vmD.VirtualMessagePtr, start, end: vmD.CharIndex, s: STRING, includePlusAndMinus: BOOLEAN _ TRUE] RETURNS [newStart: vmD.CharIndex]; -- Within vm[[start .. end)], the next word (run of non-whitespace characters) in vm is -- copied into s. Leading whitespace characters are ignored. newStart is the CharIndex -- suitable for passing into GetNextWord or GetNextNumber to get a subsequent word or -- number. -- IF includePlusAndMinus is TRUE, then + and - are treated as if they were alphanumeric. -- May raise ParseFault[stringTooSmall] if the word to be copied into s is larger than -- s.maxlength. GetNextNumber: PROCEDURE [vm: vmD.VirtualMessagePtr, start, end: vmD.CharIndex, s: STRING] RETURNS [newStart: vmD.CharIndex]; -- Within vm[[start .. end)], the next number (defined as [+/-]D*.D*[E[+/-]D*], where -- [x] indicates an optional part, +/- indicates either a plus or minus sign, D* is 0 or -- more digits, E is the letter E) in vm is copied into s. Examples: 10, -23, +.34, 2.1E-12, -- 1E3, 0.2. Leading whitespace characters are ignored. newStart is the CharIndex -- suitable for passing into GetNextWord or GetNextNumber to get a subsequent word -- or number. -- May raise ParseFault[stringTooSmall] if the number to be copied into s is larger than -- s.maxlength. May raise ParseFault[illegalNumber] if no legal number occurs next in -- vm. END. -- of MessageParse -- (635)\f1