Change representation to map from assoc list
This commit is contained in:
parent
161be3af1c
commit
4a68db622d
50
src/env.ml
50
src/env.ml
|
@ -8,25 +8,12 @@ module Var = struct
|
||||||
) else (
|
) else (
|
||||||
String.compare
|
String.compare
|
||||||
)
|
)
|
||||||
|
|
||||||
let equal a b =
|
|
||||||
match compare a b with
|
|
||||||
| Ordering.Eq -> true
|
|
||||||
| _ -> false
|
|
||||||
|
|
||||||
let hash =
|
|
||||||
if Sys.win32 then
|
|
||||||
fun x -> Hashtbl.hash (String.lowercase x)
|
|
||||||
else
|
|
||||||
Hashtbl.hash
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Map = Map.Make(Var)
|
module Map = Map.Make(Var)
|
||||||
|
|
||||||
module Table = Hashtbl.Make(Var)
|
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
{ vars : (Var.t * string) list
|
{ vars : string Map.t
|
||||||
; mutable unix : string array option
|
; mutable unix : string array option
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,24 +22,16 @@ let make vars =
|
||||||
; unix = None
|
; unix = None
|
||||||
}
|
}
|
||||||
|
|
||||||
let get t k =
|
let get t k = Map.find t.vars k
|
||||||
List.find_map t.vars ~f:(fun (k', v) -> Option.some_if (Var.equal k k') v)
|
|
||||||
|
|
||||||
let to_unix t =
|
let to_unix t =
|
||||||
match t.unix with
|
match t.unix with
|
||||||
| Some v -> v
|
| Some v -> v
|
||||||
| None ->
|
| None ->
|
||||||
let res =
|
let res =
|
||||||
let seen = Table.create 16 in
|
Map.foldi ~init:[] ~f:(fun k v acc ->
|
||||||
t.vars
|
(sprintf "%s=%s" k v)::acc
|
||||||
|> List.fold_left ~init:[] ~f:(fun uniques (k, v) ->
|
) t.vars
|
||||||
if Table.mem seen k then (
|
|
||||||
uniques
|
|
||||||
) else (
|
|
||||||
Table.add seen ~key:k ~data:();
|
|
||||||
(k, v) :: uniques
|
|
||||||
))
|
|
||||||
|> List.rev_map ~f:(fun (k, v) -> sprintf "%s=%s" k v)
|
|
||||||
|> Array.of_list in
|
|> Array.of_list in
|
||||||
t.unix <- Some res;
|
t.unix <- Some res;
|
||||||
res
|
res
|
||||||
|
@ -61,8 +40,11 @@ let of_unix arr =
|
||||||
Array.to_list arr
|
Array.to_list arr
|
||||||
|> List.map ~f:(fun s ->
|
|> List.map ~f:(fun s ->
|
||||||
match String.lsplit2 s ~on:'=' with
|
match String.lsplit2 s ~on:'=' with
|
||||||
| None -> (s, "")
|
| None ->
|
||||||
|
Sexp.code_error "Env.of_unix doesn't support env vars without '='"
|
||||||
|
["var", Sexp.To_sexp.string s]
|
||||||
| Some (k, v) -> (k, v))
|
| Some (k, v) -> (k, v))
|
||||||
|
|> Map.of_list_exn
|
||||||
|
|
||||||
let initial =
|
let initial =
|
||||||
let i =
|
let i =
|
||||||
|
@ -74,24 +56,18 @@ let initial =
|
||||||
fun () -> Lazy.force i
|
fun () -> Lazy.force i
|
||||||
|
|
||||||
let add t ~var ~value =
|
let add t ~var ~value =
|
||||||
{ vars = (var, value) :: t.vars
|
make (Map.add t.vars var value)
|
||||||
; unix = None
|
|
||||||
}
|
|
||||||
|
|
||||||
let extend t ~vars =
|
let extend t ~vars =
|
||||||
{ vars = Map.foldi ~init:t.vars ~f:(fun k v t -> (k, v) :: t) vars
|
make (Map.union t.vars vars ~f:(fun _ _ v -> Some v))
|
||||||
; unix = None
|
|
||||||
}
|
|
||||||
|
|
||||||
let sexp_of_t t =
|
let sexp_of_t t =
|
||||||
let open Sexp.To_sexp in
|
let open Sexp.To_sexp in
|
||||||
(list (pair string string)) t.vars
|
(list (pair string string)) (Map.to_list t.vars)
|
||||||
|
|
||||||
let diff x y =
|
let diff x y =
|
||||||
let to_map b = Map.of_list_reduce b ~f:(fun old _new -> old) in
|
Map.merge x.vars y.vars ~f:(fun _k vx vy ->
|
||||||
Map.merge (to_map x.vars) (to_map y.vars) ~f:(fun _k vx vy ->
|
|
||||||
match vy with
|
match vy with
|
||||||
| Some _ -> None
|
| Some _ -> None
|
||||||
| None -> vx)
|
| None -> vx)
|
||||||
|> Map.to_list
|
|
||||||
|> make
|
|> make
|
||||||
|
|
Loading…
Reference in New Issue