diff options
author | John Estabrook <jestabro@vyos.io> | 2022-06-17 20:30:52 -0500 |
---|---|---|
committer | John Estabrook <jestabro@vyos.io> | 2022-06-17 20:30:52 -0500 |
commit | dbf73551a7f770f763d6286f5080c37cdb15f20c (patch) | |
tree | 485894fce8336d0468486d611fde6e80ebe6cada /src | |
parent | 43e9a47879749d2035c39a08ec422aceac49842e (diff) | |
download | vyos-utils-dbf73551a7f770f763d6286f5080c37cdb15f20c.tar.gz vyos-utils-dbf73551a7f770f763d6286f5080c37cdb15f20c.zip |
numeric: T4467: add support for relative values: +/-N
Add option '--relative' to check that value is of the form '+/-N' for
some numeric N (e.g. +10' or '-30'), interpreted as a relative increment
or decrement, rather than a signed integer/float. This may be combined
with any other option, which will be applied to the value stripped of
the leading modifier.
Testing this extension revealed that negative values are being
interpreted as options, whether quoted or not; to address that, an
Arg.Rest keyword '--' is introduced, which will need to be passed along
with the option in interface definitions using the above. For example:
<validator name="numeric" argument="--relative --"/>
Diffstat (limited to 'src')
-rw-r--r-- | src/numeric.ml | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/numeric.ml b/src/numeric.ml index b296cec..ad3a066 100644 --- a/src/numeric.ml +++ b/src/numeric.ml @@ -3,13 +3,15 @@ type options = { nonnegative: bool; allow_float: bool; ranges: string list; + relative: bool; } let default_opts = { positive = false; nonnegative = false; allow_float = false; - ranges = [] + ranges = []; + relative = false } let opts = ref default_opts @@ -21,6 +23,8 @@ let args = [ ("--positive", Arg.Unit (fun () -> opts := {!opts with positive=true}), "Check if the number is positive (> 0)"); ("--range", Arg.String (fun s -> let optsv = !opts in opts := {optsv with ranges=(s :: optsv.ranges)}), "Check if the number is within a range (inclusive)"); ("--float", Arg.Unit (fun () -> opts := {!opts with allow_float=true}), "Allow floating-point numbers"); + ("--relative", Arg.Unit (fun () -> opts := {!opts with relative=true}), "Allow relative increment/decrement (+/-N)"); + ("--", Arg.Rest (fun s -> number_arg := s), "Interpret next item as an argument"); ] let usage = Printf.sprintf "Usage: %s [OPTIONS] <number>" Sys.argv.(0) @@ -39,6 +43,20 @@ let looks_like_number value = try let _ = Pcre.exec ~pat:"^(\\-?)[0-9]+(\\.[0-9]+)?$" value in true with Not_found -> false +let is_relative value = + try let _ = Pcre.exec ~pat:"^[+-][0-9]+$" value in true + with Not_found -> false + +let number_string_from_relative value = + String.sub value 1 (String.length value - 1) + +let get_relative opts s = + if opts.relative then + if not (is_relative s) then + failwith "Value is not a relative increment/decrement" + else number_string_from_relative s + else s + let number_of_string opts s = if not (looks_like_number s) then Printf.ksprintf failwith "'%s' is not a valid number" s else let n = float_of_string_opt s in @@ -75,7 +93,8 @@ let check_ranges ranges n = let () = try let opts = !opts in - let n = number_of_string opts !number_arg in + let s = get_relative opts !number_arg in + let n = number_of_string opts s in check_nonnegative opts n; check_positive opts n; if opts.ranges <> [] then |