(* Copyright (C) 1989-1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* *) (* Last modified on Tue Sep 22 09:17:01 PDT 1992 by mhb *) (* modified on Sun Jul 19 11:12:47 PDT 1992 by meehan *) (* modified on Fri Mar 27 03:02:41 1992 by steveg *) (* modified on Sat Feb 29 13:13:54 PST 1992 by kalsow *) (* modified on Tue May 15 11:28:23 PDT 1990 by mcjones *) (* modified on Fri Oct 6 13:58:16 PDT 1989 by brooks *) (* modified on Sun May 21 19:48:08 PDT 1989 by gidi *) MODULE Rsrc; IMPORT Bundle, FileStream, Rd, TextRd, Thread; IMPORT Env, List, Text; PROCEDURE Open (name: TEXT; path: Path): Rd.T RAISES {NotFound} = VAR p := path; BEGIN WHILE p # NIL DO TYPECASE (p.first) OF | NULL => <* ASSERT FALSE *> | TEXT (s) => TRY RETURN FileStream.OpenRead(s & "/" & name) EXCEPT Rd.Failure => END; | Bundle.T (b) => WITH t = Bundle.Get(b, name) DO IF t # NIL THEN RETURN TextRd.New(t) END END ELSE <* ASSERT FALSE *> END; p := p.tail; END; RAISE NotFound END Open; PROCEDURE Get (name: TEXT; path: Path): TEXT RAISES {NotFound, Rd.Failure, Thread.Alerted} = VAR p := path; BEGIN WHILE p # NIL DO TYPECASE (p.first) OF | NULL => <* ASSERT FALSE *> | TEXT (s) => VAR rd: Rd.T; BEGIN TRY rd := FileStream.OpenRead(s & "/" & name); EXCEPT Rd.Failure => rd := NIL END; IF rd # NIL THEN TRY RETURN Rd.GetText(rd, LAST(CARDINAL)) FINALLY Rd.Close(rd) END END END | Bundle.T (b) => WITH t = Bundle.Get(b, name) DO IF t # NIL THEN RETURN t END END ELSE <* ASSERT FALSE *> END; p := p.tail; END; RAISE NotFound END Get; PROCEDURE BuildPath (a1, a2, a3, a4: REFANY := NIL): Path = VAR p: Path; BEGIN IF a4 # NIL THEN p := Convert(a4) END; IF a3 # NIL THEN p := List.AppendD(Convert(a3), p) END; IF a2 # NIL THEN p := List.AppendD(Convert(a2), p) END; IF a1 # NIL THEN p := List.AppendD(Convert(a1), p) END; RETURN p END BuildPath; PROCEDURE Convert (a: REFANY): Path = BEGIN TYPECASE (a) OF | Bundle.T (b) => RETURN List.List1(b) | TEXT (t) => RETURN ExpandPath(t) ELSE <* ASSERT FALSE *> END END Convert; PROCEDURE ExpandPath (path: TEXT): List.T = BEGIN IF path = NIL OR Text.Empty(path) THEN RETURN NIL END; IF Text.GetChar(path, 0) = '$' THEN path := ExpandName(path) END; IF Text.Empty(path) THEN RETURN NIL ELSE RETURN List.List1(path) END END ExpandPath; PROCEDURE ExpandName (name: TEXT): TEXT = VAR head, resolved: TEXT; BEGIN head := Text.Sub(name, 1, LAST(CARDINAL)); IF Env.Get(head, resolved) THEN RETURN resolved ELSE RETURN "" END END ExpandName; <* UNUSED *> PROCEDURE oldExpandPath (path: TEXT): List.T = VAR dir : Text.T; index : INTEGER; newPath: List.T := NIL; start : INTEGER := 0; length : INTEGER := Text.Length(path); BEGIN IF path = NIL OR Text.Empty(path) THEN RETURN NIL END; WHILE start < length DO index := Text.FindChar(path, ':', start); IF index = -1 THEN dir := Text.Sub(path, start, LAST(CARDINAL)); start := LAST(CARDINAL) ELSE dir := Text.Sub(path, start, index - start); start := index + 1 END; VAR expanded := ExpandName(dir); BEGIN IF NOT Text.Empty(expanded) THEN IF Text.Equal(expanded, dir) THEN newPath := List.Append1D(newPath, expanded) ELSE newPath := List.AppendD(newPath, ExpandPath(expanded)) END END END END; RETURN newPath END oldExpandPath; <* UNUSED *> PROCEDURE oldExpandName (name: TEXT): TEXT = VAR c : CHAR; head, tail, resolved: TEXT; BEGIN IF Text.Length(name) > 0 THEN c := Text.GetChar(name, 0); IF c = '$' THEN WITH slashIndex = Text.FindChar(name, '/', 1) DO IF slashIndex > 0 THEN head := Text.Sub(name, 1, slashIndex - 1); tail := Text.Sub(name, slashIndex, LAST(CARDINAL)); ELSE head := Text.Sub(name, 1, LAST(CARDINAL)); tail := ""; END; END; IF Env.Get(head, resolved) THEN name := Text.Cat(resolved, tail); ELSE name := tail; END; END; END; RETURN name; END oldExpandName; BEGIN END Rsrc.