vbtkitutils/src/Rsrc.m3


Copyright (C) 1994, Digital Equipment Corp.

MODULE Rsrc;

IMPORT Bundle, FileRd, OSError, Pathname, Rd, TextRd, Thread;
IMPORT Env, RefList, Text;

PROCEDURE Open (name: TEXT; p: Path): Rd.T RAISES {NotFound} =
  BEGIN
    IF Pathname.Absolute(name) THEN
      IF Pathname.Valid(name) THEN
        TRY RETURN FileRd.Open(name) EXCEPT OSError.E => END
      END;
      RAISE NotFound
    END;
    WHILE p # NIL DO
      TYPECASE p.head OF
      | NULL =>                  <* ASSERT FALSE *>
      | Pathname.T (pn) =>
          TRY
            RETURN FileRd.Open(Pathname.Join(pn, name, NIL))
          EXCEPT
          | OSError.E =>
          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; p: Path): TEXT
  RAISES {NotFound, Rd.Failure, Thread.Alerted} =
  BEGIN
    WHILE p # NIL DO
      TYPECASE p.head OF
      | NULL =>                  <* ASSERT FALSE *>
      | Pathname.T (pn) =>
          VAR rd: Rd.T := NIL;
          BEGIN
            TRY
              rd := FileRd.Open (Pathname.Join (pn, name, NIL))
            EXCEPT
            | OSError.E =>
            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 =
  BEGIN
    RETURN RefList.AppendD (
             Convert (a1),
             RefList.AppendD (
               Convert (a2), RefList.AppendD (Convert (a3), Convert (a4))))
  END BuildPath;

PROCEDURE Convert (a: REFANY): Path =
  BEGIN
    TYPECASE a OF
    | NULL => RETURN NIL
    | Bundle.T (b) => RETURN RefList.List1 (b)
    | TEXT (t) => RETURN ExpandPath (t)
    ELSE                         <* ASSERT FALSE *>
    END
  END Convert;

PROCEDURE ExpandPath (path: TEXT): RefList.T =
  BEGIN
    IF NOT Text.Empty (path) AND Text.GetChar (path, 0) = '$' THEN
      path := Env.Get (Text.Sub (path, 1, LAST (CARDINAL)))
    END;
    IF path = NIL OR Text.Empty (path) THEN
      RETURN NIL
    ELSIF Pathname.Valid (path) THEN
      RETURN RefList.List1 (path)
    ELSE                         <* ASSERT FALSE *>
    END
  END ExpandPath;

BEGIN
END Rsrc.