aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/Cerrors.ml
diff options
context:
space:
mode:
Diffstat (limited to 'cparser/Cerrors.ml')
-rw-r--r--cparser/Cerrors.ml142
1 files changed, 120 insertions, 22 deletions
diff --git a/cparser/Cerrors.ml b/cparser/Cerrors.ml
index 612980f1..dffd9c14 100644
--- a/cparser/Cerrors.ml
+++ b/cparser/Cerrors.ml
@@ -18,7 +18,18 @@
open Format
open Commandline
+(* Should errors be treated as fatal *)
let error_fatal = ref false
+
+(* Maximum number of errors, 0 means unlimited *)
+let max_error = ref 0
+
+(* Whether [-Woption] should be printed *)
+let diagnostics_show_option = ref true
+
+(* Test if color diagnostics are available by testing if stderr is a tty
+ and if the environment varibale TERM is set
+*)
let color_diagnostics =
let term = try Sys.getenv "TERM" with Not_found -> "" in
let activate = try
@@ -29,6 +40,11 @@ let color_diagnostics =
let num_errors = ref 0
let num_warnings = ref 0
+
+let error_limit_reached () =
+ let max_err = !max_error in
+ max_err <> 0 && !num_errors >= max_err - 1
+
let reset () = num_errors := 0; num_warnings := 0
exception Abort
@@ -73,6 +89,7 @@ type warning_type =
| CompCert_conformance
| Inline_asm_sdump
+(* List of active warnings *)
let active_warnings: warning_type list ref = ref [
Unnamed;
Unknown_attribute;
@@ -93,8 +110,10 @@ let active_warnings: warning_type list ref = ref [
Inline_asm_sdump;
]
+(* List of errors treated as warning *)
let error_warnings: warning_type list ref = ref []
+(* Conversion from warning type to string *)
let string_of_warning = function
| Unnamed -> ""
| Unknown_attribute -> "unknown-attributes"
@@ -117,22 +136,27 @@ let string_of_warning = function
| CompCert_conformance -> "compcert-conformance"
| Inline_asm_sdump -> "inline-asm-sdump"
+(* Activate the given warning *)
let activate_warning w () =
if not (List.mem w !active_warnings) then
active_warnings:=w::!active_warnings
+(* Deactivate the given warning*)
let deactivate_warning w () =
active_warnings:=List.filter ((<>) w) !active_warnings;
error_warnings:= List.filter ((<>) w) !error_warnings
+(* Activate error for warning *)
let warning_as_error w ()=
activate_warning w ();
if not (List.mem w !error_warnings) then
error_warnings := w::!error_warnings
+(* Deactivate error for warning *)
let warning_not_as_error w () =
error_warnings:= List.filter ((<>) w) !error_warnings
+(* Activate all warnings *)
let wall () =
active_warnings:=[
Unnamed;
@@ -157,6 +181,10 @@ let wall () =
Inline_asm_sdump;
]
+let wnothing () =
+ active_warnings :=[]
+
+(* Make all warnings an error *)
let werror () =
error_warnings:=[
Unnamed;
@@ -177,19 +205,29 @@ let werror () =
Return_type;
Literal_range;
Unknown_pragmas;
+ CompCert_conformance;
Inline_asm_sdump;
]
-
+(* Generate the warning key for the message *)
let key_of_warning w =
match w with
| Unnamed -> None
- | _ -> Some ("-W"^(string_of_warning w))
-
-let key_add_werror = function
- | None -> Some ("-Werror")
- | Some s -> Some ("-Werror,"^s)
+ | _ -> if !diagnostics_show_option then
+ Some ("-W"^(string_of_warning w))
+ else
+ None
+
+(* Add -Werror to the printed keys *)
+let key_add_werror w =
+ if !diagnostics_show_option then
+ match w with
+ | None -> Some ("-Werror")
+ | Some s -> Some ("-Werror,"^s)
+ else
+ None
+(* Lookup how to print the warning *)
let classify_warning w =
let key = key_of_warning w in
if List.mem w !active_warnings then
@@ -204,33 +242,63 @@ let classify_warning w =
else
SuppressedMsg,None
+(* Print color codes if color_diagnostics are enabled *)
let cprintf fmt c =
if !color_diagnostics then
fprintf fmt c
else
ifprintf fmt c
+(* Reset color codes *)
let rsc fmt =
cprintf fmt "\x1b[0m"
+(* BOLD *)
let bc fmt =
cprintf fmt "\x1b[1m"
+(* RED *)
let rc fmt =
cprintf fmt "\x1b[31;1m"
+(* MAGENTA *)
let mc fmt =
cprintf fmt "\x1b[35;1m"
+(* Print key (if available) and flush the formatter *)
let pp_key key fmt =
let key = match key with
| None -> ""
| Some s -> " ["^s^"]" in
fprintf fmt "%s%t@." key rsc
+(* Different loc output formats *)
+type loc_format =
+ | Default
+ | MSVC
+ | Vi
+
+let diagnostics_format : loc_format ref = ref Default
+
+(* Parse the option string *)
+let parse_loc_format s =
+ let s = String.sub s 21 ((String.length s) - 21) in
+ let loc_fmt = match s with
+ | "ccomp" -> Default
+ | "msvc" -> MSVC
+ | "vi" -> Vi
+ | s -> Printf.eprintf "Invalid value '%s' in '-fdiagnostics-format=%s'\n" s s; exit 2 in
+ diagnostics_format := loc_fmt
+
+(* Print the location or ccomp for the case of unknown loc *)
let pp_loc fmt (filename,lineno) =
if filename <> "" && lineno <> -10 && filename <> "cabs loc unknown" then
- fprintf fmt "%t%s:%d:%t " bc filename lineno rsc
+ match !diagnostics_format with
+ | Default -> fprintf fmt "%t%s:%d:%t " bc filename lineno rsc
+ | MSVC -> fprintf fmt "%t%s(%d):%t " bc filename lineno rsc
+ | Vi -> fprintf fmt "%t%s +%d:%t " bc filename lineno rsc
+ else
+ fprintf fmt "%tccomp:%t " bc rsc
let error key loc fmt =
incr num_errors;
@@ -257,7 +325,7 @@ let warning loc ty fmt =
| SuppressedMsg -> ifprintf err_formatter fmt
let error loc fmt =
- if !error_fatal then
+ if !error_fatal || error_limit_reached ()then
fatal_error None loc fmt
else
error None loc fmt
@@ -276,7 +344,7 @@ let error_option w =
let key = string_of_warning w in
[Exact ("-W"^key), Unit (activate_warning w);
Exact ("-Wno-"^key), Unit (deactivate_warning w);
- Exact ("-Werror="^key), Unit ( warning_as_error w);
+ Exact ("-Werror="^key), Unit (warning_as_error w);
Exact ("-Wno-error="^key), Unit ( warning_not_as_error w)]
let warning_options =
@@ -304,20 +372,50 @@ let warning_options =
Exact ("-fdiagnostics-color"), Ignore; (* Either output supports it or no color *)
Exact ("-fno-diagnostics-color"), Unset color_diagnostics;
Exact ("-Werror"), Unit werror;
- Exact ("-Wall"), Unit wall;]
-
-let warning_help = "Diagnostic options:\n\
-\ -Wall Enable all warnings\n\
-\ -W<warning> Enable the specific <warning>\n\
-\ -Wno-<warning> Disable the specific <warning>\n\
-\ -Werror Make all warnings into errors\n\
-\ -Werror=<warning> Turn <warning> into an error\n\
-\ -Wno-error=<warning> Turn <warning> into a warning even if -Werror is\n\
- specified\n\
-\ -Wfatal-errors Turn all errors into fatal errors aborting the compilation\n\
-\ -fdiagnostics-color Turn on colored diagnostics\n\
-\ -fno-diagnostics-color Turn of colored diagnostics\n"
+ Exact ("-Wall"), Unit wall;
+ Exact ("-w"), Unit wnothing;
+ longopt_int ("-fmax-errors") ((:=) max_error);
+ Exact("-fno-diagnostics-show-option"),Unset diagnostics_show_option;
+ Exact("-fdiagnostics-show-option"),Set diagnostics_show_option;
+ _Regexp("-fdiagnostics-format=\\(ccomp\\|msvc\\|vi\\)"),Self parse_loc_format;
+ ]
+
+let warning_help = {|Diagnostic options:
+ -Wall Enable all warnings
+ -W<warning> Enable the specific <warning>
+ -Wno-<warning> Disable the specific <warning>
+ -Werror Make all warnings into errors
+ -Werror=<warning> Turn <warning> into an error
+ -Wno-error=<warning> Turn <warning> into a warning even if -Werror is
+ specified
+ -Wfatal-errors Turn all errors into fatal errors aborting the compilation
+ -fdiagnostics-color Turn on colored diagnostics
+ -fno-diagnostics-color Turn of colored diagnostics
+ -fmax-errors=<n> Maximum number of errors to report
+ -fdiagnostics-show-option Print the option name with mappable diagnostics
+ -fno-diagnostics-show-option Turn of printing of options with mappable
+ diagnostics
+|}
let raise_on_errors () =
if !num_errors > 0 then
raise Abort
+
+let crash exn =
+ if Version.buildnr <> "" && Version.tag <> "" then begin
+ let backtrace = Printexc.get_backtrace () in
+ eprintf "%tThis is CompCert, %s, Build:%s, Tag:%s%t\n"
+ bc Version.version Version.buildnr Version.tag rsc;
+ eprintf "Backtrace (please include this in your support request):\n%s"
+ backtrace;
+ eprintf "%tUncaught exception: %s.\n\
+\ Please report this problem to our support.\n\
+\ Error occurred in Build: %s, Tag: %s.\n%t"
+ rc (Printexc.to_string exn) Version.buildnr Version.tag rsc;
+ exit 2
+ end else begin
+ let backtrace = Printexc.get_backtrace ()
+ and exc = Printexc.to_string exn in
+ eprintf "Fatal error: uncaught exception %s\n%s" exc backtrace;
+ exit 2
+ end