<> <> <> <> DIRECTORY BasicTime USING [GMT, nullGMT], IO USING [STREAM], Rope USING [ROPE]; DFUtilities: CEDAR DEFINITIONS = BEGIN OPEN BasicTime, IO, Rope; <> DirectoryItem: TYPE = RECORD [ path1: ROPE, path2: ROPE, path2IsCameFrom: BOOL, -- only meaningful if path2 is non-NIL; FALSE means "ReleaseAs" exported: BOOL, -- if TRUE, "Exports" preceded or replaced "Directory" readOnly: BOOL -- if TRUE, "ReadOnly" preceded or replaced "Directory" ]; FileItem: TYPE = RECORD [ name: ROPE, -- a short name date: Date, verifyRoot: BOOL -- if TRUE, file item was preceded by a "+" ]; ImportsItem: TYPE = RECORD [ path1: ROPE, date: Date, path2: ROPE, -- if non-NIL, path following "CameFrom" exported: BOOL, -- if TRUE, "Exports" preceded or followed "Imports" form: UsingForm, list: REF UsingList -- NIL iff form ~= list ]; IncludeItem: TYPE = RECORD [ path1: ROPE, date: Date, path2: ROPE, path2IsCameFrom: BOOL -- only meaningful if path2 is non-NIL; FALSE means "ReleaseAs" ]; CommentItem: TYPE = RECORD [ text: ROPE -- exact text, including comment characters ]; WhiteSpaceItem: TYPE = RECORD [ lines: NAT ]; <> DateFormat: TYPE = {explicit, omitted, greaterThan, notEqual}; Date: TYPE = RECORD [ format: DateFormat _ $omitted, gmt: GMT _ nullGMT <<'gmt' is valid only if dateFormat = $explicit. (We don't use a variant record because it complicates the client's life too much (i.e., the compiler is unnecessarily picky about assignments involving variant records that aren't REF-containing).)>> ]; <> UsingForm: TYPE = {exports, all, list}; UsingList: TYPE = RECORD [nEntries: NAT, u: SEQUENCE length: NAT OF UsingEntry]; UsingEntry: TYPE = RECORD [ verifyRoot: BOOL _ FALSE, -- if TRUE, file name was preceded by a "+" name: ROPE -- a short name ]; <<>> <> ParseFromStream: PROC [in: STREAM, proc: ProcessItemProc, filter: Filter _ []]; <> ProcessItemProc: TYPE = PROC [item: REF ANY] RETURNS [stop: BOOL _ FALSE]; <> SyntaxError: ERROR [reason: ROPE]; <> Filter: TYPE = RECORD [ comments: BOOL _ FALSE, filterA: FilterA _ $all, filterB: FilterB _ $all, filterC: FilterC _ $all, list: REF UsingList _ NIL ]; <> <<* A Comment item passes the filter iff 'comments' is TRUE.>> <<* A WhiteSpace item passes the filter iff 'comments' is TRUE and the item immediately following it (which cannot be another WhiteSpace item) passes the filter. This implies that the last item passed is never WhiteSpace; i.e., terminal white space in the input stream will not be reported to the ProcessItemProc.>> <<* A DirectoryItem passes the filter iff its 'exported' and 'readOnly' attributes are consistent with 'filterB' and 'filterC', respectively. If a DirectoryItem is skipped, all FileItems under it will be skipped as well. However, a DirectoryItem may be passed without any of the FileItems under it being passed.>> <<* A FileItem passes the filter iff (1) the preceding DirectoryItem was passed, (2) the file name passes 'filterA' and, (3) if 'list' is non-NIL, the file name appears in the list.>> <<* An IncludeItem always passes the filter.>> <<* An ImportsItem passes the filter only if its 'exported' attribute is consistent with 'filterB' and 'filterC' is '$imported' or '$all'. The 'form' and 'list' fields of the ImportsItem are determined by "intersecting" in the obvious way the contents of the input DF and the Filter's 'filterA' and 'list' fields. If this intersection is empty, the ImportsItem is not passed.>> FilterA: TYPE = {source, derived, all}; <> FilterB: TYPE = {public, private, all}; <> FilterC: TYPE = {defining, imported, all}; <> WriteToStream: PROC [out: STREAM, proc: SupplyItemProc]; <> SupplyItemProc: TYPE = PROC RETURNS [REF ANY]; <> WriteItemToStream: PROC [out: STREAM, item: REF ANY]; <> SortUsingList: PROC [usingList: REF UsingList, nearlySorted: BOOL _ FALSE]; <> SearchUsingList: PROC [file: ROPE, list: REF UsingList] RETURNS [found: BOOL, index: NAT]; <> DifferenceOfUsingLists: PROC [a, b: REF UsingList] RETURNS [diff: REF UsingList]; <> DateToRope: PROC [date: Date] RETURNS [ROPE]; <> <<>> DateToStream: PROC [s: STREAM, date: Date]; <> <<>> ClassifyFileExtension: PROC [file: ROPE] RETURNS [FilterA]; <> <<>> GetVersionNumber: PROC [r: ROPE] RETURNS [ROPE]; <> RemoveVersionNumber: PROC [r: ROPE] RETURNS [ROPE]; <> END.