13.4 Directory Interface

ORIGIN 'file';
LIB_DEF 'directory' '../lib';
BODY 'private/directorybody';
(*
 * COPYRIGHT
 *       Copyright (C) Mjolner Informatics, 1984-96
 *       All rights reserved.
 *
 *)
---- LIB: attributes ----
directory:
  (* Generalization of disk folder/directory.  Describes the list
   * aspects of directories and contains a DiskEntry item describing
   * the other properties of a directory.
   *)
  (#
     <<SLOT DirectoryLib: attributes>>;
     
     EntryDesc:< DiskEntry;
     entry: @EntryDesc
       (* The item holding most characterizing attributes of
        * THIS(directory)
        *); 
     name: @
       (* convenient interface to entry.path *)
       (# read:
            (* Reads a directory name from the Keyboard *)
            (# do ... #);
       enter entry.path
       exit entry.path
       #);
     
     (* Directory exceptions *)
     
     DirException: Exception
       (* General directory exception *)
       (# do ...; INNER #);
     DirEntryException: DirException
       (* Error for an entry in the directory. Message:
        * "Operation failed on entry".
        *)
       (# entry: ^text enter entry[] ... #);
     NoSuchException: DirEntryException
       (* Raised on attempt to delete a file or directory that did
        * not exist in THIS(directory). Message: "Attempt to delete a
        * nonexisting entry."
        *)
       (# do ...; INNER #);
     EntryExistException: DirEntryException
       (* Raised on attempt to create a file or directory that
        * already existed in THIS(directory). Message: "Directory
        * entry already exist"
        *)
       (# do ...; INNER #);
     DirScanException: DirException
       (* Raised if a scan of THIS(directory) has failed.  Message:
        * "Scan of directory failed.", and an indication of why it
        * failed.
        *)
       (# do ...; INNER #);
     DirSearchException: DirException
       (* Raised if a find in THIS(directory) has failed.  Message:
        * "Search of directory failed.", and an indication of why it
        * failed.
        *)
       (# do ...; INNER #);
     NotFoundException: DirException
       (* Raised if findEntry.select is used in findEntry.notFound,
        * or in other situations that findEntry.found[]=NONE. Message:
        * "Attempt to use 'select' in 'findEntry' when the candidate
        * was not found."
        *)
       (# do ...; INNER #);
     
     (* Manipulations of THIS(directory) *)
     
     touch: entry.touch
       (* If the disk entry does not exist, an empty directory will
        * be created.
        *)
       (# touchD: @...; 
       do touchD 
       #);
     delete:
       (* Delete THIS(directory) *)
       (# nosuch:< NoSuchException
            (* Raised if there was no disk entry corresponding to
             * THIS(Directory)
             *);
          error:< entry.DiskEntryException
            (* Raised if other errors occurred *);
          deleteD: @...; 
       do deleteD
       #);
     createFile:
       (* Create a file named 'name' in THIS(Directory) *)
       (# name: ^text;
          newEntry: ^EntryDesc;
          exists:< EntryExistException
            (* Raised if en entry of that name already existed *);
          error:< DirEntryException
            (* Raised if other errors occurred *);
       enter name[]
       ...
       exit newEntry[]
       #);
     deleteFile: 
       (* Delete a file named 'name' in THIS(Directory) *)
       (# name: ^text;
          nosuch:< NoSuchException
            (* Raised if there was no disk entry in THIS(Directory)
             * named 'name'
             *);
          error:<DirEntryException
            (* Raised if other errors occured *)
       enter name[]
       ...
       #);
     createDir:
       (* Create a directory named 'name' in THIS(Directory) *)
       (# name: ^text;
          newEntry: ^EntryDesc;
          exists:< EntryExistException
            (* Raised if en entry of that name already existed *);
          error:< DirEntryException
            (* Raised if other errors occurred *);
       enter name[]
       ...
       exit newEntry[]
       #);
     deleteDir:
       (* Delete a directory named 'name' in THIS(Directory) *)
       (# name: ^text;
          nosuch:< NoSuchException
            (* Raised if there was no disk entry in THIS(Directory)
             * named 'name'
             *);
          error:< DirEntryException
            (* Raised if other errors occured *)
       enter name[]
       ...
       #);
     noOfEntries: IntegerValue
       (* exit the number of entries in THIS(directory) *)
       (# error:<DirException; 
       ... 
       #);
     empty: BooleanValue
       (* TRUE iff THIS(directory) is empty. Note that this does not
        * always imply NoOfEntries=0
        *)
       (# error:<DirException; 
       ... 
       #);
     findEntry:
       (* Calls INNER if entry was found in THIS(directory), and
        * otherwise calls notFound
        *)
       (# <<SLOT DirFindLib: attributes>>;
          candidate: ^text;
          (* The name of the entry to search for *)
          foundDesc:< DiskEntry;
          (* Qualification of "found" *)
          found: ^foundDesc;
          (* Reference to entry, if found.  Notice that 'found.path'
           * is relative to THIS(directory).  The full path may be
           * obtained by 'foundFullPath' Also 'foundFullPath ->
           * found.path' may be needed before is queried for modtime
           * etc., if THIS(Directory) is not the current working
           * directory.
           *)
          foundFile:< File; 
          (* Qualification of file generated in
           * select.whenfile.thefile
           *)
          foundDir:< Directory;
          (* Qualification of directory generated in
           * select.whendir.thedir
           *)
          foundFullPath: (* Fullpath of "found" *)
            (# p: ^text do ... exit p[] #);
           
          notfound:< (* Called if the entry was not found *)
            (# do INNER #);
          select:
            (* Used to distinguish between the various entries that
             * may be found
             *)
            (# error:< found.DiskEntryException;
               whenFile:<
                 (* Called when the entry found is a file *)
                 (# thefile: 
                      (* Generate an instance of foundFile
                       * corresponding to the entry found. Notice that
                       * 'found' and 'f.entry' are two distinct
                       * objects; 'f.entry' has a full path, 'found'
                       * may or may not have a path relative to
                       * THIS(Directory).
                       *)
                      (# f: ^foundFile 
                      do ...
                      exit f[]
                      #);
                 do INNER
                 #);
               whenDir:<
                 (* Called when the entry found is a directory *)
                 (# theDir: 
                      (* Generate an instance of foundDir
                       * corresponding to the entry found. Notice that
                       * 'found' and 'd.entry' are two distinct
                       * objects; 'd.entry' has a full path, 'found'
                       * may or may not have a path relative to
                       * THIS(Directory).
                       *)
                      (# d: ^foundDir 
                      do ...
                      exit d[]
                      #);
                 do INNER
                 #);
               whenOther:<
                 (* Called when the entry found is neither a file nor
                  * a directory
                  *)
                 (# do INNER #);
               selectImpl:< (* private *)
                 (# selectedInInner: @boolean
                 do ...;
                    INNER; ...;
                 #)
            do selectImpl;
            #); (* select *)
          error:< DirSearchException
            (* Raised if the search fails *);
       enter candidate[]
       do ...;
       #); (* findEntry *)
     scanEntries:
       (* Calls INNER for each entry in THIS(directory) *)
       (# <<SLOT DirScanLib: attributes>>;
          longest: @integer;
          (* The length of the longest entry-name in THIS(directory)
           *)
          foundDesc:< DiskEntry;
          (* Qualification of "found" *)
          found: ^foundDesc;
          (* Reference to entry, if found.  Notice that 'found.path'
           * is relative to THIS(directory).  The full path may be
           * obtained by 'foundFullPath' Also 'foundFullPath ->
           * found.path' may be needed before is queried for modtime
           * etc., if THIS(Directory) is not the current working
           * directory.
           *)
          foundFile:< File; 
          (* Qualification of file generated in
           * select.whenfile.thefile
           *)
          foundDir:< Directory;
          (* Qualification of directory generated in
           * select.whendir.thedir
           *)
          foundFullPath: (* Fullpath of "found"  *)
            (# p: ^text do ... exit p[] #);
          select:
            (* Used to distinguish between the various entries that
             * may be found
             *)
            (# error:< found.DiskEntryException;
               whenFile:<
                 (* Called when the entry found is a file *)
                 (# thefile: 
                      (* Generate an instance of foundFile
                       * corresponding to the entry found. Notice that
                       * 'found' and 'f.entry' are two distinct
                       * objects; 'f.entry' has a full path, 'found'
                       * may or may not have a path relative to
                       * THIS(Directory).
                       *)
                      (# f: ^foundFile 
                      do ...
                      exit f[]
                      #);
                 do INNER
                 #);
               whenDir:<
                 (* Called when the entry found is a directory *)
                 (# theDir: 
                      (* Generate an instance of foundDir
                       * corresponding to the entry found. Notice that
                       * 'found' and 'd.entry' are two distinct
                       * objects; 'd.entry' has a full path, 'found'
                       * may or may not have a path relative to
                       * THIS(Directory).
                       *)
                      (# d: ^foundDir 
                      do ...
                      exit d[]
                      #);
                 do INNER
                 #);
               whenOther:<
                 (* Called when the entry found is neither a file nor
                  * a directory
                  *)
                 (# do INNER #);
               selectImpl:< (* private *)
                 (# selectedInInner: @boolean
                 do ...;
                    INNER; ...;
                 #)
            do selectImpl;
            #); (* select *)
          error:< DirScanException
            (* Raised if the scan fails *);
          (* idx- *) (* idx- *)
       do ...;
       #); (* scanEntries *)
     private: @...;
  #)


13.4 Directory Interface
© 1990-2004 Mjølner Informatics
[Modified: Thursday July 3rd 2003 at 13:07]