@@ -167,3 +167,100 @@ let ctype_get_desc ty =
167167#else
168168 (Ctype. repr ty).Types. desc
169169#endif
170+
171+ exception Exit_with_status of int
172+
173+
174+ let execute_phrase print_outcome ppf phr =
175+ #if OCAML_VERSION > = (4 , 12 , 0 )
176+ match Toploop. execute_phrase print_outcome ppf phr with
177+ | v -> v
178+ | exception Compenv. Exit_with_status status ->
179+ raise (Exit_with_status status)
180+ #else
181+ Toploop. execute_phrase print_outcome ppf phr
182+ #endif
183+
184+ #if OCAML_VERSION < (4 , 14 , 0 )
185+ let std_err = Format. err_formatter
186+
187+ let patch_directive name directive =
188+ let patched_name = Format. asprintf " mdx_%s" name in
189+ let directive_info = Toploop. { section = " MDX PATCHED" ; doc = " Patched by MDX" } in
190+ Toploop. add_directive patched_name directive directive_info;
191+ patched_name
192+
193+ (* port of Topdirs.action_on_suberror *)
194+ let action_on_suberror b =
195+ if not b && not ! Sys. interactive then
196+ raise (Exit_with_status 125 )
197+
198+ let dir_use ppf name =
199+ action_on_suberror (Toploop. use_file ppf name)
200+
201+ let mdx_use = patch_directive " use" (Directive_string (dir_use std_err))
202+
203+ let mdx_install_printer = patch_directive " install_printer" (Directive_ident (Topdirs. dir_install_printer std_err))
204+ let mdx_remove_printer = patch_directive " remove_printer" (Directive_ident (Topdirs. dir_remove_printer std_err))
205+ #endif
206+
207+ #if OCAML_VERSION > = (4 , 11 , 0 ) && OCAML_VERSION < (4 , 14 , 0 )
208+
209+ let dir_use_output ppf name =
210+ action_on_suberror (Toploop. use_output ppf name)
211+
212+ let mdx_use_output = patch_directive " use_output" (Directive_string (dir_use_output std_err))
213+ #endif
214+
215+ #if OCAML_VERSION < (4 , 13 , 0 )
216+ let mdx_trace = patch_directive " trace" (Directive_ident (Topdirs. dir_trace std_err))
217+ let mdx_untrace = patch_directive " untrace" (Directive_ident (Topdirs. dir_untrace std_err))
218+ let mdx_untrace_all = patch_directive " untrace_all" (Directive_none (Topdirs. dir_untrace_all std_err))
219+ #endif
220+
221+ #if OCAML_VERSION < (4 , 13 , 0 )
222+ (* [load] cannot be patched to return errors because the underlying code is not exposed:
223+ It would require [Topdirs.load_file] with the first argument to be [false] but the exposed
224+ version hardcodes it to [true].
225+ *)
226+ let mdx_load = patch_directive " load" (Directive_string (Topdirs. dir_load std_err))
227+
228+ (* On the other hand, [load_rec] can be patched because the curried [true] is the only
229+ difference between these directives *)
230+ let dir_load_rec ppf name =
231+ action_on_suberror (Topdirs. load_file ppf name)
232+
233+ let mdx_load_rec = patch_directive " load_rec" (Directive_string (dir_load_rec std_err))
234+
235+ #elif OCAML_VERSION > = (4 , 13 , 0 ) && OCAML_VERSION < (4 , 14 , 0 )
236+ (* OCaml 4.13 exposes [Topeval.load_file] which allows us to patch [#load] too *)
237+ let dir_load ppf name =
238+ action_on_suberror (Topeval. load_file false ppf name)
239+
240+ let mdx_load = patch_directive " load" (Directive_string (dir_load std_err))
241+
242+ (* This uses [Topeval.load_file] because [Topdirs.load_file] is deprecated on 4.13 *)
243+ let dir_load_rec ppf name =
244+ action_on_suberror (Topeval. load_file true ppf name)
245+
246+ let mdx_load_rec = patch_directive " load_rec" (Directive_string (dir_load_rec std_err))
247+ #endif
248+
249+ let redirect_directive directive =
250+ match directive with
251+ #if OCAML_VERSION < (4 , 14 , 0 )
252+ | "load" -> mdx_load
253+ | "load_rec" -> mdx_load_rec
254+ | "use" -> mdx_use
255+ | "install_printer" -> mdx_install_printer
256+ | "remove_printer" -> mdx_remove_printer
257+ #endif
258+ #if OCAML_VERSION > = (4 , 11 , 0 ) && OCAML_VERSION < (4 , 14 , 0 )
259+ | "use_output" -> mdx_use_output
260+ #endif
261+ #if OCAML_VERSION < (4 , 13 , 0 )
262+ | "trace" -> mdx_trace
263+ | "untrace" -> mdx_untrace
264+ | "untrace_all" -> mdx_untrace_all
265+ #endif
266+ | v -> v
0 commit comments