48 lines
1.7 KiB
OCaml
48 lines
1.7 KiB
OCaml
(* libtool version format: current[:revision[:age]]
|
|
https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html *)
|
|
open Syntax
|
|
|
|
type t = {
|
|
(* The most recent interface number that this library implements *)
|
|
current: int;
|
|
(* The implementation number of the current interface *)
|
|
revision: int option;
|
|
(* The difference between the newest and oldest interfaces that this library implements *)
|
|
age: int option;
|
|
}
|
|
|
|
let is_compatible ~implementation v =
|
|
v.current <= implementation.current
|
|
&& implementation.current - Option.value ~default:0 implementation.age
|
|
<= v.current
|
|
|
|
let of_string s =
|
|
let error = Fmt.error "string does not match a libtool version format" in
|
|
let to_int s =
|
|
match int_of_string_opt s with
|
|
| None -> error
|
|
| Some i -> if i < 0 then error else Ok i
|
|
in
|
|
let* l = String.split_on_char ':' s |> Syntax.list_map to_int in
|
|
match l with
|
|
| [] -> Fmt.failwith "not possible"
|
|
| [ current ] -> Ok { current; revision= None; age= None }
|
|
| [ current; revision ] -> Ok { current; revision= Some revision; age= None }
|
|
| [ current; revision; age ] ->
|
|
Ok { current; revision= Some revision; age= Some age }
|
|
| _ -> error
|
|
|
|
let pp ppf v =
|
|
match v with
|
|
| { current; revision= None; age= None } -> Fmt.pf ppf "%d" current
|
|
| { current; revision= Some revision; age= None } ->
|
|
Fmt.pf ppf "%d:%d" current revision
|
|
| { current; revision= Some revision; age= Some age } ->
|
|
Fmt.pf ppf "%d:%d:%d" current revision age
|
|
| _ -> Fmt.failwith "corrupt version data: has age with no revision"
|
|
|
|
let jsont =
|
|
Jsont.of_of_string ~kind:"libtool version" of_string ~enc:(Fmt.str "%a" pp)
|
|
|
|
let mte_protocol_version =
|
|
"31:0:0" |> of_string |> function Error e -> Fmt.failwith "%s" e | Ok v -> v
|