diff options
| author | Chimrod <> | 2023-11-04 17:16:16 +0100 | 
|---|---|---|
| committer | Chimrod <> | 2023-11-04 17:16:16 +0100 | 
| commit | 6ada3862d96f82e44b3b19dd84d08cbb8c6a6006 (patch) | |
| tree | e2fa4e223c4ce0f3945af76f9e82e887b307a95b | |
| parent | 673da2554d3e667e0a62d5c7bbf30999f1295dc1 (diff) | |
Allow test to be enabled or disabled by command line
| -rw-r--r-- | bin/args.ml | 49 | ||||
| -rw-r--r-- | bin/args.mli | 5 | ||||
| -rw-r--r-- | bin/qsp_parser.ml | 46 | ||||
| -rw-r--r-- | lib/syntax/S.ml | 6 | ||||
| -rw-r--r-- | lib/syntax/check.ml | 1 | ||||
| -rw-r--r-- | lib/syntax/dead_end.ml | 1 | ||||
| -rw-r--r-- | lib/syntax/nested_strings.ml | 1 | ||||
| -rw-r--r-- | lib/syntax/tree.ml | 1 | ||||
| -rw-r--r-- | lib/syntax/type_of.ml | 1 | 
9 files changed, 93 insertions, 18 deletions
| diff --git a/bin/args.ml b/bin/args.ml index 0021b34..a98981c 100644 --- a/bin/args.ml +++ b/bin/args.ml @@ -1,3 +1,4 @@ +open StdLabels  module Report = Qsp_syntax.Report  let input_files = ref [] @@ -23,7 +24,25 @@ let level : string -> unit =        print_endline e;        exit 1 -let speclist printer = +let disable_module modules identifier = +  let identifier = +    String.sub identifier ~pos:1 ~len:(String.length identifier - 1) +  in +  List.iter modules ~f:(fun t -> +      let (module C : Qsp_syntax.S.Analyzer) = Qsp_syntax.Check.get_module t in +      if String.equal C.identifier identifier then C.active := false) + +let enable_module modules identifier = +  let identifier = +    String.sub identifier ~pos:1 ~len:(String.length identifier - 1) +  in +  List.iter modules ~f:(fun t -> +      let (module C : Qsp_syntax.S.Analyzer) = Qsp_syntax.Check.get_module t in +      if String.equal C.identifier identifier then C.active := true) + +let speclist modules printer = +  ignore modules; +    let common_arguments =      [        ( "--version", @@ -45,6 +64,8 @@ let speclist printer =          Arg.Set reset_line,          "\tEach line is refered from the begining of the file and not the \           location" ); +      ("-<test>", Arg.String anon_fun, "\tDisable this test"); +      ("+<test>", Arg.Unit (fun () -> ()), "\tEnable this test");      ]    and windows_arguments =      match Sys.os_type with @@ -54,9 +75,29 @@ let speclist printer =    in    common_arguments @ windows_arguments -let parse : list_tests:(Format.formatter -> unit) -> string list * t = - fun ~list_tests -> -  let speclist = speclist list_tests in +let parse : +    modules:Qsp_syntax.Check.t list -> +    list_tests:(Format.formatter -> unit) -> +    string list * t = + fun ~modules ~list_tests -> +  let speclist = speclist modules list_tests in +  let speclist = +    let r = ref speclist in +    for i = 1 to pred (Array.length Sys.argv) do +      let s = Sys.argv.(i) in +      if +        s.[0] = '-' +        && not (List.exists !r ~f:(fun (s', _, _) -> String.equal s s')) +      then +        r := +          ( s, +            Arg.Unit (fun () -> disable_module modules s), +            "\tDisable this test" ) +          :: !r +      else if s.[0] = '+' then enable_module modules s +    done; +    !r +  in    let () = Arg.parse (Arg.align speclist) anon_fun usage in    match !input_files with diff --git a/bin/args.mli b/bin/args.mli index cffd0d0..fb15542 100644 --- a/bin/args.mli +++ b/bin/args.mli @@ -3,4 +3,7 @@ type filters = { level : Qsp_syntax.Report.level option }  type t = { reset_line : bool; filters : filters }  (** All the arguments given from the command line *) -val parse : list_tests:(Format.formatter -> unit) -> string list * t +val parse : +  modules:Qsp_syntax.Check.t list -> +  list_tests:(Format.formatter -> unit) -> +  string list * t diff --git a/bin/qsp_parser.ml b/bin/qsp_parser.ml index db07c82..1b2b90c 100644 --- a/bin/qsp_parser.ml +++ b/bin/qsp_parser.ml @@ -18,32 +18,40 @@ type ctx = { error_nb : int; warn_nb : int; debug_nb : int }      List all the controls to apply    *)  let available_checks = -  [| +  [      snd @@ Qsp_syntax.Check.build (module Qsp_syntax.Type_of);      snd @@ Qsp_syntax.Check.build (module Qsp_syntax.Dead_end);      snd @@ Qsp_syntax.Check.build (module Qsp_syntax.Nested_strings); -  |] +  ] -let pp_print_module formatter (module A : Qsp_syntax.S.Analyzer) = +let pp_module formatter (module A : Qsp_syntax.S.Analyzer) =    Format.fprintf formatter "%s" A.identifier;    Format.pp_print_tab formatter (); +  (match !A.active with +  | true -> Format.fprintf formatter "*" +  | false -> Format.fprintf formatter " "); +  Format.pp_print_tab formatter ();    Format.fprintf formatter "%s" A.description;    () -let pp_print_modules formatter = +(** Print all the available modules *) +let pp_modules formatter =    let max_length = -    Array.fold_left available_checks ~init:0 ~f:(fun l v -> +    List.fold_left available_checks ~init:0 ~f:(fun l v ->          let (module A : Qsp_syntax.S.Analyzer) =            Qsp_syntax.Check.get_module v          in          max l (String.length A.identifier))    in -  let ll = Array.to_list available_checks in    Format.pp_open_tbox formatter (); -  (* Print the name, left justified, with enougth spaces for the identifier *) +  (* Print the name, left justified, with enought spaces for the all the +     identifiers *)    Format.fprintf formatter "%-*s" (max_length + 1) "Name"; +  (* Tab delimiter *) +  Format.pp_set_tab formatter (); +  Format.fprintf formatter "Active ";    Format.pp_set_tab formatter ();    Format.fprintf formatter "Description@\n"; @@ -51,21 +59,31 @@ let pp_print_modules formatter =      (Format.pp_print_list         (fun f v ->           let m = Qsp_syntax.Check.get_module v in -         pp_print_module f m) +         pp_module f m)         ~pp_sep:(fun f () -> Format.pp_force_newline f ())) -    ll; +    available_checks;    Format.pp_close_tbox formatter ();    Format.pp_print_break formatter 0 0 -module Check = Qsp_syntax.Check.Make (struct -  let t = available_checks -end) +let checkers : (module Qsp_syntax.S.Analyzer) Lazy.t = +  lazy +    (let module Check = Qsp_syntax.Check.Make (struct +       let t = +         List.filter available_checks ~f:(fun v -> +             let (module A : Qsp_syntax.S.Analyzer) = +               Qsp_syntax.Check.get_module v +             in +             !A.active) +         |> Array.of_list +     end) in +    (module Check))  (** Read the source file until getting a report (the whole location has been      read properly), or until the first syntax error.       *)  let parse_location : ctx:ctx -> Qparser.Lexbuf.t -> Args.filters -> ctx =   fun ~ctx lexbuf filters -> +  let (module Check) = Lazy.force checkers in    let result =      Qparser.Analyzer.parse (module Check) lexbuf      |> Result.map (fun (_, f) -> @@ -96,7 +114,9 @@ let parse_location : ctx:ctx -> Qparser.Lexbuf.t -> Args.filters -> ctx =  let default_ctx = { error_nb = 0; warn_nb = 0; debug_nb = 0 }  let () = -  let file_names, parameters = Args.parse ~list_tests:pp_print_modules in +  let file_names, parameters = +    Args.parse ~modules:available_checks ~list_tests:pp_modules +  in    let file_name = List.hd file_names in    let ic = Stdlib.open_in_bin file_name in diff --git a/lib/syntax/S.ml b/lib/syntax/S.ml index a961738..afb6526 100644 --- a/lib/syntax/S.ml +++ b/lib/syntax/S.ml @@ -104,7 +104,13 @@ end  module type Analyzer = sig    val identifier : string +  (** Identifier for the module *) +    val description : string +  (** Short description*) + +  val active : bool ref +  (** Is the test active or not *)    module Expression : Expression    module Instruction : Instruction with type expression = Expression.t' diff --git a/lib/syntax/check.ml b/lib/syntax/check.ml index 59eaaf1..c5dfe74 100644 --- a/lib/syntax/check.ml +++ b/lib/syntax/check.ml @@ -110,6 +110,7 @@ end  module Make (A : App) = struct    let identifier = "main_checker"    let description = "Internal module" +  let active = ref false    (* Global variable for the whole module *)    let len = Array.length A.t diff --git a/lib/syntax/dead_end.ml b/lib/syntax/dead_end.ml index bb56b2f..98c361e 100644 --- a/lib/syntax/dead_end.ml +++ b/lib/syntax/dead_end.ml @@ -2,6 +2,7 @@ open StdLabels  let identifier = "dead_end"  let description = "Check for dead end in the code" +let active = ref false  module Expression = struct    type t = unit diff --git a/lib/syntax/nested_strings.ml b/lib/syntax/nested_strings.ml index 37f352c..16ec4ac 100644 --- a/lib/syntax/nested_strings.ml +++ b/lib/syntax/nested_strings.ml @@ -2,6 +2,7 @@ open StdLabels  let identifier = "escaped_string"  let description = "Check for unnecessary use of expression encoded in string" +let active = ref true  module Expression : S.Expression with type t' = Report.t list = struct    type t = Report.t list diff --git a/lib/syntax/tree.ml b/lib/syntax/tree.ml index 8444fd9..6f99bbd 100644 --- a/lib/syntax/tree.ml +++ b/lib/syntax/tree.ml @@ -2,6 +2,7 @@ open StdLabels  let identifier = "tree"  let description = "Build the AST" +let active = ref true  module Ast = struct    type 'a literal = 'a T.literal = Text of string | Expression of 'a list diff --git a/lib/syntax/type_of.ml b/lib/syntax/type_of.ml index 224e029..223633c 100644 --- a/lib/syntax/type_of.ml +++ b/lib/syntax/type_of.ml @@ -2,6 +2,7 @@ open StdLabels  let identifier = "type_check"  let description = "Ensure all the expression are correctly typed" +let active = ref true  module Helper = struct    type type_of = | 
