default_re | Some r -> (r, Str.regexp r) ?> "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 -> (let list = try ignore(Str.search_forward re name 0); ((fileinfo d name)) :: term with Not_found -> term in (loop (list) 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))) ?>