summaryrefslogtreecommitdiff
path: root/parsing
diff options
context:
space:
mode:
authorAlain Frisch <alain@frisch.fr>2013-09-11 16:08:00 +0000
committerAlain Frisch <alain@frisch.fr>2013-09-11 16:08:00 +0000
commit47be69c2b065d1cb11a73146289ab0ca56792a9e (patch)
tree06411d2fe416b2aca4ede846813397a0c535b9ed /parsing
parent2493d3414baeaabbbc871c83608222453a5037ed (diff)
downloadocaml-47be69c2b065d1cb11a73146289ab0ca56792a9e.tar.gz
Cherry-picking commit 14093 from trunk.
git-svn-id: http://caml.inria.fr/svn/ocaml/branches/exception_registration@14104 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'parsing')
-rw-r--r--parsing/location.ml38
-rw-r--r--parsing/location.mli26
2 files changed, 64 insertions, 0 deletions
diff --git a/parsing/location.ml b/parsing/location.ml
index d3f89f4405..14d2f9513a 100644
--- a/parsing/location.ml
+++ b/parsing/location.ml
@@ -286,3 +286,41 @@ type 'a loc = {
let mkloc txt loc = { txt ; loc }
let mknoloc txt = mkloc txt none
+
+
+type error =
+ {
+ loc: t;
+ msg: string;
+ sub: error list;
+ }
+
+let error ?(loc = none) ?(sub = []) msg = {loc; msg; sub}
+
+let error_of_exn : (exn -> error option) list ref = ref []
+
+let register_error_of_exn f = error_of_exn := f :: !error_of_exn
+
+let error_of_exn exn =
+ let rec loop = function
+ | [] -> None
+ | f :: rest ->
+ match f exn with
+ | Some _ as r -> r
+ | None -> loop rest
+ in
+ loop !error_of_exn
+
+let rec report_error ppf {loc; msg; sub} =
+ print ppf loc;
+ Format.pp_print_string ppf msg;
+ List.iter (fun err -> Format.fprintf ppf "@\n@[<2>%a@]" report_error err) sub
+
+let error_of_printer loc print x =
+ let buf = Buffer.create 64 in
+ let ppf = Format.formatter_of_buffer buf in
+ Format.fprintf ppf "Error: ";
+ print ppf x;
+ pp_print_flush ppf ();
+ let msg = Buffer.contents buf in
+ error ~loc msg
diff --git a/parsing/location.mli b/parsing/location.mli
index bae9090207..a465b8a1fb 100644
--- a/parsing/location.mli
+++ b/parsing/location.mli
@@ -75,3 +75,29 @@ val show_filename: string -> string
val absname: bool ref
+
+
+(* Support for located errors *)
+
+type error =
+ {
+ loc: t;
+ msg: string;
+ sub: error list;
+ }
+
+val error: ?loc:t -> ?sub:error list -> string -> error
+
+val error_of_printer: t -> (formatter -> 'a -> unit) -> 'a -> error
+
+val error_of_exn: exn -> error option
+
+val register_error_of_exn: (exn -> error option) -> unit
+ (* Each compiler module which defines a custom type of exception
+ which can surface as a user-visible error should register
+ a "printer" for this exception using [register_error_of_exn].
+ The result of the printer is an [error] value containing
+ a location, a message, and optionally sub-messages (each of them
+ being located as well). *)
+
+val report_error: formatter -> error -> unit