Module Fpath

module Fpath: sig .. end
File system paths, file extensions, path sets and maps.

A (file system) path specifies a file or a directory in a file system hierarchy. A path has three parts:

  1. An optional, platform-dependent, volume.
  2. An optional root directory separator Fpath.dir_sep whose presence distinguishes absolute paths ("/a") from relative ones ("a")
  3. A non-empty list of Fpath.dir_sep separated segments. Segments are non empty strings except for maybe the last one. The latter distinguishes directory paths ("a/b/") from file paths ("a/b").

The path segments "." and ".." are relative path segments that respectively denote the current and parent directory. The basename of a path is its last non-empty segment if it is not a relative path segment or the empty string otherwise.

Consult a few important tips.

Note. Fpath processes paths without accessing the file system.

v0.7.1-2-gcf3e51c - homepage



Separators and segments


val dir_sep : string
dir_sep is the platform dependent natural directory separator. This is "/" on POSIX and "\\" on Windows.
val is_seg : string -> bool
is_seg s is true iff s does not contain Fpath.dir_sep or '/' or a 0x00 byte.
val is_rel_seg : string -> bool
is_rel_seg s is true iff s is a relative segment, that is "." or "..".

Paths


type t 
The type for paths.
val v : string -> t
v s is the string s as a path.
Raises Invalid_argument if s is not a valid path. Use Fpath.of_string to deal with untrusted input.
val add_seg : t -> string -> t
add_seg p seg adds segment seg to the segments of p if p's last segment is non-empty or replaces the last empty segment with seg. Examples.
Raises Invalid_argument if Fpath.is_seg seg is false.
val (/) : t -> string -> t
p / seg is Fpath.add_seg p seg. Left associative.
val append : t -> t -> t
append p q appends q to p as follows: Examples.
val (//) : t -> t -> t
p // p' is Fpath.append p p'. Left associative.
val split_volume : t -> string * t
split_volume p is the pair (vol, q) where vol is the platform dependent volume of p or the empty string if there is none and q the path p without its volume, that is its optional root Fpath.dir_sep and segments.

On POSIX if vol is non-empty then it can only be "/" (e.g. in v "//a/b"). On Windows vol may be one of the following prefixes parsed before an absolute root Fpath.dir_sep, except in the first case where a relative path can follow:

$(drive):
\\$(server)\$(share)
\\?\$(drive):
\\?\$(server)\$(share)
\\?\UNC\$(server)\$(share)
\\.\$(device)
The following invariant holds:
val segs : t -> string list
segs p is p's non-empty list of segments. Absolute paths have an initial empty string added, this allows to recover the path's string with String.concat ~sep:dir_sep. Examples.

The following invariant holds:



File and directory paths

Note. The following functions use syntactic semantic properties of paths. Given a path, these properties can be different from the one your file system attributes to it.

val is_dir_path : t -> bool
is_dir_path p is true iff p represents a directory. This means that p's last segment is either empty ("") or relative. The property is invariant with respect to normalization. Examples.
val is_file_path : t -> bool
is_file_path p is true iff p represents a file. This is the negation of Fpath.is_dir_path. This means that p's last segment is neither empty ("") nor relative. The property is invariant with respect to normalization. Examples.
val to_dir_path : t -> t
to_dir_path p is Fpath.add_seg p "". It ensure that the result represents a directory and, if converted to a string, that it ends with a Fpath.dir_sep. Examples.
val filename : t -> string
filename p is the file name of p. This is the last segment of p if p is a file path and the empty string otherwise. The result is invariant with respect to normalization. See also Fpath.basename. Examples.

Base and parent paths


val split_base : t -> t * t
split_base p splits p into a directory d and a relative base path b such that: Examples.

Note. Normalizing p before using the function ensures that b is a relative segment iff p cannot be named (like in ".", "../../", "/", etc.).

val base : t -> t
base p is snd (split_base p).
val basename : t -> string
basename p is p's last non-empty segment if non-relative or the empty string otherwise. The latter occurs only on root paths and on paths whose last non-empty segment is a relative segment. See also Fpath.filename and Fpath.base. Examples.

Note. Normalizing p before using the function ensures the empty string is only returned iff p cannot be named (like in ".", "../../", "/", etc.)

val parent : t -> t
parent p is a directory path that contains p. If p is a root path this is p itself. Examples.

Warning. parent p // base p may not represent p, use Fpath.split_base for this.


Normalization


val rem_empty_seg : t -> t
rem_empty_seg p removes an existing last empty segment of p if p is not a root path. This ensure that if p is converted to a string it will not have a trailing Fpath.dir_sep unless p is a root path. Note that this may affect p's directoryness. Examples.
val normalize : t -> t
normalize p is a path that represents the same path as p, directoryness included, and that has the following properties: Examples.

Warning. Like file and directory path functions this function does not consult the file system and is purely based on the syntactic semantic of paths which can be different from the one of your concrete file system attributes. For example in presence of symbolic links the resulting path may not point to the same entity. Use the normalization functions of your OS system library to ensure correct behaviour with respect to a concrete file system.


Prefixes

Warning. The syntactic prefix relation between paths does not, in general, entail directory containement. The following examples show this:

is_prefix (v "..") (v "../..") = true
is_prefix (v "..") (v ".") = false
However, on normalized, absolute paths, the prefix relation does entail directory containement. See also Fpath.is_rooted.
val is_prefix : t -> t -> bool
is_prefix prefix p is true if prefix is a prefix of p. This checks that: Examples.
val find_prefix : t -> t -> t option
find_prefix p p' is Some prefix if there exists prefix such that prefix is the longest path with is_prefix prefix p && is_prefix prefix p' = true and None otherwise. Note that if both p and p' are absolute and have the same volume then a prefix always exists: the root path of their volume. Examples.
val rem_prefix : t -> t -> t option
rem_prefix prefix p is: Examples.

Roots and relativization


val relativize : root:t -> t -> t option
relativize ~root p is:

Examples.

val is_rooted : root:t -> t -> bool
is_rooted root p is true iff the path p is the directory root or contained in root and that p can be relativized w.r.t. root (the normalized relative path will have no parent directory segments). Examples.

Predicates and comparison


val is_rel : t -> bool
is_rel p is true iff p is a relative path, i.e. the root directory separator is missing in p.
val is_abs : t -> bool
is_abs p is true iff p is an absolute path, i.e. the root directory separator is present in p.
val is_root : t -> bool
is_root p is true iff p is a root directory, i.e. p has the root directory separator and a single, empty, segment. Examples.

Warning. By definition this is a syntactic test. For example it will return false on "/a/.." or "/..". Normalizing the path before testing avoids this problem.

val is_current_dir : ?prefix:bool -> t -> bool
is_current_dir p is true iff p is the current relative directory, i.e. either "." or "./". If prefix is true (defaults to false) simply checks that p is relative and its first segment is ".".

Warning. By definition this is a syntactic test. For example it will return false on "./a/.." or "./.". Normalizing the path before testing avoids this problem.

val is_parent_dir : ?prefix:bool -> t -> bool
is_parent_dir p is true iff p is the relative parent directory, i.e. either ".." or "../". If prefix is true (defaults to false), simply checks that p is relative and its first segment is "..".

Warning. By definition this is a syntactic test. For example it will return false on "./a/../.." or "./..". Normalizing the path before testing avoids this problem.

val is_dotfile : t -> bool
is_dotfile p is true iff p's basename is non empty and starts with a '.'.

Warning. By definition this is a syntactic test. For example it will return false on ".ssh/.". Normalizing the path before testing avoids this problem.

val equal : t -> t -> bool
equal p p' is true if p and p' have the same volume are both relative or absolute and have the same segments.

Warning. By definition this is a syntactic test. For example equal (v "./") (v "a/..") is false. Normalizing the paths before testing avoids this problem.

val compare : t -> t -> int
compare p p' is a total order on paths compatible with Fpath.equal.

Conversions and pretty printing


val to_string : t -> string
to_string p is the path p as a string. The result can be safely converted back with Fpath.v.
val of_string : string -> (t, [ `Msg of string ]) Result.result
of_string s is the string s as a path. Result.Error is returned if The following transformations are performed on the string:
val pp : Format.formatter -> t -> unit
pp ppf p prints path p on ppf using Fpath.to_string.
val dump : Format.formatter -> t -> unit
dump ppf p prints path p on ppf using String.dump.

File extensions

The file extension (resp. multiple file extension) of a path segment is the suffix that starts at the last (resp. first) occurence of a '.' that is preceeded by at least one non '.' character. If there is no such occurence in the segment, the extension is empty. With these definitions, ".", "..", "..." and dot files like ".ocamlinit" or "..ocamlinit" have no extension, but ".emacs.d" and "..emacs.d" do have one.

Warning. The following functions act on paths whose basename is non empty and do nothing otherwise. Normalizing p before using the functions ensures that the functions do nothing iff p cannot be named, see Fpath.basename.

type ext = string 
The type for file extensions.
val get_ext : ?multi:bool -> t -> ext
get_ext p is p's basename file extension or the empty string if there is no extension. If multi is true (defaults to false), returns the multiple file extension. Examples.
val has_ext : ext -> t -> bool
has_ext e p is true iff get_ext p = e || get_ext ~multi:true p = e. If e doesn't start with a '.' one is prefixed before making the test. Examples.
val mem_ext : ext list -> t -> bool
mem_ext exts p is List.mem (get_ext p) exts || List.mem (get_ext ~multi:true p) exts.
val exists_ext : ?multi:bool -> t -> bool
exists_ext ~multi p is true iff p's basename file extension is not empty. If multi is true (default to false) returns true iff p has more than one extension. Examples.
val add_ext : ext -> t -> t
add_ext ext p is p with the string ext concatenated to p's basename, if non empty. If ext doesn't start with a '.' one is prefixed to it before concatenation except if ext is "". Examples.
Raises Invalid_argument if Fpath.is_seg ext is false.
val rem_ext : ?multi:bool -> t -> t
rem_ext p is p with the extension of p's basename removed. If multi is true (default to false), the multiple file extension is removed. Examples.
val set_ext : ?multi:bool -> ext -> t -> t
set_ext ?multi ext p is add_ext ext (rem_ext ?multi p).
val split_ext : ?multi:bool -> t -> t * ext
split_ext ?multi p is (rem_ext ?multi p, get_ext ?multi p). If this is (q, ext) the following invariant holds:
val (+) : t -> ext -> t
p + ext is add_ext ext p. Left associative.
val (-+) : t -> ext -> t
p -+ ext is set_ext ext p. Left associative.

Path sets and maps


type path = t 
type set 
The type for path sets. Membership is determined according to Fpath.equal.
module Set: sig .. end
Path sets.
type +'a map 
The type for maps from paths to values of type 'a. Paths are compared with Fpath.compare.
module Map: sig .. end
Path maps.

Tips

Examples

Fpath.add_seg

Fpath.append

Fpath.segs

Fpath.is_dir_path

Fpath.is_file_path

Fpath.to_dir_path

Fpath.filename

Fpath.split_base

Fpath.basename

Fpath.parent

Fpath.rem_empty_seg

Fpath.normalize

Fpath.is_prefix

Fpath.find_prefix

Fpath.rem_prefix

Fpath.relativize

Fpath.is_rooted

Fpath.is_root

Fpath.get_ext

Fpath.has_ext

Fpath.exists_ext

Fpath.add_ext

Fpath.rem_ext