aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/cErrors.ml27
-rw-r--r--lib/cErrors.mli5
-rw-r--r--lib/cThread.ml18
-rw-r--r--lib/cThread.mli4
-rw-r--r--lib/cUnix.ml8
-rw-r--r--lib/cUnix.mli2
-rw-r--r--lib/clib.mllib3
-rw-r--r--lib/feedback.ml194
-rw-r--r--lib/feedback.mli62
-rw-r--r--lib/flags.ml25
-rw-r--r--lib/flags.mli38
-rw-r--r--lib/future.ml18
-rw-r--r--lib/future.mli15
-rw-r--r--lib/pp.ml280
-rw-r--r--lib/pp.mli121
-rw-r--r--lib/pp_control.ml93
-rw-r--r--lib/pp_control.mli38
-rw-r--r--lib/ppstyle.ml73
-rw-r--r--lib/ppstyle.mli63
-rw-r--r--lib/richpp.ml203
-rw-r--r--lib/richpp.mli64
-rw-r--r--lib/unicode.ml24
-rw-r--r--lib/util.ml8
23 files changed, 246 insertions, 1140 deletions
diff --git a/lib/cErrors.ml b/lib/cErrors.ml
index dbebe6a48..1c1ff7e2f 100644
--- a/lib/cErrors.ml
+++ b/lib/cErrors.ml
@@ -16,16 +16,6 @@ let push = Backtrace.add_backtrace
exception Anomaly of string option * std_ppcmds (* System errors *)
-(* XXX: To move to common tagging functions in Pp, blocked on tag
- * system cleanup as we cannot define generic error tags now.
- *
- * Anyways, tagging should not happen here, but in the specific
- * listener to the msg_* stuff.
- *)
-let tag_err_str s = tag Ppstyle.(Tag.inj error_tag tag) (str s) ++ spc ()
-let err_str = tag_err_str "Error:"
-let ann_str = tag_err_str "Anomaly:"
-
let _ =
let pr = function
| Anomaly (s, pp) -> Some ("\"Anomaly: " ^ string_of_ppcmds pp ^ "\"")
@@ -102,9 +92,8 @@ let print_backtrace e = match Backtrace.get_backtrace e with
let print_anomaly askreport e =
if askreport then
- hov 0 (ann_str ++ raw_anomaly e ++ spc () ++
- strbrk "Please report at " ++ str Coq_config.wwwbugtracker ++
- str ".")
+ hov 0 (str "Anomaly" ++ spc () ++ quote (raw_anomaly e) ++ spc ()) ++
+ hov 0 (str "Please report at " ++ str Coq_config.wwwbugtracker ++ str ".")
else
hov 0 (raw_anomaly e)
@@ -124,7 +113,7 @@ let iprint_no_report (e, info) =
let _ = register_handler begin function
| UserError(s, pps) ->
- hov 0 (err_str ++ where s ++ pps)
+ hov 0 (where s ++ pps)
| _ -> raise Unhandled
end
@@ -147,13 +136,3 @@ let handled e =
let bottom _ = raise Bottom in
try let _ = print_gen bottom !handle_stack e in true
with Bottom -> false
-
-(** Prints info which is either an error or
- an anomaly and then exits with the appropriate
- error code *)
-
-let fatal_error info anomaly =
- let msg = info ++ fnl () in
- pp_with ~pp_tag:Ppstyle.pp_tag !Pp_control.err_ft msg;
- Format.pp_print_flush !Pp_control.err_ft ();
- exit (if anomaly then 129 else 1)
diff --git a/lib/cErrors.mli b/lib/cErrors.mli
index 5cffc725d..0665a8ce7 100644
--- a/lib/cErrors.mli
+++ b/lib/cErrors.mli
@@ -98,8 +98,3 @@ val noncritical : exn -> bool
(** Check whether an exception is handled by some toplevel printer. The
[Anomaly] exception is never handled. *)
val handled : exn -> bool
-
-(** Prints info which is either an error or
- an anomaly and then exits with the appropriate
- error code *)
-val fatal_error : Pp.std_ppcmds -> bool -> 'a
diff --git a/lib/cThread.ml b/lib/cThread.ml
index 4f60a6974..9f642b3ce 100644
--- a/lib/cThread.ml
+++ b/lib/cThread.ml
@@ -36,7 +36,7 @@ let really_read_fd fd s off len =
let really_read_fd_2_oc fd oc len =
let i = ref 0 in
let size = 4096 in
- let s = String.create size in
+ let s = Bytes.create size in
while !i < len do
let len = len - !i in
let r = thread_friendly_read_fd fd s ~off:0 ~len:(min len size) in
@@ -55,11 +55,13 @@ let thread_friendly_really_read_line ic =
try
let fd = Unix.descr_of_in_channel ic in
let b = Buffer.create 1024 in
- let s = String.make 1 '\000' in
- while s <> "\n" do
+ let s = Bytes.make 1 '\000' in
+ let endl = Bytes.of_string "\n" in
+ (* Bytes.equal is in 4.03.0 *)
+ while Bytes.compare s endl <> 0 do
let n = thread_friendly_read_fd fd s ~off:0 ~len:1 in
if n = 0 then raise End_of_file;
- if s <> "\n" then Buffer.add_string b s;
+ if Bytes.compare s endl <> 0 then Buffer.add_bytes b s;
done;
Buffer.contents b
with Unix.Unix_error _ -> raise End_of_file
@@ -67,15 +69,15 @@ let thread_friendly_really_read_line ic =
let thread_friendly_input_value ic =
try
let fd = Unix.descr_of_in_channel ic in
- let header = String.create Marshal.header_size in
+ let header = Bytes.create Marshal.header_size in
really_read_fd fd header 0 Marshal.header_size;
let body_size = Marshal.data_size header 0 in
let desired_size = body_size + Marshal.header_size in
if desired_size <= Sys.max_string_length then begin
- let msg = String.create desired_size in
- String.blit header 0 msg 0 Marshal.header_size;
+ let msg = Bytes.create desired_size in
+ Bytes.blit header 0 msg 0 Marshal.header_size;
really_read_fd fd msg Marshal.header_size body_size;
- Marshal.from_string msg 0
+ Marshal.from_bytes msg 0
end else begin
(* Workaround for 32 bit systems and data > 16M *)
let name, oc =
diff --git a/lib/cThread.mli b/lib/cThread.mli
index 7302dfb55..36477a116 100644
--- a/lib/cThread.mli
+++ b/lib/cThread.mli
@@ -19,8 +19,8 @@ val prepare_in_channel_for_thread_friendly_io : in_channel -> thread_ic
val thread_friendly_input_value : thread_ic -> 'a
val thread_friendly_read :
- thread_ic -> string -> off:int -> len:int -> int
+ thread_ic -> Bytes.t -> off:int -> len:int -> int
val thread_friendly_really_read :
- thread_ic -> string -> off:int -> len:int -> unit
+ thread_ic -> Bytes.t -> off:int -> len:int -> unit
val thread_friendly_really_read_line : thread_ic -> string
diff --git a/lib/cUnix.ml b/lib/cUnix.ml
index cb436511f..2542b9751 100644
--- a/lib/cUnix.ml
+++ b/lib/cUnix.ml
@@ -91,15 +91,15 @@ let rec waitpid_non_intr pid =
let run_command ?(hook=(fun _ ->())) c =
let result = Buffer.create 127 in
let cin,cout,cerr = Unix.open_process_full c (Unix.environment ()) in
- let buff = String.make 127 ' ' in
- let buffe = String.make 127 ' ' in
+ let buff = Bytes.make 127 ' ' in
+ let buffe = Bytes.make 127 ' ' in
let n = ref 0 in
let ne = ref 0 in
while n:= input cin buff 0 127 ; ne := input cerr buffe 0 127 ;
!n+ !ne <> 0
do
- let r = String.sub buff 0 !n in (hook r; Buffer.add_string result r);
- let r = String.sub buffe 0 !ne in (hook r; Buffer.add_string result r);
+ let r = Bytes.sub buff 0 !n in (hook r; Buffer.add_bytes result r);
+ let r = Bytes.sub buffe 0 !ne in (hook r; Buffer.add_bytes result r);
done;
(Unix.close_process_full (cin,cout,cerr), Buffer.contents result)
diff --git a/lib/cUnix.mli b/lib/cUnix.mli
index f03719c3d..c6bcf6347 100644
--- a/lib/cUnix.mli
+++ b/lib/cUnix.mli
@@ -46,7 +46,7 @@ val file_readable_p : string -> bool
is called on each elements read on stdout or stderr. *)
val run_command :
- ?hook:(string->unit) -> string -> Unix.process_status * string
+ ?hook:(bytes->unit) -> string -> Unix.process_status * string
(** [sys_command] launches program [prog] with arguments [args].
It behaves like [Sys.command], except that we rely on
diff --git a/lib/clib.mllib b/lib/clib.mllib
index 1e33173ee..c73ae9b90 100644
--- a/lib/clib.mllib
+++ b/lib/clib.mllib
@@ -15,7 +15,6 @@ Store
Exninfo
Backtrace
IStream
-Pp_control
Flags
Control
Loc
@@ -28,8 +27,6 @@ CStack
Util
Stateid
Pp
-Ppstyle
-Richpp
Feedback
CUnix
Envars
diff --git a/lib/feedback.ml b/lib/feedback.ml
index 57c6f30a4..df6fe3a62 100644
--- a/lib/feedback.ml
+++ b/lib/feedback.ml
@@ -15,9 +15,6 @@ type level =
| Warning
| Error
-type edit_id = int
-type state_id = Stateid.t
-type edit_or_state_id = Edit of edit_id | State of state_id
type route_id = int
type feedback_content =
@@ -35,158 +32,29 @@ type feedback_content =
(* Extra metadata *)
| Custom of Loc.t * string * xml
(* Generic messages *)
- | Message of level * Loc.t option * Richpp.richpp
+ | Message of level * Loc.t option * Pp.std_ppcmds
type feedback = {
- id : edit_or_state_id;
+ id : Stateid.t;
+ route : route_id;
contents : feedback_content;
- route : route_id;
}
let default_route = 0
-(** Feedback and logging *)
-open Pp
-open Pp_control
-
-type logger = ?loc:Loc.t -> level -> std_ppcmds -> unit
-
-let msgnl_with ?pp_tag fmt strm = msg_with ?pp_tag fmt (strm ++ fnl ())
-
-(* XXX: This is really painful! *)
-module Emacs = struct
-
- (* Special chars for emacs, to detect warnings inside goal output *)
- let emacs_quote_start = String.make 1 (Char.chr 254)
- let emacs_quote_end = String.make 1 (Char.chr 255)
-
- let emacs_quote_err g =
- hov 0 (str emacs_quote_start ++ g ++ str emacs_quote_end)
-
- let emacs_quote_info_start = "<infomsg>"
- let emacs_quote_info_end = "</infomsg>"
-
- let emacs_quote_info g =
- hov 0 (str emacs_quote_info_start++ brk(0,0) ++ g ++ brk(0,0) ++ str emacs_quote_info_end)
-
-end
-
-open Emacs
-
-let dbg_str = tag Ppstyle.(Tag.inj debug_tag tag) (str "Debug:") ++ spc ()
-let info_str = mt ()
-let warn_str = tag Ppstyle.(Tag.inj warning_tag tag) (str "Warning:") ++ spc ()
-let err_str = tag Ppstyle.(Tag.inj error_tag tag) (str "Error:" ) ++ spc ()
-
-let make_body quoter info ?loc s =
- let loc = Option.cata Pp.pr_loc (Pp.mt ()) loc in
- quoter (hov 0 (loc ++ info ++ s))
-
-(* Generic logger *)
-let gen_logger dbg err ?pp_tag ?loc level msg = match level with
- | Debug -> msgnl_with ?pp_tag !std_ft (make_body dbg dbg_str ?loc msg)
- | Info -> msgnl_with ?pp_tag !std_ft (make_body dbg info_str ?loc msg)
- | Notice -> msgnl_with ?pp_tag !std_ft msg
- | Warning -> Flags.if_warn (fun () ->
- msgnl_with ?pp_tag !err_ft (make_body err warn_str ?loc msg)) ()
- | Error -> msgnl_with ?pp_tag !err_ft (make_body err err_str ?loc msg)
-
-(* We provide a generic clear_log_backend callback for backends
- wanting to do clenaup after the print.
-*)
-let std_logger_tag = ref None
-let std_logger_cleanup = ref (fun () -> ())
-
-let std_logger ?loc level msg =
- gen_logger (fun x -> x) (fun x -> x) ?pp_tag:!std_logger_tag ?loc level msg;
- !std_logger_cleanup ()
-
-(* Rules for emacs:
- - Debug/info: emacs_quote_info
- - Warning/Error: emacs_quote_err
- - Notice: unquoted
-
- Note the inconsistency.
- *)
-let emacs_logger = gen_logger emacs_quote_info emacs_quote_err ?pp_tag:None
-
-(** Color logging. Moved from pp_style, it may need some more refactoring *)
-
-(** Not thread-safe. We should put a lock somewhere if we print from
- different threads. Do we? *)
-let make_style_stack () =
- (** Default tag is to reset everything *)
- let empty = Terminal.make () in
- let default_tag = Terminal.({
- fg_color = Some `DEFAULT;
- bg_color = Some `DEFAULT;
- bold = Some false;
- italic = Some false;
- underline = Some false;
- negative = Some false;
- })
- in
- let style_stack = ref [] in
- let peek () = match !style_stack with
- | [] -> default_tag (** Anomalous case, but for robustness *)
- | st :: _ -> st
- in
- let push tag =
- let style = match Ppstyle.get_style tag with
- | None -> empty
- | Some st -> st
- in
- (** Use the merging of the latest tag and the one being currently pushed.
- This may be useful if for instance the latest tag changes the background and
- the current one the foreground, so that the two effects are additioned. *)
- let style = Terminal.merge (peek ()) style in
- style_stack := style :: !style_stack;
- Terminal.eval style
- in
- let pop _ = match !style_stack with
- | [] -> (** Something went wrong, we fallback *)
- Terminal.eval default_tag
- | _ :: rem -> style_stack := rem;
- Terminal.eval (peek ())
- in
- let clear () = style_stack := [] in
- push, pop, clear
-
-let init_color_output () =
- let open Pp_control in
- let push_tag, pop_tag, clear_tag = make_style_stack () in
- std_logger_cleanup := clear_tag;
- std_logger_tag := Some Ppstyle.pp_tag;
- let tag_handler = {
- Format.mark_open_tag = push_tag;
- Format.mark_close_tag = pop_tag;
- Format.print_open_tag = ignore;
- Format.print_close_tag = ignore;
- } in
- Format.pp_set_mark_tags !std_ft true;
- Format.pp_set_mark_tags !err_ft true;
- Format.pp_set_formatter_tag_functions !std_ft tag_handler;
- Format.pp_set_formatter_tag_functions !err_ft tag_handler
-
-let logger = ref std_logger
-let set_logger l = logger := l
-
-let msg_info ?loc x = !logger ?loc Info x
-let msg_notice ?loc x = !logger ?loc Notice x
-let msg_warning ?loc x = !logger ?loc Warning x
-let msg_error ?loc x = !logger ?loc Error x
-let msg_debug ?loc x = !logger ?loc Debug x
-
(** Feeders *)
-let feeders = ref []
-let add_feeder f = feeders := f :: !feeders
+let feeders : (int, feedback -> unit) Hashtbl.t = Hashtbl.create 7
+
+let add_feeder =
+ let f_id = ref 0 in fun f ->
+ incr f_id;
+ Hashtbl.add feeders !f_id f;
+ !f_id
-let debug_feeder = function
- | { contents = Message (Debug, loc, pp) } ->
- msg_debug ?loc (Pp.str (Richpp.raw_print pp))
- | _ -> ()
+let del_feeder fid = Hashtbl.remove feeders fid
-let feedback_id = ref (Edit 0)
+let default_route = 0
+let feedback_id = ref Stateid.dummy
let feedback_route = ref default_route
let set_id_for_feedback ?(route=default_route) i =
@@ -198,34 +66,14 @@ let feedback ?id ?route what =
route = Option.default !feedback_route route;
id = Option.default !feedback_id id;
} in
- List.iter (fun f -> f m) !feeders
+ Hashtbl.iter (fun _ f -> f m) feeders
+(* Logging messages *)
let feedback_logger ?loc lvl msg =
- feedback ~route:!feedback_route ~id:!feedback_id
- (Message (lvl, loc, Richpp.richpp_of_pp msg))
-
-(* Output to file *)
-let ft_logger old_logger ft ?loc level mesg =
- let id x = x in
- match level with
- | Debug -> msgnl_with ft (make_body id dbg_str mesg)
- | Info -> msgnl_with ft (make_body id info_str mesg)
- | Notice -> msgnl_with ft mesg
- | Warning -> old_logger ?loc level mesg
- | Error -> old_logger ?loc level mesg
-
-let with_output_to_file fname func input =
- let old_logger = !logger in
- let channel = open_out (String.concat "." [fname; "out"]) in
- logger := ft_logger old_logger (Format.formatter_of_out_channel channel);
- try
- let output = func input in
- logger := old_logger;
- close_out channel;
- output
- with reraise ->
- let reraise = Backtrace.add_backtrace reraise in
- logger := old_logger;
- close_out channel;
- Exninfo.iraise reraise
+ feedback ~route:!feedback_route ~id:!feedback_id (Message (lvl, loc, msg))
+let msg_info ?loc x = feedback_logger ?loc Info x
+let msg_notice ?loc x = feedback_logger ?loc Notice x
+let msg_warning ?loc x = feedback_logger ?loc Warning x
+let msg_error ?loc x = feedback_logger ?loc Error x
+let msg_debug ?loc x = feedback_logger ?loc Debug x
diff --git a/lib/feedback.mli b/lib/feedback.mli
index b4bed8793..bdd236ac7 100644
--- a/lib/feedback.mli
+++ b/lib/feedback.mli
@@ -8,7 +8,7 @@
open Xml_datatype
-(* Old plain messages (used to be in Pp) *)
+(* Legacy-style logging messages (used to be in Pp) *)
type level =
| Debug
| Info
@@ -17,11 +17,7 @@ type level =
| Error
-(** Coq "semantic" infos obtained during parsing/execution *)
-type edit_id = int
-type state_id = Stateid.t
-type edit_or_state_id = Edit of edit_id | State of state_id
-
+(** Coq "semantic" infos obtained during execution *)
type route_id = int
val default_route : route_id
@@ -44,59 +40,33 @@ type feedback_content =
(* Extra metadata *)
| Custom of Loc.t * string * xml
(* Generic messages *)
- | Message of level * Loc.t option * Richpp.richpp
+ | Message of level * Loc.t option * Pp.std_ppcmds
type feedback = {
- id : edit_or_state_id; (* The document part concerned *)
- contents : feedback_content; (* The payload *)
+ id : Stateid.t; (* The document part concerned *)
route : route_id; (* Extra routing info *)
+ contents : feedback_content; (* The payload *)
}
(** {6 Feedback sent, even asynchronously, to the user interface} *)
-(** Moved here from pp.ml *)
-
-(* Morally the parser gets a string and an edit_id, and gives back an AST.
- * Feedbacks during the parsing phase are attached to this edit_id.
- * The interpreter assignes an exec_id to the ast, and feedbacks happening
- * during interpretation are attached to the exec_id.
- * Only one among state_id and edit_id can be provided. *)
-
-(** A [logger] takes a level plus a pretty printing doc and logs it *)
-type logger = ?loc:Loc.t -> level -> Pp.std_ppcmds -> unit
-
-(** [set_logger l] makes the [msg_*] to use [l] for logging *)
-val set_logger : logger -> unit
-
-(** [std_logger] standard logger to [stdout/stderr] *)
-val std_logger : logger
-
-(** [init_color_output ()] Enable color in the std_logger *)
-val init_color_output : unit -> unit
+(* The interpreter assignes an state_id to the ast, and feedbacks happening
+ * during interpretation are attached to it.
+ *)
-(** [feedback_logger] will produce feedback messages instead IO events *)
-val feedback_logger : logger
-val emacs_logger : logger
+(** [add_feeder f] adds a feeder listiner [f], returning its id *)
+val add_feeder : (feedback -> unit) -> int
-
-(** [add_feeder] feeders observe the feedback *)
-val add_feeder : (feedback -> unit) -> unit
-
-(** Prints feedback messages of kind Message(Debug,_) using msg_debug *)
-val debug_feeder : feedback -> unit
+(** [del_feeder fid] removes the feeder with id [fid] *)
+val del_feeder : int -> unit
(** [feedback ?id ?route fb] produces feedback fb, with [route] and
[id] set appropiatedly, if absent, it will use the defaults set by
[set_id_for_feedback] *)
-val feedback :
- ?id:edit_or_state_id -> ?route:route_id -> feedback_content -> unit
+val feedback : ?id:Stateid.t -> ?route:route_id -> feedback_content -> unit
(** [set_id_for_feedback route id] Set the defaults for feedback *)
-val set_id_for_feedback : ?route:route_id -> edit_or_state_id -> unit
-
-(** [with_output_to_file file f x] executes [f x] with logging
- redirected to a file [file] *)
-val with_output_to_file : string -> ('a -> 'b) -> 'a -> 'b
+val set_id_for_feedback : ?route:route_id -> Stateid.t -> unit
(** {6 output functions}
@@ -125,7 +95,3 @@ val msg_error : ?loc:Loc.t -> Pp.std_ppcmds -> unit
val msg_debug : ?loc:Loc.t -> Pp.std_ppcmds -> unit
(** For debugging purposes *)
-
-
-
-
diff --git a/lib/flags.ml b/lib/flags.ml
index 5b080151c..00f515b5a 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -86,8 +86,6 @@ let in_toplevel = ref false
let profile = false
let print_emacs = ref false
-let coqtop_ui = ref false
-
let xml_export = ref false
let ide_slave = ref false
@@ -97,7 +95,6 @@ let time = ref false
let raw_print = ref false
-let record_print = ref true
let univ_print = ref false
@@ -146,16 +143,16 @@ let beautify = ref false
let beautify_file = ref false
(* Silent / Verbose *)
-let silent = ref false
-let make_silent flag = silent := flag; ()
-let is_silent () = !silent
-let is_verbose () = not !silent
+let quiet = ref false
+let silently f x = with_option quiet f x
+let verbosely f x = without_option quiet f x
-let silently f x = with_option silent f x
-let verbosely f x = without_option silent f x
+let if_silent f x = if !quiet then f x
+let if_verbose f x = if not !quiet then f x
-let if_silent f x = if !silent then f x
-let if_verbose f x = if not !silent then f x
+let make_silent flag = quiet := flag
+let is_silent () = !quiet
+let is_verbose () = not !quiet
let auto_intros = ref true
let make_auto_intros flag = auto_intros := flag
@@ -183,12 +180,6 @@ let warn = ref true
let make_warn flag = warn := flag; ()
let if_warn f x = if !warn then f x
-(* The number of printed hypothesis in a goal *)
-
-let print_hyps_limit = ref (None : int option)
-let set_print_hyps_limit n = print_hyps_limit := n
-let print_hyps_limit () = !print_hyps_limit
-
(* Flags for external tools *)
let browser_cmd_fmt =
diff --git a/lib/flags.mli b/lib/flags.mli
index bd365e653..0b00ac13c 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -8,6 +8,8 @@
(** Global options of the system. *)
+(** Command-line flags *)
+
val boot : bool ref
val load_init : bool ref
@@ -16,8 +18,11 @@ type compilation_mode = BuildVo | BuildVio | Vio2Vo
val compilation_mode : compilation_mode ref
val compilation_output_name : string option ref
+(* Flag set when the test-suite is called. Its only effect to display
+ verbose information for `Fail` *)
val test_mode : bool ref
+(** Async-related flags *)
type async_proofs = APoff | APonLazy | APon
val async_proofs_mode : async_proofs ref
type cache = Force
@@ -46,20 +51,27 @@ val in_toplevel : bool ref
val profile : bool
-val print_emacs : bool ref
-val coqtop_ui : bool ref
+(* Legacy flags *)
+(* -emacs option: printing includes emacs tags, will affect stm caching. *)
+val print_emacs : bool ref
+(* -xml option: xml hooks will be called *)
val xml_export : bool ref
+(* -ide_slave: printing will be more verbose, will affect stm caching *)
val ide_slave : bool ref
val ideslave_coqtop_flags : string option ref
+(* -time option: every command will be wrapped with `Time` *)
val time : bool ref
+(* development flag to detect race conditions, it should go away. *)
val we_are_parsing : bool ref
+(* Set Printing All flag. For some reason it is a global flag *)
val raw_print : bool ref
-val record_print : bool ref
+
+(* Univ print flag, never set anywere. Maybe should belong to Univ? *)
val univ_print : bool ref
type compat_version = V8_2 | V8_3 | V8_4 | V8_5 | V8_6 | Current
@@ -69,17 +81,27 @@ val version_strictly_greater : compat_version -> bool
val version_less_or_equal : compat_version -> bool
val pr_version : compat_version -> string
+(* Beautify command line flags, should move to printing? *)
val beautify : bool ref
val beautify_file : bool ref
-val make_silent : bool -> unit
-val is_silent : unit -> bool
-val is_verbose : unit -> bool
+(* Coq quiet mode. Note that normal mode is called "verbose" here,
+ whereas [quiet] supresses normal output such as goals in coqtop *)
+val quiet : bool ref
val silently : ('a -> 'b) -> 'a -> 'b
val verbosely : ('a -> 'b) -> 'a -> 'b
val if_silent : ('a -> unit) -> 'a -> unit
val if_verbose : ('a -> unit) -> 'a -> unit
+(* Deprecated *)
+val make_silent : bool -> unit
+[@@ocaml.deprecated "Please use Flags.quiet"]
+val is_silent : unit -> bool
+[@@ocaml.deprecated "Please use Flags.quiet"]
+val is_verbose : unit -> bool
+[@@ocaml.deprecated "Please use Flags.quiet"]
+
+(* Miscellaneus flags for vernac *)
val make_auto_intros : bool -> unit
val is_auto_intros : unit -> bool
@@ -111,10 +133,6 @@ val without_option : bool ref -> ('a -> 'b) -> 'a -> 'b
(** Temporarily extends the reference to a list *)
val with_extra_values : 'c list ref -> 'c list -> ('a -> 'b) -> 'a -> 'b
-(** If [None], no limit *)
-val set_print_hyps_limit : int option -> unit
-val print_hyps_limit : unit -> int option
-
(** Options for external tools *)
(** Returns string format for default browser to use from Coq or CoqIDE *)
diff --git a/lib/future.ml b/lib/future.ml
index ea0382a63..1360b7ac4 100644
--- a/lib/future.ml
+++ b/lib/future.ml
@@ -151,8 +151,8 @@ let chain ~pure ck f =
create ~uuid ~name fix_exn (match !c with
| Closure _ | Delegated _ -> Closure (fun () -> f (force ~pure ck))
| Exn _ as x -> x
- | Val (v, None) when pure -> Closure (fun () -> f v)
- | Val (v, Some _) when pure -> Closure (fun () -> f v)
+ | Val (v, None) when pure -> Val (f v, None)
+ | Val (v, Some _) when pure -> Val (f v, None)
| Val (v, Some state) -> Closure (fun () -> !unfreeze state; f v)
| Val (v, None) ->
match !ck with
@@ -191,9 +191,9 @@ let transactify f x =
let purify_future f x = if is_over x then f x else purify f x
let compute x = purify_future (compute ~pure:false) x
let force ~pure x = purify_future (force ~pure) x
-let chain ?(greedy=true) ~pure x f =
+let chain ~pure x f =
let y = chain ~pure x f in
- if is_over x && greedy then ignore(force ~pure y);
+ if is_over x then ignore(force ~pure y);
y
let force x = force ~pure:false x
@@ -204,13 +204,13 @@ let join kx =
let sink kx = if is_val kx then ignore(join kx)
-let split2 ?greedy x =
- chain ?greedy ~pure:true x (fun x -> fst x),
- chain ?greedy ~pure:true x (fun x -> snd x)
+let split2 x =
+ chain ~pure:true x (fun x -> fst x),
+ chain ~pure:true x (fun x -> snd x)
-let map2 ?greedy f x l =
+let map2 f x l =
CList.map_i (fun i y ->
- let xi = chain ?greedy ~pure:true x (fun x ->
+ let xi = chain ~pure:true x (fun x ->
try List.nth x i
with Failure _ | Invalid_argument _ ->
CErrors.anomaly (Pp.str "Future.map2 length mismatch")) in
diff --git a/lib/future.mli b/lib/future.mli
index c780faf32..2a025ae84 100644
--- a/lib/future.mli
+++ b/lib/future.mli
@@ -113,8 +113,9 @@ val is_exn : 'a computation -> bool
val peek_val : 'a computation -> 'a option
val uuid : 'a computation -> UUID.t
-(* [chain greedy pure c f] chains computation [c] with [f].
- * The [greedy] and [pure] parameters are tricky:
+(* [chain pure c f] chains computation [c] with [f].
+ * [chain] forces immediately the new computation if the old one is_over (Exn or Val).
+ * The [pure] parameter is tricky:
* [pure]:
* When pure is true, the returned computation will not keep a copy
* of the global state.
@@ -124,10 +125,8 @@ val uuid : 'a computation -> UUID.t
* one forces c' and then c''.
* [join c; chain ~pure:false c g] is invalid and fails at runtime.
* [force c; chain ~pure:false c g] is correct.
- * [greedy]:
- * The [greedy] parameter forces immediately the new computation if
- * the old one is_over (Exn or Val). Defaults to true. *)
-val chain : ?greedy:bool -> pure:bool ->
+ *)
+val chain : pure:bool ->
'a computation -> ('a -> 'b) -> 'b computation
(* Forcing a computation *)
@@ -143,9 +142,9 @@ val join : 'a computation -> 'a
val sink : 'a computation -> unit
(*** Utility functions ************************************************* ***)
-val split2 : ?greedy:bool ->
+val split2 :
('a * 'b) computation -> 'a computation * 'b computation
-val map2 : ?greedy:bool ->
+val map2 :
('a computation -> 'b -> 'c) ->
'a list computation -> 'b list -> 'c list
diff --git a/lib/pp.ml b/lib/pp.ml
index f3bb47539..66feae761 100644
--- a/lib/pp.ml
+++ b/lib/pp.ml
@@ -6,64 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-module Glue : sig
-
- (** The [Glue] module implements a container data structure with
- efficient concatenation. *)
-
- type 'a t
-
- val atom : 'a -> 'a t
- val glue : 'a t -> 'a t -> 'a t
- val empty : 'a t
- val is_empty : 'a t -> bool
- val iter : ('a -> unit) -> 'a t -> unit
-
-end = struct
-
- type 'a t = GEmpty | GLeaf of 'a | GNode of 'a t * 'a t
-
- let atom x = GLeaf x
-
- let glue x y =
- match x, y with
- | GEmpty, _ -> y
- | _, GEmpty -> x
- | _, _ -> GNode (x,y)
-
- let empty = GEmpty
-
- let is_empty x = x = GEmpty
-
- let rec iter f = function
- | GEmpty -> ()
- | GLeaf x -> f x
- | GNode (x,y) -> iter f x; iter f y
-
-end
-
-module Tag :
-sig
- type t
- type 'a key
- val create : string -> 'a key
- val inj : 'a -> 'a key -> t
- val prj : t -> 'a key -> 'a option
-end =
-struct
-
-module Dyn = Dyn.Make(struct end)
-
-type t = Dyn.t
-type 'a key = 'a Dyn.tag
-let create = Dyn.create
-let inj = Dyn.Easy.inj
-let prj = Dyn.Easy.prj
-
-end
-
-open Pp_control
-
(* The different kinds of blocks are:
\begin{description}
\item[hbox:] Horizontal block no line breaking;
@@ -72,54 +14,35 @@ open Pp_control
this block is small enough to fit on a single line
\item[hovbox:] Horizontal or Vertical block: breaks lead to new line
only when necessary to print the content of the block
- \item[tbox:] Tabulation block: go to tabulation marks and no line breaking
- (except if no mark yet on the reste of the line)
\end{description}
*)
+type pp_tag = string
+
type block_type =
- | Pp_hbox of int
- | Pp_vbox of int
- | Pp_hvbox of int
+ | Pp_hbox of int
+ | Pp_vbox of int
+ | Pp_hvbox of int
| Pp_hovbox of int
- | Pp_tbox
-
-type str_token =
-| Str_def of string
-| Str_len of string * int (** provided length *)
-type 'a ppcmd_token =
- | Ppcmd_print of 'a
- | Ppcmd_box of block_type * ('a ppcmd_token Glue.t)
+type doc_view =
+ | Ppcmd_empty
+ | Ppcmd_string of string
+ | Ppcmd_glue of doc_view list
+ | Ppcmd_box of block_type * doc_view
+ | Ppcmd_tag of pp_tag * doc_view
+ (* Are those redundant? *)
| Ppcmd_print_break of int * int
- | Ppcmd_set_tab
- | Ppcmd_print_tbreak of int * int
- | Ppcmd_white_space of int
| Ppcmd_force_newline
- | Ppcmd_print_if_broken
- | Ppcmd_open_box of block_type
- | Ppcmd_close_box
- | Ppcmd_close_tbox
| Ppcmd_comment of string list
- | Ppcmd_open_tag of Tag.t
- | Ppcmd_close_tag
-
-type 'a ppdir_token =
- | Ppdir_ppcmds of 'a ppcmd_token Glue.t
- | Ppdir_print_newline
- | Ppdir_print_flush
-
-type ppcmd = str_token ppcmd_token
-
-type std_ppcmds = ppcmd Glue.t
-type 'a ppdirs = 'a ppdir_token Glue.t
+(* Following discussion on #390, we play on the safe side and make the
+ internal representation opaque here. *)
+type t = doc_view
+type std_ppcmds = t
-let (++) = Glue.glue
-
-let app = Glue.glue
-
-let is_empty g = Glue.is_empty g
+let repr x = x
+let unrepr x = x
(* Compute length of an UTF-8 encoded string
Rem 1 : utf8_length <= String.length (equal if pure ascii)
@@ -157,25 +80,32 @@ let utf8_length s =
done ;
!cnt
+let app s1 s2 = match s1, s2 with
+ | Ppcmd_empty, s
+ | s, Ppcmd_empty -> s
+ | s1, s2 -> Ppcmd_glue [s1; s2]
+
+let seq s = Ppcmd_glue s
+
+let (++) = app
+
(* formatting commands *)
-let str s = Glue.atom(Ppcmd_print (Str_def s))
-let stras (i, s) = Glue.atom(Ppcmd_print (Str_len (s, i)))
-let brk (a,b) = Glue.atom(Ppcmd_print_break (a,b))
-let tbrk (a,b) = Glue.atom(Ppcmd_print_tbreak (a,b))
-let tab () = Glue.atom(Ppcmd_set_tab)
-let fnl () = Glue.atom(Ppcmd_force_newline)
-let pifb () = Glue.atom(Ppcmd_print_if_broken)
-let ws n = Glue.atom(Ppcmd_white_space n)
-let comment l = Glue.atom(Ppcmd_comment l)
+let str s = Ppcmd_string s
+let brk (a,b) = Ppcmd_print_break (a,b)
+let fnl () = Ppcmd_force_newline
+let ws n = Ppcmd_print_break (n,0)
+let comment l = Ppcmd_comment l
(* derived commands *)
-let mt () = Glue.empty
-let spc () = Glue.atom(Ppcmd_print_break (1,0))
-let cut () = Glue.atom(Ppcmd_print_break (0,0))
-let align () = Glue.atom(Ppcmd_print_break (0,0))
-let int n = str (string_of_int n)
-let real r = str (string_of_float r)
-let bool b = str (string_of_bool b)
+let mt () = Ppcmd_empty
+let spc () = Ppcmd_print_break (1,0)
+let cut () = Ppcmd_print_break (0,0)
+let align () = Ppcmd_print_break (0,0)
+let int n = str (string_of_int n)
+let real r = str (string_of_float r)
+let bool b = str (string_of_bool b)
+
+(* XXX: To Remove *)
let strbrk s =
let rec aux p n =
if n < String.length s then
@@ -184,50 +114,18 @@ let strbrk s =
else str (String.sub s p (n-p)) :: spc () :: aux (n+1) (n+1)
else aux p (n + 1)
else if p = n then [] else [str (String.sub s p (n-p))]
- in List.fold_left (++) Glue.empty (aux 0 0)
-
-let pr_loc_pos loc =
- if Loc.is_ghost loc then (str"<unknown>")
- else
- let loc = Loc.unloc loc in
- int (fst loc) ++ str"-" ++ int (snd loc)
-
-let pr_loc loc =
- if Loc.is_ghost loc then str"<unknown>" ++ fnl ()
- else
- let fname = loc.Loc.fname in
- if CString.equal fname "" then
- Loc.(str"Toplevel input, characters " ++ int loc.bp ++
- str"-" ++ int loc.ep ++ str":" ++ fnl ())
- else
- Loc.(str"File " ++ str "\"" ++ str fname ++ str "\"" ++
- str", line " ++ int loc.line_nb ++ str", characters " ++
- int (loc.bp-loc.bol_pos) ++ str"-" ++ int (loc.ep-loc.bol_pos) ++
- str":" ++ fnl())
+ in Ppcmd_glue (aux 0 0)
-let ismt = is_empty
+let ismt = function | Ppcmd_empty -> true | _ -> false
(* boxing commands *)
-let h n s = Glue.atom(Ppcmd_box(Pp_hbox n,s))
-let v n s = Glue.atom(Ppcmd_box(Pp_vbox n,s))
-let hv n s = Glue.atom(Ppcmd_box(Pp_hvbox n,s))
-let hov n s = Glue.atom(Ppcmd_box(Pp_hovbox n,s))
-let t s = Glue.atom(Ppcmd_box(Pp_tbox,s))
-
-(* Opening and closing of boxes *)
-let hb n = Glue.atom(Ppcmd_open_box(Pp_hbox n))
-let vb n = Glue.atom(Ppcmd_open_box(Pp_vbox n))
-let hvb n = Glue.atom(Ppcmd_open_box(Pp_hvbox n))
-let hovb n = Glue.atom(Ppcmd_open_box(Pp_hovbox n))
-let tb () = Glue.atom(Ppcmd_open_box Pp_tbox)
-let close () = Glue.atom(Ppcmd_close_box)
-let tclose () = Glue.atom(Ppcmd_close_tbox)
+let h n s = Ppcmd_box(Pp_hbox n,s)
+let v n s = Ppcmd_box(Pp_vbox n,s)
+let hv n s = Ppcmd_box(Pp_hvbox n,s)
+let hov n s = Ppcmd_box(Pp_hovbox n,s)
(* Opening and closed of tags *)
-let open_tag t = Glue.atom(Ppcmd_open_tag t)
-let close_tag () = Glue.atom(Ppcmd_close_tag)
-let tag t s = open_tag t ++ s ++ close_tag ()
-let eval_ppcmds l = l
+let tag t s = Ppcmd_tag(t,s)
(* In new syntax only double quote char is escaped by repeating it *)
let escape_string s =
@@ -254,71 +152,34 @@ let rec pr_com ft s =
Some s2 -> Format.pp_force_newline ft (); pr_com ft s2
| None -> ()
-type tag_handler = Tag.t -> Format.tag
-
(* pretty printing functions *)
-let pp_dirs ?pp_tag ft =
- let pp_open_box = function
+let pp_with ft =
+ let cpp_open_box = function
| Pp_hbox n -> Format.pp_open_hbox ft ()
| Pp_vbox n -> Format.pp_open_vbox ft n
| Pp_hvbox n -> Format.pp_open_hvbox ft n
| Pp_hovbox n -> Format.pp_open_hovbox ft n
- | Pp_tbox -> Format.pp_open_tbox ft ()
in
- let rec pp_cmd = function
- | Ppcmd_print tok ->
- begin match tok with
- | Str_def s ->
- let n = utf8_length s in
- Format.pp_print_as ft n s
- | Str_len (s, n) ->
- Format.pp_print_as ft n s
- end
- | Ppcmd_box(bty,ss) -> (* Prevent evaluation of the stream! *)
- pp_open_box bty ;
- if not (Format.over_max_boxes ()) then Glue.iter pp_cmd ss;
- Format.pp_close_box ft ()
- | Ppcmd_open_box bty -> pp_open_box bty
- | Ppcmd_close_box -> Format.pp_close_box ft ()
- | Ppcmd_close_tbox -> Format.pp_close_tbox ft ()
- | Ppcmd_white_space n -> Format.pp_print_break ft n 0
- | Ppcmd_print_break(m,n) -> Format.pp_print_break ft m n
- | Ppcmd_set_tab -> Format.pp_set_tab ft ()
- | Ppcmd_print_tbreak(m,n) -> Format.pp_print_tbreak ft m n
- | Ppcmd_force_newline -> Format.pp_force_newline ft ()
- | Ppcmd_print_if_broken -> Format.pp_print_if_newline ft ()
+ let rec pp_cmd = let open Format in function
+ | Ppcmd_empty -> ()
+ | Ppcmd_glue sl -> List.iter pp_cmd sl
+ | Ppcmd_string str -> let n = utf8_length str in
+ pp_print_as ft n str
+ | Ppcmd_box(bty,ss) -> cpp_open_box bty ;
+ if not (over_max_boxes ()) then pp_cmd ss;
+ pp_close_box ft ()
+ | Ppcmd_print_break(m,n) -> pp_print_break ft m n
+ | Ppcmd_force_newline -> pp_force_newline ft ()
| Ppcmd_comment coms -> List.iter (pr_com ft) coms
- | Ppcmd_open_tag tag ->
- begin match pp_tag with
- | None -> ()
- | Some f -> Format.pp_open_tag ft (f tag)
- end
- | Ppcmd_close_tag ->
- begin match pp_tag with
- | None -> ()
- | Some _ -> Format.pp_close_tag ft ()
- end
- in
- let pp_dir = function
- | Ppdir_ppcmds cmdstream -> Glue.iter pp_cmd cmdstream
- | Ppdir_print_newline -> Format.pp_print_newline ft ()
- | Ppdir_print_flush -> Format.pp_print_flush ft ()
+ | Ppcmd_tag(tag, s) -> pp_open_tag ft tag;
+ pp_cmd s;
+ pp_close_tag ft ()
in
- fun (dirstream : _ ppdirs) ->
- try
- Glue.iter pp_dir dirstream
- with reraise ->
- let reraise = Backtrace.add_backtrace reraise in
- let () = Format.pp_print_flush ft () in
- Exninfo.iraise reraise
-
-(* pretty printing functions WITHOUT FLUSH *)
-let pp_with ?pp_tag ft strm =
- pp_dirs ?pp_tag ft (Glue.atom (Ppdir_ppcmds strm))
-
-(* pretty printing functions WITH FLUSH *)
-let msg_with ?pp_tag ft strm =
- pp_dirs ?pp_tag ft (Glue.atom(Ppdir_ppcmds strm) ++ Glue.atom(Ppdir_print_flush))
+ try pp_cmd
+ with reraise ->
+ let reraise = Backtrace.add_backtrace reraise in
+ let () = Format.pp_print_flush ft () in
+ Exninfo.iraise reraise
(* If mixing some output and a goal display, please use msg_warning,
so that interfaces (proofgeneral for example) can easily dispatch
@@ -326,7 +187,7 @@ let msg_with ?pp_tag ft strm =
(** Output to a string formatter *)
let string_of_ppcmds c =
- Format.fprintf Format.str_formatter "@[%a@]" (msg_with ?pp_tag:None) c;
+ Format.fprintf Format.str_formatter "@[%a@]" pp_with c;
Format.flush_str_formatter ()
(* Copy paste from Util *)
@@ -353,7 +214,7 @@ let pr_nth n =
(* [prlist pr [a ; ... ; c]] outputs [pr a ++ ... ++ pr c] *)
-let prlist pr l = List.fold_left (fun x e -> x ++ pr e) Glue.empty l
+let prlist pr l = Ppcmd_glue (List.map pr l)
(* unlike all other functions below, [prlist] works lazily.
if a strict behavior is needed, use [prlist_strict] instead.
@@ -418,4 +279,3 @@ let prvect_with_sep sep elem v = prvecti_with_sep sep (fun _ -> elem) v
let prvect elem v = prvect_with_sep mt elem v
let surround p = hov 1 (str"(" ++ p ++ str")")
-
diff --git a/lib/pp.mli b/lib/pp.mli
index 8342a983d..7a191b01a 100644
--- a/lib/pp.mli
+++ b/lib/pp.mli
@@ -6,19 +6,65 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(** Pretty-printers. *)
+(** Coq document type. *)
+
+(** Pretty printing guidelines ******************************************)
+(* *)
+(* `Pp.t` or `Pp.std_ppcmds` is the main pretty printing document type *)
+(* in the Coq system. Documents are composed laying out boxes, and *)
+(* users can add arbitrary tag metadata that backends are free *)
+(* *)
+(* The datatype has a public view to allow serialization or advanced *)
+(* uses, however regular users are _strongly_ warned againt its use, *)
+(* they should instead rely on the available functions below. *)
+(* *)
+(* Box order and number is indeed an important factor. Try to create *)
+(* a proper amount of boxes. The `++` operator provides "efficient" *)
+(* concatenation, but using the list constructors is usually preferred. *)
+(* *)
+(* That is to say, this: *)
+(* *)
+(* `hov [str "Term"; hov (pr_term t); str "is defined"]` *)
+(* *)
+(* is preferred to: *)
+(* *)
+(* `hov (str "Term" ++ hov (pr_term t) ++ str "is defined")` *)
+(* *)
+(************************************************************************)
-type std_ppcmds
+(* XXX: Improve and add attributes *)
+type pp_tag = string
+
+(* Following discussion on #390, we play on the safe side and make the
+ internal representation opaque here. *)
+type t
+type std_ppcmds = t
+
+type block_type =
+ | Pp_hbox of int
+ | Pp_vbox of int
+ | Pp_hvbox of int
+ | Pp_hovbox of int
+
+type doc_view =
+ | Ppcmd_empty
+ | Ppcmd_string of string
+ | Ppcmd_glue of t list
+ | Ppcmd_box of block_type * t
+ | Ppcmd_tag of pp_tag * t
+ (* Are those redundant? *)
+ | Ppcmd_print_break of int * int
+ | Ppcmd_force_newline
+ | Ppcmd_comment of string list
+
+val repr : std_ppcmds -> doc_view
+val unrepr : doc_view -> std_ppcmds
(** {6 Formatting commands} *)
val str : string -> std_ppcmds
-val stras : int * string -> std_ppcmds
val brk : int * int -> std_ppcmds
-val tbrk : int * int -> std_ppcmds
-val tab : unit -> std_ppcmds
val fnl : unit -> std_ppcmds
-val pifb : unit -> std_ppcmds
val ws : int -> std_ppcmds
val mt : unit -> std_ppcmds
val ismt : std_ppcmds -> bool
@@ -30,15 +76,12 @@ val comment : string list -> std_ppcmds
val app : std_ppcmds -> std_ppcmds -> std_ppcmds
(** Concatenation. *)
+val seq : std_ppcmds list -> std_ppcmds
+(** Multi-Concatenation. *)
+
val (++) : std_ppcmds -> std_ppcmds -> std_ppcmds
(** Infix alias for [app]. *)
-val eval_ppcmds : std_ppcmds -> std_ppcmds
-(** Force computation. *)
-
-val is_empty : std_ppcmds -> bool
-(** Test emptyness. *)
-
(** {6 Derived commands} *)
val spc : unit -> std_ppcmds
@@ -58,46 +101,10 @@ val h : int -> std_ppcmds -> std_ppcmds
val v : int -> std_ppcmds -> std_ppcmds
val hv : int -> std_ppcmds -> std_ppcmds
val hov : int -> std_ppcmds -> std_ppcmds
-val t : std_ppcmds -> std_ppcmds
-
-(** {6 Opening and closing of boxes} *)
-
-val hb : int -> std_ppcmds
-val vb : int -> std_ppcmds
-val hvb : int -> std_ppcmds
-val hovb : int -> std_ppcmds
-val tb : unit -> std_ppcmds
-val close : unit -> std_ppcmds
-val tclose : unit -> std_ppcmds
-
-(** {6 Opening and closing of tags} *)
-
-module Tag :
-sig
- type t
- (** Type of tags. Tags are dynamic types comparable to {Dyn.t}. *)
-
- type 'a key
- (** Keys used to inject tags *)
- val create : string -> 'a key
- (** Create a key with the given name. Two keys cannot share the same name, if
- ever this is the case this function raises an assertion failure. *)
+(** {6 Tagging} *)
- val inj : 'a -> 'a key -> t
- (** Inject an object into a tag. *)
-
- val prj : t -> 'a key -> 'a option
- (** Project an object from a tag. *)
-end
-
-val tag : Tag.t -> std_ppcmds -> std_ppcmds
-val open_tag : Tag.t -> std_ppcmds
-val close_tag : unit -> std_ppcmds
-
-(** {6 Utilities} *)
-
-val string_of_ppcmds : std_ppcmds -> string
+val tag : pp_tag -> std_ppcmds -> std_ppcmds
(** {6 Printing combinators} *)
@@ -165,15 +172,9 @@ val surround : std_ppcmds -> std_ppcmds
val pr_vertical_list : ('b -> std_ppcmds) -> 'b list -> std_ppcmds
-val pr_loc : Loc.t -> std_ppcmds
-
-(** {6 Low-level pretty-printing functions with and without flush} *)
+(** {6 Main renderers, to formatter and to string } *)
-(** FIXME: These ignore the logging settings and call [Format] directly *)
-type tag_handler = Tag.t -> Format.tag
+(** [pp_with fmt pp] Print [pp] to [fmt] and don't flush [fmt] *)
+val pp_with : Format.formatter -> std_ppcmds -> unit
-(** [msg_with ?pp_tag fmt pp] Print [pp] to [fmt] and flush [fmt] *)
-val msg_with : ?pp_tag:tag_handler -> Format.formatter -> std_ppcmds -> unit
-
-(** [msg_with ?pp_tag fmt pp] Print [pp] to [fmt] and don't flush [fmt] *)
-val pp_with : ?pp_tag:tag_handler -> Format.formatter -> std_ppcmds -> unit
+val string_of_ppcmds : std_ppcmds -> string
diff --git a/lib/pp_control.ml b/lib/pp_control.ml
deleted file mode 100644
index 890ffe0a1..000000000
--- a/lib/pp_control.ml
+++ /dev/null
@@ -1,93 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(* Parameters of pretty-printing *)
-
-type pp_global_params = {
- margin : int;
- max_indent : int;
- max_depth : int;
- ellipsis : string }
-
-(* Default parameters of pretty-printing *)
-
-let dflt_gp = {
- margin = 78;
- max_indent = 50;
- max_depth = 50;
- ellipsis = "..." }
-
-(* A deeper pretty-printer to print proof scripts *)
-
-let deep_gp = {
- margin = 78;
- max_indent = 50;
- max_depth = 10000;
- ellipsis = "..." }
-
-(* set_gp : Format.formatter -> pp_global_params -> unit
- * set the parameters of a formatter *)
-
-let set_gp ft gp =
- Format.pp_set_margin ft gp.margin ;
- Format.pp_set_max_indent ft gp.max_indent ;
- Format.pp_set_max_boxes ft gp.max_depth ;
- Format.pp_set_ellipsis_text ft gp.ellipsis
-
-let set_dflt_gp ft = set_gp ft dflt_gp
-
-let get_gp ft =
- { margin = Format.pp_get_margin ft ();
- max_indent = Format.pp_get_max_indent ft ();
- max_depth = Format.pp_get_max_boxes ft ();
- ellipsis = Format.pp_get_ellipsis_text ft () }
-
-(* with_fp : 'a pp_formatter_params -> Format.formatter
- * returns of formatter for given formatter functions *)
-
-let with_fp chan out_function flush_function =
- let ft = Format.make_formatter out_function flush_function in
- Format.pp_set_formatter_out_channel ft chan;
- ft
-
-(* Output on a channel ch *)
-
-let with_output_to ch =
- let ft = with_fp ch (output ch) (fun () -> flush ch) in
- set_gp ft deep_gp;
- ft
-
-let std_ft = ref Format.std_formatter
-let _ = set_dflt_gp !std_ft
-
-let err_ft = ref Format.err_formatter
-let _ = set_gp !err_ft deep_gp
-
-let deep_ft = ref (with_output_to stdout)
-let _ = set_gp !deep_ft deep_gp
-
-(* For parametrization through vernacular *)
-let default = Format.pp_get_max_boxes !std_ft ()
-let default_margin = Format.pp_get_margin !std_ft ()
-
-let get_depth_boxes () = Some (Format.pp_get_max_boxes !std_ft ())
-let set_depth_boxes v =
- Format.pp_set_max_boxes !std_ft (match v with None -> default | Some v -> v)
-
-let get_margin () = Some (Format.pp_get_margin !std_ft ())
-let set_margin v =
- let v = match v with None -> default_margin | Some v -> v in
- Format.pp_set_margin Format.str_formatter v;
- Format.pp_set_margin !std_ft v;
- Format.pp_set_margin !deep_ft v;
- (* Heuristic, based on usage: the column on the right of max_indent
- column is 20% of width, capped to 30 characters *)
- let m = max (64 * v / 100) (v-30) in
- Format.pp_set_max_indent Format.str_formatter m;
- Format.pp_set_max_indent !std_ft m;
- Format.pp_set_max_indent !deep_ft m
diff --git a/lib/pp_control.mli b/lib/pp_control.mli
deleted file mode 100644
index d26f89eb3..000000000
--- a/lib/pp_control.mli
+++ /dev/null
@@ -1,38 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(** Parameters of pretty-printing. *)
-
-type pp_global_params = {
- margin : int;
- max_indent : int;
- max_depth : int;
- ellipsis : string }
-
-val dflt_gp : pp_global_params
-val deep_gp : pp_global_params
-val set_gp : Format.formatter -> pp_global_params -> unit
-val set_dflt_gp : Format.formatter -> unit
-val get_gp : Format.formatter -> pp_global_params
-
-
-(** {6 Output functions of pretty-printing. } *)
-
-val with_output_to : out_channel -> Format.formatter
-
-val std_ft : Format.formatter ref
-val err_ft : Format.formatter ref
-val deep_ft : Format.formatter ref
-
-(** {6 For parametrization through vernacular. } *)
-
-val set_depth_boxes : int option -> unit
-val get_depth_boxes : unit -> int option
-
-val set_margin : int option -> unit
-val get_margin : unit -> int option
diff --git a/lib/ppstyle.ml b/lib/ppstyle.ml
deleted file mode 100644
index aa47c5167..000000000
--- a/lib/ppstyle.ml
+++ /dev/null
@@ -1,73 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-module String = CString
-
-type t = string
-(** We use the concatenated string, with dots separating each string. We
- forbid the use of dots in the strings. *)
-
-let tags : Terminal.style option String.Map.t ref = ref String.Map.empty
-
-let make ?style tag =
- let check s = if String.contains s '.' then invalid_arg "Ppstyle.make" in
- let () = List.iter check tag in
- let name = String.concat "." tag in
- let () = assert (not (String.Map.mem name !tags)) in
- let () = tags := String.Map.add name style !tags in
- name
-
-let repr t = String.split '.' t
-
-let get_style tag =
- try String.Map.find tag !tags with Not_found -> assert false
-
-let set_style tag st =
- try tags := String.Map.update tag st !tags with Not_found -> assert false
-
-let clear_styles () =
- tags := String.Map.map (fun _ -> None) !tags
-
-let dump () = String.Map.bindings !tags
-
-let parse_config s =
- let styles = Terminal.parse s in
- let set accu (name, st) =
- try String.Map.update name (Some st) accu with Not_found -> accu
- in
- tags := List.fold_left set !tags styles
-
-let tag = Pp.Tag.create "ppstyle"
-
-(** Default tag is to reset everything *)
-let default = Terminal.({
- fg_color = Some `DEFAULT;
- bg_color = Some `DEFAULT;
- bold = Some false;
- italic = Some false;
- underline = Some false;
- negative = Some false;
-})
-
-let empty = Terminal.make ()
-
-let error_tag =
- let style = Terminal.make ~bold:true ~fg_color:`WHITE ~bg_color:`RED () in
- make ~style ["message"; "error"]
-
-let warning_tag =
- let style = Terminal.make ~bold:true ~fg_color:`WHITE ~bg_color:`YELLOW () in
- make ~style ["message"; "warning"]
-
-let debug_tag =
- let style = Terminal.make ~bold:true ~fg_color:`WHITE ~bg_color:`MAGENTA () in
- make ~style ["message"; "debug"]
-
-let pp_tag t = match Pp.Tag.prj t tag with
-| None -> ""
-| Some key -> key
diff --git a/lib/ppstyle.mli b/lib/ppstyle.mli
deleted file mode 100644
index d9fd75765..000000000
--- a/lib/ppstyle.mli
+++ /dev/null
@@ -1,63 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(** Highlighting of printers. Used for pretty-printing terms that should be
- displayed on a color-capable terminal. *)
-
-(** {5 Style tags} *)
-
-type t = string
-
-(** Style tags *)
-
-val make : ?style:Terminal.style -> string list -> t
-(** Create a new tag with the given name. Each name must be unique. The optional
- style is taken as the default one. *)
-
-val repr : t -> string list
-(** Gives back the original name of the style tag where each string has been
- concatenated and separated with a dot. *)
-
-val tag : t Pp.Tag.key
-(** An annotation for styles *)
-
-(** {5 Manipulating global styles} *)
-
-val get_style : t -> Terminal.style option
-(** Get the style associated to a tag. *)
-
-val set_style : t -> Terminal.style option -> unit
-(** Set a style associated to a tag. *)
-
-val clear_styles : unit -> unit
-(** Clear all styles. *)
-
-val parse_config : string -> unit
-(** Add all styles from the given string as parsed by {!Terminal.parse}.
- Unregistered tags are ignored. *)
-
-val dump : unit -> (t * Terminal.style option) list
-(** Recover the list of known tags together with their current style. *)
-
-(** {5 Color output} *)
-
-val pp_tag : Pp.tag_handler
-(** Returns the name of a style tag that is understandable by the formatters
- that have been inititialized through {!init_color_output}. To be used with
- {!Pp.pp_with}. *)
-
-(** {5 Tags} *)
-
-val error_tag : t
-(** Tag used by the {!Pp.msg_error} function. *)
-
-val warning_tag : t
-(** Tag used by the {!Pp.msg_warning} function. *)
-
-val debug_tag : t
-(** Tag used by the {!Pp.msg_debug} function. *)
diff --git a/lib/richpp.ml b/lib/richpp.ml
deleted file mode 100644
index d1c6d158e..000000000
--- a/lib/richpp.ml
+++ /dev/null
@@ -1,203 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-open Util
-open Xml_datatype
-
-type 'annotation located = {
- annotation : 'annotation option;
- startpos : int;
- endpos : int
-}
-
-type 'a stack =
-| Leaf
-| Node of string * 'a located gxml list * int * 'a stack
-
-type 'a context = {
- mutable stack : 'a stack;
- (** Pending opened nodes *)
- mutable offset : int;
- (** Quantity of characters printed so far *)
- mutable annotations : 'a option Int.Map.t;
- (** Map associating annotations to indexes *)
- mutable index : int;
- (** Current index of annotations *)
-}
-
-(** We use Format to introduce tags inside the pretty-printed document.
- Each inserted tag is a fresh index that we keep in sync with the contents
- of annotations.
-
- We build an XML tree on the fly, by plugging ourselves in Format tag
- marking functions. As those functions are called when actually writing to
- the device, the resulting tree is correct.
-*)
-let rich_pp annotate ppcmds =
-
- let context = {
- stack = Leaf;
- offset = 0;
- annotations = Int.Map.empty;
- index = (-1);
- } in
-
- let pp_tag obj =
- let index = context.index + 1 in
- let () = context.index <- index in
- let obj = annotate obj in
- let () = context.annotations <- Int.Map.add index obj context.annotations in
- string_of_int index
- in
-
- let pp_buffer = Buffer.create 180 in
-
- let push_pcdata () =
- (** Push the optional PCData on the above node *)
- let len = Buffer.length pp_buffer in
- if len = 0 then ()
- else match context.stack with
- | Leaf -> assert false
- | Node (node, child, pos, ctx) ->
- let data = Buffer.contents pp_buffer in
- let () = Buffer.clear pp_buffer in
- let () = context.stack <- Node (node, PCData data :: child, pos, ctx) in
- context.offset <- context.offset + len
- in
-
- let open_xml_tag tag =
- let () = push_pcdata () in
- context.stack <- Node (tag, [], context.offset, context.stack)
- in
-
- let close_xml_tag tag =
- let () = push_pcdata () in
- match context.stack with
- | Leaf -> assert false
- | Node (node, child, pos, ctx) ->
- let () = assert (String.equal tag node) in
- let annotation =
- try Int.Map.find (int_of_string node) context.annotations
- with _ -> None
- in
- let annotation = {
- annotation = annotation;
- startpos = pos;
- endpos = context.offset;
- } in
- let xml = Element (node, annotation, List.rev child) in
- match ctx with
- | Leaf ->
- (** Final node: we keep the result in a dummy context *)
- context.stack <- Node ("", [xml], 0, Leaf)
- | Node (node, child, pos, ctx) ->
- context.stack <- Node (node, xml :: child, pos, ctx)
- in
-
- let open Format in
-
- let ft = formatter_of_buffer pp_buffer in
-
- let tag_functions = {
- mark_open_tag = (fun tag -> let () = open_xml_tag tag in "");
- mark_close_tag = (fun tag -> let () = close_xml_tag tag in "");
- print_open_tag = ignore;
- print_close_tag = ignore;
- } in
-
- pp_set_formatter_tag_functions ft tag_functions;
- pp_set_mark_tags ft true;
-
- (* Set formatter width. This is currently a hack and duplicate code
- with Pp_control. Hopefully it will be fixed better in Coq 8.7 *)
- let w = pp_get_margin str_formatter () in
- let m = max (64 * w / 100) (w-30) in
- pp_set_margin ft w;
- pp_set_max_indent ft m;
-
- (** The whole output must be a valid document. To that
- end, we nest the document inside <pp> tags. *)
- pp_open_tag ft "pp";
- Pp.(pp_with ~pp_tag ft ppcmds);
- pp_close_tag ft ();
-
- (** Get the resulting XML tree. *)
- let () = pp_print_flush ft () in
- let () = assert (Buffer.length pp_buffer = 0) in
- match context.stack with
- | Node ("", [xml], 0, Leaf) -> xml
- | _ -> assert false
-
-
-let annotations_positions xml =
- let rec node accu = function
- | Element (_, { annotation = Some annotation; startpos; endpos }, cs) ->
- children ((annotation, (startpos, endpos)) :: accu) cs
- | Element (_, _, cs) ->
- children accu cs
- | _ ->
- accu
- and children accu cs =
- List.fold_left node accu cs
- in
- node [] xml
-
-let xml_of_rich_pp tag_of_annotation attributes_of_annotation xml =
- let rec node = function
- | Element (index, { annotation; startpos; endpos }, cs) ->
- let attributes =
- [ "startpos", string_of_int startpos;
- "endpos", string_of_int endpos
- ]
- @ (match annotation with
- | None -> []
- | Some annotation -> attributes_of_annotation annotation
- )
- in
- let tag =
- match annotation with
- | None -> index
- | Some annotation -> tag_of_annotation annotation
- in
- Element (tag, attributes, List.map node cs)
- | PCData s ->
- PCData s
- in
- node xml
-
-type richpp = xml
-
-let repr xml = xml
-let richpp_of_xml xml = xml
-let richpp_of_string s = PCData s
-
-let richpp_of_pp pp =
- let annotate t = match Pp.Tag.prj t Ppstyle.tag with
- | None -> None
- | Some key -> Some (Ppstyle.repr key)
- in
- let rec drop = function
- | PCData s -> [PCData s]
- | Element (_, annotation, cs) ->
- let cs = List.concat (List.map drop cs) in
- match annotation.annotation with
- | None -> cs
- | Some s -> [Element (String.concat "." s, [], cs)]
- in
- let xml = rich_pp annotate pp in
- Element ("_", [], drop xml)
-
-let raw_print xml =
- let buf = Buffer.create 1024 in
- let rec print = function
- | PCData s -> Buffer.add_string buf s
- | Element (_, _, cs) -> List.iter print cs
- in
- let () = print xml in
- Buffer.contents buf
-
diff --git a/lib/richpp.mli b/lib/richpp.mli
deleted file mode 100644
index 287d265a8..000000000
--- a/lib/richpp.mli
+++ /dev/null
@@ -1,64 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(** This module offers semi-structured pretty-printing. *)
-
-(** Each annotation of the semi-structured document refers to the
- substring it annotates. *)
-type 'annotation located = {
- annotation : 'annotation option;
- startpos : int;
- endpos : int
-}
-
-(** [rich_pp get_annotations ppcmds] returns the interpretation
- of [ppcmds] as a semi-structured document
- that represents (located) annotations of this string.
- The [get_annotations] function is used to convert tags into the desired
- annotation. *)
-val rich_pp :
- (Pp.Tag.t -> 'annotation option) -> Pp.std_ppcmds ->
- 'annotation located Xml_datatype.gxml
-
-(** [annotations_positions ssdoc] returns a list associating each
- annotations with its position in the string from which [ssdoc] is
- built. *)
-val annotations_positions :
- 'annotation located Xml_datatype.gxml ->
- ('annotation * (int * int)) list
-
-(** [xml_of_rich_pp ssdoc] returns an XML representation of the
- semi-structured document [ssdoc]. *)
-val xml_of_rich_pp :
- ('annotation -> string) ->
- ('annotation -> (string * string) list) ->
- 'annotation located Xml_datatype.gxml ->
- Xml_datatype.xml
-
-(** {5 Enriched text} *)
-
-type richpp
-(** Type of text with style annotations *)
-
-val richpp_of_pp : Pp.std_ppcmds -> richpp
-(** Extract style information from formatted text *)
-
-val richpp_of_xml : Xml_datatype.xml -> richpp
-(** Do not use outside of dedicated areas *)
-
-val richpp_of_string : string -> richpp
-(** Make a styled text out of a normal string *)
-
-val repr : richpp -> Xml_datatype.xml
-(** Observe the styled text as XML *)
-
-(** {5 Debug/Compat} *)
-
-(** Represent the semi-structured document as a string, dropping any additional
- information. *)
-val raw_print : richpp -> string
diff --git a/lib/unicode.ml b/lib/unicode.ml
index ced5e258c..959ccaf73 100644
--- a/lib/unicode.ml
+++ b/lib/unicode.ml
@@ -124,27 +124,11 @@ exception End_of_input
let utf8_of_unicode n =
if n < 128 then
String.make 1 (Char.chr n)
- else if n < 2048 then
- let s = String.make 2 (Char.chr (128 + n mod 64)) in
- begin
- s.[0] <- Char.chr (192 + n / 64);
- s
- end
- else if n < 65536 then
- let s = String.make 3 (Char.chr (128 + n mod 64)) in
- begin
- s.[1] <- Char.chr (128 + (n / 64) mod 64);
- s.[0] <- Char.chr (224 + n / 4096);
- s
- end
else
- let s = String.make 4 (Char.chr (128 + n mod 64)) in
- begin
- s.[2] <- Char.chr (128 + (n / 64) mod 64);
- s.[1] <- Char.chr (128 + (n / 4096) mod 64);
- s.[0] <- Char.chr (240 + n / 262144);
- s
- end
+ let (m,s) = if n < 2048 then (2,192) else if n < 65536 then (3,224) else (4,240) in
+ String.init m (fun i ->
+ let j = (n lsr ((m - 1 - i) * 6)) land 63 in
+ Char.chr (j + if i = 0 then s else 128))
(* If [s] is some UTF-8 encoded string
and [i] is a position of some UTF-8 character within [s]
diff --git a/lib/util.ml b/lib/util.ml
index 9fb0d48ee..0d2425f27 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -161,11 +161,11 @@ let iraise = Exninfo.iraise
let open_utf8_file_in fname =
let is_bom s =
- Int.equal (Char.code s.[0]) 0xEF &&
- Int.equal (Char.code s.[1]) 0xBB &&
- Int.equal (Char.code s.[2]) 0xBF
+ Int.equal (Char.code (Bytes.get s 0)) 0xEF &&
+ Int.equal (Char.code (Bytes.get s 1)) 0xBB &&
+ Int.equal (Char.code (Bytes.get s 2)) 0xBF
in
let in_chan = open_in fname in
- let s = " " in
+ let s = Bytes.make 3 ' ' in
if input in_chan s 0 3 < 3 || not (is_bom s) then seek_in in_chan 0;
in_chan