module Kwfile:sig..end
These don't do I/O in general, but include functions that read
directories and perform stats.
Author(s): Keith Waclena
val filesplit : ?sep:string -> string -> string listfilesplit ?sep fn: split a filename into its components
Filename.dirname and Filename.basename have all sorts of wild
boundary conditions!
This is "supposedly" better than a string split on "/" because we
get a. automatic normalization and b. portability across different
pathseps
sep : the path separator (default: Filename.dir_sep)fn : the filenameval join : string -> string -> stringjoin dir file returns a file name that designates file file in directory dir.
This is what Filename.concat does, but that function is more literal
than I want it to be, e.g. Filename.concat "." "/etc/motd"
returns ".//etc/motd", which I think is weird; join "."
"/etc/motd" instead returns "/etc/motd".
Returns "joined" filename
dir : directory pathnameval extsplit : string -> string * string optionextsplit path splits a file path into two parts by separating the extension (if any).
Returns a pair, the fst of which is the path with the extension
removed, and the snd of which is the extension as a string option.
Returns the pair, front part and optional extension
path : a pathnameval extjoin : string * string option -> stringextjoin path joins an optional extension onto a file path; the dual of Kwfile.extsplit.
So, p = extjoin (extsplit p). Useful for changing an extension:
# Kwfile.extsplit "foo.xml" |> (id &&& k (Some "jpg")) |> extjoin;;
\- : string = "foo.jpg"
# Kwfile.extsplit "foo.xml" |> (id &&& k None) |> extjoin;;
\- : string = "foo"
#
pair : a pathname and extension option, as returned by Kwfile.extsplitval extension : string -> stringextension file returns the file's extension, without the '.'
if no extension, return ""val squiggle : ?respect_env:bool -> string -> string"HOME" env var is respected unless ~respect_env is falserespect_env : respect (i.e. trust) the value of env dir "HOME"? (default: true)fn : file nameval (~~) : ?respect_env:bool -> string -> string
val makesafe : string -> stringmakesafe path returns a "safe" version of the pathname (intended for web applications).
"Safe" means all instances of ".", ".." and any leading "/"'s
are eliminated. "Safe" does not mean that any shell
metacharacters are eliminated! This function assumes you will be
using system calls on the resulting "safe" pathname, not passing
it to a shell.
find(1).val mkdirs : ?mode:Unix.file_perm -> string -> unitmkdirs ?mode path: make all the directories in path (including parent directories, as needed).
Like the shell's mkdir -p. No error if any of the directories exist.
mode : the mode of newly-created directoriespath : the path of the new directoryval fold_dir : ('a -> string -> 'a) -> 'a -> string -> 'afold_dir f init dir: fold over the files in a directory (not recursive).
Tail-recursive. Applies f acc fn to each file in dir (excluding . and ..);
sub-directories are not recursed into.
f : function f acc filename to apply to each filedir : the directory (or file, even) to fold overval fold : ?follow:bool ->
?err:(int -> 'a -> string -> exn -> 'a) ->
(int -> 'a -> string -> 'a) -> 'a -> string -> 'afold ?follow ?err f acc dir: fold over a directory hierarchy (recursive).
NOT tail-recursive in depth of tree, but is tail-recursive in
breadth of any given sub-directory.
follow : whether to descend into symlinked sub-directories (default: false, as per find(1))err : alternate function err depth acc filename exn called (instead of f) if there's an
exception exn associated with stat'ing or opendir'ing dir (default: re-raise exn)f : function f depth acc filename to apply to each fileacc : the accumulatordir : the directory (or file, even) to fold overKwfile.fold.
Examples:
fold (igndepth (flip cons)) [] "."
fold (maxdepth 2 (flip cons)) [] "."
val igndepth : 'a -> 'b -> 'aigndepth f: makes a function that's suitable for List.fold_left suitable for Kwfile.fold by
ignoring the depth parameter.
Use this if you don't care about how deep you are when you process a file.
val maxdepth : 'a -> ('b -> 'c -> 'b) -> 'a -> 'b -> 'c -> 'bmaxdepth n f: converts a function that's suitable for List.fold_left into a function
suitable for Kwfile.fold that's only applied to files up to a maximum depth of n.val pred : ('a -> 'b -> bool) -> ('a -> 'c -> 'b -> 'c) -> 'a -> 'c -> 'b -> 'cpred p f: converts a function that's suitable for Kwfile.fold into one that that's only
applied if p depth filename returns true.val ignexn : ('a -> 'b -> 'c -> 'd) -> 'a -> 'b -> 'c -> 'e -> 'dignexn f: makes function that's suitable for Kwfile.fold's f parameter suitable for
its ~err parameter by ignoring the exception.
Use this if you want to process un-stat-able files the same way as stat-able ones. For example, to simply count all files in a directory hierarchy, do:
let count _ a _ = a+1 in fold ~err:(ignexn count) count 0
module Find:sig..end
val glob : ?pred:(string -> bool) ->
(string -> string -> string -> 'a) -> string -> 'a listKwfile.fold_dir.glob ?pred map dir: return list of results of
applying map to each file in a directory
NOT tail-recursive.
Returns list of "mapped" results of all matching files
pred : predicate (string -> bool) on a filename (default: (fun x -> true))map : function (string -> string -> string -> 'a) to apply to each filename in result list; saves you a List.map over the result; parameters are directoryname, basename, and full path (i.e. (Filename.concat directoryname basename))dir : directory to processval isemptydir : string -> boolpath (presumed a directory) an empty directory?
This is faster (and uses less space) than
0 = List.length (glob (fun _ _ _ -> ()) path)
if the directory contains a lot of files.
Raises Unix.Unix_error (Unix.ENOTDIR, "opendir", ...) if path not a directory
Returns bool
path : path to a directoryval isfile : string -> boolboolf : filenameval isdirectory : string -> boolboolf : filenameval ischaracter : string -> boolboolf : filenameval isblock : string -> boolboolf : filenameval islink : string -> boolboolf : filenameval isfifo : string -> boolboolf : filenameval issocket : string -> boolboolf : filenameval access : string -> Unix.access_permission list -> boolbool range and no exceptionsboolf : filenameperms : Unix.access_permission listval isreadable : string -> boolboolf : filenameval iswriteable : string -> boolboolf : filenameval isexecutable : string -> boolboolf : filenameval isexefile : string -> boolboolf : filenameval exists : string -> boolboolf : filenameval which : string -> string listPATH
Lookup a (potential) executable name in (Sys.getenv "$PATH") and
return all the candidates found, in PATH order.
Returns list of (basename,fullpath) pairs for each executable found
sought : name of the executable in questiontype tempfile = {
|
filename : |
|
chan : |
val temp_file_name : ?tmpdir:string -> string -> string -> stringtemp_file_name ?tmpdir prefix suffix: return a random filenametmpdir : directory in which to make tmpfile (default: value of TMPDIR env var, else /tmp)prefix : temp filename prefixsuffix : temp filename suffixval open_temp_file : ?tmpdir:string ->
?mode:Pervasives.open_flag list ->
?perm:int -> string -> string -> string * Pervasives.out_channel(filename,out_channel)tmpdir : directory in which to make tmpfile (default: value of TMPDIR env var, else /tmp)mode : list of open modesperm : file permissions (default: 0o600)prefix : temp filename prefixsuffix : temp filename suffixval tempfiles : ?n:int ->
?tmpdir:string ->
string -> string list -> (string, tempfile) Hashtbl.ttempfile's
Example:
let t = Kwfile.tempfiles "myself" ["foo"; "bar"] in
Printf.fprintf (Hashtbl.find t "foo").Kwfile.chan "foo stuff";
Printf.fprintf (Hashtbl.find t "bar").Kwfile.chan "bar stuff";
Hashtbl.iter (fun _ {Kwfile.chan=c} -> close_out c) t;
Hashtbl.iter (fun _ {Kwfile.filename=f} -> Sys.remove f) t;
n : initial size of hash table (default: 2)tmpdir : directory in which to make tmpfileprefix : string to prefix to each temp file name, typically something like (Filename.basename Sys.argv(0))handles : list of tempfile "handles" (strings)val with_temp_file : ?remove:(string -> unit) ->
?tmpdir:string -> string -> string -> (string -> 'a) -> 'awith_temp_file ?remove ?tmpdir prefix suffix f: call f tmp where tmp is a newly-created
temp file, making sure to remove the temp file after the evaluation of f.
If you want to examine the temp file for debugging purposes, you can use e..g.
with_temp_file ~remove:ignore or to see the name of the temp file, something like:
with_temp_file ~remove:(fun fn -> prerr_endline fn; Sys.remove fn).
If it's possible that f might not create the temp file, and you want to avoid a
Sys_error "No such file or directory" exception, you can use e.g.
with_temp_file ~remove:(ignex Sys.remove).
remove : function to remove the temp file (default: Sys.remove)tmpdir : directory in which to make tmpfile (default: value of TMPDIR env var, else /tmp)prefix : temp filename prefixsuffix : temp filename suffixf : the function