diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/validate_value.ml | 99 | 
1 files changed, 61 insertions, 38 deletions
| diff --git a/src/validate_value.ml b/src/validate_value.ml index 6d52618..32d34de 100644 --- a/src/validate_value.ml +++ b/src/validate_value.ml @@ -1,30 +1,16 @@ -type check = Regex of string | Exec of string | Grp | Faux +type argopt = RegexOpt of string | ExecOpt of string | GroupSeparator +type check = Regex of string | Exec of string | Group of check list +let options = ref []  let checks = ref [] +let value = ref "" -let find_next_grp n l = -  let rec aux i = function -    | [] -> List.length l -    | h::t -> -      if i > n && h = Grp then i -      else aux (i+1) t -  in aux 0 l - -let get_next_range = -  let n = ref (-1) in -  let f () = -    let i = !n and j = (n := find_next_grp !n !checks; !n) in -    (i, j) in -  f +let buf = Buffer.create 4096  let rec validate_value buf value_constraint value =    match value_constraint with -  | Faux -> false -  | Grp -> -    let (k, j) = get_next_range () in -    let in_grp i = if i > k && i < j then true else false in -    let conj_checks = List.filteri (fun i _ -> in_grp i) !checks in -    List.fold_left (&&) true (List.map (fun e -> validate_value buf e value) conj_checks) +  | Group l -> +    List.for_all (fun c -> validate_value buf c value) l    | Regex s ->      (try let _ = Pcre.exec ~pat:s value in true       with Not_found -> false) @@ -45,36 +31,73 @@ let rec validate_value buf value_constraint value =        let () = Buffer.add_string buf out; Buffer.add_string buf "\n" in        false -let value = ref "" -  let args = [ -  ("--regex", Arg.String (fun s -> checks := (Regex s) :: !checks), "Check the value against a regex"); -  ("--exec", Arg.String (fun s -> checks := (Exec s) :: !checks), "Check the value against an external command"); -  ("--grp", Arg.Unit (fun () -> checks := (Grp) :: !checks), "Group following arguments, joining results with logical and"); +  ("--regex", Arg.String (fun s -> options := (RegexOpt s) :: !options), "Check the value against a regex"); +  ("--exec", Arg.String (fun s -> options := (ExecOpt s) :: !options), "Check the value against an external command"); +  ("--grp", Arg.Unit (fun () -> options := (GroupSeparator) :: !options), "Group following arguments, combining results with logical and");    ("--value", Arg.String (fun s -> value := s), "Value to check");  ]  let usage = Printf.sprintf "Usage: %s [OPTIONS] <number>" Sys.argv.(0)  let () = Arg.parse args (fun _ -> ()) usage -let buf = Buffer.create 4096 +let find_next_group n l = +  let rec aux i = function +    | [] -> List.length l +    | h::t -> +      if i > n && h = GroupSeparator then i +      else aux (i+1) t +  in aux 0 l + +let get_next_range = +  let n = ref (-1) in +  let f () = +    let i = !n and j = (n := find_next_group !n !options; !n) in +    (i, j) in +  f + +let option_to_check opt = +  match opt with +  | RegexOpt s -> Regex s +  | ExecOpt s -> Exec s +  | GroupSeparator -> raise (Invalid_argument "GroupSeparator in isolation has no corresponding check") + +let read_initial_options j = +  if j > 0 then +    let initial_options = List.filteri (fun i _ -> i < j) !options in +    ignore (List.map (fun c -> checks := (option_to_check c) :: !checks) initial_options); () +  else () + +let read_group_options i j = +  if i < j then +    let group_options = List.filteri (fun k _ -> i < k && k < j) !options in +    let l = List.map (fun c -> option_to_check c) group_options in +    checks := (Group l) :: !checks; () +  else () + +let read_options () = +  options := List.rev(!options); + +  let (_, j) = get_next_range () in +  read_initial_options j; -let mask l = -  let (k, j) = get_next_range () in -  let imask i e = -    match e with -    | Grp -> Grp -    | _ -> if i >= k && i <= j then e else Faux in -  List.mapi (fun i e -> imask i e) l +  let quit_loop = ref false in +  while not !quit_loop do +    let i, j = get_next_range () in +    if i < j then +      read_group_options i j +    else +      quit_loop := true +  done  let validate = -  checks := List.rev(!checks); +  read_options ();    let value = !value in -  let disj_checks = mask !checks in -  match disj_checks with +  let checks = !checks in +  match checks with    | [] -> false    | _ -> -    List.fold_left (||) false (List.map (fun c -> validate_value buf c value) disj_checks) +    List.exists (fun c -> validate_value buf c value) checks  let _ =    if validate then exit 0 else | 
