2024-10-08 15:05:45 +00:00
|
|
|
## vim: filetype=ocaml
|
|
|
|
|
|
2024-10-10 16:56:42 +02:00
|
|
|
module TargetInformation = struct
|
|
|
|
|
let c_free =
|
|
|
|
|
foreign ~from:c_lib "ada_target_info_free"
|
|
|
|
|
(ptr void @-> raisable void)
|
|
|
|
|
|
|
|
|
|
type t = unit ptr ptr
|
|
|
|
|
|
|
|
|
|
let read c_value =
|
|
|
|
|
let finalise arg =
|
|
|
|
|
c_free (!@ arg)
|
|
|
|
|
in
|
|
|
|
|
allocate ~finalise (ptr void) c_value
|
|
|
|
|
|
|
|
|
|
let write value = (!@ value)
|
|
|
|
|
|
|
|
|
|
let c_type = view (ptr void) ~read ~write
|
|
|
|
|
|
|
|
|
|
let load =
|
|
|
|
|
foreign ~from:c_lib "ada_target_info_load"
|
|
|
|
|
(string @-> raisable c_type)
|
|
|
|
|
|
|
|
|
|
let c_set =
|
|
|
|
|
foreign ~from:c_lib "ada_target_info_set"
|
|
|
|
|
(AnalysisContextStruct.c_type @-> c_type @-> raisable void)
|
|
|
|
|
|
|
|
|
|
let set ctx info = c_set ctx.c_value info
|
|
|
|
|
end
|
|
|
|
|
|
2025-09-15 14:54:56 +00:00
|
|
|
module GPROptionsStruct : sig
|
|
|
|
|
type t
|
|
|
|
|
val c_type : t typ
|
|
|
|
|
val create : unit -> t
|
|
|
|
|
val add_switch : t -> int -> string -> string -> bool -> unit
|
|
|
|
|
end = struct
|
|
|
|
|
type t = unit ptr ptr
|
|
|
|
|
|
|
|
|
|
let c_free =
|
|
|
|
|
foreign ~from:c_lib "ada_gpr_options_free"
|
|
|
|
|
(ptr void @-> raisable void)
|
|
|
|
|
|
|
|
|
|
let read c_value =
|
|
|
|
|
let finalise arg =
|
|
|
|
|
c_free (!@ arg)
|
|
|
|
|
in
|
|
|
|
|
allocate ~finalise (ptr void) c_value
|
|
|
|
|
|
|
|
|
|
let write value = (!@ value)
|
|
|
|
|
|
|
|
|
|
let c_type = view (ptr void) ~read ~write
|
|
|
|
|
|
|
|
|
|
let create =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name('gpr_options_create')}"
|
|
|
|
|
(void @-> raisable c_type)
|
|
|
|
|
|
|
|
|
|
let add_switch =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name('gpr_options_add_switch')}"
|
|
|
|
|
(c_type @-> int @-> string @-> string @-> bool @-> raisable void)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module GPROptions = struct
|
|
|
|
|
type t = GPROptionsStruct.t
|
|
|
|
|
|
|
|
|
|
type gpr_option =
|
|
|
|
|
| AP
|
|
|
|
|
| Autoconf
|
|
|
|
|
| Config
|
|
|
|
|
| Db
|
|
|
|
|
| DbMinus
|
|
|
|
|
| ImplicitWith
|
|
|
|
|
| ResolveLinks
|
|
|
|
|
| NoProject
|
|
|
|
|
| P
|
|
|
|
|
| PrintGPRRegistry
|
|
|
|
|
| RelocateBuildTree
|
|
|
|
|
| RootDir
|
|
|
|
|
| RTS
|
|
|
|
|
| SrcSubdirs
|
|
|
|
|
| Subdirs
|
|
|
|
|
| Target
|
|
|
|
|
| X
|
|
|
|
|
|
|
|
|
|
let c_gpr_option = function
|
|
|
|
|
| AP -> 0
|
|
|
|
|
| Autoconf -> 1
|
|
|
|
|
| Config -> 2
|
|
|
|
|
| Db -> 3
|
|
|
|
|
| DbMinus -> 4
|
|
|
|
|
| ImplicitWith -> 5
|
|
|
|
|
| ResolveLinks -> 6
|
|
|
|
|
| NoProject -> 7
|
|
|
|
|
| P -> 8
|
|
|
|
|
| PrintGPRRegistry -> 9
|
|
|
|
|
| RelocateBuildTree -> 10
|
|
|
|
|
| RootDir -> 11
|
|
|
|
|
| RTS -> 12
|
|
|
|
|
| SrcSubdirs -> 13
|
|
|
|
|
| Subdirs -> 14
|
|
|
|
|
| Target -> 15
|
|
|
|
|
| X -> 16
|
|
|
|
|
|
|
|
|
|
let create () = GPROptionsStruct.create ()
|
|
|
|
|
|
|
|
|
|
let add_switch
|
|
|
|
|
switch
|
|
|
|
|
?(param = "")
|
|
|
|
|
?(index = "")
|
|
|
|
|
?(override = false)
|
|
|
|
|
gpr_options =
|
|
|
|
|
GPROptionsStruct.add_switch
|
|
|
|
|
gpr_options (c_gpr_option switch) param index override
|
|
|
|
|
|
|
|
|
|
let quick_create
|
|
|
|
|
?(scenario_vars=[])
|
|
|
|
|
?target
|
|
|
|
|
?runtime
|
|
|
|
|
project =
|
|
|
|
|
let opts = GPROptionsStruct.create () in
|
|
|
|
|
add_switch P ~param:project opts;
|
|
|
|
|
List.iter
|
|
|
|
|
(fun (k, v) -> add_switch X ~param:(k ^ "=" ^ v) opts)
|
|
|
|
|
scenario_vars ;
|
|
|
|
|
( match target with
|
|
|
|
|
| Some "" | None -> ()
|
|
|
|
|
| Some target -> add_switch Target ~param:target opts ) ;
|
|
|
|
|
( match runtime with
|
|
|
|
|
| Some "" | None -> ()
|
|
|
|
|
| Some rts -> add_switch RTS ~param:rts opts) ;
|
|
|
|
|
opts
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
2022-10-11 12:25:45 +02:00
|
|
|
module GPRProject = struct
|
2022-10-25 17:52:58 +02:00
|
|
|
type string_array
|
|
|
|
|
|
|
|
|
|
let c_string_array : string_array structure typ =
|
|
|
|
|
structure "string_array"
|
|
|
|
|
|
|
|
|
|
let array_length = field c_string_array "length" int
|
|
|
|
|
|
|
|
|
|
let array_c_ptr = field c_string_array "c_ptr" (ptr string)
|
|
|
|
|
|
|
|
|
|
let () = seal c_string_array
|
|
|
|
|
|
|
|
|
|
let c_free_string_array =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name("free_string_array")}"
|
|
|
|
|
(ptr c_string_array @-> raisable void)
|
|
|
|
|
|
|
|
|
|
let read_string_array c_value =
|
|
|
|
|
let result =
|
|
|
|
|
List.init
|
|
|
|
|
(!@ (c_value |-> array_length))
|
|
|
|
|
(fun i -> (!@ ((!@ (c_value |-> array_c_ptr)) +@ i)))
|
|
|
|
|
in
|
|
|
|
|
c_free_string_array c_value ;
|
|
|
|
|
result
|
|
|
|
|
|
|
|
|
|
let write_string_array _value =
|
|
|
|
|
(* Not used for now *)
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
|
|
let string_array = view (ptr c_string_array) ~read:read_string_array ~write:write_string_array
|
|
|
|
|
|
2022-10-11 12:25:45 +02:00
|
|
|
type t = unit ptr ptr
|
|
|
|
|
|
|
|
|
|
let gpr_project_free =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name("gpr_project_free")}"
|
|
|
|
|
(ptr void @-> raisable void)
|
|
|
|
|
|
|
|
|
|
let read c_value =
|
|
|
|
|
let finalise arg =
|
|
|
|
|
gpr_project_free (!@ arg)
|
|
|
|
|
in
|
|
|
|
|
allocate ~finalise (ptr void) c_value
|
|
|
|
|
|
|
|
|
|
let write value = (!@ value)
|
|
|
|
|
|
|
|
|
|
let c_type = view (ptr void) ~read ~write
|
|
|
|
|
|
|
|
|
|
let gpr_project_load =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name("gpr_project_load")}"
|
2025-09-15 14:54:56 +00:00
|
|
|
(GPROptionsStruct.c_type @-> bool @-> ptr c_type @-> ptr string_array
|
2024-09-04 10:33:18 +00:00
|
|
|
@-> raisable void)
|
2022-10-11 12:25:45 +02:00
|
|
|
|
2022-10-12 14:13:36 +02:00
|
|
|
let gpr_project_create_preprocessor =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name("gpr_project_create_preprocessor")}"
|
|
|
|
|
(c_type @-> string @-> ptr int @-> raisable FileReader.c_type)
|
|
|
|
|
|
2025-09-15 14:54:56 +00:00
|
|
|
let load ?(ada_only = false) options : t =
|
2022-10-25 17:52:58 +02:00
|
|
|
(* Use allocate_n to avoid having to give it an initial value *)
|
|
|
|
|
let result = allocate_n ~count:1 c_type in
|
|
|
|
|
let errors = allocate_n ~count:1 string_array in
|
2025-09-15 14:54:56 +00:00
|
|
|
gpr_project_load options ada_only result errors ;
|
2022-10-25 17:52:58 +02:00
|
|
|
(* Not sure what to do with errors here as we already have an exception *)
|
|
|
|
|
!@ result
|
2022-10-11 12:25:45 +02:00
|
|
|
|
|
|
|
|
let c_source_files =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name("gpr_project_source_files")}"
|
2023-03-28 10:14:34 +00:00
|
|
|
(c_type @-> int @-> ptr void @-> raisable string_array)
|
2022-10-11 12:25:45 +02:00
|
|
|
|
|
|
|
|
type source_file_mode =
|
|
|
|
|
| Default
|
|
|
|
|
| RootProject
|
|
|
|
|
| WholeProject
|
|
|
|
|
| WholeProjectWithRuntime
|
|
|
|
|
|
|
|
|
|
let write_source_file_mode = function
|
|
|
|
|
| Default -> 0
|
|
|
|
|
| RootProject -> 1
|
|
|
|
|
| WholeProject -> 2
|
|
|
|
|
| WholeProjectWithRuntime -> 3
|
|
|
|
|
|
|
|
|
|
let source_files ?(mode = Default) gpr_project =
|
2023-03-28 10:14:34 +00:00
|
|
|
c_source_files gpr_project (write_source_file_mode mode) null
|
2022-10-12 14:13:36 +02:00
|
|
|
|
|
|
|
|
type line_mode =
|
|
|
|
|
| DeleteLines
|
|
|
|
|
| BlankLines
|
|
|
|
|
| CommentLines
|
2025-09-17 14:15:27 +00:00
|
|
|
| EmptyCommentLines
|
2022-10-12 14:13:36 +02:00
|
|
|
|
|
|
|
|
let create_preprocessor ?(project = "") ?line_mode gpr_project =
|
|
|
|
|
let line_mode_c =
|
|
|
|
|
match line_mode with
|
|
|
|
|
| Some DeleteLines ->
|
|
|
|
|
allocate int 0
|
|
|
|
|
| Some BlankLines ->
|
|
|
|
|
allocate int 1
|
|
|
|
|
| Some CommentLines ->
|
|
|
|
|
allocate int 2
|
2025-09-17 14:15:27 +00:00
|
|
|
| Some EmptyCommentLines ->
|
|
|
|
|
allocate int 3
|
2022-10-12 14:13:36 +02:00
|
|
|
| None ->
|
|
|
|
|
from_voidp int null
|
|
|
|
|
in
|
|
|
|
|
gpr_project_create_preprocessor gpr_project project line_mode_c
|
2023-09-14 14:41:50 +02:00
|
|
|
|
|
|
|
|
let gpr_project_create_unit_provider =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name("gpr_project_create_unit_provider")}"
|
|
|
|
|
(c_type @-> string @-> raisable UnitProvider.c_type)
|
|
|
|
|
|
|
|
|
|
let create_unit_provider ?(project = "") gpr_project =
|
|
|
|
|
let result = gpr_project_create_unit_provider gpr_project project in
|
|
|
|
|
(* The unit provider keeps an internal reference to the project. Use
|
|
|
|
|
the keep argument to simulate the same behaviour and avoid freeing
|
|
|
|
|
the project file too early. *)
|
|
|
|
|
UnitProvider.wrap ~keep:gpr_project result
|
2023-09-14 15:50:52 +02:00
|
|
|
|
|
|
|
|
let gpr_project_initialize_context =
|
|
|
|
|
foreign ~from:c_lib "${capi.get_name("gpr_project_initialize_context")}"
|
|
|
|
|
( c_type @-> AnalysisContextStruct.c_type @-> string
|
|
|
|
|
@-> ptr void @-> bool @-> int @-> raisable void )
|
|
|
|
|
|
|
|
|
|
let create_analysis_context
|
|
|
|
|
?(with_trivia = true)
|
2024-10-25 12:21:18 +00:00
|
|
|
?(tab_stop = ${cfg.library.defaults.tab_stop})
|
2023-09-14 15:50:52 +02:00
|
|
|
?(project = "")
|
|
|
|
|
gpr_project : analysis_context =
|
|
|
|
|
if tab_stop < 1 then
|
|
|
|
|
raise (Invalid_argument "Invalid tab_stop (positive integer expected)") ;
|
2023-09-15 14:38:40 +02:00
|
|
|
let c_context =
|
|
|
|
|
AnalysisContextStruct.allocate_analysis_context ~keep:gpr_project ()
|
|
|
|
|
in
|
2023-09-14 15:50:52 +02:00
|
|
|
gpr_project_initialize_context
|
|
|
|
|
gpr_project
|
|
|
|
|
c_context
|
|
|
|
|
project
|
|
|
|
|
Ctypes.null (* TODO: bind the event handlers API to OCaml *)
|
|
|
|
|
with_trivia
|
|
|
|
|
tab_stop ;
|
|
|
|
|
{ c_value= c_context
|
|
|
|
|
; unit_provider= UnitProvider.null }
|
2022-10-11 12:25:45 +02:00
|
|
|
end
|