GAP (ref) - Chapter 9: Files and Filenames

Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 Bib Ind
[Top of Book] [Contents] [Previous Chapter] [Next Chapter]

[MathJax on]

9 Files and Filenames
9.1 Portability
9.1-1 LastSystemError
9.2 GAP Root Directories
9.3 GAP Package Directories
9.4 Directories
9.4-1 IsDirectory
9.4-2 Directory
9.4-3 DirectoryTemporary
9.4-4 DirectoryCurrent
9.4-5 ChangeDirectoryCurrent
9.4-6 DirectoriesLibrary
9.4-7 DirectoriesSystemPrograms
9.4-8 DirectoryContents
9.4-9 DirectoryDesktop
9.4-10 DirectoryHome
9.5 File Names
9.5-1 Filename
9.5-2 PathSystemProgram
9.6 Special Filenames
9.7 File Access
9.7-1 IsExistingFile
9.7-2 IsReadableFile
9.7-3 IsWritableFile
9.7-4 IsExecutableFile
9.7-5 IsDirectoryPath
9.8 File Operations
9.8-1 Read
9.8-2 ReadAsFunction
9.8-3 PrintTo and AppendTo
9.8-4 LogTo
9.8-5 InputLogTo
9.8-6 OutputLogTo
9.8-7 CrcFile
9.8-8 RemoveFile
9.8-9 UserHomeExpand
9.8-10 Reread

### 9 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 9.4 describes how to construct directory objects for the common GAP and system directories. Using the command `Filename` (9.5-1) 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 9.7.

#### 9.1 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` (9.1-1).

##### 9.1-1 LastSystemError

`‣ LastSystemError`( ) | ( function )

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

#### 9.2 GAP Root Directories

When GAP is started it determines a list of directories which we call the GAP root directories. In a running GAP session this list can be found in `GAPInfo.RootPaths`.

The core part of GAP knows which files to read relative to its root directories. For example when GAP wants to read its library file `lib/group.gd`, it appends this path to each path in `GAPInfo.RootPaths` until it finds the path of an existing file. The first file found this way is read.

Any subdirectories named `pkg/` in one of the directories in `GAPInfo.RootPaths` are added to `GAPInfo.PackageDirectories` (see 9.3), which controls where GAP looks for available packages.

The root directories are specified via one or several of the `-l paths` command line options, see 3.1. Furthermore, by default GAP automatically prepends a user specific GAP root directory to the list; this can be avoided by calling GAP with the `-r` option. The name of this user specific directory depends on your operating system, it can be found in `GAPInfo.UserGapRoot`. This directory can be used to tell GAP about personal preferences, to always load some additional code, to install additional packages, or to overwrite some GAP files. See 3.2 for more information how to do this. After GAP has been started, one can add additional root directories via the function `ExtendRootDirectories` (76.2-4).

#### 9.3 GAP Package Directories

When GAP is started it determines a list of directories potentially containing packages. We refer to these as the GAP package directories. In a running GAP session this list can be found in `GAPInfo.PackageDirectories`.

Every subdirectory `pkg` in a GAP root directory is automatically added to this list. Further package directories can be specified via one or several `--packagedirs paths` command line options, see 3.1, or after GAP has been started via the function `ExtendPackageDirectories` (76.2-5). The order of the directories in `GAPInfo.PackageDirectories` is as follows: first the package directories specified via the command line option `--packagedirs`, then the subdirectories `pkg` of the GAP root directories that were known at startup in the same order, and finally the directories added after GAP has been started.

GAP looks for available packages by examining each of the directories in `GAPInfo.PackageDirectories`.

#### 9.4 Directories

##### 9.4-1 IsDirectory

`‣ IsDirectory`( obj ) | ( category )

`IsDirectory` is a category of directories.

##### 9.4-2 Directory

`‣ Directory`( string ) | ( operation )

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 `~` (tilde) character for a path relative to the user's home directory (but a string beginning with `"~other_user"` is not interpreted as a path relative to `other_user`'s home directory, as in a UNIX shell).

Paths are otherwise taken relative to the current directory.

##### 9.4-3 DirectoryTemporary

`‣ DirectoryTemporary`( ) | ( function )

returns a directory object in the category `IsDirectory` (9.4-1) 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 upon termination of the GAP job that created the directory.

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

A warning message is given if more than 1000 temporary directories are created in any GAP session.

##### 9.4-4 DirectoryCurrent

`‣ DirectoryCurrent`( ) | ( function )

returns the directory object for the current directory.

##### 9.4-5 ChangeDirectoryCurrent

`‣ ChangeDirectoryCurrent`( path ) | ( function )

Changes the current directory. Returns `true` on success and `fail` on failure.

##### 9.4-6 DirectoriesLibrary

`‣ DirectoriesLibrary`( [name] ) | ( function )

`DirectoriesLibrary` returns the directory objects for the GAP library name as a list. name must be one of `"lib"` (the default), `"doc"`, `"tst"`, and so on.

The string `""` is also legal and with this argument `DirectoriesLibrary` returns the list of GAP root directories. The return value of this call 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 directories (see 9.2) 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` (9.5-1) 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` (9.4-3) instead.

##### 9.4-7 DirectoriesSystemPrograms

`‣ DirectoriesSystemPrograms`( ) | ( function )

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

##### 9.4-8 DirectoryContents

`‣ DirectoryContents`( dir ) | ( function )

This function returns a list of filenames/directory names that reside in the directory dir. The argument dir can either be given as a string indicating the name of the directory or as a directory object (see `IsDirectory` (9.4-1)). If an error occurs (the specified directory does not exist or has no read permissions), `fail` is returned. In this case `LastSystemError` (9.1-1) can be used to get information about the error.

The ordering of the list entries can depend on the operating system.

An interactive way to show the contents of a directory is provided by the function `BrowseDirectory` (Browse: BrowseDirectory) from the GAP package Browse.

##### 9.4-9 DirectoryDesktop

`‣ DirectoryDesktop`( ) | ( function )

returns a directory object for the user's desktop directory as defined on many modern operating systems. The function is intended to provide a cross-platform interface to a directory that is easily accessible by the user.

Under Unix systems (including macOS) this will be the `Desktop` directory in the user's home directory if it exists, and the user's home directory otherwise. Under Windows it will be the user's `Desktop` folder (or the appropriate name under different languages).

##### 9.4-10 DirectoryHome

`‣ DirectoryHome`( ) | ( function )

returns a directory object for the user's home directory, defined as a directory in which the user will typically have full read and write access. The function is intended to provide a cross-platform interface to a directory that is easily accessible by the user.

Under Unix systems (including macOS) this will be the usual user home directory. Under Windows it will be the user's `My Documents` folder (or the appropriate name under different languages).

#### 9.5 File Names

##### 9.5-1 Filename

`‣ Filename`( dir, name ) | ( operation )

`‣ Filename`( list-of-dirs, name ) | ( operation )

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.

For example, in order to locate the system program `date` use `PathSystemProgram` (9.5-2).

    gap> date := PathSystemProgram( "date" );
    "/bin/date"

In order to locate the library file `files.gd` use `DirectoriesLibrary` (9.4-6) together with the second form of `Filename`.

    gap> path := DirectoriesLibrary();;
    gap> Filename( path, "files.gd" );
    "./lib/files.gd"

In order to construct filenames for new files in a temporary directory use `DirectoryTemporary` (9.4-3) together with the first form of `Filename`.

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

##### 9.5-2 PathSystemProgram

`‣ PathSystemProgram`( name ) | ( function )

`PathSystemProgram` returns either the path of the first executable file name in one of the directories returned by `DirectoriesSystemPrograms` (9.4-7), or `fail` if no such file exists.

#### 9.6 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 Ctrl-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.

#### 9.7 File Access

When the following functions return `false` one can use `LastSystemError` (9.1-1) to find out the reason (as provided by the operating system), see the examples.

##### 9.7-1 IsExistingFile

`‣ IsExistingFile`( filename ) | ( function )

`IsExistingFile` returns `true` if a file with the filename filename exists and can be seen by the GAP process. Otherwise `false` is returned.

    gap> IsExistingFile( "/bin/date" );     # file `/bin/date' exists
    true
    gap> IsExistingFile( "/bin/date.new" ); # non existing `/bin/date.new'
    false
    gap> IsExistingFile( "/bin/date/new" ); # `/bin/date' is not a directory
    false
    gap> LastSystemError().message;
    "Not a directory"

##### 9.7-2 IsReadableFile

`‣ IsReadableFile`( filename ) | ( function )

`IsReadableFile` returns `true` if a file with the filename filename exists and the GAP process has read permissions for the file, or `false` if this is not the case.

    gap> IsReadableFile( "/bin/date" );     # file `/bin/date' is readable
    true
    gap> IsReadableFile( "/bin/date.new" ); # non-existing `/bin/date.new'
    false
    gap> LastSystemError().message;
    "No such file or directory"

##### 9.7-3 IsWritableFile

`‣ IsWritableFile`( filename ) | ( function )

`IsWritableFile` returns `true` if a file with the filename filename exists and the GAP process has write permissions for the file, or `false` if this is not the case.

    gap> IsWritableFile( "/bin/date" );  # file `/bin/date' is not writable
    false

##### 9.7-4 IsExecutableFile

`‣ IsExecutableFile`( filename ) | ( function )

`IsExecutableFile` returns `true` if a file with the filename filename 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.

    gap> IsExecutableFile( "/bin/date" );   # ... but executable
    true

##### 9.7-5 IsDirectoryPath

`‣ IsDirectoryPath`( filename ) | ( function )

`IsDirectoryPath` returns `true` if the file with the filename filename 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` (9.7-3), resp. `IsExecutableFile` (9.7-4) to check such permissions.

#### 9.8 File Operations

##### 9.8-1 Read

`‣ Read`( filename ) | ( operation )

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

`Read` first opens the file filename. 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 6.1).

If a statement in the file causes an error a break loop is entered (see 6.4). 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 Ctrl-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 6.7) 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 upper limit of 15 on the number of files that may be open simultaneously.

##### 9.8-2 ReadAsFunction

`‣ ReadAsFunction`( filename ) | ( operation )

reads the file with filename filename as a function and returns this function.

Example

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

    local a;

    a := 10;
    return a*10;

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

    gap> a := 1;
    1
    gap> ReadAsFunction("/tmp/example.g")();
    100
    gap> a;
    1

##### 9.8-3 PrintTo and AppendTo

`‣ PrintTo`( filename[, obj1, ...] ) | ( function )

`‣ AppendTo`( filename[, obj1, ...] ) | ( function )

`PrintTo` works like `Print` (6.3-4), except that the arguments obj1, ... (if present) are printed to the file with the name filename 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 filename argument empties that file.

`AppendTo` works like `PrintTo`, except that the output does not overwrite the previous contents of the file, but is appended to the file.

There is an upper limit of 15 on the number of output files that may be open simultaneously.

Note that one should be careful not to write to a logfile (see `LogTo` (9.8-4)) with `PrintTo` or `AppendTo`.

##### 9.8-4 LogTo

`‣ LogTo`( filename ) | ( operation )

`‣ LogTo`( ) | ( operation )

Calling `LogTo` with a string filename causes the subsequent interaction to be logged to the file with the name filename, i.e., everything you see on your terminal will also appear in this file. (`LogTo` (10.4-5) may also be used to log to a stream.) 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.

Called without arguments, `LogTo` stops logging to a file or stream.

##### 9.8-5 InputLogTo

`‣ InputLogTo`( filename ) | ( operation )

`‣ InputLogTo`( ) | ( operation )

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

Called without arguments, `InputLogTo` stops logging to a file or stream.

##### 9.8-6 OutputLogTo

`‣ OutputLogTo`( filename ) | ( operation )

`‣ OutputLogTo`( ) | ( operation )

Calling `OutputLogTo` with a string filename causes the subsequent output to be logged to the file with the name filename, i.e., everything GAP prints on your terminal will also appear in this file. Note that `OutputLogTo` and `LogTo` (9.8-4) cannot be used at the same time while `InputLogTo` (9.8-5) and `OutputLogTo` can. Note that `OutputLogTo` will overwrite the previous contents of this file if it already existed.

Called without arguments, `OutputLogTo` stops logging to a file or stream.

##### 9.8-7 CrcFile

`‣ CrcFile`( filename ) | ( function )

This function computes a CRC (cyclic redundancy check) number for the content of the file filename.

`CrcFile` computes a CRC (cyclic redundancy check) checksum value for the file with filename filename and returns this value as an integer. The function returns `fail` if an error occurred, for example, if filename does not exist. In this case the function `LastSystemError` (9.1-1) can be used to get information about the error. See also `CrcFile` and `HexSHA256` (27.9-7).

    gap> CrcFile( "lib/morpheus.gi" );
    2705743645

##### 9.8-8 RemoveFile

`‣ RemoveFile`( filename ) | ( function )

will remove the file with filename filename 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 filename. In this case the function `LastSystemError` (9.1-1) can be used to get information about the error.

##### 9.8-9 UserHomeExpand

`‣ UserHomeExpand`( str ) | ( function )

If the string str starts with a `'~'` character this function returns a new string with the leading `'~'` substituted by the user's home directory as stored in `GAPInfo.UserHome`. Otherwise str is returned unchanged.

##### 9.8-10 Reread

`‣ Reread`( filename ) | ( function )

`‣ REREADING` | ( global variable )

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 4.9) 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( filename )` sets the global variable `REREADING` to `true`, reads the file named by filename 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` (13.4-4) and `NewInfoClass` (7.4-1) with parameters identical to those of an existing representation or info class will return the existing object, and methods installed with `InstallMethod` (78.3-1) 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 76.3-11 and 3.3 for more information.

It is not advisable to use `Reread` programmatically. For example, if a file that contains calls to `Reread` is read with `Reread` then `REREADING` may be reset too early.

[Top of Book] [Contents] [Previous Chapter] [Next Chapter]
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 Bib Ind

generated by GAPDoc2HTML