I'm developping a plugin in frama-c and I want to get line number in source code. In this little script for example:
open Cil_types
open Cil_types
open Cil_datatype
let print_loc kf =
let locals = Kernel_function.get_locals kf in
List.iter (fun vi ->
let line = Cil_datatype.Location.pretty_line Format.sprintf "%a" Printer.pp_location vi.vdecl in
Format.printf "Line %a: %a %s@."
Printer.pp_location vi.vdecl Printer.pp_typ vi.vtype vi.vname
) locals
let () =
Db.Main.extend (fun () ->
Format.printf "Printing all local vars...@.";
let fun_name = "main" in
let kf = Globals.Functions.find_by_name fun_name in
print_loc kf;
Format.printf "done!@.")
Printer.pp_location
print the full path. I want just the line number.
I found pretty_line
in Cil_datatype.Location
module and tried to use it but I can not. I'm getting compile errors and I have not found an example of using this function in Frama-C sources.
I tried this,
let print_loc kf =
let locals = Kernel_function.get_locals kf in
List.iter (fun vi ->
let line = Cil_datatype.Location.pretty_line Format.sprintf "%a" Printer.pp_location vi.vdecl in
Format.printf "Line %d: %a %s@." line Printer.pp_typ vi.vtype vi.vname) locals
And I got this error message
Error: This function has type Format.formatter -> Cil_datatype.Location.t -> unit It is applied to too many arguments; maybe you forgot a `;'.
I tried several combinations, but in any case, either I get the previous error message or I get this message:
Error: This expression has type Format.formatter -> Cil_types.location -> unit but an expression was expected of type unit -> 'a -> string Type Format.formatter is not compatible with type unit
Can I get the information about line number otherwise? Or How can I properly use Cil_datatype.Location.pretty_line
?
Thanks
octachtron's answer summarizes nicely how to use pretty_line
with a format string. However, if you want to use the line number as an integer (not necessarily to print it with %d
), Cil_datatype.Location.t
is a concrete type, more precisely an alias to Cil_types.location
, which is itself a pair of Lexing.location
. Hence,
for retrieving the line where the location starts, you can simply do
...
let line = (fst vi.vdecl).Lexing.pos_lnum in
...