package dune-site
Embed locations information inside executable and libraries
Install
Dune Dependency
Authors
Maintainers
Sources
dune-3.19.1.tbz
sha256=a10386f980cda9417d1465466bed50dd2aef9c93b9d06a0f7feeedb0a1541158
sha512=d1622939713133a1f28617229896298d6ef194c48a47d011e4b752490fc83893cc920a8395d7ac60bc384a6c9b233ebf0665f38f74f2774a983e9d3b241a7746
doc/src/dune-site.plugins/plugins.ml.html
Source file plugins.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
open Dune_site.Private_ module Data = Dune_site_plugins_data let meta_fn = "META" let readdir = let ( / ) = Filename.concat in let readdir_noexn dir = try Sys.readdir dir with | Sys_error _ -> [||] in fun dirs -> List.concat (List.map (fun dir -> List.filter (fun entry -> Sys.file_exists (dir / entry / meta_fn)) (Array.to_list (readdir_noexn dir))) dirs) ;; let rec lookup dirs file = match dirs with | [] -> None | dir :: dirs -> let file' = Filename.concat dir file in if Sys.file_exists file' then Some file' else lookup dirs file ;; module type S = sig val paths : string list val list : unit -> string list val load_all : unit -> unit val load : string -> unit end let rec check_predicates predicates = match Sys.backend_type, predicates with | _, [] -> true | Sys.Native, Meta_parser.Pos "byte" :: _ -> false | Sys.Bytecode, Meta_parser.Pos "native" :: _ -> false | Sys.Native, Meta_parser.Pos "native" :: predicates -> check_predicates predicates | Sys.Bytecode, Meta_parser.Pos "byte" :: predicates -> check_predicates predicates | Sys.Native, Meta_parser.Neg "native" :: _ -> false | Sys.Bytecode, Meta_parser.Neg "byte" :: _ -> false | Sys.Native, Meta_parser.Neg "byte" :: predicates -> check_predicates predicates | Sys.Bytecode, Meta_parser.Neg "native" :: predicates -> check_predicates predicates | _, Meta_parser.Pos pred :: predicates -> Data.findlib_predicates_set_by_dune pred && check_predicates predicates | _, Meta_parser.Neg pred :: predicates -> (not (Data.findlib_predicates_set_by_dune pred)) && check_predicates predicates ;; let check_predicates_with_plugin predicates = let rec aux predicates has_plugin acc = match predicates with | [] -> has_plugin && check_predicates acc | Meta_parser.Pos "plugin" :: predicates -> aux predicates true acc | predicate :: predicates -> aux predicates has_plugin (predicate :: acc) in aux predicates false [] ;; let rec get_plugin plugins requires entries = match entries with | [] -> List.rev plugins, List.rev requires | Meta_parser.Comment _ :: entries -> get_plugin plugins requires entries | Package _ :: entries -> get_plugin plugins requires entries | Rule { var = "plugin"; predicates; action = Set; value } :: entries when check_predicates predicates -> get_plugin [ value ] requires entries | Rule { var = "plugin"; predicates; action = Add; value } :: entries when check_predicates predicates -> get_plugin (value :: plugins) requires entries (* archive(native|byte,plugin) is the way used in the wild before findlib supported plugins *) | Rule { var = "archive"; predicates; action = Set; value } :: entries when check_predicates_with_plugin predicates -> get_plugin [ value ] requires entries | Rule { var = "archive"; predicates; action = Add; value } :: entries when check_predicates_with_plugin predicates -> get_plugin (value :: plugins) requires entries | Rule { var = "requires"; predicates; action = Set; value } :: entries when check_predicates predicates -> get_plugin plugins [ value ] entries | Rule { var = "requires"; predicates; action = Add; value } :: entries when check_predicates predicates -> get_plugin plugins (value :: requires) entries | Rule _ :: entries -> get_plugin plugins requires entries ;; exception Thread_library_required_by_plugin_but_not_required_by_main_executable exception Library_not_found of { search_paths : string list ; prefix : string list ; name : string } exception Plugin_not_found of { search_paths : string list ; name : string } let () = Printexc.register_printer (function | Thread_library_required_by_plugin_but_not_required_by_main_executable -> Some (Format.asprintf "%a" Format.pp_print_text "It is not possible to dynamically link a plugin which uses the thread \ library with an executable not already linked with the thread library.") | Plugin_not_found { search_paths; name } -> Some (Format.sprintf "The plugin %S can't be found in the search paths %S." name (String.concat ":" search_paths)) | Library_not_found { search_paths; prefix = []; name } -> Some (Format.sprintf "The library %S can't be found in the search paths %S." name (String.concat ":" search_paths)) | Library_not_found { search_paths; prefix; name } -> Some (Format.sprintf "The sub-library %S can't be found in the library %s in the search paths %S." name (String.concat "." prefix) (String.concat ":" search_paths)) | _ -> None) ;; let rec find_library ~dirs ~prefix ~suffix directory meta = let rec find_directory directory = function | [] -> directory | Meta_parser.Rule { var = "directory"; predicates = []; action = Set; value } :: _ -> (match directory with | None -> Some value | Some old -> Some (Filename.concat old value)) | _ :: entries -> find_directory directory entries in match suffix with | [] -> find_directory directory meta, meta | pkg :: suffix -> let directory = find_directory directory meta in let rec aux pkg = function | [] -> raise (Library_not_found { search_paths = dirs; prefix = List.rev prefix; name = pkg }) | Meta_parser.Package { name = Some name; entries } :: _ when String.equal name pkg -> find_library ~dirs ~prefix:(pkg :: prefix) ~suffix directory entries | _ :: entries -> aux pkg entries in aux pkg meta ;; let extract_words s ~is_word_char = let rec skip_blanks i = if i = String.length s then [] else if is_word_char s.[i] then parse_word i (i + 1) else skip_blanks (i + 1) and parse_word i j = if j = String.length s then [ StringLabels.sub s ~pos:i ~len:(j - i) ] else if is_word_char s.[j] then parse_word i (j + 1) else StringLabels.sub s ~pos:i ~len:(j - i) :: skip_blanks (j + 1) in skip_blanks 0 ;; let extract_comma_space_separated_words s = extract_words s ~is_word_char:(function | ',' | ' ' | '\t' | '\n' -> false | _ -> true) ;; let split_all l = List.concat (List.map extract_comma_space_separated_words l) let find_plugin ~dirs ~dir ~suffix (meta : Meta_parser.t) = let directory, meta = find_library ~dirs ~prefix:(Option.to_list meta.name) ~suffix None meta.entries in let plugins, requires = get_plugin [] [] meta in let directory = match directory with | None -> dir | Some pkg_dir -> if pkg_dir.[0] = '+' || pkg_dir.[0] = '^' then Filename.concat (Lazy.force Helpers.stdlib) (String.sub pkg_dir 1 (String.length pkg_dir - 1)) else if Filename.is_relative pkg_dir then Filename.concat dir pkg_dir else pkg_dir in let plugins = split_all plugins in let requires = split_all requires in directory, plugins, requires ;; let load file ~pkg = let entries = let ic = open_in file in try let lb = Lexing.from_channel ic in lb.lex_curr_p <- { pos_fname = file; pos_lnum = 1; pos_bol = 0; pos_cnum = 0 }; let r = Meta_parser.Parse.entries lb 0 [] in close_in ic; r with | exn -> close_in ic; raise exn in { Meta_parser.name = Some pkg; entries } ;; let lookup_and_load_one_dir ~dir ~pkg = let meta_file = Filename.concat dir meta_fn in if Sys.file_exists meta_file then Some (load meta_file ~pkg) else ( (* Alternative layout *) let dir = Filename.dirname dir in let meta_file = Filename.concat dir (meta_fn ^ "." ^ pkg) in if Sys.file_exists meta_file then Some (load meta_file ~pkg) else None) ;; let split ~dirs name = match String.split_on_char '.' name with | [] -> raise (Library_not_found { search_paths = dirs; prefix = []; name }) | pkg :: rest -> pkg, rest ;; let lookup_and_summarize alldirs name = let pkg, suffix = split ~dirs:alldirs name in let rec loop dirs = match dirs with | [] -> List.assoc_opt pkg Data.builtin_library |> (function | None -> raise (Library_not_found { search_paths = alldirs; prefix = []; name }) | Some meta -> find_plugin ~dirs:alldirs ~dir:(Lazy.force Helpers.stdlib) ~suffix meta) | dir :: dirs -> let dir = Filename.concat dir pkg in (match lookup_and_load_one_dir ~dir ~pkg with | None -> loop dirs | Some p -> find_plugin ~dirs:alldirs ~dir ~suffix p) in loop alldirs ;; let loaded_libraries = lazy (let h = Hashtbl.create 10 in List.iter (fun s -> Hashtbl.add h s ()) Data.already_linked_libraries; h) ;; let load_gen ~load_requires dirs name = let loaded_libraries = Lazy.force loaded_libraries in if not (Hashtbl.mem loaded_libraries name) then ( if name = "threads" then raise Thread_library_required_by_plugin_but_not_required_by_main_executable; Hashtbl.add loaded_libraries name (); let directory, plugins, requires = lookup_and_summarize dirs name in List.iter load_requires requires; List.iter (fun p -> let file = Filename.concat directory p in Dune_site_backend.Linker.load file) plugins) ;; let rec load_requires name = load_gen ~load_requires (Lazy.force Helpers.ocamlpath) name let load_plugin plugin_paths name = match lookup plugin_paths (Filename.concat name meta_fn) with | None -> raise (Plugin_not_found { search_paths = plugin_paths; name }) | Some meta_file -> let meta = load meta_file ~pkg:name in let plugins, requires = get_plugin [] [] meta.entries in assert (plugins = []); let requires = split_all requires in List.iter load_requires requires ;; module Make (X : sig val paths : string list end) : S = struct include X let list () = List.sort String.compare (readdir paths) let load name = load_plugin paths name let load_all () = List.iter load (list ()) end let load = load_requires let available name = Hashtbl.mem (Lazy.force loaded_libraries) name || let ocamlpath = Lazy.force Helpers.ocamlpath in try ignore (lookup_and_summarize ocamlpath name); true with | _ -> (* CR - What exceptions are being swallowed here? *) false ;;
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>