Skip to content

Commit 19095a9

Browse files
Patch and redirect available directives
They have to be redirected because by default they write to stdout, but we capture stderr (and in 4.14 they write to stderr). Unfortunately, just overwriting them in the directives Hashtbl does not work, since the ordering of additions is somewhat undefined so they might be overwritten. A safer way is to create new directives and rewrite those to be evaluated to them. Also, `"use"` is a builtin directive, not from findlib so needs to be excluded to get the error message printed.
1 parent df4e3cc commit 19095a9

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

lib/top/compat_top.ml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,36 @@ let execute_phrase print_outcome ppf phr =
179179
#else
180180
Toploop.execute_phrase print_outcome ppf phr
181181
#endif
182+
183+
#if OCAML_VERSION < (4, 14, 0)
184+
let std_err = Format.err_formatter
185+
186+
let patch_directive name directive =
187+
let patched_name = Format.asprintf "mdx_%s" name in
188+
let directive_info = Toploop.{ section = "MDX PATCHED"; doc = "Patched by MDX" } in
189+
Toploop.add_directive patched_name directive directive_info;
190+
patched_name
191+
192+
let mdx_load = patch_directive "load" (Directive_string (Topdirs.dir_load std_err))
193+
let mdx_use = patch_directive "use" (Directive_string (Topdirs.dir_use std_err))
194+
let mdx_use_output = patch_directive "use_output" (Directive_string (Topdirs.dir_use_output std_err))
195+
let mdx_install_printer = patch_directive "install_printer" (Directive_ident (Topdirs.dir_install_printer std_err))
196+
let mdx_remove_printer = patch_directive "remove_printer" (Directive_ident (Topdirs.dir_remove_printer std_err))
197+
let mdx_trace = patch_directive "trace" (Directive_ident (Topdirs.dir_trace std_err))
198+
let mdx_untrace = patch_directive "untrace" (Directive_ident (Topdirs.dir_untrace std_err))
199+
let mdx_untrace_all = patch_directive "untrace_all" (Directive_none (Topdirs.dir_untrace_all std_err))
200+
#endif
201+
202+
let redirect_directive directive =
203+
match directive with
204+
#if OCAML_VERSION < (4, 14, 0)
205+
| "load" -> mdx_load
206+
| "use" -> mdx_use
207+
| "use_output" -> mdx_use_output
208+
| "install_printer" -> mdx_install_printer
209+
| "remove_printer" -> mdx_remove_printer
210+
| "trace" -> mdx_trace
211+
| "untrace" -> mdx_untrace
212+
| "untrace_all" -> mdx_untrace_all
213+
#endif
214+
| v -> v

lib/top/compat_top.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,6 @@ exception Exit_with_status of int
6464

6565
val execute_phrase :
6666
bool -> Format.formatter -> Parsetree.toplevel_phrase -> bool
67+
68+
(* If the directive has to be intercepted, this function will return the new name of the directive *)
69+
val redirect_directive : string -> string

lib/top/mdx_top.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ module Phrase = struct
161161

162162
let is_findlib_directive =
163163
let findlib_directive = function
164-
| "require" | "use" | "camlp4o" | "camlp4r" | "thread" -> true
164+
| "require" | "camlp4o" | "camlp4r" | "thread" -> true
165165
| _ -> false
166166
in
167167
function
@@ -290,6 +290,12 @@ module Rewrite = struct
290290
in
291291
Btype.backtrack snap;
292292
Ptop_def pstr)
293+
| Ptop_dir pdir ->
294+
let pdir_name = pdir.pdir_name in
295+
let pdir_name =
296+
{ pdir_name with txt = Compat_top.redirect_directive pdir_name.txt }
297+
in
298+
Ptop_dir { pdir with pdir_name }
293299
| _ -> phrase
294300

295301
(** [top_directive require "pkg"] builds the AST for [#require "pkg"] *)

0 commit comments

Comments
 (0)