summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2021-06-22 15:28:57 +0700
committerGitHub <noreply@github.com>2021-06-22 15:28:57 +0700
commit538fe55830e7effe61663c208fa021403360fff8 (patch)
tree666a7d674bce10a7db7a7eec083667f17f113c13
parented9a41190997d4a46c1e8efd21ac06aeb0965965 (diff)
parent9b593c24700a3e0e0b37fa3cf4161f305a9c7ccb (diff)
downloadvyos-utils-538fe55830e7effe61663c208fa021403360fff8.tar.gz
vyos-utils-538fe55830e7effe61663c208fa021403360fff8.zip
Merge pull request #1 from jestabro/T3574
T3574: add support for --grp argument
-rw-r--r--src/validate_value.ml82
1 files changed, 70 insertions, 12 deletions
diff --git a/src/validate_value.ml b/src/validate_value.ml
index 0b4148f..32d34de 100644
--- a/src/validate_value.ml
+++ b/src/validate_value.ml
@@ -1,7 +1,16 @@
-type check = Regex of string | Exec of string
+type argopt = RegexOpt of string | ExecOpt of string | GroupSeparator
+type check = Regex of string | Exec of string | Group of check list
-let validate_value buf value_constraint value =
+let options = ref []
+let checks = ref []
+let value = ref ""
+
+let buf = Buffer.create 4096
+
+let rec validate_value buf value_constraint value =
match value_constraint with
+ | 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)
@@ -22,27 +31,76 @@ let validate_value buf value_constraint value =
let () = Buffer.add_string buf out; Buffer.add_string buf "\n" in
false
-let value = ref ""
-
-let checks = 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");
+ ("--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 _ =
- let buf = Buffer.create 4096 in
+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 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 =
+ read_options ();
let value = !value in
let checks = !checks in
match checks with
- | [] -> exit 0
+ | [] -> false
| _ ->
- List.iter (fun c -> if (validate_value buf c value) then exit 0 else ()) checks;
+ List.exists (fun c -> validate_value buf c value) checks
+
+let _ =
+ if validate then exit 0 else
(* If we got this far, value validation failed.
Show the user output from the validators.
*)