dune/src/env.ml

81 lines
1.6 KiB
OCaml

open Import
module Var = struct
type t = string
let compare =
if Sys.win32 then (
fun a b -> String.compare (String.lowercase a) (String.lowercase b)
) else (
String.compare
)
end
module Map = Map.Make(Var)
type t =
{ vars : string Map.t
; mutable unix : string array option
}
let make vars =
{ vars
; unix = None
}
let empty = make Map.empty
let get t k = Map.find t.vars k
let to_unix t =
match t.unix with
| Some v -> v
| None ->
let res =
Map.foldi ~init:[] ~f:(fun k v acc ->
(sprintf "%s=%s" k v)::acc
) t.vars
|> Array.of_list in
t.unix <- Some res;
res
let of_unix arr =
Array.to_list arr
|> List.map ~f:(fun s ->
match String.lsplit2 s ~on:'=' with
| None ->
Exn.code_error "Env.of_unix: entry without '=' found in the environ"
["var", Sexp.To_sexp.string s]
| Some (k, v) -> (k, v))
|> Map.of_list_multi
|> Map.map ~f:(function
| [] -> assert false
| x::_ -> x)
let initial = make (of_unix (Unix.environment ()))
let add t ~var ~value =
make (Map.add t.vars var value)
let extend t ~vars =
make (Map.union t.vars vars ~f:(fun _ _ v -> Some v))
let extend_env x y =
extend x ~vars:y.vars
let sexp_of_t t =
let open Sexp.To_sexp in
(list (pair string string)) (Map.to_list t.vars)
let diff x y =
Map.merge x.vars y.vars ~f:(fun _k vx vy ->
match vy with
| Some _ -> None
| None -> vx)
|> make
let update t ~var ~f =
make (Map.update t.vars var ~f)
let of_string_map m =
make (String.Map.foldi ~init:Map.empty ~f:(fun k v acc -> Map.add acc k v) m)