package devkit
Development kit - general purpose library
Install
Dune Dependency
Authors
Maintainers
Sources
devkit-1.20240429.tbz
sha256=222f8ac131b1d970dab7eeb2714bfd6b9338b88b1082e6e01c136ae19e7eaef4
sha512=c9e6d93e3d21e5530c0f4d5baca51bf1f0a5d19248f8af7678d0665bb5cdf295d7aaaaa3e50eb2e44b8720e55097cc675af4dc8ec45acf9da39feb3eae1405d5
doc/src/devkit.core/static_config.ml.html
Source file static_config.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
open Prelude open Printf open ExtLib exception Error of string let fail fmt = ksprintf (fun s -> raise (Error s)) fmt module Label : sig type t = private string val make : string -> t end = struct type t = string let make s = let open Stre.ASCII in if s <> "" && is_alpha s.[0] && (List.for_all (fun c -> c = '_' || is_alnum c) @@ String.explode s) then s else fail "bad label %S" s end let make_value v (show : 'a -> string) (load : string -> 'a) = object val mutable contents = v val mutable dirty = false method get = contents method set y = dirty <- true; contents <- y method show = show contents method load s = dirty <- true; contents <- load s method dirty = dirty method reset = dirty <- false; contents <- v end type any_value = < show : string; load : string -> unit; dirty : bool; reset : unit; > type 'a value = < get : 'a; set : 'a -> unit; dirty : bool; > type group = { label : Label.t; groups : (Label.t, group) Hashtbl.t; values : (Label.t, any_value) Hashtbl.t; parent : group option; } let group_name g = let rec loop acc g = match g.parent with | None -> String.concat "." (List.rev acc) | Some g' -> loop ((g.label :> string) :: acc) g' in loop [] g let value_name g (k:Label.t) = match group_name g with | "" -> (k:>string) | s -> s ^ "." ^ (k:>string) let make_node show load group label (v : 'a) = let label = Label.make label in if Hashtbl.mem group.values label then fail "duplicate label %S" (label :> string); let v = make_value v show load in Hashtbl.replace group.values label (v :> any_value); (v :> 'a value) let int = make_node string_of_int int_of_string let long = make_node Int64.to_string Int64.of_string let string = make_node id id let float = make_node string_of_float float_of_string let bool = make_node string_of_bool (fun s -> match String.lowercase_ascii s with | "false" | "no" -> false | "true" | "yes" -> true | s -> fail "not a boolean : %S" s) let group parent label = let label = Label.make label in match Hashtbl.find_option parent.groups label with | Some x -> x | None -> let group = { label = label; parent = Some parent; groups = Hashtbl.create 1; values = Hashtbl.create 1; } in Hashtbl.add parent.groups label group; group let new_root () = { parent = None; groups = Hashtbl.create 1; values = Hashtbl.create 1; label = Label.make "whatever"; } let rec iter f g = Hashtbl.iter (fun k v -> f (value_name g k) v) g.values; Hashtbl.iter (fun _ g -> iter f g) g.groups let reset = iter (fun _ v -> v#reset) let read root s = reset root; let store k v = let rec loop g = function | [name] -> Hashtbl.find g.values name | x::xs -> loop (Hashtbl.find g.groups x) xs | [] -> fail "bad key %S" k in let o = loop root (List.map Label.make @@ Stre.nsplitc k '.') in o#load v in let store k v = try store k v with (* | Not_found -> prerr_endline (Printf.sprintf "Skipping unknown option : %S = %S" k v) *) | exn -> fail "Failed to store option : %S = %S : %s" k v (Exn.to_string exn) in let io = IO.input_string s in let line = ref 0 in try while true do match Exn.catch IO.read_line io with | None -> raise Exit | Some s -> let s = s ^ "\n" in incr line; try Scanf.sscanf s " #" () with Scanf.Scan_failure _ | End_of_file -> try Scanf.sscanf s " %!" () with Scanf.Scan_failure _ | End_of_file -> try Scanf.sscanf s "%s = %s@\n%!" (fun k v -> store k (String.strip v)) with Scanf.Scan_failure _ | End_of_file -> try Scanf.sscanf s "%s := %c%s@\n%!" (fun k c tail -> let pos = String.index tail c in String.iter (function ' ' | '\t' -> () | _ -> fail "extra characters after %C-delimtied value" c) (String.slice tail ~first:(pos+1)); store k (String.slice tail ~last:pos)) with Scanf.Scan_failure _ | End_of_file -> try Scanf.sscanf s "%s : %d\n%!" (fun k n -> assert (n >= 0); let l = List.init (n+1) (fun _ -> incr line; IO.read_line io) in store k (String.concat "\n" l)) with Scanf.Scan_failure _ | End_of_file -> fail "can't parse line" done with | Exit -> () | exn -> let s = match exn with Failure s -> s | Error s -> s | exn -> Exn.to_string exn in fail "error at line %d : %s" !line s let choose_quote s = let preferred = [ '"'; '\''; '`'; '|'; '!'; '@'; '#'; '%' ] in let ok = Array.make 256 true in String.iter (fun c -> ok.(Char.code c) <- false) s; try Some (List.find (fun c -> ok.(Char.code c)) preferred) with Not_found -> None let show ?(all=false) root = let iter f = iter (fun name v -> if v#dirty || all then f name v#show) in let b = Buffer.create 10 in iter begin fun name v -> match String.fold_left (fun n c -> if c = '\n' then n + 1 else n) 0 v with | 0 -> if Stre.starts_with v " " || Stre.ends_with v " " then begin match choose_quote v with | None -> bprintf b "%s :%d\n%s\n" name 0 v | Some c -> bprintf b "%s := %c%s%c\n" name c v c end else bprintf b "%s = %s\n" name v | n -> bprintf b "%s :%d\n%s\n" name n v end root; Buffer.contents b let load root file = reset root; match Exn.catch Std.input_file file with None -> () | Some s -> read root s let save ?all root file = Files.save_as file (fun ch -> output_string ch (show ?all root)) class base root filename = object initializer load root filename method save () = save root filename method load () = load root filename end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>