open Printf module CLI = struct type t = { verbose: bool; max_files: int; dir_to_list: string; sort_order: [`alpha | `chrono | `owner] option; args: string list; } let default = { verbose=false; max_files=100; dir_to_list="."; sort_order=None; args=[]; } let sort_order_of_string = function | "alpha" -> Some `alpha | "chrono" -> Some `chrono | "owner" -> Some `owner | _ -> None let usage = sprintf {|MyLs2000 is a revolutionary file listing tool Usage: cli [-v] [-n] [-d ] [-s {alpha|chrono|owner}] [--] [args...] Options:|} let parse argv = let t = ref default in let specs = Arg.align Arg.[ "-v", Unit (fun () -> t := {!t with verbose=true}), " Enable verbose mode"; "-n", Int (fun n -> t := {!t with max_files=n}), sprintf " Sets maximum number of files to list (default: %d)" default.max_files; "-d", String (fun s -> t := {!t with dir_to_list=s}), " Names directory to list files"; "-s", Symbol (["alpha"; "chrono"; "owner"], fun s -> t := {!t with sort_order=sort_order_of_string s}), " Allows to sort files alphabetically, chronologically, or by owner"; "--", Rest (fun arg -> t := {!t with args=(!t.args @ [arg])}), " Stop interpreting keywords and print the rest"; ] in let f arg = t := {!t with args=(!t.args @ [arg])} in match Arg.parse_argv argv specs f usage with | () -> !t | exception Arg.Bad message -> eprintf "%s" message; exit 2 | exception Arg.Help message -> printf "%s" message; exit 0 end let main = let result = CLI.parse Sys.argv in match result with { verbose; max_files; dir_to_list; sort_order; args; } -> printf "-v %b\n-n %d\n-d %S\n" verbose max_files dir_to_list; List.iter print_endline args (* Original from https://scylardor.fr/2013/10/14/ocaml-parsing-a-programs-arguments-with-the-arg-module/ let verbose = ref false let max_files_to_list = ref 1 let dir_to_list = ref "." let time_hours = ref 0 let time_minutes = ref 0 let sort_files = function "alpha" -> print_endline "Alpha sort" | "chrono" -> print_endline "Chrono sort" | "owner" -> print_endline "Owner sort" | _ -> raise (Arg.Bad("Shouldn't happen")) let main = begin let speclist = [("-v", Arg.Set verbose, "Enables verbose mode"); ("-n", Arg.Set_int max_files_to_list, "Sets maximum number of files to list"); ("-d", Arg.Set_string dir_to_list, "Names directory to list files"); ("-t", Arg.Tuple ([Arg.Set_int time_hours ; Arg.Set_int time_minutes]), "Sets creation hours and minutes listed files have to match"); ("-s", Arg.Symbol (["alpha"; "chrono"; "owner"], sort_files), " Allows to sort listed files alphabetically, chronologically, or by owner"); ("--", Arg.Rest (fun arg -> print_endline ("The rest contains: " ^ arg)), "Stop interpreting keywords and prints the rest"); ] in let usage_msg = "MyLs2000 is a revolutionary file listing tool. Options available:" in Arg.parse speclist (fun anon -> print_endline ("Anonymous argument: " ^ anon)) usage_msg; print_endline ("Verbose mode: " ^ string_of_bool !verbose); print_endline ("Max files to list: " ^ string_of_int !max_files_to_list); print_endline ("Directory to list files: " ^ !dir_to_list); print_endline ("Time of files to list: " ^ string_of_int(!time_hours) ^ ":" ^ string_of_int(!time_minutes)); end *)