You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
1.9 KiB

(*
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
open PolyVariantEqual
module F = Format
module L = Logging
let multilink_file_name = "multilink.txt"
type t = string String.Table.t
let add multilinks fname = String.Table.set multilinks ~key:(Filename.basename fname) ~data:fname
let create () : t = String.Table.create ~size:1 ()
(* Cache of multilinks files read from disk *)
let multilink_files_cache = String.Table.create ~size:1 ()
let reset_cache () = String.Table.clear multilink_files_cache
let read ~dir : t option =
let multilink_fname = Filename.concat dir multilink_file_name in
match Utils.read_file multilink_fname with
| Error _ ->
None
| Ok lines ->
let links = create () in
List.iter
~f:(fun line -> String.Table.set links ~key:(Filename.basename line) ~data:line)
lines ;
String.Table.set multilink_files_cache ~key:dir ~data:links ;
Some links
(* Write a multilink file in the given directory *)
let write multilinks ~dir =
let fname = Filename.concat dir multilink_file_name in
let outc = Out_channel.create fname in
String.Table.iteri
~f:(fun ~key:_ ~data:src -> Out_channel.output_string outc (src ^ "\n"))
multilinks ;
Out_channel.close outc
let lookup ~dir =
try Some (String.Table.find_exn multilink_files_cache dir) with
| Not_found_s _ | Caml.Not_found ->
read ~dir
let resolve fname =
let fname_s = DB.filename_to_string fname in
if Sys.file_exists fname_s = `Yes then fname
else
let base = Filename.basename fname_s in
let dir = Filename.dirname fname_s in
match lookup ~dir with
| None ->
fname
| Some links ->
try DB.filename_from_string (String.Table.find_exn links base) with
| Not_found_s _ | Caml.Not_found ->
fname