More.FpathFile paths.
A file path is a syntactic specification of a file or a directory location in a file system hierarchy. It is made of three parts:
"C:", or "//volume"). In general unless otherwise noted the operations in the module preserve the volume of paths."/a" versus "a")."a/b/" versus "a/b"). But a directory can also be specified by a file path and a syntactic directory path may not be a directory (e.g. a symlink).The paths 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 (e.g. on "/" or "..").
Platform dependence. When the documentation talks about POSIX it means every platform out there but Windows.
natural_dir_sep_char is the natural directory separator for the platform. This is '\\' if Sys.win32 and '/' otherwise.
Warning. Do not test for equality against this character to assert directory separators. Use is_dir_sep_char, some platforms support more than one directory separator.
natural_dir_sep is natural_dir_sep_char as a string.
Warning. Do not test for equality against this string to assert directory separators. Use is_dir_sep, some platforms support more than one directory separator.
is_dir_sep_char c is true iff c is a directory separator on the platform. This means c is '/' or it is '\\' and Sys.win32 is true.
is_dir_sep s is true if s is a singelton string and is_dir_sep_char s.[0] is true.
val v : string -> tv s is the string s as a file path. Raises Invalid_argument if s is not a valid path. Use of_string to deal with untrusted input.
Warning. In code only use "/" in string literals as the directory separator even on Windows platforms (don't be upset, the module gives them back to you with backslashes).
val fmt : ('a, Stdlib.Format.formatter, unit, t) Stdlib.format4 -> 'afmt … is Fmt.kstr v ….
append p q appends q to p as follows:
q is absolute or has a non-empty volume then q is returned.q's segments to p using append_segment.val null : tnull represents a file on the OS that discards all writes and returns end of file on reads. This is NUL if Sys.win32 is true and /dev/null otherwise. See also is_null.
val is_null : t -> boolis_null p is equal p null.
val dash : tdash is "-". This value is used in command line interfaces to denote standard input or output. See also is_dash.
val is_dash : t -> boolis_dash p is equal p dash.
Warning. It's generaly not a good idea to assume there is a single current or parent directory, use is_current_dir or is_parent_dir to test them. On Windows each volume maintains its own current directory.
val is_current_dir : t -> boolis_current_dir p is true if p is either "." or "./".
val is_parent_dir : t -> boolis_parent_dir p is true if p is either ".." or "../".
Warning. Do not assume there is a single root path and that this root is /, use is_root to test for root paths. For example on Windows every volume has a root.
val is_root : t -> boolis_root p is true iff p is a root directory, i.e. p has the root directory separator and a single, empty, segment.
drop_root_sep p is p without is root directory separator. If p is a root, the resulting path is ".". The result is guaranted to be relative, the volume is kept on Windows, not on POSIX (as the path would remain absolute).
ensure_root_sep p is p prefixed by a root directory separator unless it already has one. The result is guaranteed to be absolute and the volume of p is preserved. If p is_current_dir then only the root is kept in the result.
This is equivalent to Fpath.(root_of p // p).
cut_volume p is vol, q with:
vol the platform dependent volume of p or "" if there is none and q. On POSIX the volume is taken to be the first segment if the path starts with two //. The interpretation of that segment is implementation dependent.q the path of p without its volume. On POSIX if p has the form "//[^/]*" the resulting path is the root /val take_volume : t -> stringtake_volume p is fst (split_volume p).
set_volume s p is p whose volume is changed or added to s. Raises Invalid_argument if is_segment s is false.
is_segment s is true iff s does not contain a null byte or a directory separator as asserted by is_dir_sep_char.
append_segment p seg is:
p with the last segment replaced by seg, if the last segment is empty.p with segment seg added, otherwiseThis errors if is_segment seg is false. FIXME error format.
val take_last_segment : t -> stringtake_last_segment p is the last segment of p, this is "" on syntactic directory paths or is_root paths. See also basename.
drop_last_segment p is p without it's last segment. This is p on is_root and "." on singleton paths. See also parent and syntactic directory paths.
cut_last_segment p is (drop_last_segment p, take_last_segement p).
p / seg is append_segment p seg |> Result.get_ok'. Left associative. Warning. Use append_segment to deal with untrusted seg values.
val to_segments : t -> string listto_segments p is p's non-empty list of segments. Absolute paths have an empty string in the front, this allows to recover the path's string with String.concat natural_dir_sep, note however that you may have lost the volume along the way. Also if you want to convert to an URL path rather use to_url_path.
val of_segments : ?volume:string -> string list -> tof_segments segs is a path from the given list of segments. Absolute paths are represented with an empty string in the front, see to_segments. The root is represented by ["";""]. volume if non-empty is used as the volume of the path, note that on POSIX this turns a relative list of segments into an absolute one. Spurious empty segments are dropped, except for the last one.
Note. The following functions use syntactic semantic properties of paths. Given a path, these properties can be different from the ones your file system attributes to it.
val basename : ?drop_exts:bool -> t -> stringbasename p is the last non-empty segment of p or the empty string otherwise. The latter occurs only on root paths and on paths whose last non-empty segment is a relative segment. If drop_exts is true (default to false) the basename's multiple extension, if any, is removed from the segment.
basepath is like basename but returns a file path with the result or "." if the result is empty which can be detected by is_current_dir.
parent p is a directory path that contains p. If p is a root path this is p itself. If p is in the current directory this is ".".
The file extension (resp. multiple file extensions) 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 a single one.
TODO In the fpath package we correct e.g. has_ext if the given ext has no ext. I think we should either check and raise Invalid_argument or correct.
val exists_ext : t -> boolexists_ext p is true iff p has a file or multiple file extension.
val exists_multi_ext : t -> boolexists_multi_ext p is true iff p has a multiple file extension.
has_ext ext p is true iff String.equal (take_ext n multi:false p) e || String.equal (take_ext ~multi:true p) e.
take_ext ~multi p is the file extension or multiple file extension if multi is true of the basename of p.
The empty string is returned if there is no extension. By definition this operates on the directory name of directory paths, not on the final empty segment.
drop_ext multi p is p with the extension of p's basename removed. If multi is true (defaults to false), the multiple file extension is removed.
append_ext ext p is p with ext concatenated to p's basename.
Note. ext is not required to start with a . it can be used for arbitrary basename extension.
with_ext ~multi ext p is append_ext ext (drop_ext ~multi p).
p + ext is append_ext p ext. Left associative.
val is_syntactic_dir : t -> boolis_syntactic_dir p is true iff p syntactically represents a directory. This means that p is ".", ".." or ends with "/", "/." or "/..".
Note. This a syntactic check, the file system may attribute different properties to these paths.
ensure_trailing_dir_sep p is add_segment p "". This ensures that p has a final empty segment and thus a trailing directory separator when converted to a string.
drop_trailing_dir_sep p ensures p has no final empty segment unless p is a root path. When p is not a root path this ensure that p has no trailing directory separator when converted to a string.
strictly_start_with ~prefix p is true iff p starts with prefix but is not prefix itself regardless of directoryness. Otherwise said if prefix is a strict prefix of p that respects path segments.
More formally the invocation returns true iff the following two conditions hold:
not Fpath.(equal (to_dir_path prefix) (to_dir_path p))Fpath.(String.starts_with ~prefix:(to_string (to_dir_path prefix) (to_string p))) is trueWarning. By definition stricty_starts_with ~prefix:p p is false. Note also that the prefix relation does not entail directory containement; for example stricly_starts_with ~prefix:(v "..") (v "../..") holds. It holds however if you Os.Path.realpath the paths.
drop_strict_prefix prefix p is:
None if strictly_starts_with ~prefix p is false.Some q otherwise where q is p without the string prefix Fpath.to_dir_path prefix. This means that q is always relative, that it preserves p's syntactic directoryness and that Fpath.(equal (prefix // q) p) holds.Warning. By definition strip_strict_prefix p p is None.
remove_strictly_prefixed ps is ps without elements that have a strict prefixes in ps. Basically if a path p strictly prefixes another in ps, only p is kept. The list order is preserved. Duplicates are not removed, use distinct for this.
reroot ~src_root ~dst_root p assumes src_root strictly prefixes p removes the prefix and prepends dst_root to the result.
Raises Invalid_argument if dst_root is not a strict prefix of src. In particular note that p cannot be src_root.
relative ~to_dir p is q such that to_dir // q represents the same path as p. Note that q is not necessarily relative: if to_dir is relative and p is absolute p is returned.
Warning. This function is mostly broken at the moment.
Raises Invalid_argument if path to_dir contains "..".
val is_relative : t -> boolis_relative p is true iff p is a relative path, i.e. the root directory separator is missing in p.
val is_absolute : t -> boolis_absolute p is true iff p is an absolute path, i.e. the root directory separator is present in p.
equal_basename p0 p1 is String.equal (basename p0) (basename p1).
type path = tmodule Set : sig ... endPath sets.
module Map : sig ... endPath maps.
sort_by_parent ps maps elements of ps by their Fpath.parent.
val sort_by_ext : multi:bool -> Set.t -> Set.t String.Map.tsort_by_ext ~multi ps maps elements of ps by their extension as determined by Fpath.take_ext ~multi.
A search path is a list of paths separated by a designated separator in which elements are looked up in left to right priority order. A well known search path is PATH in which executable binaries are looked up.
search_path_sep is the default platform specific separator for search paths. This is ";" if Sys.win32 and ":" otherwise.
val list_of_search_path :
?sep:string ->
string ->
(t list, string) Stdlib.resultlist_of_search_path ~sep s splits s on sep (defaults to search_path_sep) and parses the result with of_string, ignoring empty strings.
This means that sep is not allowed to appear in the file paths, consecutive sep are ignored and the order in the resulting list matches the left-to-right order of paths in s.
If one of_string errors on a path p with e the function errors with the message:
Fmt.str "Illegal path %a in search path: %s" pp p eval of_string : string -> (t, string) Stdlib.resultof_string s is the string s as a path. The following transformations are performed on the string:
0x2F) occurence is converted to \ (0x5C)An error returned if s is "" or if it contains a null byte. The error string mentions s.
val to_string : t -> stringto_string p is the path p as a string. The result can be safely converted back with v.
val to_url_path : ?escape_space:bool -> t -> stringto_url_path ~escape_space p is the path p as an URL path. This is p with the directory separator replaced by '/' and with the following characters percent encoded: '%', '?', '#', ' ' (if escape_space is true, default), and the US-ASCII control characters.
If Sys.win32 is true and p has a drive a '/' is prepended to the result.
Note. In 2019, the standard definition of URLs is in a sorry state. Assuming p is UTF-8 encoded. It is believed the above function should lead to an URL path component that can be parsed by HTML5's definition of URL parsing.
pp ppf p prints path p on ppf. The path is quoted with Filename.quote if needed. For now this means if it contains spaces (U+0020).
val error :
t ->
('b, Stdlib.Format.formatter, unit, ('a, string) Stdlib.result)
Stdlib.format4 ->
'berror p fmt … is Fmt.error ("%a: " ^^ fmt) pp_unquoted p … .
val prefix_msg : t -> string -> stringprefix_msg p msg is Fmt.str "%a: %s" pp_unquoted msg.