[ Operating System | Reference Manual | Alphabetic Index ]

# existing_file(++Base, ++Completions, ++Permissions, -MatchedFile)

Finds any existing file subject to the specified conditions.

Base
  The start of a file or path name (atom or string, possibly with a library/1 wrapper)
Completions
  Possible completions for Base (list of atomic elements)
Permissions
  Permissions (list of readable,writable,executable)
MatchedFile
  An existing file that matches the specification.

## Description

This predicate will search for any existing files that match the specifications given in the first three arguments: the file starts with Base, which is an absolute or relative partial file name. Possible completions (usually file extensions) given in Completions are appended to Base, in the order they are given, to give a complete name. If a proper file (i.e. non-directory) with this name exists, the ECLiPSe process's permission for this file are checked against the Permissions list (readable, writable, executable). If the permissions match, then the filename is returned in MatchedFile.

Base may have a library/1 wrapper around the name. If this is used, the file is searched for in the directories specified in library path (including any subdirectory with the same name as given in the library/1 wrapper, i.e. we check for both lib/foo.eco and lib/foo/foo.eco). The search order is the order in which the library directories appear in the library_path flag of get_flag/2, and for each directory, the completions are tried in the order in which they appear in the list Completions. All matching files are returned via backtracking. If only the first one is required, use once/1.

MatchedFile is the same type as Base (atom or string). Also, if Base is a relative (absolute) pathname, then so is MatchedFile. If Base starts with '~' or enviroment variables (specified with a leading '$'), these are substituted. If the library(...) wrapper is used, the proper library path is substituted. Note that the executable permission for Windows may be approximate, because Windows (especially Vista) has a different system for dealing with execute permission.

The predicates canonical_path_name/2 and existing_file/4 are intended as replacement for absolute_file_name/2 in previous releases. The functionality of completing an incomplete name and returning an absolute path of absolute_file_name/2 has been separated. The following approximately implements the old absolute_file_name/2:

        absolute_file_name(Rel, Abs) :-
    	(Rel == user ->
    	    Abs == user
    	; get_flag(prolog_suffix, Sufs),
    	  (existing_file(Rel, Sufs, [], ExtRel) -> true ; ExtRel = Rel),
    	  canonical_path_name(ExtRel, Abs)
            ).

### Modes and Determinism

- existing_file(++, ++, ++, -) is nondet

### Fail Conditions

MatchedFile cannot be found.

### Resatisfiable

Succeeds once for every matching file

### Exceptions

(5) type error
  Base, Completions, Permissions not of right type.
(6) out of range
  Base is an empty atom or string.

## Examples

    Success:

          % Trying different file extensions, including the empty one:
          ?- existing_file("hello", [".ecl",".txt",""], [], File).
          File = "hello.txt"     More? (;)
          No (0.00s cpu)         % assuming hello.ecl and hello do not exist

          % Looking for one of several files in the parent directory:
          ?- existing_file("../", ["a.txt","b.txt","c.txt"], [readable], File).
          File = "../a.txt"     More? (;)
          File = "../c.txt"     More? (;)
          No (0.00s cpu)        % assuming b.txt does not exist or is not readable

          % Looking for a precompiled library:
          ?- existing_file(library(fd), [".eco"], [readable], File).
          File = '/homes/ks15/Eclipse/lib/fd.eco'     More? (;)
          No (0.00s cpu)

          % Looking for source files:
          ?- get_flag(prolog_suffix, Exts),
             existing_file("hello", Exts, [readable], File).
          File = "hello.ecl"     More? (;)
          No (0.00s cpu)

          % Looking for different file names:
          [eclipse 1]: existing_file(test, [1,2,3], [], File).
          File = test1     More? (;)
          File = test3     More? (;)
          No (0.00s cpu)

    Failure:

          [eclipse 1]:  existing_file(library(fd), [], [readable], File).
          % no Completions at all; will always fail

          [eclipse 1]:  existing_file(library(fd), [""], [readable], File).
          % no library file with just 'fd' as the name (file has a suffix)

## See Also

canonical_path_name / 2, get_flag / 2, os_file_name / 2, pathname / 4