-- FileUtil.Mesa
-- Last Modified By kap&wsh February 22, 1980 1:24 PM
-- Last Modified By Paul Rovner On July 1, 1982 5:54 pm
DIRECTORY
Ascii,
Rope USING[ToRefText, ROPE, Concat, Fetch, Size, Equal, Substr, FromChar],
IO USING[Handle, GetChar],
FileUtilDefs,
Directory USING [Lookup, Error];
FileUtil: PROGRAM
IMPORTS IO, Directory, Rope
EXPORTS FileUtilDefs
= BEGIN
-- Exported procedures (public)
UpperCase: PUBLIC PROC[ch: CHARACTER] RETURNS[CHARACTER] =
{SELECT ch FROM
IN ['a..'z] => RETURN[ch - 'a + 'A];
ENDCASE => RETURN[ch]};
-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
FileExists: PUBLIC PROC [fileName: Rope.ROPE] RETURNS [BOOLEAN]=
{[] ← Directory.Lookup[LOOPHOLE[Rope.ToRefText[fileName]] ! Directory.Error => GOTO failed];
RETURN[TRUE];
EXITS failed => RETURN[FALSE]};
-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- If name has an extension, and it is not the desired one, result is
-- FALSE. If the extension is the one desired, result is TRUE. If the
-- name has no extension, tack the desired one on and return TRUE.
ExtendFileName: PUBLIC PROC [name, extension: Rope.ROPE]
RETURNS [extendedName: Rope.ROPE, extended: BOOLEAN] =
{s: INT = Rope.Size[name];
FOR i: INT IN [0 .. s)
DO IF Rope.Fetch[name,i] = '. THEN -- the name has an extension already
RETURN[name, Rope.Equal[Rope.Substr[name, i + 1, s - (i + 1)],
extension]];
ENDLOOP;
-- here if the name has no extension; tack on the desired one
IF name = NIL
THEN RETURN[NIL, FALSE]
ELSE RETURN[Rope.Concat[Rope.Concat[name, "."], extension], TRUE]};
-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- Snarf "words" (terminated by SP, TAB or CR) from s until either
-- one is found which has (or can be extended with) the
-- indicated extension or s is exhausted. '/...' word suffixes are stuck into 'switches'
-- name = NIL => none found. Otherwise, name is the
-- (extended) file name.
GetExtendedFileName: PUBLIC PROC [s: IO.Handle,
extensionName: Rope.ROPE,
extensionRequired: BOOLEAN ← TRUE]
RETURNS[name, switches: Rope.ROPE] =
{ letter: CHARACTER;
name ← switches ← NIL;
letter ← IO.GetChar[s ! ANY => GOTO failure];
WHILE letter = Ascii.SP
OR letter = Ascii.TAB
OR letter = Ascii.CR
DO letter ← IO.GetChar[s ! ANY => GOTO failure] ENDLOOP;
-- skip leading spaces, tabs, and CRs
WHILE letter # Ascii.SP
AND letter # Ascii.TAB
AND letter # Ascii.CR
DO -- get the next name
IF letter = '/ THEN
{letter ← IO.GetChar[s ! ANY => GOTO out];
UNTIL letter = Ascii.SP
OR letter = Ascii.TAB
OR letter = Ascii.CR
DO
switches ← Rope.Concat[switches, Rope.FromChar[letter]];
letter ← IO.GetChar[s ! ANY => GOTO out];
ENDLOOP;
EXIT};
name ← Rope.Concat[name, Rope.FromChar[letter]];
letter ← IO.GetChar[s ! ANY => GOTO out];
ENDLOOP;
GOTO out;
EXITS
out => {extended: BOOLEAN ← FALSE;
IF extensionName # NIL
THEN [name, extended] ← ExtendFileName[name, extensionName];
IF extensionRequired AND NOT extended THEN name ← switches ← NIL};
failure => NULL}; -- no filename found
-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
IsSwitch: PUBLIC PROC [ch: CHARACTER, switches: Rope.ROPE] RETURNS[BOOLEAN] =
{FOR i: INT IN [0..Rope.Size[switches]) DO
IF UpperCase[ch] = UpperCase[Rope.Fetch[switches,i]] THEN RETURN[TRUE] ENDLOOP;
RETURN[FALSE]};
END.