14.8 Pathhandler Interface

ORIGIN '~beta/basiclib/betaenv';
LIB_DEF 'pathhandler' '../lib';
BODY 'private/pathhandlerbody';
(*
 * COPYRIGHT
 *       Copyright Mjolner Informatics, 1992-96
 *       All rights reserved.
 *)
-- LIB: Attributes --
(* idx=2 *) (* Utility patterns *)
DirectoryChar: charValue
(* The character which is used in this operating system to merge local
 * names to full path-names. Placed here to allow use without having
 * an instance of pathhandler.
 *) (# ... #);
DirectoryCharRegExp:
(* The character(s) which are used in this operating system to merge local
 * names to full path-names.  On DOS/Windows this is a regexp that matches
 * \ or /
 *)
  (# t: ^text;  ... exit t[] #);
IsDirectoryChar: booleanValue
(* The difference between this and the above is that on DOS/Windows
 * both / and \ are valid directory chars, but the canonical one is
 * \.
 *) (# c: @char;  enter c ... #);
CurrentDirectory:
(* The current working directory of this process.
 * Placed here to allow use without having an instance of pathhandler.
 *)
  (# cwd: ^text;  ... exit cwd[] #);
searchPath:
  (* Default program search path on this platform *)
  (# path: ^text;
  ...
  exit path[]
  #);
searchPathDelimiter: charValue
  (* Default separator between directories in search paths on this platform *)
  (# ... #);
scanSearchPath:
(* Scan through a list of paths separated by the delimiter
 * specified. INNER is called for each path found in
 * the list.
 * If pathlist is none, the default searchPath is used.
 * If delimiter is 0, the default searchPathDelimiter is used.
 *)
  (#
     pathlist: ^text;
     (* list if paths seperated by delimiter *)
     delimiter: @char;
     path: ^text;
     (* pathlist component set before each call of INNER *)
     
  enter (pathlist[],delimiter)
  ...
  #);
applDirectory:
  (# path: ^text
  ...
  exit path[]
  #);
PathHandler:
(*
 *  This pattern converts the Mjolner path notation to and from full native paths.
 *
 *  The following abbreviations are handled:
 *
 *      ~    is expanded into the home directory of the user
 *      ~foo is expanded into the home directory of foo
 *      .    is interpreted relatively to another path 
 *           (see ConvertFilePath below)
 *      ..   is interpreted relatively to another path 
 *           (see ConvertFilePath below)
 * 
 *      Environment variables like $(HOME) are expanded within paths.
 *
 *  PathHandler examines the environment variable
 *      
 *      BETALIB. If set, this determines the home directory of the Mjolner 
 *               BETA system. 
 * 
 *      The value of BETALIB may, but need not, be terminated by '/'.
 *)
  (#
     <<SLOT PathHandlerLib:Attributes>>;
     BetaLib:
     (* Mjolner BETA System home directory *)
       (# value: ^text;  ... exit value[] #);
     CurrentDirectory: (* The current working directory of this process *)
       (# value: ^text;  ... exit value[] #);
     ConvertFilePath:<
     (* Convert the 'path' relative to 'basis'.
      * 
      * Within 'path' the conversion expands the abbreviations mentioned
      * above.  '..' is a relative path designating the parent of a directory
      * (if any) whereas '.' is a relative path designating the directory
      * itself.  If path starts with ~, this is expanded to the home
      * directory of the user, and if it starts with ~foo, this is expanded
      * to the home directory of the user foo. These expansions ignore basis.
      * These abbreviations are only expanded if they are the first
      * component(s) of 'path'.
      * 
      * The only meaningful abbreviation in 'basis' is that it may start with
      * '.' Using this, 'basis' may be specified as the relative path '.'
      * instead of the absolute path THIS(PathHandler).CurrentDirectory.
      * 
      * If both the path and the basis are relative paths, the result will be
      * a relative path, otherwise it will be an absolute path.  Path and
      * basis may be terminated by '/', but need not be.
      * 
      * The resulting path will contian the native DirectoryChar as separators.
      *        
      *)
       (#
          path,basis,convertedpath: ^text;
          NoFather:< Exception
          (* Raised if there are too many '..' in the beginning of 'path'
           * compared to the given (absolute) basis.
           * If basis is relative, excess '..'s will be converted to '..'
           *) (#  ... #);
          convert:
            @...
       enter (path[],basis[])
       do convert; INNER
       exit convertedpath[]
       #);
     DirectoryChar: @char
     (* The character which is used in this operating system to merge local
      * names to full path-names; '/' in unix, ':' on Macintosh, '\' on Windows
      *) ;
     LocalPath:
     (* Given a path and a basis, exit the local path relative to the basis,
      * if possible.
      * 
      * The local path will be a path relative to basis, if basis is a prefix
      * of path. If this is not the case, it is attempted to use some of the
      * paths allready converted by THIS(PathHandler) as prefix to path. In
      * this case the result may be a relative path, or it may be a path in
      * the form ~foo.  If it is not possible to find any legal prefix, the
      * exception LocalPathException is raised and the original path is
      * exited. LocalPathException has the continue attribute set to true by
      * default; set it to false in a further binding, if you want to catch
      * this error.
      * 
      * The resulting path will contain '/' as separators.
      *)
       (#
          path,basis: ^text;
          localName: ^text;
          LocalPathException:< Exception
            (#  ... #);
          localize:
            @...;
          
       enter (path[],basis[])
       do localize
       exit localName[]
       #);
     init:< (#  ... #);
     Private:
       @...;
     
  #);
FilenameConverter: PathHandler
  (#
  (* This pathhandler is capable of keeping track of files which have 
   * allready been "converted".
   * 
   * convertFilePath will return the same pathname every time the same 
   * file is accessed even if the absolute path-names differs.
   *  
   * E.g. if /users/beta/basiclib/current is a link to the directory 
   * ~cn/beta/basiclib then
   *       '/users/beta/basiclib/current/file.bet' -> convertFilePath -> ...
   * and 
   *       '~cn/beta/basiclib/file.bet' -> convertFilePath -> ...
   *  
   * will give the same result, and the result will be the exit-parameter of
   * the first executed call of "convertFilePath".
   * Notice that if the file itself is a link to another file, these two
   * disk entries are considered different.
   * Notice also that in this special pathhandler, it is significant whether
   * the path are terminated by '/' or not: If it is, the path is considered
   * a directory.
   *)
     <<SLOT FileNameConverterLib:Attributes>>;
     convertFilePath::< 
       (#
          fileNotFound:<
            (# do INNER #);
          convert:
            @...
       do convert
       #);
     init::<  (#  ... #);
     FCPrivate: @...
  #)


14.8 Pathhandler Interface
© 1994-2004 Mjølner Informatics
[Modified: Thursday April 24th 2003 at 12:32]