Skip to content

Instantly share code, notes, and snippets.

@keleshev
Last active November 25, 2020 22:27
Show Gist options
  • Select an option

  • Save keleshev/2f1e86dd47c3ec45b979d4757dae3dde to your computer and use it in GitHub Desktop.

Select an option

Save keleshev/2f1e86dd47c3ec45b979d4757dae3dde to your computer and use it in GitHub Desktop.

Revisions

  1. keleshev revised this gist Nov 25, 2020. 1 changed file with 49 additions and 50 deletions.
    99 changes: 49 additions & 50 deletions cli.ml
    Original file line number Diff line number Diff line change
    @@ -1,78 +1,77 @@

    open Printf

    module CLI = struct
    type t = {
    mutable verbose: bool;
    mutable max_files_to_list: int;
    mutable dir_to_list: string;
    mutable time_hours: int;
    mutable time_minutes: int;
    mutable sort_order: [`alpha | `chrono | `owner] option;
    mutable args: string list;
    mutable rest: string list;
    verbose: bool;
    max_files: int;
    dir_to_list: string;
    sort_order: [`alpha | `chrono | `owner] option;
    args: string list;
    }

    let t = {
    let default = {
    verbose=false;
    max_files_to_list=1;
    max_files=100;
    dir_to_list=".";
    time_hours=0;
    time_minutes=0;
    sort_order=None;
    args=[];
    rest=[];
    }

    let dump {
    verbose;
    max_files_to_list;
    dir_to_list;
    time_hours;
    time_minutes;
    sort_order;
    args;
    rest;
    } =
    Printf.printf "=> %b %d %s\n" verbose max_files_to_list dir_to_list

    let sort_order_of_string = function
    | "alpha" -> Some `alpha
    | "chrono" -> Some `chrono
    | "owner" -> Some `owner
    | _ -> None

    let usage =
    "MyLs2000 is a revolutionary file listing tool. Options available:"

    let specs = Arg.[
    "-v", Unit (fun () -> t.verbose <- true),
    "Enable verbose mode";
    "-n", Int (fun n -> t.max_files_to_list <- n),
    "Sets maximum number of files to list";
    "-d", String (fun s -> t.dir_to_list <- s),
    "Names directory to list files";
    "-t", Tuple [Int (fun h -> t.time_hours <- h);
    Int (fun m -> t.time_minutes <- m)],
    "Sets creation hours and minutes listed files have to match";
    "--sort-order", Symbol (["alpha"; "chrono"; "owner"],
    fun s -> t.sort_order <- sort_order_of_string s),
    "Allows to sort files alphabetically, chronologically, or by owner";
    "--", Rest (fun arg -> t.rest <- t.rest @ [arg]),
    "Stop interpreting keywords and print the rest";
    ]

    let () =
    Arg.parse specs (fun arg -> t.args <- t.args @ [arg]) usage;
    let usage = sprintf {|MyLs2000 is a revolutionary file listing tool

    Usage:
    cli [-v] [-n] [-d <dir>] [-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 "<n> Sets maximum number of files to list (default: %d)"
    default.max_files;
    "-d", String (fun s -> t := {!t with dir_to_list=s}),
    "<dir> 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 =
    CLI.dump CLI.t
    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 https://scylardor.fr/2013/10/14/ocaml-parsing-a-programs-arguments-with-the-arg-module/
    (* 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
  2. keleshev created this gist Nov 25, 2020.
    107 changes: 107 additions & 0 deletions cli.ml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,107 @@


    module CLI = struct
    type t = {
    mutable verbose: bool;
    mutable max_files_to_list: int;
    mutable dir_to_list: string;
    mutable time_hours: int;
    mutable time_minutes: int;
    mutable sort_order: [`alpha | `chrono | `owner] option;
    mutable args: string list;
    mutable rest: string list;
    }

    let t = {
    verbose=false;
    max_files_to_list=1;
    dir_to_list=".";
    time_hours=0;
    time_minutes=0;
    sort_order=None;
    args=[];
    rest=[];
    }

    let dump {
    verbose;
    max_files_to_list;
    dir_to_list;
    time_hours;
    time_minutes;
    sort_order;
    args;
    rest;
    } =
    Printf.printf "=> %b %d %s\n" verbose max_files_to_list dir_to_list

    let sort_order_of_string = function
    | "alpha" -> Some `alpha
    | "chrono" -> Some `chrono
    | "owner" -> Some `owner
    | _ -> None

    let usage =
    "MyLs2000 is a revolutionary file listing tool. Options available:"

    let specs = Arg.[
    "-v", Unit (fun () -> t.verbose <- true),
    "Enable verbose mode";
    "-n", Int (fun n -> t.max_files_to_list <- n),
    "Sets maximum number of files to list";
    "-d", String (fun s -> t.dir_to_list <- s),
    "Names directory to list files";
    "-t", Tuple [Int (fun h -> t.time_hours <- h);
    Int (fun m -> t.time_minutes <- m)],
    "Sets creation hours and minutes listed files have to match";
    "--sort-order", Symbol (["alpha"; "chrono"; "owner"],
    fun s -> t.sort_order <- sort_order_of_string s),
    "Allows to sort files alphabetically, chronologically, or by owner";
    "--", Rest (fun arg -> t.rest <- t.rest @ [arg]),
    "Stop interpreting keywords and print the rest";
    ]

    let () =
    Arg.parse specs (fun arg -> t.args <- t.args @ [arg]) usage;
    end


    let main =
    CLI.dump CLI.t




    (* Original 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
    *)