% This file was created automatically from files.msk.
% DO NOT EDIT!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%W  files.msk                 GAP documentation              Frank Celler
%W                                                     & Martin Schoenert
%%
%H  @(#)$Id: files.msk,v 1.4 2003/03/26 17:46:07 gap Exp $
%%
%Y  Copyright 1997,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,   Germany
%%
%%  This file    contains the  description of   the   file, filename  and
%%  directory functions.
%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Chapter{Files and Filenames}

Files are identified by filenames, which are represented in {\GAP} as
strings.  Filenames can be created directly by the user or a program, but
of course this is operating system dependent.

Filenames for some files can  be constructed in  a system independent way
using the following functions.  This is done by first getting a directory
object for the directory the file shall  reside in, and then constructing
the filename.  However, it is  sometimes necessary to construct filenames
of files in subdirectories relative to a given directory object.  In this
case the directory separator is *always* `{'/'}' even under DOS or MacOS.

Section "Directories" describes how  to  construct directory objects
for the common {\GAP} and system directories.
Using the command `Filename' described in section~"Filename"
it is possible to construct a filename pointing to a file in these
directories.
There are also functions to test for accessibility of files,
see~"File Access".

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Portability}

For portability filenames and directory  names should be restricted to at
most   8 alphanumerical characters  optionally followed  by a dot `{'.'}'
and between 1 and 3 alphanumerical characters.  Upper case letters should
be  avoided because some  operating systems  do  not make any distinction
between case,  so that `NaMe', `Name'  and  `name' all  refer to the same
file  whereas  some   operating  systems are case   sensitive.   To avoid
problems only lower case characters should be used.

Another function which is system-dependent is:
\>LastSystemError() F

`LastSystemError' returns a record describing the last system error  that
has occurred.
This record   contains  at least   the  component  `message' which   is a
string. This message is, however,  highly operating system dependent  and
should only be used as an informational message for the user.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{GAP Root Directory}

When   starting {\GAP} it is possible   to specify various directories as
root directories.  In  {\GAP}'s view of  the world these  directories are
merged  into one meta-directory.  This  directory is called *{\GAP}  root
directory* in the following.

For example, if `<root1>;<root2>;...' is passed as argument to `-l'  when
{\GAP} is started and {\GAP} wants to locate a file `lib/group.gd' in the
{\GAP} root  directory  it  will  first  check  if  the  file  exists  in
`<root1>', if not, it checks `<root2>', and so on.

This layout makes  it possible to  have one  system-wide  installation of
{\GAP}  which is read-only  but still  allows users  to modify individual
files.  Therefore instead of constructing an absolute path name to a file
you should always use `DirectoriesLibrary' or `DirectoriesPackageLibrary'
together with `Filename' to construct a filename for a file in the {\GAP}
root directory.

*Example*

Suppose that the system-wide installation lives in  `/usr/local/lib/gap4'
and you want to modify the file  `lib/files.gd'  without  disturbing  the
system installation.

In this case create  a  new  directory  `/home/myhome/gap'  containing  a
subdirectory `lib' which contains the modified `lib/files.gd'.

The directory/file structure now looks like

\begintt
/usr/local/lib/gap4/
/usr/local/lib/gap4/lib/
/usr/local/lib/gap4/lib/files.gd
/home/myhome/gap/
/home/myhome/gap/lib
/home/myhome/gap/lib/files.gd
\endtt


If you start {\GAP} using (under UNIX)

\begintt
you@unix> gap -l '/home/myhome/gap;/usr/local/lib/gap4'
\endtt

then the  file  `/home/myhome/gap/lib/files.gd'  will  be  used  whenever
{\GAP} references the file with filename  `lib/files.gd'  in  the  {\GAP}
root directory.

This setup also  allows one to easily install  new {\GAP} packages or
bugfixes even if no access to the system {\GAP} installation  is possible.
Simply unpack the files into ``/home/myhome/gap''.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Directories}

\>Directory( <string> ) O

returns a directory object for the string <string>.
`Directory' understands `.' for ``current directory'', that is, the
directory in which {\GAP} was started.
It also understands absolute paths.

If the variable `GAPInfo.UserHome' is defined (this may depend on the
operating system) then `Directory' understands a string with a leading
`~' character for a path relative to the user's home directory.

Paths are otherwise taken relative to the current directory.


\>DirectoryTemporary( <hint> ) F
\>DirectoryTemporary( ) F

returns  a directory  object in the   category `IsDirectory' for a  *new*
temporary directory.   This is guaranteed to  be  newly created and empty
immediately  after the call to `DirectoryTemporary'.   {\GAP} will make a
reasonable effort   to *remove* this   directory  either  when a  garbage
collection  collects the directory   object  or upon termination  of  the
{\GAP}   job that   created  the  directory.     <hint> can  be  used  by
`DirectoryTemporary' to construct    the  name  of the    directory   but
`DirectoryTemporary' is free to use only a  part of <hint> or even ignore
it completely.

If `DirectoryTemporary' is  unable to create a  new  directory, `fail' is
returned.  In this case `LastSystemError' can be  used to get information
about the error.


\>DirectoryCurrent( ) F

returns the directory object for the current directory.



\>DirectoriesLibrary( ) F
\>DirectoriesLibrary( <name> ) F

returns the directory objects for the {\GAP} library <name> as a list.
<name> must be one of `"lib"' (the default), `"grp"', `"prim"',
and so on.
The string `""' is also legal and with this argument `DirectoriesLibrary'
returns the list of {\GAP} root directories; the return value of
`DirectoriesLibrary("");' differs from `GAPInfo.RootPaths' in that the
former is a list of directory objects and the latter a list of strings.

The directory <name> must exist in at least one of the root directories,
otherwise `fail' is returned.

As the files in the {\GAP} root directory (see~"GAP Root Directory") can
be distributed into different directories in the filespace a list of
directories is returned.  In order to find an existing file in a {\GAP}
root directory you should pass that list to `Filename' (see~"Filename")
as the first argument.
In order to create a filename for a new file inside a {\GAP} root
directory you should pass the first entry of that list.
However, creating files inside the {\GAP} root directory is not
recommended, you should use `DirectoryTemporary' instead.


\>DirectoriesSystemPrograms( ) F

`DirectoriesSystemPrograms' returns the directory objects for the list of
directories where the system programs reside as a list.  Under UNIX this
would usually represent `\$PATH'.



\>DirectoryContents( <name> ) F

This function returns a list of filenames/directory names that reside in
the directory with name <name> (given as a string). It is an error, if
such a directory does not exist. 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Filename}\nolabel

\>Filename( <dir>, <name> ) O
\>Filename( <list-of-dirs>, <name> ) O

If the first argument is a directory object <dir>, `Filename' returns the
(system dependent) filename as a string for the file with name <name>  in
the directory <dir>.
`Filename' returns the filename regardless of whether the directory
contains a file with name <name> or not.

If the first argument is a list <list-of-dirs> (possibly of length 1) of
directory objects, then `Filename' searches the directories in order, and
returns the filename for the file <name> in the first directory which
contains a file <name> or `fail' if no directory contains a file <name>.



*Examples*

In    order    to    locate    the    system    program    `date'     use
`DirectoriesSystemPrograms' together with the second form of `Filename'.

%notest
\beginexample
gap> path := DirectoriesSystemPrograms();;
gap> date := Filename( path, "date" );
"/bin/date"
\endexample

In order to locate the library file `files.gd'  use  `DirectoriesLibrary'
together with the second form of `Filename'.

%notest
\beginexample
gap> path := DirectoriesLibrary();;
gap> Filename( path, "files.gd" );
"./lib/files.gd"
\endexample

In  order to construct filenames for  new  files in a temporary directory
use `DirectoryTemporary' together with the first form of `Filename'.

%notest
\beginexample
gap> tmpdir := DirectoryTemporary();;
gap> Filename( [ tmpdir ], "file.new" );
fail
gap> Filename( tmpdir, "file.new" );    
"/var/tmp/tmp.0.021738.0001/file.new"
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Special Filenames}

The special filename `"*stdin*"' denotes the standard  input,  i.e.,  the
stream through which the  user  enters  commands  to  {\GAP}.  The  exact
behaviour of reading from `"*stdin*"' is operating system dependent,  but
usually the following happens.  If  {\GAP}  was  started  with  no  input
redirection, statements are read from the terminal stream until the  user
enters the end of file character, which is usually <ctr>-'D'.  Note  that
terminal streams are special, in  that  they  may  yield  ordinary  input
*after*  an  end  of  file.  Thus  when  control  returns  to  the   main
read-eval-print loop the user can continue with  {\GAP}.  If  {\GAP}  was
started with an input redirection, statements are read from  the  current
position in the input file up to  the  end  of  the  file.  When  control
returns to the main read eval view  loop  the  input  stream  will  still
return end of file, and {\GAP} will terminate.

The  special filename `"*errin*"' denotes   the stream connected  to  the
UNIX `stderr' output. This stream is usually connected to  the  terminal,
even if the standard input was  redirected,  unless  the  standard  error
stream was also redirected, in which case opening of `"*errin*"' fails.

The special filename `"*stdout*"'  can be used to  print to  the standard
output.

The special  filename `"*errout*"' can be  used to  print to the standard
error output file, which is usually  connected  to  the terminal, even if
the standard output was redirected.
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{File Access}

When the following functions return `false' one can use `LastSystemError'
(see~"LastSystemError") to find  out  the  reason  (as  provided  by  the
operating system).

\>IsExistingFile( <name-file> ) F

returns `true' if a file with the filename <name-file> exists and can be
seen by the {\GAP} process. Otherwise `false' is returned.

\>IsReadableFile( <name-file> ) F

returns `true' if a file with the filename <name-file> exists  *and*  the
{\GAP} process has read permissions for the file, or `false' if 
this is not the case.

\>IsWritableFile( <name-file> ) F

returns `true' if a file with the filename <name-file> exists  *and*  the
{\GAP} process has write permissions for  the  file,  or  `false'  if  
this is not the case.

\>IsExecutableFile( <name-file> ) F

returns `true'  if a  file with  the filename  <name-file> exists  *and* the
{\GAP} process has  execute permissions for the file, or  `false' if this is
not the case. Note that execute permissions do not imply that it is possible
to execute the file, e.g., it may only be executable on a different machine.

\>IsDirectoryPath( <name-file> ) F

returns `true' if the file with the filename <name-file> exists *and*  is
a directory and  `false' otherwise.
Note that this function does not check if the {\GAP} process actually has
write  or  execute  permissions  for   the   directory   (you   can   use
`IsWritableFile'   (see~"IsWritableFile"),    resp.    `IsExecutableFile'
(see~"IsExecutableFile") to check such permissions).

*Examples*

Note,   in   particular,    how    one    may    use    `LastSystemError'
(see~"LastSystemError") to discover the reason  a  file  access  function
returns `false'.

\beginexample
gap> IsExistingFile( "/bin/date" );     # the file `/bin/date' exists
true
gap> IsExistingFile( "/bin/date.new" ); # the file `/bin/date.new' does not exist
false
gap> IsExistingFile( "/bin/date/new" ); # `/bin/date' is not a directory
false
gap> LastSystemError().message;
"Not a directory"
gap> IsReadableFile( "/bin/date" );     # the file `/bin/date' is readable
true
gap> IsReadableFile( "/bin/date.new" ); # the file `/bin/date.new' does not exist
false
gap> LastSystemError().message;        
"No such file or directory"
gap> IsWritableFile( "/bin/date" );     # the file `/bin/date' is not writable ...
false
gap> IsExecutableFile( "/bin/date" );   # ... but executable
true
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{File Operations}

\>Read( <name-file> ) O

reads the input from the file with the filename <name-file>, which must
be given as a string.

`Read' first opens the file <name-file>.  If the file does not exist, or
if {\GAP} cannot open it, e.g., because of access restrictions,
an error is signalled.

Then the contents of the file are read and evaluated, but the results are
not printed.  The reading and evaluations happens exactly as described
for the main loop (see "Main Loop").

If a statement in the file causes an error a break loop is entered
(see~"Break Loops").
The input for this break loop is not taken from the file, but from the
input connected to the `stderr' output of {\GAP}.
If `stderr' is not connected to a terminal, no break loop is entered.
If this break loop is left with `quit' (or `<ctr>-D'), {\GAP} exits from
the `Read' command, and from all enclosing `Read' commands,
so that control is normally returned to an interactive prompt.
The `QUIT' statement (see~"Leaving GAP") can also be used in the break
loop to exit {\GAP} immediately.

Note that a statement must not begin in one file and end in another.
I.e., <eof> (`end-of-file') is not treated as whitespace,
but as a special symbol that must not appear inside any statement.

Note that one file may very well contain a read statement causing another
file to be read, before input is again taken from the first file.
There is an operating system dependent maximum on the number of files
that may be open simultaneously.  Usually it is 15.


\>ReadAsFunction( <name-file> ) O

reads the file with filename <name-file> as a function and returns this
function.



*Example*

Suppose that the file `/tmp/example.g' contains the following

\begintt
local a;

a := 10;
return a*10;
\endtt

Reading the file as a function will not affect a global variable `a'.

%notest
\beginexample
gap> a := 1;
1
gap> ReadAsFunction("/tmp/example.g")();
100
gap> a;
1
\endexample

\>PrintTo( <name-file>[, <obj1>, ...] ) F

works like `Print'  (see~"Print"),  except  that  the  arguments  <obj1>,
{\dots} (if present) are printed to the file with  the  name  <name-file>
instead of the standard output. This file must of course be  writable  by
{\GAP}. Otherwise  an  error  is  signalled.  Note  that  `PrintTo'  will
*overwrite* the previous contents of this file if it already existed;  in
particular, `PrintTo' with just the  <name-file>  argument  empties  that
file. `AppendTo' can be used to append to a file (see "AppendTo").  There
is an operating system dependent maximum on the number  of  output  files
that may be open simultaneously, usually this is 14.

\>AppendTo( <name-file>[, <obj1>, ...] ) F

works like `PrintTo' (see~"PrintTo"), except that  the  output  does  not
overwrite the previous contents of the file, but is appended to the file.

\>LogTo( <name-file> ) O

causes the subsequent interaction to be logged  to the file with the name
<name-file>, i.e., everything you  see on your  terminal will also appear
in this file. `LogTo' may also be used to log to a stream (see~"LogTo!for
streams").
This file must of course be writable  by {\GAP}, otherwise an error is
signalled.  Note  that   `LogTo'  will overwrite the   previous
contents of this file if it already existed.

\>LogTo()!{stop logging} M

In this form `LogTo' stops logging to a file or stream.

\>InputLogTo( <name-file> ) O

causes the  subsequent  input to be   logged to the   file with  the name
<name-file>, i.e., everything you type  on your terminal will also appear
in this file.  Note that `InputLogTo'  and `LogTo' cannot  be used at the
same time while `InputLogTo' and `OutputLogTo' can.
Note  that   `InputLogTo'  will overwrite the   previous
contents of this file if it already existed.

\>InputLogTo()!{stop logging input} M

In this form `InputLogTo' stops logging to a file or stream.

\>OutputLogTo( <name-file> ) O

causes   the subsequent output to   be logged to  the file  with the name
<name-file>,  i.e., everything {\GAP} prints  on  your terminal will also
appear in this file.  Note that  `OutputLogTo' and `LogTo' cannot be used
at the same time while `InputLogTo' and `OutputLogTo' can.
Note  that   `OutputLogTo'  will overwrite the   previous
contents of this file if it already existed.

\>OutputLogTo()!{stop logging output} M

In this form `OutputLogTo' stops logging to a file or stream.

*Note* that one should be careful not to write to a logfile with
`PrintTo' or `AppendTo'.
% The same holds of course for the redirection of output to a file.

\>CrcFile( <name-file> ) F

computes a checksum value for the file with filename <name-file> and
returns this value as an integer.
See Section~"CRC Numbers" for an example.
The function returns `fail' if a system error occurred, say, for example,
if <name-file> does not exist.
In this case the function `LastSystemError' (see~"LastSystemError")
can be used to get information about the error.



\>RemoveFile( <name-file> ) F

will remove the file with filename <name-file> and returns `true' in case
of  success.  The function returns `fail' if a system error occurred, for
example, if your permissions do not allow the removal of <name-file>.
In this case the function `LastSystemError' (see~"LastSystemError")
can be used to get information about the error.

\>Reread( <name-file> ) F
\>`REREADING'{REREADING}@{`REREADING'}

In general, it is not possible to read the same {\GAP} library file
twice, or to read a compiled version after reading a {\GAP} version,
because crucial global variables are made read-only (see "More about
Global Variables") and filters and methods are added to global tables.

A partial solution to this problem is provided by the function
`Reread' (and related functions `RereadLib' etc.).  `Reread(
<name-file> )' sets the global variable `REREADING' to `true', reads
the file named by <name-file> and then resets `REREADING'. Various
system functions behave differently when `REREADING' is set to
true. In particular, assignment to read-only global variables is
permitted, calls to `NewRepresentation' (see "prg:NewRepresentation"
in ``Programming in {\GAP}'') and
`NewInfoClass' (see "NewInfoClass") with parameters identical to those
of an existing representation or info class will return the existing
object, and methods installed with `InstallMethod' (see
"prg:InstallMethod" in ``Programming in {\GAP}'') may sometimes displace
existing methods.

This function may not entirely produce the intended results,
especially if what has changed is the super-representation of a
representation or the requirements of a method. In these cases, it is
necessary to restart {\GAP} to read the modified file.

An additional use of `Reread' is to load the compiled version of a
file for which the {\GAP} language version had previously been read
(or perhaps was included in a saved workspace). See "The Compiler" and 
"Saving and Loading a Workspace" for more information.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%E

