diff --git a/.ocamlformat b/.ocamlformat index 4e1d5ce..0081ed7 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1,2 +1,4 @@ profile = default -margin=90 \ No newline at end of file +margin=90 +parse-docstrings = true +wrap-comments = true diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a498c3..2baa47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [2.0.0] -- current + +### Changed + +- + ## [1.6.1] -- 2024-08-21 ### Fixed diff --git a/minidebug_runtime.ml b/minidebug_runtime.ml index 4a5addd..91b4977 100644 --- a/minidebug_runtime.ml +++ b/minidebug_runtime.ml @@ -212,6 +212,7 @@ module type Debug_runtime = sig val global_prefix : string val snapshot : unit -> unit val description : string + val no_debug_if : bool -> unit end let exceeds ~value ~limit = match limit with None -> false | Some limit -> limit < value @@ -414,6 +415,7 @@ module Flushing (Log_to : Shared_config) : Debug_runtime = struct let global_prefix = global_prefix let snapshot () = () let description = Log_to.description + let no_debug_if _condition = () end let default_html_config = PrintBox_html.Config.(tree_summary true default) @@ -422,8 +424,6 @@ let default_md_config = PrintBox_md.Config.(foldable_trees default) module type PrintBox_runtime = sig include Debug_runtime - val no_debug_if : bool -> unit - type config = { mutable hyperlink : [ `Prefix of string | `No_hyperlinks ]; mutable toc_specific_hyperlink : string option; @@ -454,8 +454,8 @@ let anchor_entry_id ~is_pure_text ~entry_id = let id = Int.to_string entry_id in (* TODO(#40): Not outputting a self-link, since we want the anchor in summaries, mostly to avoid generating tables in HTML. *) - (* let uri = "{#" ^ id ^ "}" in - let inner = if print_entry_ids then B.line uri else B.empty in *) + (* let uri = "{#" ^ id ^ "}" in let inner = if print_entry_ids then B.line uri else + B.empty in *) let anchor = B.anchor ~id B.empty in if is_pure_text then B.hlist ~bars:false [ anchor; B.line " " ] else anchor @@ -887,7 +887,8 @@ module PrintBox (Log_to : Shared_config) = struct | _ -> ()); (* Note: we treat a tree under a box as part of that box. *) stack := - (* Design choice: exclude does not apply to its own entry -- it's about propagating children. *) + (* Design choice: exclude does not apply to its own entry -- it's about propagating + children. *) match !stack with | { highlight = false; _ } :: bs when config.prune_upto >= List.length !stack -> bs | { body = []; _ } :: bs when config.log_level <> Everything -> bs @@ -1171,8 +1172,8 @@ module PrintBox (Log_to : Shared_config) = struct loop sexp let highlight_box ?(hl_body = false) b = - (* Recall the design choice: [exclude] does not apply to its own entry. - Therefore, an entry "propagates its highlight". *) + (* Recall the design choice: [exclude] does not apply to its own entry. Therefore, an + entry "propagates its highlight". *) let hl = match (config.exclude_on_path, config.highlight_terms, hl_body) with | None, None, _ | Some _, None, false -> false @@ -1206,7 +1207,8 @@ module PrintBox (Log_to : Shared_config) = struct let hl_body, bs = List.split @@ List.map loop l in let hl_body = List.exists (fun x -> x) hl_body in let hl, b = - (* Design choice: Don't render headers of multiline values as monospace, to emphasize them. *) + (* Design choice: Don't render headers of multiline values as monospace, to + emphasize them. *) highlight_box ~hl_body @@ if as_tree then B.text s else B.text_with_style B.Style.preformatted s in @@ -1229,7 +1231,7 @@ module PrintBox (Log_to : Shared_config) = struct else "" in if String.length str > 0 && String.length str < config.max_inline_sexp_length then - (* TODO: Desing choice: consider not using monospace, at least for descr. *) + (* TODO: Desing choice: consider not using monospace, at least for descr. *) highlight_box @@ B.text_with_style B.Style.preformatted @@ match descr with None -> str | Some d -> d ^ " = " ^ str diff --git a/minidebug_runtime.mli b/minidebug_runtime.mli index 105fec7..cd9d2ec 100644 --- a/minidebug_runtime.mli +++ b/minidebug_runtime.mli @@ -1,6 +1,6 @@ (** The functors creating a [Debug_runtime] module that {{:http://lukstafi.github.io/ppx_minidebug/ppx_minidebug/Minidebug_runtime/index.html} - [ppx_minidebug]} requires. *) + [ppx_minidebug]} requires. *) type time_tagged = Not_tagged | Clock | Elapsed type elapsed_times = Not_reported | Seconds | Milliseconds | Microseconds | Nanoseconds @@ -13,19 +13,20 @@ type location_format = | Range_line | Range_pos -(** The log levels, for both (in scope) compile time, and for the PrintBox runtime. When considered at - compile time, inspecting strings requires string literals, at runtime it applies to all string values. - Not logging at compile time means the corresponding loggingcode is not generated; not logging at - runtime means the logging state is not updated. *) +(** The log levels, for both (in scope) compile time, and for the PrintBox runtime. When + considered at compile time, inspecting strings requires string literals, at runtime it + applies to all string values. Not logging at compile time means the corresponding + loggingcode is not generated; not logging at runtime means the logging state is not + updated. *) type log_level = | Nothing (** Does not log anything. *) | Prefixed of string array - (** Behaves as [Nonempty_entries] and additionally: only logs "leaf" values when the inspected string - starts with one of the prefixes. *) + (** Behaves as [Nonempty_entries] and additionally: only logs "leaf" values when the + inspected string starts with one of the prefixes. *) | Prefixed_or_result of string array - (** Behaves as [Nonempty_entries] and additionally: only logs "leaf" values when the inspected string - starts with one of the prefixes, or the value is marked as a result. Doesn't output results - of an entry if there are no non-result logs. *) + (** Behaves as [Nonempty_entries] and additionally: only logs "leaf" values when the + inspected string starts with one of the prefixes, or the value is marked as a + result. Doesn't output results of an entry if there are no non-result logs. *) | Nonempty_entries (** Does not log entries without children (treating results as children). *) | Everything (** Does not restrict logging. *) @@ -70,37 +71,39 @@ val shared_config : ?for_append:bool -> string -> (module Shared_config) -(** Sets up a file with the given path, or if [split_files_after] is given, creates a directory - to store the files. By default the logging will not be time tagged and will be appending - to the file / creating more files. If [time_tagged] is [Clock], entries will be tagged with a date - and clock time; if it is [Elapsed], they will be tagged with the time span elapsed since the start - of the process (using [Mtime_clock.elapsed]). - If [split_files_after] is given and [for_append] is false, clears the directory. - If the opened file exceeds [split_files_after] characters, [Shared_config.refresh_ch ()] - returns true; if in that case [Shared_config.debug_ch ()] is called, it will create and return a new file. - - If [elapsed_times] is different from [Not_reported], the elapsed time spans are printed for log - subtrees, in the corresponding units with precision up to 1%. The times include printing out logs, - therefore might not be reliable for profiling. In the runtime creation functions, [elapsed_times] - defaults to [Not_reported]. - - If [print_entry_ids] is true, the [entry_id] identifiers are printed on log headers with the syntax - [{#ID}]; by default they are omitted. If [verbose_entry_ids] is true, the [entry_id] identifiers - are also printed on logged values. - - If [global_prefix] is given, the log header messages (and the log closing messages for the flushing - backend) are prefixed with it. - - If [table_of_contents_ch] is given or [with_table_of_contents=true], outputs selected log headers - to this channel. The provided file name is used as a prefix for links to anchors of the log headers. - Note that debug runtime builders that take a channel instead of a file name, will use [global_prefix] - instead for the anchor links. The setting [toc_entry] controls the selection of headers to include - in a ToC (it defaults to [And []], which means including all entries). *) +(** Sets up a file with the given path, or if [split_files_after] is given, creates a + directory to store the files. By default the logging will not be time tagged and will + be appending to the file / creating more files. If [time_tagged] is [Clock], entries + will be tagged with a date and clock time; if it is [Elapsed], they will be tagged + with the time span elapsed since the start of the process (using + [Mtime_clock.elapsed]). If [split_files_after] is given and [for_append] is false, + clears the directory. If the opened file exceeds [split_files_after] characters, + [Shared_config.refresh_ch ()] returns true; if in that case + [Shared_config.debug_ch ()] is called, it will create and return a new file. + + If [elapsed_times] is different from [Not_reported], the elapsed time spans are + printed for log subtrees, in the corresponding units with precision up to 1%. The + times include printing out logs, therefore might not be reliable for profiling. In the + runtime creation functions, [elapsed_times] defaults to [Not_reported]. + + If [print_entry_ids] is true, the [entry_id] identifiers are printed on log headers + with the syntax [{#ID}]; by default they are omitted. If [verbose_entry_ids] is true, + the [entry_id] identifiers are also printed on logged values. + + If [global_prefix] is given, the log header messages (and the log closing messages for + the flushing backend) are prefixed with it. + + If [table_of_contents_ch] is given or [with_table_of_contents=true], outputs selected + log headers to this channel. The provided file name is used as a prefix for links to + anchors of the log headers. Note that debug runtime builders that take a channel + instead of a file name, will use [global_prefix] instead for the anchor links. The + setting [toc_entry] controls the selection of headers to include in a ToC (it defaults + to [And []], which means including all entries). *) (** When using the {{:http://lukstafi.github.io/ppx_minidebug/ppx_minidebug/Minidebug_runtime/index.html} - [ppx_minidebug]} syntax extension, provide a module called [Debug_runtime] with - this signature in scope of the instrumented code. *) + [ppx_minidebug]} syntax extension, provide a module called [Debug_runtime] with this + signature in scope of the instrumented code. *) module type Debug_runtime = sig val close_log : fname:string -> start_lnum:int -> entry_id:int -> unit @@ -138,18 +141,26 @@ module type Debug_runtime = sig val snapshot : unit -> unit (** For [PrintBox] runtimes, outputs the current logging stack to the logging channel. - If the logging channel supports that, an output following a snapshot will rewind the channel - to the state prior to the snapshot. Does nothing for the [Flushing] runtimes. *) + If the logging channel supports that, an output following a snapshot will rewind the + channel to the state prior to the snapshot. Does nothing for the [Flushing] + runtimes. *) val description : string - (** A description that should be sufficient to locate where the logs end up. - If not configured explicitly, it will be some combination of: - the global prefix, the file name or "stdout". *) + (** A description that should be sufficient to locate where the logs end up. If not + configured explicitly, it will be some combination of: the global prefix, the file + name or "stdout". *) + + val no_debug_if : bool -> unit + (** For [PrintBox] runtimes, when passed true within the scope of a log subtree, + disables the logging of this subtree and its subtrees. Does not do anything when + passed false ([no_debug_if false] does {e not} re-enable the log). Does nothing for + the [Flushing] runtimes. *) end -(** The output is flushed line-at-a-time, so no output should be lost if the traced program crashes. - The logged traces are still indented, but if the values to print are multi-line, their formatting - might be messy. The indentation is also smaller (half of PrintBox). *) +(** The output is flushed line-at-a-time, so no output should be lost if the traced + program crashes. The logged traces are still indented, but if the values to print are + multi-line, their formatting might be messy. The indentation is also smaller (half of + PrintBox). *) module Flushing : functor (_ : Shared_config) -> Debug_runtime val default_html_config : PrintBox_html.Config.t @@ -158,78 +169,81 @@ val default_md_config : PrintBox_md.Config.t module type PrintBox_runtime = sig include Debug_runtime - val no_debug_if : bool -> unit - (** When passed true within the scope of a log subtree, disables the logging of this subtree and its - subtrees. Does not do anything when passed false ([no_debug_if false] does {e not} re-enable - the log). *) - type config = { mutable hyperlink : [ `Prefix of string | `No_hyperlinks ]; (** If [hyperlink] is [`Prefix prefix], code pointers are rendered as hyperlinks. - When [prefix] is either empty, starts with a dot, or starts with ["http:"] or ["https:"], - the link address has the form [sprintf "%s#L%d" fname start_lnum], allowing browsing in HTML directly. - Otherwise, it has the form [sprintf "%s:%d:%d" fname start_lnum (start_colnum + 1)], - intended for editor-specific prefixes such as ["vscode://file/"]. - - Note that rendering a link on a node will make the node non-foldable, therefore it is best - to combine [`prefix prefix] with [values_first_mode]. *) + When [prefix] is either empty, starts with a dot, or starts with ["http:"] or + ["https:"], the link address has the form [sprintf "%s#L%d" fname start_lnum], + allowing browsing in HTML directly. Otherwise, it has the form + [sprintf "%s:%d:%d" fname start_lnum (start_colnum + 1)], intended for + editor-specific prefixes such as ["vscode://file/"]. + + Note that rendering a link on a node will make the node non-foldable, + therefore it is best to combine [`prefix prefix] with [values_first_mode]. *) mutable toc_specific_hyperlink : string option; - (** If provided, overrides [hyperlink] as the prefix used for generating URIs pointing to anchors - in logs. *) + (** If provided, overrides [hyperlink] as the prefix used for generating URIs + pointing to anchors in logs. *) mutable backend : [ `Text | `Html of PrintBox_html.Config.t | `Markdown of PrintBox_md.Config.t ]; - (** If the content is [`Text], logs are generated as monospaced text; for other settings as html - or markdown. *) + (** If the content is [`Text], logs are generated as monospaced text; for other + settings as html or markdown. *) mutable boxify_sexp_from_size : int; - (** If positive, [Sexp.t]-based logs with this many or more atoms are converted to print-boxes - before logging. Disabled by default (i.e. negative). *) + (** If positive, [Sexp.t]-based logs with this many or more atoms are converted to + print-boxes before logging. Disabled by default (i.e. negative). *) mutable highlight_terms : Re.re option; - (** Uses a highlight style for logs on paths ending with a log matching the regular expression. *) + (** Uses a highlight style for logs on paths ending with a log matching the + regular expression. *) mutable exclude_on_path : Re.re option; - (** Does not propagate the highlight status from child logs through log headers matching - the given regular expression. *) + (** Does not propagate the highlight status from child logs through log headers + matching the given regular expression. *) mutable prune_upto : int; - (** At depths lower than [prune_upto] (or equal if counting from 1) only ouptputs highlighted boxes. - This makes it simpler to trim excessive logging while still providing some context. - Defaults to [0] -- no pruning. *) + (** At depths lower than [prune_upto] (or equal if counting from 1) only ouptputs + highlighted boxes. This makes it simpler to trim excessive logging while still + providing some context. Defaults to [0] -- no pruning. *) mutable truncate_children : int; - (** If > 0, only the given number of the most recent children is kept at each node. - Defaults to [0] -- keep all (no pruning). *) + (** If > 0, only the given number of the most recent children is kept at each + node. Defaults to [0] -- keep all (no pruning). *) mutable values_first_mode : bool; - (** If set to true, does not put the source code location of a computation as a header of its subtree. - Rather, puts the result of the computation as the header of a computation subtree, - if rendered as a single line -- or just the name, and puts the result near the top. - If false, puts the result at the end of the computation subtree, i.e. preserves the order - of the computation. *) + (** If set to true, does not put the source code location of a computation as a + header of its subtree. Rather, puts the result of the computation as the + header of a computation subtree, if rendered as a single line -- or just the + name, and puts the result near the top. If false, puts the result at the end + of the computation subtree, i.e. preserves the order of the computation. *) mutable max_inline_sexp_size : int; - (** Maximal size (in atoms) up to which a sexp value can be inlined during "boxification". *) + (** Maximal size (in atoms) up to which a sexp value can be inlined during + "boxification". *) mutable max_inline_sexp_length : int; - (** Maximal length (in characters/bytes) up to which a sexp value can be inlined during "boxification". *) + (** Maximal length (in characters/bytes) up to which a sexp value can be inlined + during "boxification". *) mutable log_level : log_level; (** How much to log, see {!type:log_level}. *) mutable snapshot_every_sec : float option; - (** If given, output a snapshot of the pending logs when at least the given time (in seconds) has - passed since the previous output. This is only checked at calls to log values. *) + (** If given, output a snapshot of the pending logs when at least the given time + (in seconds) has passed since the previous output. This is only checked at + calls to log values. *) mutable sexp_unescape_strings : bool; - (** If true, when a value is a sexp atom or is decomposed into a sexp atom by boxification, it is - not printed as a sexp, but the string of the atom is printed directly. Defaults to [true]. *) + (** If true, when a value is a sexp atom or is decomposed into a sexp atom by + boxification, it is not printed as a sexp, but the string of the atom is + printed directly. Defaults to [true]. *) mutable with_toc_listing : bool; - (** If true, outputs non-collapsed trees of ToC entries in the Table of Contents files. *) + (** If true, outputs non-collapsed trees of ToC entries in the Table of Contents + files. *) mutable toc_flame_graph : bool; - (** If true, outputs a minimalistic rendering of a flame graph in the Table of Contents files, with - boxes positioned to reflect both the ToC entries hierarchy and elapsed times for the opening - and closing of entries. Not supported in the [`Text] backend. *) + (** If true, outputs a minimalistic rendering of a flame graph in the Table of + Contents files, with boxes positioned to reflect both the ToC entries + hierarchy and elapsed times for the opening and closing of entries. Not + supported in the [`Text] backend. *) mutable flame_graph_separation : int; - (** How many pixels a single box, for a log header, is expected to take in a flame graph. Defaults to [40]. - Note: ideally the height of a flame tree should be calculated automatically, then this setting - would disappear. *) + (** How many pixels a single box, for a log header, is expected to take in a flame + graph. Defaults to [40]. Note: ideally the height of a flame tree should be + calculated automatically, then this setting would disappear. *) } val config : config end -(** The logged traces will be pretty-printed as trees using the `printbox` package. This logger - supports conditionally disabling a particular nesting of the logs, regardless of where - in the nesting level [no_debug_if] is called. *) +(** The logged traces will be pretty-printed as trees using the `printbox` package. This + logger supports conditionally disabling a particular nesting of the logs, regardless + of where in the nesting level [no_debug_if] is called. *) module PrintBox : functor (_ : Shared_config) -> PrintBox_runtime val debug_file : @@ -259,18 +273,19 @@ val debug_file : ?snapshot_every_sec:float -> string -> (module PrintBox_runtime) -(** Creates a PrintBox-based debug runtime configured to output html or markdown to a file with - the given name suffixed with [".log"], [".html"] or [".md"] depending on the backend. - By default the logging will not be time tagged and the file will be created or erased by - this function. The default [boxify_sexp_from_size] value is 50. - - Setting [~with_toc_listing:true] or [~toc_flame_graph:true] or both will create an additional - log file, the given name suffixed with ["-toc"] and the corresponding file name extension. This file - will collect selected entries, hyperlinking to anchors in the main logging file(s). - - By default [backend] is [`Markdown PrintBox.default_md_config]. - See {!type:PrintBox.config} for details about PrintBox-specific parameters. - See {!shared_config} for the details about shared parameters. *) +(** Creates a PrintBox-based debug runtime configured to output html or markdown to a file + with the given name suffixed with [".log"], [".html"] or [".md"] depending on the + backend. By default the logging will not be time tagged and the file will be created + or erased by this function. The default [boxify_sexp_from_size] value is 50. + + Setting [~with_toc_listing:true] or [~toc_flame_graph:true] or both will create an + additional log file, the given name suffixed with ["-toc"] and the corresponding file + name extension. This file will collect selected entries, hyperlinking to anchors in + the main logging file(s). + + By default [backend] is [`Markdown PrintBox.default_md_config]. See + {!type:PrintBox.config} for details about PrintBox-specific parameters. See + {!shared_config} for the details about shared parameters. *) val debug : ?debug_ch:out_channel -> @@ -293,11 +308,11 @@ val debug : ?snapshot_every_sec:float -> unit -> (module PrintBox_runtime) -(** Creates a PrintBox-based debug runtime for the [`Text] backend. By default it will log to [stdout] - and will not be time tagged. +(** Creates a PrintBox-based debug runtime for the [`Text] backend. By default it will log + to [stdout] and will not be time tagged. - See {!type:PrintBox.config} for details about PrintBox-specific parameters. - See {!shared_config} for the details about shared parameters. *) + See {!type:PrintBox.config} for details about PrintBox-specific parameters. See + {!shared_config} for the details about shared parameters. *) val debug_flushing : ?debug_ch:out_channel -> @@ -316,9 +331,9 @@ val debug_flushing : ?for_append:bool -> unit -> (module Debug_runtime) -(** Creates a flushing-based debug runtime. By default it will log to [stdout] and will not be - time tagged. At most one of [debug_ch], [filename] can be provided. Adds the suffix [".log"] - to the file name if [filename] is given. +(** Creates a flushing-based debug runtime. By default it will log to [stdout] and will + not be time tagged. At most one of [debug_ch], [filename] can be provided. Adds the + suffix [".log"] to the file name if [filename] is given. See {!shared_config} for the details about shared parameters. *) @@ -326,5 +341,5 @@ val forget_printbox : (module PrintBox_runtime) -> (module Debug_runtime) (** Upcasts the runtime. *) val sexp_of_lazy_t : ('a -> Sexplib0.Sexp.t) -> 'a lazy_t -> Sexplib0.Sexp.t -(** Unlike [Lazy.sexp_of_t] available in the [Base] library, does not force the lazy value, - only converts it if it's already computed and non-exception. *) +(** Unlike [Lazy.sexp_of_t] available in the [Base] library, does not force the lazy + value, only converts it if it's already computed and non-exception. *)