Module Flx_cil_pretty


module Flx_cil_pretty: sig .. end
Flx_cil_utility functions for pretty-printing. The major features provided by this module are Flx_cil_pretty-printing occurs in two stages: The formatting algorithm is not optimal but it does a pretty good job while still operating in linear time. The original version was based on a pretty printer by Philip Wadler which turned out to not scale to large jobs.


API
type doc 
The type of unformated documents. Elements of this type can be * constructed in two ways. Either with a number of constructor shown below, * or using the Flx_cil_pretty.dprintf function with a printf-like interface. * The Flx_cil_pretty.dprintf method is slightly slower so we do not use it for * large jobs such as the output routines for a compiler. But we use it for * small jobs such as logging and error messages.

Constructors for the doc type.
val nil : doc
Constructs an empty document
val (++) : doc -> doc -> doc
Concatenates two documents. This is an infix operator that associates to the left.
val text : string -> doc
A document that prints the given string
val num : int -> doc
A document that prints an integer in decimal form
val real : float -> doc
A document that prints a real number
val chr : char -> doc
A document that prints a character. This is just like Flx_cil_pretty.text with a one-character string.
val line : doc
A document that consists of a mandatory newline. This is just like (text "\n"). The new line will be indented to the current indentation level, unless you use Flx_cil_pretty.leftflush right after this.
val leftflush : doc
Use after a Flx_cil_pretty.line to prevent the indentation. Whatever follows * next will be flushed left. Indentation resumes on the next line.
val break : doc
A document that consists of either a space or a line break. Also called an optional line break. Such a break will be taken only if necessary to fit the document in a given width. If the break is not taken a space is printed instead.
val align : doc
Mark the current column as the current indentation level. Does not print anything. All taken line breaks will align to this column. The previous alignment level is saved on a stack.
val unalign : doc
Reverts to the last saved indentation level.
val mark : doc
Mark the beginning of a markup section. The width of a markup section is * considered 0 for the purpose of computing identation
val unmark : doc
The end of a markup section

Syntactic sugar
val indent : int -> doc -> doc
Indents the document. Same as ((text " ") ++ align ++ doc ++ unalign), with the specified number of spaces.
val markup : doc -> doc
Prints a document as markup. The marked document cannot contain line * breaks or alignment constructs.
val seq : sep:doc ->
doit:('a -> doc) -> elements:'a list -> doc
Formats a sequence. sep is a separator, doit is a function that * converts an element to a document.
val docList : doc ->
('a -> doc) -> unit -> 'a list -> doc
An alternative function for printing a list. The unit argument is there * to make this function more easily usable with the Flx_cil_pretty.dprintf * interface.
val d_list : string ->
(unit -> 'a -> doc) -> unit -> 'a list -> doc
sm: Yet another list printer. This one accepts the same kind of * printing function that Flx_cil_pretty.dprintf does, and itself works * in the dprintf context. Also accepts * a string as the separator since that's by far the most common.
val docArray : doc ->
(int -> 'a -> doc) -> unit -> 'a array -> doc
Formats an array. A separator and a function that prints an array element
val docOpt : (unit -> 'a -> doc) -> unit -> 'a option -> doc
Prints an 'a option with None or Some
val insert : unit -> doc -> doc
A function that is useful with the printf-like interface
val dprintf : ('a, unit, doc) Pervasives.format -> 'a
This function provides an alternative method for constructing doc objects. The first argument for this function is a format string argument (of type ('a, unit, doc) format; if you insist on understanding what that means see the module Printf). The format string is like that for the printf function in C, except that it understands a few more formatting controls, all starting with the @ character.

The following special formatting characters are understood (these do not correspond to arguments of the function):

In addition to the usual printf % formatting characters the following two new characters are supported:
dprintf "Name=%s, SSN=%7d, Children=@[%a@]\n"
             pers.name pers.ssn (docList (chr ',' ++ break) text)
             pers.children

The result of dprintf is a Flx_cil_pretty.doc. You can format the document and emit it using the functions Flx_cil_pretty.fprint and Flx_cil_pretty.sprint.

val fprint : Pervasives.out_channel -> width:int -> doc -> unit
Format the document to the given width and emit it to the given channel
val sprint : width:int -> doc -> string
Format the document to the given width and emit it as a string
val fprintf : Pervasives.out_channel ->
('a, unit, doc) Pervasives.format -> 'a
Like Flx_cil_pretty.dprintf followed by Flx_cil_pretty.fprint
val printf : ('a, unit, doc) Pervasives.format -> 'a
Like Flx_cil_pretty.fprintf applied to stdout
val eprintf : ('a, unit, doc) Pervasives.format -> 'a
Like Flx_cil_pretty.fprintf applied to stderr
val gprintf : (doc -> doc) ->
('a, unit, doc) Pervasives.format -> 'a
Like Flx_cil_pretty.dprintf but more general. It also takes a function that is * invoked on the constructed document but before any formatting is done.
val withPrintDepth : int -> (unit -> unit) -> unit
Invokes a thunk, with printDepth temporarily set to the specified value

The following variables can be used to control the operation of the printer
val printDepth : int Pervasives.ref
Specifies the nesting depth of the align/unalign pairs at which everything is replaced with ellipsis
val printIndent : bool Pervasives.ref
If false then does not indent
val fastMode : bool Pervasives.ref
If set to true then optional breaks are taken only when the document has exceeded the given width. This means that the printout will looked more ragged but it will be faster
val flushOften : bool Pervasives.ref
If true the it flushes after every print
val countNewLines : int Pervasives.ref
Keep a running count of the taken newlines. You can read and write this * from the client code if you want