Skip to content

Commit c08e1d1

Browse files
committed
coqpp: set location annotation when exiting user-provided code
Return of coq#19910, but with simpler implementation. It's a bit less efficient in principle (we write to a string, replace some lines in it then output to file instead of streaming to file) but AFAIK we don't work with big enough mlg files for it to matter.
1 parent 7c2fbfc commit c08e1d1

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

coqpp/coqpp_main.ml

+31-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,30 @@ let fatal msg =
1919

2020
let mk_code s = { code = s; loc = None }
2121

22+
(** Annotating at the end of user code with the current line of the generated file.
23+
24+
To get the current line while generating the output we would need
25+
to flush format and either intercept format's output
26+
(Format.formatter_of_out_functions) or read the generated file as
27+
we generate it. This is both inconvenient to write, and also the
28+
flushing breaks the formatting.
29+
30+
Instead we generate the code with the following dummy annotation
31+
and afterwards replace it with the real annotation.
32+
*)
33+
let exit_code_str = "# COQPP EXIT CODE"
34+
35+
let exit_code fmt () =
36+
fprintf fmt "@<0>%s" ("\n"^exit_code_str^"\n")
37+
38+
let fix_exit_code ~filename str =
39+
let lines = String.split_on_char '\n' str in
40+
let lines = List.mapi (fun i l ->
41+
if String.equal l exit_code_str then
42+
asprintf "# %i \"%s\"" (i+2) filename
43+
else l) lines in
44+
String.concat "\n" lines
45+
2246
let print_code fmt c =
2347
match c.loc with
2448
| None -> fprintf fmt "%s" c.code
@@ -27,7 +51,8 @@ let print_code fmt c =
2751
let loc = loc.loc_start in
2852
let padding = String.make (loc.pos_cnum - loc.pos_bol + 1) ' ' in
2953
let code_insert = asprintf "\n# %i \"%s\"\n%s%s" loc.pos_lnum loc.pos_fname padding c.code in
30-
fprintf fmt "@[@<0>%s@]@\n" code_insert
54+
fprintf fmt "@[@<0>%s@]" code_insert;
55+
exit_code fmt ()
3156

3257
module StringSet = Set.Make(String)
3358

@@ -712,10 +737,11 @@ let main args =
712737
let file = parse args in
713738
let output = output_name file in
714739
let ast = parse_file file in
715-
let chan = open_out output in
716740
let () = file_name := Filename.basename file in
717-
let fmt = formatter_of_out_channel chan in
718-
let iter ast = Format.fprintf fmt "@[%a@]%!" pr_ast ast in
719-
let () = List.iter iter ast in
741+
let iter fmt ast = Format.fprintf fmt "@[%a@]%!" pr_ast ast in
742+
let str = asprintf "%a" (fun fmt ast -> List.iter (iter fmt) ast) ast in
743+
let str = fix_exit_code ~filename:output str in
744+
let chan = open_out output in
745+
let () = output_string chan str in
720746
let () = close_out chan in
721747
exit 0

0 commit comments

Comments
 (0)