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

(* Utility patterns *)
DirectoryChar:
  (* 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.
   *)
  (# c: @char;
  ...
  exit c
  #);
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[]
  #);
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 search path of the machine.
   * If delimiter is 0, the default delimiter for searchpaths
   * 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-2002 Mjølner Informatics
[Modified: Friday August 10th 2001 at 14:42]