-- 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.