;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*-

=Node: 4Manipulating Files*

=Text:
3MANIPULATING FILES*

     This section describes functions for doing things to files aside from reading or writing their
contents.

3truename* 1object*                                                                                                
        Returns the truename of the file specified somehow by 1object*.  If 1object* is a plausible
        stream, it is asked for the truename with the 2:truename* operation.  Otherwise, 1object* is
        converted to a pathname and that pathname is opened to get its file's truename.  

3delete-file* 1file* &key 1(error-p* 3t1)** 1query?*                                                              
3deletef* 1file* &optional 1(error-p* 3t1)** 1query?*                                                               
        Both delete the specified file.  The two functions differ in accepting keyword arguments
        versus positional arguments.  1file* may contain wildcard characters, in which case multiple files
        are deleted.

        If 1query?* is non-2nil*, the user is queried about each file (whether there are wildcards or not).
        Only the files that the user confirms are actually deleted.

        If 1error-p* is 2t*, then if an error occurs it is signaled as a Lisp error.  If 1error-p* is 2nil* and an
        error occurs, the error message is returned as a condition object.  Otherwise, the value is a
        list of elements, one for each file considered.  The car of each element is the truename of
        the file, and the cadr is non-2nil* if the file was actually deleted (it is always 2t* unless querying
        was done).  

3undelete-file* 1file* &key 1(error-p* 3t1)** 1query?*                                                           
3undeletef* 1file* &optional 1(error-p* 3t1)** 1query?*                                                            
        Both undelete the specified file.  Wildcards are allowed, just as in 2deletef*.  The rest of the
        calling conventions are the same as well.  The two functions differ in taking keyword
        arguments versus positional arguments.

        Not all file systems support undeletion, and if it is not supported on the one you are using, it
        gets an error or returns a string according to 1error-p*.  To find out whether a particular file
        system supports this, send the 2:undeletable-p* operation to a pathname.  If it returns 2t*, the file
        system of that pathname supports undeletion.  

3rename-file* 1file* 1new-name* &key 1(error-p* 3t1)** 1query?*                                                 
3renamef* 1file* 1new-name* &optional 1(error-p* 3t1)** 1query?*                                                  
        Both rename the specified file to 1new-name* (a pathname or string).  The two functions differ
        in taking keyword arguments versus positional arguments.  1file* may contain wildcards, in which
        case multiple files are renamed.  Each file's new name is produced by passing 1new-name* to
        2merge-pathname-defaults* with the file's truename as the defaults.  Therefore, 1new-name*
        should be a string in this case.

        If 1query?* is non-2nil*, the user is queried about each file (whether there are wildcards or not).
        Only the files that the user confirms are actually renamed.

        If 1error-p* is 2t*, then if an error occurs it is signaled as a Lisp error.  If 1error-p* is 2nil* and an
        error occurs, the error message is returned as a condition object.  Otherwise, the value is a
        list of elements, one for each file considered.  The car of each element is the original
        truename of the file, the cadr is the name it was to be renamed to, and the caddr is non-2nil* if
        the file was renamed.  The caddr is 2nil* if the user was queried and said no.  

3copy-file* 1file* 1new-name* &key 1(error* 3t1)** 1(copy-creation-date* 3t1)** 1(copy-author* 3t1)** 1report-stream*
	1(create-directories* 3:query1)** 1(characters* 3:default1)** 1(byte-size* 3:default1)**
        Copies the file specified by 1file* to the name 1new-name*.

        1characters* and 1byte-size* specify what mode of I/O to use to transfer the data.  1characters*
        can be 

        2t*             to specify character input and output.  

        2nil*            for binary input and output, 

        2:ask*          meaning ask the user which one 

        2:maybe-ask*  
                      meaning ask if it is not possible to tell with certainty which method is best, 

        2:default*      meaning to guess as well as possible automatically.  

        If binary transfer is done, 1byte-size* specifies the byte size to use; 2:default* means to ask the
        file system for the byte size that the old file is stored in, just as it does in 2open*.

        1copy-author* and 1copy-creation-date* say whether to set those properties of the new file to
        be the same as those of the old file.  If a property is not copied, it is set to your login name
        or the current date and time.

        1report-stream*, if non-2nil*, is a stream on which a message should be printed describing the file
        copied, where it is copied to, and which mode was used.

        1create-directories* says what to do if the output filename specifies a directory that does not
        exist.  It can be 2t* meaning create the directory, 2nil* meaning treat it as an error, or 2:query*
        meaning ask the user which one to do.  The default is 2:query*.

        1error*, if 2nil*, means that if an error happens then this function should just return an error
        indication.

        If the pathname to copy from contains wildcards, multiple files are copied.  The new name for
        each file is obtained by merging 1new-name* (parsed into a pathname) with that file's truename
        as a default.  The mode of copy is determined for each file individually, and each copy is
        reported on the 1report-stream* if there is one.  If 1error* is 2nil*, an error in copying one file does
        not prevent the others from being copied.

        There are four values.  If wildcards were used, each value is a list with one element
        describing each file that matched; otherwise, each value describes the single file specified
        (though the value may be a list anyway).  The values, for each file, are:  

        1output-file*  
                      The defaulted pathname to be opened for output in copying this file.  

        1truename*    The truename of the file copied 

        1outcome*    The truename of the new file, If the file was successfully copied.  A condition
                      object, if there was an error and 1error* was 2nil*.  2nil* if the user was asked whether
                      to copy this file and said no.  

        1mode*        A Common Lisp type descriptor such as 2string-char* or 2(unsigned-byte 8)* saying
                      how the file was copied.  

3probe-file* 1file*                                                                                                 
3probef* 1file*                                                                                                       
        Returns 2nil* if there is no file named 1file*; otherwise returns a pathname that is the true name of
        the file, which can be different from 1file* because of file links, version numbers, etc.  If 1file* is
        a stream, this function cannot return 2nil*.

        Any problem in opening the file except for 2fs:file-not-found* signals an error.

        2probef* is the Maclisp name; 2probe-file* is the Common Lisp name.  

3file-write-date* 1file*                                                                                          
        Returns the creation date/time of 1file*, as a universal time.  

3file-author* 1file*                                                                                                
        Returns the name of the author of 1file* (the user who wrote it), as a string.  

3viewf* 2file* &optional 1(output-stream* 3*standard-output*1)** 1leader*                                  
        Copies the contents of the specified file, opened in character mode, onto 2output-stream*.
        Normally this has the effect of printing the file on the terminal.  1leader* is passed along to
        2stream-copy-until-eof* (see 4(IOSYSTEM-1)Output Functions*).  

3fs:create-link* 1link-name* 1link-to* &key 1(error* 3t1)**                                                     
        Creates a link named 1link-name* which points to a file named 1link-to*.  An error happens if the
        host specified in 1link-name* does not support links, or for any of the usual problems that can
        happen in creating a file.  

=Node: 4Loading Files*

=Text:
3LOADING FILES*

     To 1load* a file is to read through the file, evaluating each form in it.  Programs are typically
stored in files; the expressions in the file are mostly special forms such as 2defun* and 2defvar* which
define the functions and variables of the program.

     Loading a compiled (or QFASL) file is similar, except that the file does not contain text but rather
pre-digested expressions created by the compiler which can be loaded more quickly.

     These functions are for loading single files.  There is a system for keeping track of programs
which consist of more than one file; for further information refer to
4(SYSTEMS-0)Maintaining Large Systems*.

3load* 1file* &key 1verbose* 1print* 1(if-does-not-exist* 3t1)** 1set-default-pathname* 1package*                 
        Loads the specified file into the Lisp environment.  If 1file* is a stream, 2load* reads from it;
        otherwise 1file* is defaulted from the default pathname defaults and the result specifies a file to
        be opened.  If the file is a QFASL file, 2fasload* is used; otherwise 2readfile* is used.  If 1file*
        specifies a name but no type, 2load* looks first for the canonical type 2:qfasl* and then for the
        canonical type 2:lisp*.

        Normally the file is read into the package specified in its attribute list, but if 1package* is
        supplied then the file is read in that package.  If 1package* is 2nil* and 1verbose* is 2nil*, 2load* prints a
        message saying what file is being loaded and what package is being used.  1verbose* defaults
        to the value of 2*load-verbose**.

        If 1if-does-not-exist* is 2nil*, 2load* just returns 2nil* if no file with the specified name exists.  Error
        conditions other than 2fs:file-not-found* are not handled by this option.

        If a file is loaded, 2load* returns the file's truename.

        If 1print* is non-2nil*, the value of each expression evaluated from the file is printed on
        2*standard-output**.

        1pathname* is defaulted from the default pathname defaults.  If 1set-default-pathname* is
        non-2nil*, the pathname defaults are set to the name of the file loaded.  The default for
        1set-default-pathname* is 2t*.

        2load* used to be called with a different calling sequence:  

                3(load 1pathname* 1pkg* 1nonexistent-ok**
                3      1dont-set-default*)*

        This calling sequence is detected and still works, but it is obsolete.  

3*load-verbose**                                                                              1Variable*        
        Is the default value for the 1verbose* argument to 2load*.  

3readfile* 1file* &optional 1pkg* 1no-msg-p*                                                                        
        2readfile* is the version of 2load* for text files.  It reads and evaluates each expression in the file.
        As with 2load*, 1pkg* can specify what package to read the file into.  Unless 1no-msg-p* is 2t*, a
        message is printed indicating what file is being read into what package.  

3fasload* 1file* &optional 1pkg* 1no-msg-p*                                                                          
        2fasload* is the version of 2load* for QFASL files.  It defines functions and performs other
        actions as directed by the specifications inserted in the file by the compiler.  As with 2load*, 1pkg*
        can specify what package to read the file into.  Unless 1no-msg-p* is 2t*, a message is printed
        indicating what file is being read into what package.  

=Node: 4Pathname Operations *t4hat Access Files*

=Text:
3PATHNAME OPERATIONS THAT ACCESS FILES*

     Here are the operations that access files.  Many accept an argument 1error* or 1error-p* which
specifies whether to signal an error or to return a condition instance, if the file cannot be accessed.
For these arguments, 2nil* and non-2nil* are the only significant values.  2:reprompt* has no special
meaning as a value.  That value when passed to one of the file accessing functions (2open*, 2deletef*,
etc.) has its special significance at a higher level.

3:truename*                                                                     1Operation on 2pathname**        
        Returns a pathname object describing the exact name of the file specified by the pathname
        the object is sent to.

        This may be different from the original pathname.  For example, the original pathname may
        have 2:newest* as the version, but the truename always has a number as the version if the file
        system supports versions.  

3:open* 1pathname* &rest 1options*                                              1Operation on 2pathname**        
        Opens a stream for the file named by the pathname.  The argument 1pathname* is what the
        2:pathname* operation on the resulting stream should return.  When a logical pathname is
        opened, 1pathname* is that logical pathname, but 2self* is its translated pathname.

        1options* is a list of alternating keywords and values, as would be passed to 2open*.  The old
        style of 2open* keywords are not allowed; when they are used with 2open*, 2open* converts them
        to the new style before sending the 2:open* message.  

3:delete* &optional 1(error-p* 3t1)**                                          1Operation on 2pathname**        
3:undelete* &optional 1(error-p* 3t1)**                                       1Operation on 2pathname**        
        Respectively delete or undelete the file specified by the pathname.

        All file systems support 2:delete* but not all support 2:undelete*.

        If 1error-p* is 2nil*, problems such as nonexistent files cause a string describing the problem to be
        returned.  Otherwise, they signal an error.  

3:undeletable-p*                                                             1Operation on 2pathname**        
        Returns 2t* if this pathname is for a file system which allows deletion to be undone.  Such
        pathnames support the 2:undelete* and 2:expunge* operations.  

3:rename* 1new-name* &optional 1(error-p* 3t1)**                             1Operation on 2pathname**        
        Renames the file specified by the pathname.  1new-name*, a string or pathname, specifies the
        name to rename to.  If it is a string, it is parsed using 2self* as the defaults.

        If 1error-p* is 2nil*, problems such as nonexistent files cause a string describing the problem to be
        returned.  Otherwise, they signal an error.  

3:complete-string* 1string* 1options*                                         1Operation on 2pathname**        
        Attempts to complete the filename 1string*, returning the results.  This operation is used by the
        function 2fs:complete-pathname* (see 4(FILEACCESS-3)Accessing Directories*).  
        The pathname the message is sent to is used for defaults.  1options* is a list whose elements
        may include 2:deleted*, 2:read* (file is for input), 2:write* (it's for output), 2:old* (only existing files 
        allowed), or 2:new-ok* (new files are allowed too).

        There are two values:  a string, which is the completion as far as possible, and a flag, which
        can be 2:old*, 2:new* or 2nil*.  2:old* says that the returned string names an existing file, 2:new* says
        that the returned string is no file but some completion was done, 2nil* says that no completion
        was possible.  

3:change-properties* 1error-p* &rest 1properties*                          1Operation on 2pathname**        
        Changes the properties of the file specified by the pathname.  1properties* should be an
        alternating list of property names and values.  

3:directory-list* 1options*                                                  1Operation on 2pathname**        
        Performs the work of 2(fs:directory-list 1this-pathname* 1options*...)*.  

3:properties*                                                                 1Operation on 2pathname**        
        Returns a property list (in the form of a directory-list element) and a list of settable
        properties.  See 4(FILEACCESS-3)Accessing Directories* for more information on file properties.  

3:wildcard-map* 1function* 1plistp* 1dir-list-options* &rest 1args*              1Operation on 2pathname**        
        Maps 1function* over all the files specified by this pathname (which may contain wildcards).
        Each time 1function* is called, its first argument is a pathname with no wildcards, or else a
        directory-list element (whose car is a pathname and whose cdr contains property names and
        values).  The elements of 1args* are given to 1function* as additional arguments.

        1plistp* says whether 1function*'s first argument should be a directory-list element or just a
        pathname.  2t* specifies a directory-list element.  That provides more information, but it makes it
        necessary to do extra work if the specified pathname does 1not* contain wildcards.

        1dir-list-options* is passed to 2fs:directory-list*.  You can use this to get deleted files mentioned
        in the list, for example.  

The remaining file-access operations are defined only on certain file systems.

3:expunge* &key 1(error* 3t1)**                                                1Operation on 2pathname**        
        Expunges the directory specified by the host, device and directory components of the
        pathname.

        The argument 1error* says whether to signal an error if the directory does not exist.  2nil* means
        just return a string instead.  

3:create-directory* &key 1(error* 3t1)**                                  1Operation on 2pathname**        
        Creates the directory specified in this pathname.  

3:remote-connect* &key 1(error* 3t1)** 1access*                            1Operation on 2pathname**        
        Performs the work of 2fs:remote-connect* with the same arguments on this pathname's host.  

=Node: 4File Attribute Lists*

=Text:
3FILE ATTRIBUTE LISTS*

     Any text file can contain an 1attribute list* that specifies several attributes of the file.  The
above loading functions, the compiler, and the editor look at this property list.  Attribute lists are
especially useful in program source files, i.e.  a file that is intended to be loaded (or compiled and
then loaded).  QFASL files also contain attribute lists, copied from their source files.

     If the first non-blank line in a text file contains the three characters `3-*-*', some text, and `3-*-*'
again, the text is recognized as the file's attribute list.  Each attribute consists of the attribute name,
a colon, and the attribute value.  If there is more than one attribute they are separated by
semicolons.  An example of such an attribute list is:  

        3; -*- Mode:Lisp; Package:Cellophane; Base:10 -*-*

     This defines three attributes:  mode, package, and base.  The initial semicolon makes the line
look like a comment rather than a Lisp expression.  Another example is:  

        3.c Part of the Lisp Machine manual.  -*- Mode:Bolio -*-*

     An attribute name is made up of letters, numbers, and otherwise-undefined punctuation
characters such as hyphens.  An attribute value can be such a name, or a decimal number, or
several such items separated by commas.  Spaces may be used freely to separate tokens.  Upper
and lower-case letters are not distinguished.  There is 1no* quoting convention for special characters
such as colons and semicolons.

     If the attribute list text contains no colons, it is an old Emacs format, containing only the value
of the 2Mode* attribute.

     The file attribute list format actually has nothing to do with Lisp; it is just a convention for
placing some information into a file that is easy for a program to interpret.  The Emacs editor on the
PDP-10 knows how to interpret these attribute lists (primarily in order to look at the 2Mode* attribute).

     The Lisp Machine handles the attribute list stored in the file by parsing it into a Lisp data
structure, a property list.  Attribute names are interpreted as Lisp symbols and are interned on the
keyword package.  Numbers are interpreted as Lisp fixnums and are read in decimal.  If a attribute
value contains any commas, then the commas separate several expressions that are formed into a
list.

     When a file is compiled, its attribute list data structure is stored in the QFASL file.  It can be
loaded back from the QFASL file as well.  The representation in the QFASL file resembles nothing
described here, but when the attribute list is extracted from there, the same Lisp data structure
described above is obtained.

     When a file is edited, loaded, or compiled, its file attribute list is read in and the properties are
stored on the property list of the generic pathname (see 4(FILENAMES-2)Generic Pathnames*) for
that file, where they can be retrieved with the 2:get* and 2:plist* messages.  This is done using the
function 2fs:read-attribute-list*, below.  So the way you examine the properties of a file is usually to
use messages to a pathname object that represents the generic pathname of a file.  Note that there
are other properties there, too.

     Here the attribute names with standard meanings:  The editor major mode to be used when
editing this file.  This is typically the name of the language in which the file is written.  The most
common values are 2Lisp* and 2Text*.

2Package*     This attribute specifies the package in which symbols in the file should be interned.  The
              attribute may be either the name of a package, or a list that specifies both the package
              name and how to create the package if it does not exist.  If it is a list, it should look like
              2(1name* 1superpackage* 1initial-size* 1...options...*)*.  See 4(PACKAGES-0)Packages* for more
              information about packages.

2Base*         The number base in which the file is written (remember, it is always parsed in decimal).
              This affects both 2*read-base** and 2*print-base**, since it is confusing to have the input
              and output bases be different.  The most common values are 8 and 10.

2Readtable*   The value specifies the syntax (that is, the choice of readtable) to use for reading Lisp
              objects from this file.  The defined values are 2t* or 2traditional* for traditional Lisp Machine
              syntax, and 2cl* or 2common-lisp* for Common Lisp syntax.  If you do not specify this
              option, the objects in the file are read using whatever readtable is current in the program
              that reads them.

2Lowercase*  
              If the attribute value is not 2nil*, the file is written in lower-case letters and the editor does
              not translate to upper case.  (The editor does not translate to upper case by default
              unless the user enables Electric Shift Lock mode.)

2Fonts*        The attribute value is a list of font names, separated by commas.  The editor uses this
              for files that are to be displayed in a specific font, or contain multiple fonts.  If this
              attribute is present, the file is actually stored in the file system with font-change
              indicators.  A font-change indicator is an epsilon (3*) followed by a digit or 3**.  31n** means
              to enter font 1n*.  The previous font is saved on a stack and 31*** means to pop the stack,
              returning to the previous font.  If the file includes an epsilon as part of its contents, it is
              stored as 3*.

              When expressions are read from such files, font-change indicators are ignored, and 3* is
              treated as a single 3*.

2Backspace*  If the attribute value is not 2nil*, 2Overstrike* characters in the file should cause characters
              to overprint on each other.  The default is to disallow overprinting and display
              2Overstrike* the way other special function keys are displayed.  This default is to prevent
              the confusion that can be engendered by overstruck text.

2Patch-File*  If the attribute value is not 2nil*, the file is a 1patch file*.  When it is loaded the system will
              not complain about function redefinitions.  In a patch file, the 2defvar* special-form turns
              into 2defconst*; thus patch files always reinitialize variables.  Patch files are usually
              created by special editor commands described in 4(SYSTEMS-2)The Patch Facility*.

2Cold-Load*  A non-2nil* value for this attribute identifies files that are part of the cold load, the core
              from which a new system version is built.  Certain features that do not work in the cold
              load check this flag to give an error or a compiler warning if used in such files, so that
              the problem can be detected sooner.

     You are free to define additional file attributes of your own.  However, to avoid accidental name
conflicts, you should choose names that are different from all the names above, and from any
names likely to be defined by anybody else's programs.

     The following functions are used to examine file attribute lists:

3fs:file-attribute-list* 1pathname*                                                                        
        Returns the attribute list of the file specified by the pathname.  This works on both text files
        and QFASL files.  

3fs:extract-attribute-list* 1stream*                                                                      
        Returns the attribute list read from the specified stream, which should be pointing to the
        beginning of a file.  This works on both text streams and QFASL file binary streams.  After
        the attribute list is read, the stream's pointer is set back to the beginning of the file using the
        2:set-pointer* file stream operation (see ).  

3fs:read-attribute-list* 1pathname* 1stream*                                                               
        1pathname* should be a pathname object (1not* a string or namelist, but an actual pathname);
        usually it is a generic pathname (see 4(FILENAMES-2)Generic Pathnames*).  1stream* should be
        a stream that has been opened and is pointing to the beginning of the file whose file attribute
        list is to be parsed.  The attribute list is read from the stream and then corresponding
        properties are placed on the specified 1pathname*.  The attribute list is also returned.  

     The fundamental way that programs in the Lisp Machine notice the presence of properties on a
file's attribute list is by examining the property list in the generic pathname.  However, there is
another way that is more convenient for some applications.  File attributes can cause special
variables to be bound whenever Lisp expressions are being read from the file--when the file is being
loaded, when it is being compiled, when it is being read from by the editor, and when its QFASL file
is being loaded.  This is how the 2Package* and 2Base* attributes work.  You can also deal with
attributes this way, by using the following function:

3fs:file-attribute-bindings* 1pathname*                                                                  
        Returns values describing the special variables that should be bound before reading
        expressions from file 1pathname*.  It examines the property list of 1pathname* and finds all those
        property names that have 2fs:file-attribute-bindings* properties.  Each such property name
        specifies a set of variables to bind and a set of values to which to bind them.  This function
        returns two values, a list of all the variables and a list of all the corresponding values.
        Usually you use this function by calling it on a generic pathname that has had
        2fs:read-attribute-list* done on it, and then you use the two returned values as the first two
        arguments of a 2progv* special form (see 4(EVAL-1)Variable Binding Constructs*).  Inside the
        body of the 2progv* the specified bindings will be in effect.

        1pathname* may be anything acceptable as the first argument of 2get*.  Usually it is a generic
        pathname.

        Of the standard attribute names, the following ones have 2fs:file-attribute-bindings*, with the
        following effects.  2Package* binds the variable 2package* (see 4(PACKAGES-1)The Current Package*)
        to the package.  2Base* binds the variables 2*print-base** (see
        4(READPRINT-1)Options that Control Printing*) and 2*read-base** (see
        4(READPRINT-2)What The Reader Accepts*) to the value.  2Readtable* binds the variable
        2readtable* to a value computed from the specified attribute.  2Patch-file* binds
        2fs:this-is-a-patch-file* to the value.  2Cold-load* binds 2si:file-in-cold-load* to the value.  2Fonts*
        binds 2si:read-discard-font-changes* to 2t*.

        Any properties whose names do not have 2fs:file-attribute-bindings* properties are ignored
        completely.

        You can also add your own attribute names that affect bindings.  If an indicator symbol has
        an 2fs:file-attribute-bindings* property, the value of that property is a function that is called
        when a file with a file attribute of that name is going to be read from.  The function is given
        three arguments:  the file pathname, the attribute name, and the attribute value.  It must return
        two values:  a list of variables to be bound and a list of values to bind them to.  The
        function for the 2Base* keyword could have been defined by:  

                3(defun (:base file-attribute-bindings) (file ignore bse)*
                3  (if (not (and (typep bse 'fixnum)*
                		3(> bse 1)*
                		3(< bse 37.)))*
                3      (ferror 'fs:invalid-file-attrbute*
                	3      "File ~A has an illegal -*- Base:~D -*-"*
                	3      file bse))*
                3  (values (list 'base 'ibase) (list bse bse)))

fs:extract-attribute-bindings* 1stream*                                                                
        Returns two values:  a list of variables, and a corresponding list of values to bind them to,
        giving the attribute bindings of the attribute list found on 1stream* 

3fs:invalid-file-attribute* (3error*)                                                1Condition*        
        An attribute in the file attribute list had a bad value.  This is detected within
        2fs:file-attribute-bindings*.  

