DFInternal.mesa
Copyright Ó 1985, 1986, 1991 by Xerox Corporation. All rights reserved.
Levin on December 16, 1983 2:05 pm
Russ Atkinson (RRA) January 19, 1987 1:42:51 pm PST
Michael Plass, January 23, 1992 10:15 am PST
DIRECTORY
DFOperations USING [InfoClass, InteractionProc],
DFUtilities USING [Date],
FS USING [ErrorDesc],
IO USING [STREAM],
Rope USING [ROPE];
DFInternal: CEDAR DEFINITIONS = BEGIN OPEN DFOperations, DFUtilities, IO, Rope;
Interaction Stuff
Client: TYPE = REF ClientDescriptor;
ClientDescriptor: TYPE = RECORD [
proc: InteractionProc,
data: REF, -- to be passed as 'clientData' parameter of 'proc'
log: STREAM,
errlog: STREAM,
workingDir: ROPE
];
SimpleInteraction: PROC [client: Client, interaction: REF];
Used for any `interaction' that doesn't expect a response. SimpleInteraction handles any client-requested abort internally, with 'DoAbort' being invoked. Note that if ISTYPE[interaction, REF InfoInteraction] = TRUE and interaction.class = $abort, abort processing does NOT occur; that is, SimpleInteraction returns normally to its caller. This is because SimpleInteraction doesn't discriminate on the interaction type.
YesOrNo: PROC [client: Client, message: ROPE, default: BOOL, blunder: BOOL ¬ FALSE]
RETURNS [BOOL];
Used for YesNoInteraction. Abort processing is handled internally, with 'DoAbort' being invoked.
DoInteraction: PROC [client: Client, interaction: REF] RETURNS [response: REF];
Used for the general case, including (for now) ChoiceInteraction. DoInteraction handles any client-requested abort internally, with 'DoAbort' being invoked. Note that if ISTYPE[interaction, REF InfoInteraction] = TRUE and interaction.class = $abort, abort processing does NOT occur; that is, DoInteraction returns normally to its caller. This is because DoInteraction doesn't discriminate on the interaction type.
CheckAbort: PROC [client: Client];
interacts with the client and, if an abort is requested, triggers 'DoAbort'.
DoAbort: PROC
[log: STREAM, message: ROPE, proc: InteractionProc ¬ NIL, clientData: REF ¬ NIL];
If 'proc' and 'message' are non-NIL, an InfoInteraction occurs. The message is then logged on 'log'. Finally, AbortDF is raised.
AbortDF: ERROR;
raised only by DoAbort.
DefaultInteractionProc: InteractionProc;
to be used when callers of DFOperations procedures have 'interact' = NIL.
File Info Stuff
LocalFileInfo: TYPE = RECORD [
name: ROPE,
attachedTo: ROPE,
date: Date ¬ [],
keep: INT ¬ -1
];
RemoteFileInfo: TYPE = RECORD [
name: ROPE,
date: Date ¬ []
];
GetFileInfo: PROC [info: REF, notFoundOK: BOOL ¬ FALSE, remoteCheck: BOOL ¬ FALSE, client: Client ¬ NIL, errorLevel: InfoClass ¬ $error];
'info' must be either REF LocalFileInfo or REF RemoteFileInfo.
Behavior for ISTYPE[info, REF LocalFileInfo] = TRUE: info.name is assumed to describe a local file. If info.date.format ~= $explicit, any trailing version number on info.name is stripped off; otherwise the version number is retained (even if info.date.gmt = BasicTime.nullGMT; this permits a lookup with "version number as truth"). The file is looked up and, if found, info.date.format is set to $explicit and info.date.gmt is set to the file's create date. The remoteCheck parameter is passed to FS; thus, if a local file is attached to a remote file and remoteCheck = TRUE, the server will be interrogated to ensure that the file exists remotely. In any case, if the file doesn't exist and notFoundOK is TRUE, info.date is set to [$omitted, BasicTime.nullGMT]. All other cases trigger error handling, discussed below.
Behavior for ISTYPE[info, REF RemoteFileInfo] = TRUE: The remote file specified by info.name and info.date is looked up, using a create time search on info.date.gmt if info.date.format = $explicit. The remoteCheck parameter is ignored. If the file exists, info.date.format is set to $explicit and info.date.gmt is set to the file's create date. If the file doesn't exist and notFoundOK is TRUE, info.date is set to [$omitted, BasicTime.nullGMT]. All other cases trigger error handling, discussed below.
Error handling: Except as described above, all occurrences of FS.Error propagate to the client. However, if the caller supplies a non-NIL value for 'client', substantial error handling will first occur internally. In this case (client ~= NIL), RetryFSOperation will be called. If it returns TRUE, GetFileInfo will be (re)executed in its entirety. If RetryFSOperation returns FALSE, ReportFSError will be called with the obvious parameters. Note that if ReportFSError is invoked and errorLevel = $abort, AbortDF will be raised (see description of ReportFSError, below).
LocalFile: PROC [file: ROPE, client: Client] RETURNS [BOOL];
ShortName: PROC [file: ROPE, keepVersion: BOOL ¬ FALSE] RETURNS [ROPE];
Error Handling
RetryFSOperation: PROC [error: FS.ErrorDesc, client: Client] RETURNS [retry: BOOL];
determines whether a retry of an FS operation is appropriate. Any necessary waiting has been done inside this procedure (client can simply say RETRY in catch phrase).
ReportFSError: PROC
[error: FS.ErrorDesc, info: REF, client: Client, errorLevel: InfoClass ¬ $error];
'info' is either REF LocalInfo or REF RemoteInfo. SimpleInteraction is invoked with an InfoInteraction at the specified errorLevel. Then, if errorLevel = $abort, DoAbort[client.log] is invoked, causing AbortDF to be raised.
END.