DIRECTORY Ascii, Rope USING[ROPE, Concat, Fetch, Size, Equal, Substr, FromChar], IO USING[STREAM, GetChar], FileUtilDefs, FS USING [FileInfo, Error]; FileUtil: PROGRAM IMPORTS IO, FS, Rope EXPORTS FileUtilDefs = BEGIN 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 [ans: BOOL _ TRUE] = { [] _ FS.FileInfo[fileName ! FS.Error => {ans _ FALSE; CONTINUE}]; }; 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; IF name = NIL THEN RETURN[NIL, FALSE] ELSE RETURN[Rope.Concat[Rope.Concat[name, "."], extension], TRUE]}; GetExtendedFileName: PUBLIC PROC [s: IO.STREAM, 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; 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. ÆFileUtil.Mesa Last Modified By kap&wsh February 22, 1980 1:24 PM Last Modified By Paul Rovner On October 12, 1983 0:13 am Exported procedures (public) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. here if the name has no extension; tack on the desired one * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. skip leading spaces, tabs, and CRs * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Ê‚˜Jšœ ™ Jšœ3™3Jšœ8™8J˜šÏk ˜ J˜Jšœœœ0˜?Jšœœœ ˜J˜ Jšœœ˜J˜—šœ ˜Jšœœœ˜Jšœ ˜—Jšœ˜J˜Jšœ™J˜Jš Ïn œœœ œœ œ˜:šœœ˜Jšœ œ˜$Jšœœ˜J˜—Jšœ;™;šž œœœœœœœ˜LJš œœœœœ˜Ašœ˜J˜——šœ;™;JšœB™BJšœB™BJšœ?™?—šžœœœœ˜8Jšœœ œ˜6šœœ˜šœœœ ˜šœœœÏc$˜Hšœ8˜>J˜ ——šœ˜Jšœ:™:——šœ˜ Jšœœœœ˜Jšœœ1œ˜CJ˜———šœ;™;Jšœ?™?Jšœ4™4JšœV™VJšœ0™0Jšœ™—š žœœœœœ˜/Jšœœ˜Jšœœœ˜"Jšœœ˜$—šœ œ˜Jšœœ˜Jšœ œ œœ ˜-J˜šœ˜Jšœ˜Jšœ˜š œ œ œœ œ˜8Jšœ"™"J˜——šœ˜Jšœ˜Jšœ˜—šœŸ˜šœ ˜šœ œ œœ˜+šœ˜Jšœ˜Jšœ˜š˜J˜8Jšœ œ œœ˜)Jšœ˜——Jšœ˜——J˜0Jšœ œ œœ˜)—Jšœ˜J˜Jšœ˜ J˜š˜šœœœ˜"šœ˜Jšœ8˜<—Jš œœœ œœ˜B—Jšœ œŸ˜&J˜——Jšœ;™;šžœœœ œœœœ˜Mšœœœœ˜*Jš œ3œœœœ˜OJšœœ˜J˜J˜——Jšœ˜J˜—…— è