Browse thread
[Caml-list] A global exception handler...
-
Jonathan Roewen
-
Till Varoquaux
- Nicolas Pouillard
-
Till Varoquaux
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Nicolas Pouillard <nicolas.pouillard@i...> |
| Subject: | Re: [Caml-list] A global exception handler... |
On 7/6/06, Till Varoquaux <till.varoquaux@gmail.com> wrote:
> On 7/6/06, Jonathan Roewen <jonathan.roewen@gmail.com> wrote:
> > Hi,
> >
> > Is it possible to register a global exception handler?
> >
> > I suppose I could just nest everything inside one giant function if I
> > really had to, but I like my toplevel expressions ;-)
> >
> CamlP4 might come in handy here. I'm guessing you could rewrite your
> program so that all your toplevel expressions are in one main ()
> function using camlp4. It would have some limitations though: for
> instance your exception handler could not use anything defined in main
> (unless you where using references). I'm guessing it's not so bad
> because whatever happens you cannot have a global exception handler
> relying to much on stuff defined in your programm.
Here is a simple Camlp4 filter that written for the new Camlp4 version (CVS) :
$ cat global_handler.ml
open Camlp4.PreCast;
value ghost = Loc.ghost;
value global_handler_ref = ref <:expr@ghost<>>;
value find_global_handler = object
inherit Ast.map as super;
method str_item st = do {
match st with
[ <:str_item< value global_handler = $f$ >> -> global_handler_ref.val := f
| _ -> () ];
super#str_item st
};
end;
AstFilters.register_str_item_filter
(fun st ->
let _ = find_global_handler#str_item st in
<:str_item@ghost< try let module Main = struct $st$ end in ()
with e -> $global_handler_ref.val$ e >>);
$ ocamlc -I +camlp4 -c -pp camlp4rf global_handler.ml
$ cat global_handler_test.ml
open Format;;
let f1 x = printf "f1 %d@." x;;
let f2 x = printf "f2 %f@." x;;
let f3 x = printf "f3 %s@." x;;
f1 1;;
f2 1.1;;
f3 "1.1.1";;
raise (Failure "test");;
let global_handler e =
(* Note that I need to give the complete name for eprintf since
Format is not opened in the new environment of global_handler. *)
Format.eprintf "global_handler: %s@." (Printexc.to_string e)
$ ocamlc -pp 'camlp4o global_handler.cmo' global_handler_test.ml
$ ./a.out
f1 1
f2 1.100000
f3 1.1.1
global_handler: Failure("test")
$ camlp4o global_handler.cmo -printer OCaml global_handler_test.ml
try
let module Main =
struct
open Format
let f1 x = printf "f1 %d@." x
let f2 x = printf "f2 %f@." x
let f3 x = printf "f3 %s@." x
let _ = f1 1
let _ = f2 1.1
let _ = f3 "1.1.1"
let _ = raise (Failure "test")
let global_handler e =
(* Note that I need to give the complete name for eprintf since
Format is not opened in the new environment of global_handler. *)
Format.eprintf "global_handler: %s@." (Printexc.to_string e)
end
in ()
with
| e ->
(fun e -> Format.eprintf "global_handler: %s@." (Printexc.to_string e)) e
Cheers,
--
Nicolas Pouillard