package goblint
Static analysis framework for C
Install
Dune Dependency
Authors
Maintainers
Sources
goblint-2.5.0.tbz
sha256=452d8491527aea21f2cbb11defcc14ba0daf9fdb6bdb9fc0af73e56eac57b916
sha512=1993cd45c4c7fe124ca6e157f07d17ec50fab5611b270a434ed1b7fb2910aa85a8e6eaaa77dad770430710aafb2f6d676c774dd33942d921f23e2f9854486551
doc/src/goblint.library/libraryDsl.ml.html
Source file libraryDsl.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
open LibraryDesc module Access = LibraryDesc.Access (* avoid spurious dependency cycle due to ocamldep overapprox ambiguity between Access and LibraryDesc.Access *) (** First-class patterns for arguments matching. @see <https://github.com/ocaml-ppx/ppxlib/blob/main/src/ast_pattern.ml> for inspiration from ppxlib. *) module Pattern = struct (** @param a Type of value to match. @param k Type of continuation function. @param r Return type of match. *) type ('a, 'k, 'r) t = 'a -> 'k -> 'r exception Expected of string let fail s = raise (Expected s) let __: _ t = fun x k -> k x let drop: _ t = fun _ k -> k let nil: _ t = fun x k -> match x with | [] -> k | _ -> fail "Library function is called with more arguments than expected." let ( ^:: ) (p1: _ t) (p2: _ t): _ t = fun x k -> match x with | x1 :: x2 -> let k = p1 x1 k in let k = p2 x2 k in k | [] -> fail "^::" end type access = | Access of LibraryDesc.Access.t | If of (unit -> bool) * access let rec eval_access = function | Access acc -> Some acc | If (p, access) -> if p () then eval_access access else None type ('k, 'l, 'r) arg_desc = { accesses: access list; match_arg: (Cil.exp, 'k, 'r) Pattern.t; match_var_args: (Cil.exp list, 'l, 'r) Pattern.t; } type ('k, 'r) args_desc = | []: ('r, 'r) args_desc | VarArgs: (_, 'l, 'r) arg_desc -> ('l, 'r) args_desc | (::): ('k, _, 'm) arg_desc * ('m, 'r) args_desc -> ('k, 'r) args_desc let rec match_args: type k r. (k, r) args_desc -> (Cil.exp list, k, r) Pattern.t = function | [] -> Pattern.nil | VarArgs {match_var_args; _} -> match_var_args | {match_arg; _} :: args -> Pattern.(match_arg ^:: match_args args) let rec accs: type k r. (k, r) args_desc -> Accesses.t = fun args_desc args -> match args_desc, args with | [], [] -> [] | VarArgs arg_desc, args -> List.filter_map (fun access -> match eval_access access with | Some acc -> Some (acc, args) | None -> None ) arg_desc.accesses | arg_desc :: args_desc, arg :: args -> let accs'' = accs args_desc args in List.fold_left (fun (accs'': (Access.t * Cil.exp list) list) (access: access) -> match eval_access access with | Some acc -> begin match List.assoc_opt acc accs'' with | Some args -> (acc, arg :: args) :: List.remove_assoc acc accs'' | None -> (acc, [arg]) :: accs'' end | None -> accs'' ) accs'' arg_desc.accesses | _, _ -> invalid_arg "accs" let special ?(attrs:attr list=[]) args_desc special_cont = { special = Fun.flip (match_args args_desc) special_cont; accs = accs args_desc; attrs; } let special' ?(attrs:attr list=[]) args_desc special_cont = { special = (fun args -> Fun.flip (match_args args_desc) (special_cont ()) args); (* eta-expanded such that special_cont is re-executed on each call instead of once during LibraryFunctions construction *) accs = accs args_desc; attrs; } let unknown ?attrs args_desc = special ?attrs args_desc Unknown let empty____desc = { match_arg = Pattern.(__); match_var_args = Pattern.(__); accesses = []; } let __ (_name: string) accesses = { empty____desc with accesses; } let __' accesses = { empty____desc with accesses; } let empty_drop_desc = { match_arg = Pattern.drop; match_var_args = Pattern.drop; accesses = []; } let drop (_name: string) accesses = { empty_drop_desc with accesses; } let drop' accesses = { empty_drop_desc with accesses; } let r = Access { kind = Read; deep = false; } let r_deep = Access { kind = Read; deep = true; } let w = Access { kind = Write; deep = false; } let w_deep = Access { kind = Write; deep = true; } let f = Access { kind = Free; deep = false; } let f_deep = Access { kind = Free; deep = true; } let s = Access { kind = Spawn; deep = false; } let s_deep = Access { kind = Spawn; deep = true; } let c = Access { kind = Spawn; deep = false; } (* TODO: Sound, but very imprecise hack for calls to function pointers given as arguments. *) let c_deep = Access { kind = Spawn; deep = true; } let if_ p access = If (p, access)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>