1995-08-09 08:06:35 -07:00
|
|
|
(***********************************************************************)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Objective Caml *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
1999-11-17 10:59:06 -08:00
|
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
|
|
(* under the terms of the Q Public License version 1.0. *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
|
|
|
(* $Id$ *)
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
open Lexing
|
|
|
|
|
|
|
|
type t =
|
1999-09-08 10:42:36 -07:00
|
|
|
{ loc_start: int; loc_end: int; loc_ghost: bool }
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1999-09-08 10:42:36 -07:00
|
|
|
let none = { loc_start = -1; loc_end = -1; loc_ghost = true }
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1999-09-08 10:42:36 -07:00
|
|
|
let symbol_rloc () =
|
|
|
|
{ loc_start = Parsing.symbol_start(); loc_end = Parsing.symbol_end();
|
|
|
|
loc_ghost = false }
|
|
|
|
|
|
|
|
let symbol_gloc () =
|
|
|
|
{ loc_start = Parsing.symbol_start(); loc_end = Parsing.symbol_end();
|
|
|
|
loc_ghost = true }
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let rhs_loc n =
|
1999-09-08 10:42:36 -07:00
|
|
|
{ loc_start = Parsing.rhs_start n; loc_end = Parsing.rhs_end n;
|
|
|
|
loc_ghost = false }
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let input_name = ref ""
|
|
|
|
|
|
|
|
let input_lexbuf = ref (None : lexbuf option)
|
|
|
|
|
|
|
|
(* Terminal info *)
|
|
|
|
|
1998-09-02 11:21:00 -07:00
|
|
|
let status = ref Terminfo.Uninitialised
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
(* Print the location using standout mode. *)
|
|
|
|
|
1995-09-08 01:55:59 -07:00
|
|
|
let num_loc_lines = ref 0 (* number of lines already printed after input *)
|
|
|
|
|
1997-11-12 04:32:53 -08:00
|
|
|
let rec highlight_locations loc1 loc2 =
|
1995-05-04 03:15:53 -07:00
|
|
|
match !status with
|
1998-09-02 11:21:00 -07:00
|
|
|
Terminfo.Uninitialised ->
|
|
|
|
status := Terminfo.setup stdout; highlight_locations loc1 loc2
|
|
|
|
| Terminfo.Bad_term ->
|
2001-09-08 12:16:19 -07:00
|
|
|
begin match !input_lexbuf with
|
|
|
|
None -> false
|
|
|
|
| Some lb ->
|
2001-09-26 00:27:38 -07:00
|
|
|
try
|
2001-09-26 00:33:07 -07:00
|
|
|
if Sys.getenv "TERM" = "character" then false else raise Not_found
|
2001-09-26 00:27:38 -07:00
|
|
|
with Not_found ->
|
2001-09-08 12:16:19 -07:00
|
|
|
try
|
|
|
|
(* Char 0 is at offset -lb.lex_abs_pos in lb.lex_buffer. *)
|
|
|
|
let pos0 = -lb.lex_abs_pos in
|
|
|
|
(* Do nothing if the buffer does not contain the whole phrase. *)
|
|
|
|
if pos0 < 0 then raise Exit;
|
|
|
|
(* Count number of lines in phrase *)
|
|
|
|
let lines = ref !num_loc_lines in
|
|
|
|
for i = pos0 to String.length lb.lex_buffer - 1 do
|
|
|
|
if lb.lex_buffer.[i] = '\n' then incr lines
|
|
|
|
done;
|
|
|
|
let pos_at_bol = ref 0 in
|
|
|
|
print_string "Toplevel input:\n# ";
|
|
|
|
(* Print the input, switching to standout for the location *)
|
|
|
|
for pos = 0 to String.length lb.lex_buffer - pos0 - 1 do
|
|
|
|
let c = lb.lex_buffer.[pos + pos0] in
|
|
|
|
if c = '\n' then begin
|
|
|
|
if !pos_at_bol <= loc1.loc_start && loc1.loc_end <= pos then
|
|
|
|
begin
|
|
|
|
print_string "\n ";
|
|
|
|
for i = !pos_at_bol to loc1.loc_start - 1 do
|
|
|
|
print_char ' '
|
|
|
|
done;
|
|
|
|
for i = loc1.loc_start to loc1.loc_end - 1 do
|
|
|
|
print_char '^'
|
|
|
|
done;
|
|
|
|
print_char '\n'
|
|
|
|
end
|
|
|
|
else if !pos_at_bol <= loc1.loc_start && loc1.loc_start < pos
|
|
|
|
then begin
|
|
|
|
print_char '\r';
|
|
|
|
print_char (if !pos_at_bol = 0 then '#' else ' ');
|
|
|
|
print_char ' ';
|
|
|
|
for i = !pos_at_bol to loc1.loc_start - 1 do
|
|
|
|
print_char '.'
|
|
|
|
done;
|
|
|
|
print_char '\n'
|
|
|
|
end
|
|
|
|
else if !pos_at_bol <= loc1.loc_end && loc1.loc_end < pos
|
|
|
|
then begin
|
|
|
|
for i = pos - 1 downto loc1.loc_end do
|
|
|
|
print_string "\b.\b";
|
|
|
|
done;
|
|
|
|
print_char '\n';
|
|
|
|
end
|
|
|
|
else print_char '\n';
|
|
|
|
pos_at_bol := pos + 1;
|
|
|
|
if pos < String.length lb.lex_buffer - pos0 - 1 then
|
|
|
|
print_string " "
|
|
|
|
else ();
|
|
|
|
end
|
|
|
|
else print_char c;
|
|
|
|
done;
|
|
|
|
flush stdout;
|
|
|
|
true;
|
|
|
|
with Exit -> false
|
|
|
|
end
|
1998-09-02 11:21:00 -07:00
|
|
|
| Terminfo.Good_term num_lines ->
|
1995-05-04 03:15:53 -07:00
|
|
|
match !input_lexbuf with
|
|
|
|
None -> false
|
|
|
|
| Some lb ->
|
1998-09-02 11:21:00 -07:00
|
|
|
try
|
|
|
|
(* Char 0 is at offset -lb.lex_abs_pos in lb.lex_buffer. *)
|
|
|
|
let pos0 = -lb.lex_abs_pos in
|
|
|
|
(* Do nothing if the buffer does not contain the whole phrase. *)
|
|
|
|
if pos0 < 0 then raise Exit;
|
1995-05-04 03:15:53 -07:00
|
|
|
(* Count number of lines in phrase *)
|
1995-09-08 01:55:59 -07:00
|
|
|
let lines = ref !num_loc_lines in
|
1995-05-04 03:15:53 -07:00
|
|
|
for i = pos0 to String.length lb.lex_buffer - 1 do
|
|
|
|
if lb.lex_buffer.[i] = '\n' then incr lines
|
|
|
|
done;
|
|
|
|
(* If too many lines, give up *)
|
1998-09-02 11:21:00 -07:00
|
|
|
if !lines >= num_lines - 2 then raise Exit;
|
|
|
|
(* Move cursor up that number of lines *)
|
1998-10-02 06:02:32 -07:00
|
|
|
flush stdout; Terminfo.backup !lines;
|
1998-09-02 11:21:00 -07:00
|
|
|
(* Print the input, switching to standout for the location *)
|
|
|
|
let bol = ref false in
|
1998-10-02 06:02:32 -07:00
|
|
|
print_string "# ";
|
1998-09-02 11:21:00 -07:00
|
|
|
for pos = 0 to String.length lb.lex_buffer - pos0 - 1 do
|
|
|
|
if !bol then (print_string " "; bol := false);
|
|
|
|
if pos = loc1.loc_start || pos = loc2.loc_start then
|
1998-10-02 06:02:32 -07:00
|
|
|
(flush stdout; Terminfo.standout true);
|
1998-09-02 11:21:00 -07:00
|
|
|
if pos = loc1.loc_end || pos = loc2.loc_end then
|
1998-10-02 06:02:32 -07:00
|
|
|
(flush stdout; Terminfo.standout false);
|
1998-09-02 11:21:00 -07:00
|
|
|
let c = lb.lex_buffer.[pos + pos0] in
|
|
|
|
print_char c;
|
|
|
|
bol := (c = '\n')
|
|
|
|
done;
|
1998-10-02 06:02:32 -07:00
|
|
|
flush stdout;
|
1998-09-02 11:21:00 -07:00
|
|
|
(* Make sure standout mode is over *)
|
|
|
|
Terminfo.standout false;
|
|
|
|
(* Position cursor back to original location *)
|
|
|
|
Terminfo.resume !num_loc_lines;
|
2000-10-31 06:55:30 -08:00
|
|
|
flush stdout;
|
1998-09-02 11:21:00 -07:00
|
|
|
true;
|
|
|
|
with Exit -> false
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
(* Print the location in some way or another *)
|
|
|
|
|
2000-03-06 14:12:09 -08:00
|
|
|
open Format
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1995-09-08 01:55:59 -07:00
|
|
|
let reset () =
|
|
|
|
num_loc_lines := 0
|
|
|
|
|
1999-12-30 05:12:10 -08:00
|
|
|
let (msg_file, msg_line, msg_chars, msg_to, msg_colon, msg_head) =
|
1996-11-07 03:01:05 -08:00
|
|
|
match Sys.os_type with
|
1996-11-02 10:03:23 -08:00
|
|
|
| "MacOS" -> ("File \"", "\"; line ", "; characters ", " to ", "", "### ")
|
|
|
|
| _ -> ("File \"", "\", line ", ", characters ", "-", ":", "")
|
|
|
|
|
2000-03-06 14:12:09 -08:00
|
|
|
let print ppf loc =
|
1995-05-04 03:15:53 -07:00
|
|
|
if String.length !input_name = 0 then
|
2000-02-08 12:00:06 -08:00
|
|
|
if highlight_locations loc none then () else
|
2000-03-06 14:12:09 -08:00
|
|
|
fprintf ppf "Characters %i-%i:@." loc.loc_start loc.loc_end
|
1995-05-04 03:15:53 -07:00
|
|
|
else begin
|
1997-02-04 07:40:22 -08:00
|
|
|
let (filename, linenum, linebeg) =
|
|
|
|
Linenum.for_position !input_name loc.loc_start in
|
2000-03-06 14:12:09 -08:00
|
|
|
fprintf ppf "%s%s%s%i" msg_file filename msg_line linenum;
|
|
|
|
fprintf ppf "%s%i" msg_chars (loc.loc_start - linebeg);
|
|
|
|
fprintf ppf "%s%i%s@.%s"
|
|
|
|
msg_to (loc.loc_end - linebeg) msg_colon msg_head;
|
1995-05-04 03:15:53 -07:00
|
|
|
end
|
|
|
|
|
2000-03-06 14:12:09 -08:00
|
|
|
let print_warning loc ppf w =
|
2000-10-26 06:38:43 -07:00
|
|
|
if Warnings.is_active w then begin
|
|
|
|
let printw ppf w =
|
|
|
|
let n = Warnings.print ppf w in
|
|
|
|
num_loc_lines := !num_loc_lines + n
|
|
|
|
in
|
2000-10-31 06:55:30 -08:00
|
|
|
fprintf ppf "%a" print loc;
|
|
|
|
fprintf ppf "Warning: %a@." printw w;
|
|
|
|
pp_print_flush ppf ();
|
2000-10-26 06:38:43 -07:00
|
|
|
incr num_loc_lines;
|
|
|
|
end
|
1998-11-05 00:02:52 -08:00
|
|
|
;;
|
1995-09-08 01:55:59 -07:00
|
|
|
|
2000-03-06 14:12:09 -08:00
|
|
|
let prerr_warning loc w = print_warning loc err_formatter w;;
|
|
|
|
|
1997-04-15 12:18:41 -07:00
|
|
|
let echo_eof () =
|
|
|
|
print_newline ();
|
1997-05-13 07:45:28 -07:00
|
|
|
incr num_loc_lines
|