default_re | Some r -> (r, Str.regexp r) ?> . (* The above call to list_files occurs in the first stage, but it produces code to be executed in the second stage. The first stage stats all the files and computes MD5 sums. The second stage filters according to the regular expression, passed to list_files as code. The definition of list_files appears later in this script. *) ?> "name" (* default sort order *) | Some o -> o in (* Sorting occurs entirely in the second stage. The function sort_by is also defined later in this script. *) let list = sort_by ord list in ?>
files matching ordered by

 puts f.prn) list ?>
List.stable_sort cmp_ext list | "kind" -> List.stable_sort cmp_kind list | "time" -> List.stable_sort cmp_mtime list | "size" -> List.stable_sort cmp_size list | _ -> list (* already sorted by name *) (* The following format string is used to generate the prn field of each entry. The column headings are defined similarly. *) let entry_fmt = format_of_string "%-32s %-13s %5s \ \ %s%s\n" let header = sprintf "%-32s %-13s %-5s %s\n" "checksum" "last modified" "size" "name" (* Generate `human-readable' sizes *) let human_size n = if n < 1024 then sprintf "%4d " n else if n < 102400 then sprintf "%4.1fk" (float_of_int n/.1024.) else if n < 1024000 then sprintf "%4dk" (n/1024) else if n < 104857600 then sprintf "%4.1fM" (float_of_int n/.1048576.) else sprintf "%4dM" (n/1048576) (* Generate kind and symbol (like `ls --F') from filename extension and/or file permissions. *) let reg_kinds ext perm = let k = match ext with | "a" -> "lib" | "cma" -> "lib" | "cmi" -> "obj" | "cmo" -> "obj" | "ml" -> "src" | "sml" -> "src" | "mli" -> "hdr" | "sig" -> "hdr" | _ -> "" in let i = if perm land 0o111 = 0 then "" else "*" in match (k,i) with | ("", "*") -> ("exe", "*") | other -> other (* Gather all the info for file `f' in directory `d'. *) let fileinfo d f = let path = Filename.concat d f in let st = stat path in let md5 = (*if st.st_kind = S_REG then Digest.to_hex (Digest.file path) else*) "" in let ext = try let i = String.rindex f '.' + 1 in Str.string_after f i with Not_found -> "" in let (kind, indicator) = match st.st_kind with | S_DIR -> ("dir", "/") | S_FIFO -> ("fifo", "|") | S_BLK -> ("bdev", "") | S_CHR -> ("cdev", "") | S_LNK -> ("link", "@") | S_SOCK -> ("sock", "=") | S_REG -> reg_kinds ext st.st_perm in let prn = sprintf entry_fmt md5 (TimeStamp.brief st.st_mtime) (human_size st.st_size) f kind f indicator in {name=f; ext=ext; kind=kind; md5=md5; mtime=st.st_mtime; size=st.st_size; prn=prn} (* List filenames, in reverse alphabetical order *) let cmp x y = - (compare x y) let rec read_all dh files = try read_all dh (readdir dh :: files) with End_of_file -> closedir dh; List.sort cmp files (* Walk through all the files and gather their information, then generate code to filter based on filename. *) let list_files d re = let rec loop term files = match files with [] -> term | name::files -> . .~term in .~(loop .. files)>. in loop .<[]>. (read_all (opendir d) []) (* Generate code to print the option tags, adding the `selected' attribute as appropriate. *) let rec ord_options puts ord opts = match opts with [] -> .<()>. | (tag,text)::opts -> .<(kprintf .~puts "\n" (if .~ord = tag then "selected" else "") tag text; .~(ord_options puts ord opts))>. (* End of `dir.meta' *) ?>