PFSFullName:
PROC [ fileName:
ROPE, wDir:
ROPE ¬
NIL ]
RETURNS [ fullName:
ROPE ] ~ {
BEGIN
ENABLE
PFS.Error => {
Report["\n***PFS.Error: %g\n", [rope[error.explanation]] ];
IF error.code = $illegalName THEN GOTO tryAgain ELSE GOTO Bogus
};
fullNamePath: PFS.PATH ¬ PFSNames.ExpandName[PFS.PathFromRope[fileName], PFS.PathFromRope[wDir]];
fullName ¬ PFS.RopeFromPath[fullNamePath];
EXITS
Bogus => { ERROR BadName };
tryAgain => NULL;
END;
try getting rid of spaces and tabs in the name
BEGIN
BEGIN
ENABLE
PFS.Error => { Report["\n***PFS.Error: %g (%g)\n",
[rope[error.explanation]], [rope[fileName]] ];
GOTO Bogus2 };
temp: REF TEXT ¬ RefText.ObtainScratch[RefText.line];
temp.length ¬ 0;
FOR i:
INT
IN [0..fileName.Length[])
DO
c: CHAR ~ fileName.Fetch[i];
IF (c = ' ) OR ( c = '\t ) THEN LOOP;
[] ¬ RefText.AppendChar[temp, c];
ENDLOOP;
fileName ¬ Rope.FromRefText[temp];
RefText.ReleaseScratch[temp];
fullName ¬ PFS.RopeFromPath[ PFSNames.ExpandName[PFS.PathFromRope[fileName], PFS.PathFromRope[wDir]] ];
EXITS
Bogus2 => { ERROR BadName };
END;
END;
};
PFSFileOpenOrCreate:
PROC [ name:
ROPE, how:
ATOM ]
RETURNS [ fileData: BCFileData] ~ {
ENABLE
PFS.Error => {
Report["\n***PFS.Error: %g (%g)\n", [rope[error.explanation]], [rope[name]] ];
GOTO cant;
};
retry: BOOL ¬ FALSE;
fullFName: PFS.PATH;
ownerOnlyMode: UnixTypes.Mode ~ [ owner: [true, true, false] ];
readOnly: BOOL ~ how = $openRO;
ro: REF BOOL ~ NEW[BOOL ¬ readOnly];
clientData: REF ANY ~ ro;
DoCreate:
PROC = {
strm: STREAM ¬ PFS.StreamOpen[PFS.PathFromRope[fileData.name], $create ];
fd: UnixTypes.FD ¬ PFSBackdoor.FDFromOpenStream[strm];
[] ¬ UnixSysCalls.FChMod[fd, ownerOnlyMode];
strm.Close[];
IF retry THEN fullFName ¬ PFS.FileInfo[PFS.PathFromRope[fileData.name]].fullFName;
};
fileData ¬ NEW[BCFileDataRec ¬ [name: name, clientData: clientData] ];
IF how = $create THEN DoCreate[];
fullFName ¬
PFS.FileInfo[
PFS.PathFromRope[fileData.name] !
PFS.Error =>
IF ( error.code = $unknownFile )
THEN
SELECT
TRUE
FROM
( how = $openOrCreate ) => { retry ¬ TRUE; DoCreate[]; CONTINUE };
( how = $openRO ) => {
Report["\n*** ReadOnly requested but %g doesn't exist\n", [rope[name]] ];
GOTO cant;
};
ENDCASE => REJECT;
].fullFName;
fileData.name ¬ PFS.RopeFromPath[fullFName];
IF
NOT readOnly
THEN fileData.writeStream ¬
PFS.StreamOpen[fullFName, $write !
PFS.Error =>
IF ( error.code = $unknownFile ) AND ( how = $openOrCreate ) THEN
{ retry ¬ TRUE; DoCreate[]; CONTINUE } ELSE REJECT
];
IF retry THEN fileData.writeStream ¬ PFS.StreamOpen[fullFName, $write ! PFS.Error =>
Report["\n**** PFS.Error: %g, during PFSFileOpenOrCreate\n", [rope[error.explanation]]] ];
fileData.readStream ¬ PFS.StreamOpen[ fullFName ! PFS.Error =>
Report["\n**** PFS.Error: %g, during PFSFileOpenOrCreate\n", [rope[error.explanation]]] ];
EXITS cant => ERROR OpenFailed;
};
PFSSetByteCount:
PROC [ fileData: BCFileData, bytes:
INT ] ~ {
ro: REF BOOL ~ NARROW[fileData.clientData];
IF ro THEN RETURN;
fileData.writeStream ¬ PFS.StreamOpen[PFS.PathFromRope[fileData.name], $write ];
fileData.writeStream.SetLength[bytes];
fileData.writeStream.Close[];
fileData.writeStream ¬ NIL;
};
PFSIconSetter:
PROC[iconFileName:
ROPE] = {
iconFile: PFS.PATH ¬ PFSNames.ExpandName[PFS.PathFromRope[iconFileName], squirrelAwayMyStartingDir];
iconFileRope: ROPE ~ PFS.RopeFromPath[iconFile];
BlackCherry.msgSetIcon ¬ Icons.NewIconFromFile[iconFileRope, 1];
IF BlackCherry.msgSetIcon = unInit THEN BlackCherry.msgSetIcon ¬ tool
ELSE BlackCherry.msgIcon ¬ Icons.NewIconFromFile[iconFileRope, 2];
};
Init:
PROC = {
procs: BlackCherry.FileProcs ¬
NEW[BlackCherry.FileProcsRec ¬ [
fullName: PFSFullName,
openOrCreate: PFSFileOpenOrCreate,
setByteCount: PFSSetByteCount,
iconSetter: PFSIconSetter
] ];
BlackCherry.RegisterFileProcs[procs];
squirrelAwayMyStartingDir ¬ PFS.GetWDir[];
};