Skip to content
Snippets Groups Projects
Commit 9d8937ca authored by Loïc Correnson's avatar Loïc Correnson
Browse files

[server] optional fields in states

parent f659aeff
No related branches found
No related tags found
No related merge requests found
...@@ -281,13 +281,13 @@ export interface functionsData { ...@@ -281,13 +281,13 @@ export interface functionsData {
/** Signature */ /** Signature */
signature: string; signature: string;
/** Is the function the main entry point */ /** Is the function the main entry point */
main: boolean; main?: boolean;
/** Is the function defined? */ /** Is the function defined? */
defined: boolean; defined?: boolean;
/** Is the function from the Frama-C stdlib? */ /** Is the function from the Frama-C stdlib? */
stdlib: boolean; stdlib?: boolean;
/** Is the function a Frama-C builtin? */ /** Is the function a Frama-C builtin? */
builtin: boolean; builtin?: boolean;
/** Has the function been analyzed by Eva */ /** Has the function been analyzed by Eva */
eva_analyzed?: boolean; eva_analyzed?: boolean;
} }
...@@ -299,10 +299,10 @@ export const jFunctionsData: Json.Loose<functionsData> = ...@@ -299,10 +299,10 @@ export const jFunctionsData: Json.Loose<functionsData> =
'#functions expected'), '#functions expected'),
name: Json.jFail(Json.jString,'String expected'), name: Json.jFail(Json.jString,'String expected'),
signature: Json.jFail(Json.jString,'String expected'), signature: Json.jFail(Json.jString,'String expected'),
main: Json.jFail(Json.jBoolean,'Boolean expected'), main: Json.jBoolean,
defined: Json.jFail(Json.jBoolean,'Boolean expected'), defined: Json.jBoolean,
stdlib: Json.jFail(Json.jBoolean,'Boolean expected'), stdlib: Json.jBoolean,
builtin: Json.jFail(Json.jBoolean,'Boolean expected'), builtin: Json.jBoolean,
eva_analyzed: Json.jBoolean, eva_analyzed: Json.jBoolean,
}); });
...@@ -314,15 +314,15 @@ export const jFunctionsDataSafe: Json.Safe<functionsData> = ...@@ -314,15 +314,15 @@ export const jFunctionsDataSafe: Json.Safe<functionsData> =
export const byFunctionsData: Compare.Order<functionsData> = export const byFunctionsData: Compare.Order<functionsData> =
Compare.byFields Compare.byFields
<{ key: Json.key<'#functions'>, name: string, signature: string, <{ key: Json.key<'#functions'>, name: string, signature: string,
main: boolean, defined: boolean, stdlib: boolean, builtin: boolean, main?: boolean, defined?: boolean, stdlib?: boolean,
eva_analyzed?: boolean }>({ builtin?: boolean, eva_analyzed?: boolean }>({
key: Compare.string, key: Compare.string,
name: Compare.alpha, name: Compare.alpha,
signature: Compare.string, signature: Compare.string,
main: Compare.boolean, main: Compare.defined(Compare.boolean),
defined: Compare.boolean, defined: Compare.defined(Compare.boolean),
stdlib: Compare.boolean, stdlib: Compare.defined(Compare.boolean),
builtin: Compare.boolean, builtin: Compare.defined(Compare.boolean),
eva_analyzed: Compare.defined(Compare.boolean), eva_analyzed: Compare.defined(Compare.boolean),
}); });
......
...@@ -371,8 +371,8 @@ struct ...@@ -371,8 +371,8 @@ struct
Cil.hasAttribute "fc_stdlib" vi.vattr || Cil.hasAttribute "fc_stdlib" vi.vattr ||
Cil.hasAttribute "fc_stdlib_generated" vi.vattr Cil.hasAttribute "fc_stdlib_generated" vi.vattr
let is_analyzed kf = let is_eva_analyzed kf =
if Db.Value.is_computed () then Some (!Db.Value.is_called kf) else None if Db.Value.is_computed () then !Db.Value.is_called kf else false
let iter f = let iter f =
Globals.Functions.iter Globals.Functions.iter
...@@ -397,27 +397,32 @@ struct ...@@ -397,27 +397,32 @@ struct
~name:"main" ~name:"main"
~descr:(Md.plain "Is the function the main entry point") ~descr:(Md.plain "Is the function the main entry point")
~data:(module Data.Jbool) ~data:(module Data.Jbool)
~default:false
~get:Kernel_function.is_entry_point; ~get:Kernel_function.is_entry_point;
States.column model States.column model
~name:"defined" ~name:"defined"
~descr:(Md.plain "Is the function defined?") ~descr:(Md.plain "Is the function defined?")
~data:(module Data.Jbool) ~data:(module Data.Jbool)
~default:false
~get:Kernel_function.is_definition; ~get:Kernel_function.is_definition;
States.column model States.column model
~name:"stdlib" ~name:"stdlib"
~descr:(Md.plain "Is the function from the Frama-C stdlib?") ~descr:(Md.plain "Is the function from the Frama-C stdlib?")
~data:(module Data.Jbool) ~data:(module Data.Jbool)
~default:false
~get:is_stdlib; ~get:is_stdlib;
States.column model States.column model
~name:"builtin" ~name:"builtin"
~descr:(Md.plain "Is the function a Frama-C builtin?") ~descr:(Md.plain "Is the function a Frama-C builtin?")
~data:(module Data.Jbool) ~data:(module Data.Jbool)
~default:false
~get:is_builtin; ~get:is_builtin;
States.column model States.column model
~name:"eva_analyzed" ~name:"eva_analyzed"
~descr:(Md.plain "Has the function been analyzed by Eva") ~descr:(Md.plain "Has the function been analyzed by Eva")
~data:(module Data.Joption (Data.Jbool)) ~data:(module Data.Jbool)
~get:is_analyzed; ~default:false
~get:is_eva_analyzed;
States.register_array model States.register_array model
~package ~key ~package ~key
~name:"functions" ~name:"functions"
......
...@@ -92,23 +92,55 @@ let register_state (type a) ~package ~name ~descr ...@@ -92,23 +92,55 @@ let register_state (type a) ~package ~name ~descr
(* --- Model Signature --- *) (* --- Model Signature --- *)
(* -------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------- *)
type 'a column = Package.fieldInfo * ('a -> json) type 'a column = Package.fieldInfo * ('a -> json option)
type 'a model = 'a column list ref type 'a model = 'a column list ref
let model () = ref [] let model () = ref []
let mkfield (model : 'a model) fd (js : 'a -> json option) =
let open Package in
let name = fd.fd_name in
if List.exists (fun (fd,_) -> fd.fd_name = name) !model then
raise (Invalid_argument "Server.States.column: duplicate name") ;
model := (fd , js) :: !model
let column (type a b) ~name ~descr let column (type a b) ~name ~descr
~(data: b Request.output) ~(get : a -> b) (model : a model) = ~(data: b Request.output)
~(get : a -> b)
?(default: b option)
(model : a model) =
let module D = (val data) in
match default with
| None ->
let fd = Package.{
fd_name = name ;
fd_type = D.jtype ;
fd_descr = descr ;
} in
mkfield model fd (fun a -> Some (D.to_json (get a)))
| Some d ->
let fd = Package.{
fd_name = name ;
fd_type = Joption D.jtype ;
fd_descr = descr ;
} in
mkfield model fd (fun a ->
let v = get a in
if v = d then None else Some (D.to_json v)
)
let option (type a b) ~name ~descr
~(data: b Request.output) ~(get : a -> b option) (model : a model) =
let module D = (val data) in let module D = (val data) in
if List.exists (fun (fd,_) -> fd.Package.fd_name = name) !model then
raise (Invalid_argument "Server.States.column: duplicate name") ;
let fd = Package.{ let fd = Package.{
fd_name = name ; fd_name = name ;
fd_type = D.jtype ; fd_type = Joption D.jtype ;
fd_descr = descr ; fd_descr = descr ;
} in } in
model := (fd , fun a -> D.to_json (get a)) :: !model mkfield model fd (fun a -> match get a with
| None -> None
| Some b -> Some (D.to_json b))
module Kmap = Map.Make(String) module Kmap = Map.Make(String)
...@@ -127,7 +159,7 @@ type 'a array = { ...@@ -127,7 +159,7 @@ type 'a array = {
fkey : string ; fkey : string ;
key : 'a -> string ; key : 'a -> string ;
iter : ('a -> unit) -> unit ; iter : ('a -> unit) -> unit ;
getter : (string * ('a -> json)) list ; getter : (string * ('a -> json option)) list ;
(* [LC+JS] (* [LC+JS]
The two following fields allow to keep an array in sync The two following fields allow to keep an array in sync
with the current project and still have a polymorphic data type. *) with the current project and still have a polymorphic data type. *)
...@@ -206,8 +238,9 @@ type buffer = { ...@@ -206,8 +238,9 @@ type buffer = {
let add_entry buffer cols fkey key v = let add_entry buffer cols fkey key v =
let fjs = List.fold_left (fun fjs (fd,to_json) -> let fjs = List.fold_left (fun fjs (fd,to_json) ->
try (fd , to_json v) :: fjs match to_json v with
with Not_found -> fjs | Some js -> (fd , js) :: fjs
| None | exception Not_found -> fjs
) [] cols in ) [] cols in
let row = (fkey, `String key) :: fjs in let row = (fkey, `String key) :: fjs in
buffer.updated <- `Assoc row :: buffer.updated ; buffer.updated <- `Assoc row :: buffer.updated ;
...@@ -267,7 +300,7 @@ let register_array ~package ~name ~descr ~key ...@@ -267,7 +300,7 @@ let register_array ~package ~name ~descr ~key
?(add_update_hook : 'a callback option) ?(add_update_hook : 'a callback option)
?(add_remove_hook : 'a callback option) ?(add_remove_hook : 'a callback option)
?(add_reload_hook : unit callback option) ?(add_reload_hook : unit callback option)
model = (model : 'a model) =
let open Markdown in let open Markdown in
let href = link ~name () in let href = link ~name () in
let columns = List.rev !model in let columns = List.rev !model in
......
...@@ -76,12 +76,23 @@ type 'a model (** Columns array model *) ...@@ -76,12 +76,23 @@ type 'a model (** Columns array model *)
val model : unit -> 'a model val model : unit -> 'a model
(** Populate an array model with a new field. (** Populate an array model with a new field.
Columns with name `"id"` and `"_index"` are reserved for internal use. *) If a [~default] value is given, the field becomes optional and
the field is omitted when equal to the default value (compared with [=]).
*)
val column : val column :
name:string -> name:string ->
descr:Markdown.text -> descr:Markdown.text ->
data:('b Request.output) -> data:('b Request.output) ->
get:('a -> 'b) -> get:('a -> 'b) ->
?default:'b ->
'a model -> unit
(** Populate an array model with a new optional field. *)
val option :
name:string ->
descr:Markdown.text ->
data:('b Request.output) ->
get:('a -> 'b option) ->
'a model -> unit 'a model -> unit
(** Synchronized array state. *) (** Synchronized array state. *)
......
...@@ -7,19 +7,13 @@ ...@@ -7,19 +7,13 @@
"key": "kf#24", "key": "kf#24",
"name": "g", "name": "g",
"signature": "int g(int y);", "signature": "int g(int y);",
"defined": true, "defined": true
"stdlib": false,
"builtin": false,
"eva_analyzed": null
}, },
{ {
"key": "kf#20", "key": "kf#20",
"name": "f", "name": "f",
"signature": "int f(int x);", "signature": "int f(int x);",
"defined": true, "defined": true
"stdlib": false,
"builtin": false,
"eva_analyzed": null
} }
], ],
"removed": [], "removed": [],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment