GNAT GPL User's Guide: The GNAT Pretty-Printer gnatpp

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

# 14. The GNAT Pretty-Printer `gnatpp`

> 14.1 Switches for `gnatpp` |  |
> 14.2 Formatting Rules |  |

The `gnatpp` tool is an ASIS-based utility for source reformatting / pretty-printing. It takes an Ada source file as input and generates a reformatted version as output. You can specify various style directives via switches; e.g., identifier case conventions, rules of indentation, and comment layout.

Note: A newly-redesigned set of formatting algorithms used by gnatpp is now available. To invoke the old formatting algorithms, use the ``--pp-old'` switch. Support for ``--pp-old'` will be removed in some future version.

To produce a reformatted file, `gnatpp` invokes the Ada compiler and generates and uses the ASIS tree for the input source; thus the input must be legal Ada code, and the tool should have all the information needed to compile the input source. To provide this information, you may specify as a tool parameter the project file the input source belongs to (or you may call `gnatpp` through the `gnat` driver (see 12.2 The GNAT Driver and Project Files). Another possibility is to specify the source search path and needed configuration files in ``-cargs'` section of `gnatpp` call, see the description of the `gnatpp` switches below.

`gnatpp` cannot process sources that contain preprocessing directives.

The `gnatpp` command has the form

    $ gnatpp [switches] filename [-cargs gcc_switches]

where

- switches is an optional sequence of switches defining such properties as the formatting rules, the source search path, and the destination for the output source file

- filename is the name (including the extension) of the source file to reformat; wildcards or several file names on the same gnatpp command are allowed. The file name may contain path information; it does not have to follow the GNAT file naming rules

- ``gcc_switches'` is a list of switches for `gcc`. They will be passed on to all compiler invocations made by `gnatpp` to generate the ASIS trees. Here you can provide ``-I'` switches to form the source search path, use the ``-gnatec'` switch to set the configuration file, etc.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 14.1 Switches for `gnatpp`

The following subsections describe the various switches accepted by `gnatpp`, organized by category.

You specify a switch by supplying a name and generally also a value. In many cases the values for a switch with a given name are incompatible with each other (for example the switch that controls the casing of a reserved word may have exactly one value: upper case, lower case, or mixed case) and thus exactly one such switch can be in effect for an invocation of `gnatpp`. If more than one is supplied, the last one is used. However, some values for the same switch are mutually compatible. You may supply several such switches to `gnatpp`, but then each must be specified in full, with both the name and the value. Abbreviated forms (the name appearing once, followed by each value) are not permitted.

> 14.1.1 Alignment Control |  |
> 14.1.2 Casing Control |  |
> 14.1.3 General Text Layout Control |  |
> 14.1.4 Other Formatting Options |  |
> 14.1.5 Setting the Source Search Path |  |
> 14.1.6 Output File Control |  |
> 14.1.7 Other `gnatpp` Switches |  |

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.1.1 Alignment Control

Programs can be easier to read if certain constructs are vertically aligned. By default alignment of the following constructs is set ON: `:` in declarations, `:=` in initializations in declarations `:=` in assignment statements, `=>` in associations, and `at` keywords in the component clauses in record representation clauses.

``-A0'`
  Set alignment to OFF

``-A1'`
  Set alignment to ON

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.1.2 Casing Control

`gnatpp` allows you to specify the casing for reserved words, pragma names, attribute designators and identifiers. For identifiers you may define a general rule for name casing but also override this rule via a set of dictionary files.

Three types of casing are supported: lower case, upper case, and mixed case. "Mixed case" means that the first letter, and also each letter immediately following an underscore, are converted to their uppercase forms; all the other letters are converted to their lowercase forms.

``-aL'`
  Attribute designators are lower case

``-aU'`
  Attribute designators are upper case

``-aM'`
  Attribute designators are mixed case (this is the default)

``-kL'`
  Keywords (technically, these are known in Ada as reserved words) are lower case (this is the default)

``-kU'`
  Keywords are upper case

``-nD'`
  Name casing for defining occurrences are as they appear in the source file (this is the default)

``-nU'`
  Names are in upper case

``-nL'`
  Names are in lower case

``-nM'`
  Names are in mixed case

``-neD'`
  Enumeration literal casing for defining occurrences are as they appear in the source file. Overrides -n casing setting.

``-neU'`
  Enumeration literals are in upper case. Overrides -n casing setting.

``-neL'`
  Enumeration literals are in lower case. Overrides -n casing setting.

``-neM'`
  Enumeration literals are in mixed case. Overrides -n casing setting.

``-neD'`
  Names introduced by type and subtype declarations are always cased as they appear in the declaration in the source file. Overrides -n casing setting.

``-ntU'`
  Names introduced by type and subtype declarations are always in upper case. Overrides -n casing setting.

``-ntL'`
  Names introduced by type and subtype declarations are always in lower case. Overrides -n casing setting.

``-ntM'`
  Names introduced by type and subtype declarations are always in mixed case. Overrides -n casing setting.

``-nnU'`
  Names introduced by number declarations are always in upper case. Overrides -n casing setting.

``-nnL'`
  Names introduced by number declarations are always in lower case. Overrides -n casing setting.

``-nnM'`
  Names introduced by number declarations are always in mixed case. Overrides -n casing setting.

``-pL'`
  Pragma names are lower case

``-pU'`
  Pragma names are upper case

``-pM'`
  Pragma names are mixed case (this is the default)

``-Dfile'`
  Use file as a dictionary file that defines the casing for a set of specified names, thereby overriding the effect on these names by any explicit or implicit -n switch. To supply more than one dictionary file, use several ``-D'` switches.

  ``gnatpp'` implicitly uses a default dictionary file to define the casing for the Ada predefined names and the names declared in the GNAT libraries.

``-D-'`
  Do not use the default dictionary file; instead, use the casing defined by a ``-n'` switch and any explicit dictionary file(s)

The structure of a dictionary file, and details on the conventions used in the default dictionary file, are defined in 14.2.4 Name Casing.

The ``-D-'` and ``-Dfile'` switches are mutually compatible.

This group of `gnatpp` switches controls the layout of comments and complex syntactic constructs. See 14.2.3 Formatting Comments for details on their effect.

``-c0'`
  All comments remain unchanged.

``-c1'`
  GNAT-style comment line indentation. This is the default.

``-c3'`
  GNAT-style comment beginning.

``-c4'`
  Fill comment blocks.

``-c5'`
  Keep unchanged special form comments. This is the default.

``--comments-only'`
  Format just the comments.

``--no-separate-is'`
  Do not place the keyword `is` on a separate line in a subprogram body in case if the spec occupies more than one line.

``--separate-loop-then'`
  Place the keyword `loop` in FOR and WHILE loop statements and the keyword `then` in IF statements on a separate line.

``--no-separate-loop-then'`
  Do not place the keyword `loop` in FOR and WHILE loop statements and the keyword `then` in IF statements on a separate line. This option is incompatible with ``--separate-loop-then'` option.

``--use-on-new-line'`
  Start each USE clause in a context clause from a separate line.

``--insert-blank-lines'`
  Insert blank lines where appropriate (between bodies and other large constructs).

``--preserve-blank-lines'`
  Preserve blank lines in the input. By default, gnatpp will squeeze multiple blank lines down to one.

The ``-c'` switches are compatible with one another, except that the ``-c0'` switch disables all other comment formatting switches.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.1.3 General Text Layout Control

These switches allow control over line length and indentation.

``-Mnnn'`
  Maximum line length, nnn from 32...256, the default value is 79

``-innn'`
  Indentation level, nnn from 1...9, the default value is 3

``-clnnn'`
  Indentation level for continuation lines (relative to the line being continued), nnn from 1...9. The default value is one less than the (normal) indentation level, unless the indentation is set to 1 (in which case the default value for continuation line indentation is also 1)

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.1.4 Other Formatting Options

These switches control other formatting not listed above.

``--decimal-grouping=n'`
  Put underscores in decimal literals (numeric literals without a base) every n characters. If a literal already has one or more underscores, it is not modified. For example, with `--decimal-grouping=3`, `1000000` will be changed to `1_000_000`.

``--based-grouping=n'`
  Same as `--decimal-grouping`, but for based literals. For example, with `--based-grouping=4`, `16#0001FFFE#` will be changed to `16#0001_FFFE#`.

``--RM-style-spacing'`
  Do not insert an extra blank before various occurrences of `(' and `:'. This also turns off alignment.

``-ff'`
  Insert a Form Feed character after a pragma Page.

``--call_threshold=nnn'`
  If the number of parameter associations is greater than nnn and if at least one association uses named notation, start each association from a new line. If nnn is 0, no check for the number of associations is made; this is the default.

``--par_threshold=nnn'`
  If the number of parameter specifications is greater than nnn (or equal to nnn in case of a function), start each specification from a new line. This feature is disabled by default.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.1.5 Setting the Source Search Path

To define the search path for the input source file, `gnatpp` uses the same switches as the GNAT compiler, with the same effects:

``-Idir'`

``-I-'`

``-gnatec=path'`

``--RTS=path'`

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.1.6 Output File Control

By default the output is sent to a file whose name is obtained by appending the ``.pp'` suffix to the name of the input file. If the file with this name already exists, it is overwritten. Thus if the input file is ``my_ada_proc.adb'` then `gnatpp` will produce ``my_ada_proc.adb.pp'` as output file. The output may be redirected by the following switches:

``--output-dir=dir'`
  Generate output file in directory ``dir'` with the same name as the input file. If ``dir'` is the same as the directory containing the input file, the input file is not processed; use ``-rnb'` if you want to update the input file in place.

``-pipe'`
  Send the output to `Standard_Output`

``-o output_file'`
  Write the output into output_file. If output_file already exists, `gnatpp` terminates without reading or processing the input file.

``-of output_file'`
  Write the output into output_file, overwriting the existing file (if one is present).

``-r'`
  Replace the input source file with the reformatted output, and copy the original input source into the file whose name is obtained by appending the ``.npp'` suffix to the name of the input file. If a file with this name already exists, `gnatpp` terminates without reading or processing the input file.

``-rf'`
  Like ``-r'` except that if the file with the specified name already exists, it is overwritten.

``-rnb'`
  Replace the input source file with the reformatted output without creating any backup copy of the input source.

``--eol=xxx'`
  Specifies the line-ending style of the reformatted output file. The xxx string specified with the switch may be:
  - "``dos'`" MS DOS style, lines end with CR LF characters
  - "``crlf'`" the same as ``dos'`
  - "``unix'`" UNIX style, lines end with LF character
  - "``lf'`" the same as ``unix'`

``-We'`
  Specify the wide character encoding method for the input and output files. e is one of the following:

  - h Hex encoding

  - u Upper half encoding

  - s Shift/JIS encoding

  - e EUC encoding

  - 8 UTF-8 encoding

  - b Brackets encoding (default value)

Options ``-o'` and ``-of'` are allowed only if the call to gnatpp contains only one file to reformat. Option ``--eol'` and ``-W'` cannot be used together with ``-pipe'` option.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.1.7 Other `gnatpp` Switches

The additional `gnatpp` switches are defined in this subsection.

``--version'`
  Display copyright and version, then exit disregarding all other options.

``--help'`
  Display usage, then exit disregarding all other options.

``-P file'`
  Indicates the name of the project file that describes the set of sources to be processed. The exact set of argument sources depends on other options specified; see below.

``-U'`
  If a project file is specified and no argument source is explicitly specified (either directly or by means of ``-files'` option), process all the units of the closure of the argument project. Otherwise this option has no effect.

``-U main_unit'`
  If a project file is specified and no argument source is explicitly specified (either directly or by means of ``-files'` option), process the closure of units rooted at main_unit. Otherwise this option has no effect.

``-Xname=value'`
  Indicates that external variable name in the argument project has the value value. Has no effect if no project is specified as tool argument.

``--incremental'`
  Incremental processing on a per-file basis. Source files are only processed if they have been modified, or if files they depend on have been modified. This is similar to the way gnatmake/gprbuild only compiles files that need to be recompiled.

``--pp-off=xxx'`
  Use `--xxx` as the command to turn off pretty printing, instead of the default `--!pp off`.

``--pp-on=xxx'`
  Use `--xxx` as the command to turn pretty printing back on, instead of the default `--!pp on`.

``--pp-old'`
  Use the old formatting algorithms.

``-files filename'`
  Take the argument source files from the specified file. This file should be an ordinary text file containing file names separated by spaces or line breaks. You can use this switch more than once in the same call to `gnatpp`. You also can combine this switch with an explicit list of files.

``-jn'`
  Without ``--incremental'`, use n processes to carry out the tree creations (internal representations of the argument sources). On a multiprocessor machine this speeds up processing of big sets of argument sources. If n is 0, then the maximum number of parallel tree creations is the number of core processors on the platform. This option cannot be used together with ``-r'`, ``-rf'` or ``-rnb'` option.

  With ``--incremental'`, use n `gnatpp` processes to perform pretty-printing in parallel. n = 0 means the same as above. In this case, ``-r'`, ``-rf'` or ``-rnb'` options are allowed.

``-t'`
  Print out execution time.

``-v'`
  Verbose mode

``-q'`
  Quiet mode

If a project file is specified and no argument source is explicitly specified (either directly or by means of ``-files'` option), and no ``-U'` is specified, then the set of processed sources is all the immediate units of the argument project.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 14.2 Formatting Rules

The following subsections show how `gnatpp` treats white space, comments, program layout, and name casing. They provide detailed descriptions of the switches shown above.

> 14.2.1 Disabling Pretty Printing |  |
> 14.2.2 White Space and Empty Lines |  |
> 14.2.3 Formatting Comments |  |
> 14.2.4 Name Casing |  |

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.2.1 Disabling Pretty Printing

Pretty printing is highly heuristic in nature, and sometimes doesn't do exactly what you want. If you wish to format a certain region of code by hand, you can turn off pretty printing in that region by surrounding it with special comments that start with `--!pp off` and `--!pp on`. The text in that region will then be reproduced verbatim in the output with no formatting.

To disable pretty printing for the whole file, put `--!pp off` at the top, with no following `--!pp on`.

The comments must appear on a line by themselves, with nothing preceding except spaces. The initial text of the comment must be exactly `--!pp off` or `--!pp on` (case sensitive), but may be followed by arbitrary additional text. For example:

    package Interrupts is
       --!pp off -- turn off pretty printing so "Interrupt_Kind" lines up
       type            Interrupt_Kind is
         (Asynchronous_Interrupt_Kind,
           Synchronous_Interrupt_Kind,
                 Green_Interrupt_Kind);
       --!pp on -- reenable pretty printing

       ...

You can specify different comment strings using the `--pp-off` and `--pp-on` switches. For example, if you say `gnatpp --pp-off=' pp-' *.ad?` then gnatpp will recognize comments of the form `-- pp-` instead of `--!pp off` for disabling pretty printing. Note that the leading `--` of the comment is not included in the argument to these switches.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.2.2 White Space and Empty Lines

`gnatpp` does not have an option to control space characters. It will add or remove spaces according to the style illustrated by the examples in the Ada Reference Manual. The output file will contain no lines with trailing white space.

By default, a sequence of one or more blank lines in the input is converted to a single blank line in the output; multiple blank lines are squeezed down to one. The ``--preserve-blank-lines'` option turns off the squeezing; each blank line in the input is copied to the output. The ``--insert-blank-lines'` option causes additional blank lines to be inserted if not already present in the input (e.g. between bodies).

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.2.3 Formatting Comments

Comments in Ada code are of two kinds:

- a whole-line comment, which appears by itself (possibly preceded by white space) on a line

- an end-of-line comment, which follows some other Ada code on the same line.

A whole-line comment is indented according to the surrounding code, with some exceptions. Comments that start in column 1 are kept there. If possible, comments are not moved so far to the right that the maximum line length is exceeded. The ``-c0'` option turns off comment formatting. Special-form comments such as SPARK-style `--#...` are left alone.

For an end-of-line comment, `gnatpp` tries to leave the same number of spaces between the end of the preceding Ada code and the beginning of the comment as appear in the original source.

The ``-c3'` switch (GNAT style comment beginning) has the following effect:

- For each whole-line comment that does not end with two hyphens, `gnatpp` inserts spaces if necessary after the starting two hyphens to ensure that there are at least two spaces between these hyphens and the first non-blank character of the comment.

The ``-c4'` switch specifies that whole-line comments that form a paragraph will be filled in typical word processor style (that is, moving words between lines to make the lines other than the last similar in length ).

The ``--comments-only'` switch specifies that only the comments are formatted; the rest of the program text is left alone. The comments are formatted according to the -c3 and -c4 switches; other formatting switches are ignored. For example, ``--comments-only -c4'` means to fill comment paragraphs, and do nothing else. Likewise, ``--comments-only -c3'` ensures comments start with at least two spaces after `--`, and ``--comments-only -c3 -c4'` does both. If ``--comments-only'` is given without ``-c3'` or ``-c4'`, then gnatpp doesn't format anything.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 14.2.4 Name Casing

`gnatpp` always converts the usage occurrence of a (simple) name to the same casing as the corresponding defining identifier.

You control the casing for defining occurrences via the ``-n'` switch. With ``-nD'` ("as declared", which is the default), defining occurrences appear exactly as in the source file where they are declared. The other values for this switch --- ``-nU'`, ``-nL'`, ``-nM'` --- result in upper, lower, or mixed case, respectively. If `gnatpp` changes the casing of a defining occurrence, it analogously changes the casing of all the usage occurrences of this name.

If the defining occurrence of a name is not in the source compilation unit currently being processed by `gnatpp`, the casing of each reference to this name is changed according to the value of the ``-n'` switch (subject to the dictionary file mechanism described below). Thus `gnatpp` acts as though the ``-n'` switch had affected the casing for the defining occurrence of the name.

The options ``-ax'`, ``-kx'`, ``-nex'`, ``-ntx'`, ``-nnx'`, and ``-px'` allow finer-grained control over casing for attributes, keywords, enumeration literals, types, named numbers and pragmas, respectively. ``-ntx'` covers subtypes and task and protected bodies as well.

Some names may need to be spelled with casing conventions that are not covered by the upper-, lower-, and mixed-case transformations. You can arrange correct casing by placing such names in a dictionary file, and then supplying a ``-D'` switch. The casing of names from dictionary files overrides any ``-n'` switch.

To handle the casing of Ada predefined names and the names from GNAT libraries, `gnatpp` assumes a default dictionary file. The name of each predefined entity is spelled with the same casing as is used for the entity in the Ada Reference Manual (usually mixed case). The name of each entity in the GNAT libraries is spelled with the same casing as is used in the declaration of that entity.

The ``-D-'` switch suppresses the use of the default dictionary file. Instead, the casing for predefined and GNAT-defined names will be established by the ``-n'` switch or explicit dictionary files. For example, by default the names `Ada.Text_IO` and `GNAT.OS_Lib` will appear as just shown, even in the presence of a ``-nU'` switch. To ensure that even such names are rendered in uppercase, additionally supply the ``-D-'` switch (or else place these names in upper case in a dictionary file).

A dictionary file is a plain text file; each line in this file can be either a blank line (containing only space characters), an Ada comment line, or the specification of exactly one casing schema.

A casing schema is a string that has the following syntax:

      casing_schema ::= identifier | *simple_identifier*

      simple_identifier ::= letter{letter_or_digit}

(See Ada Reference Manual, Section 2.3) for the definition of the identifier lexical element and the letter_or_digit category.)

The casing schema string can be followed by white space and/or an Ada-style comment; any amount of white space is allowed before the string.

If a dictionary file is passed as the value of a ``-Dfile'` switch then for every simple name and every identifier, `gnatpp` checks if the dictionary defines the casing for the name or for some of its parts (the term "subword" is used below to denote the part of a name which is delimited by "_" or by the beginning or end of the word and which does not contain any "_" inside):

- if the whole name is in the dictionary, `gnatpp` uses for this name the casing defined by the dictionary; no subwords are checked for this word

- for every subword `gnatpp` checks if the dictionary contains the corresponding string of the form `*simple_identifier*`, and if it does, the casing of this simple_identifier is used for this subword

- if the whole name does not contain any "_" inside, and if for this name the dictionary contains two entries - one of the form identifier, and another - of the form *simple_identifier*, then the first one is applied to define the casing of this name

- if more than one dictionary file is passed as `gnatpp` switches, each dictionary adds new casing exceptions and overrides all the existing casing exceptions set by the previous dictionaries

- when `gnatpp` checks if the word or subword is in the dictionary, this check is not case sensitive

For example, suppose we have the following source to reformat:

    procedure test is
       name1 : integer := 1;
       name4_name3_name2 : integer := 2;
       name2_name3_name4 : Boolean;
       name1_var : Float;
    begin
       name2_name3_name4 := name4_name3_name2 > name1;
    end;

And suppose we have two dictionaries:

    dict1:
       NAME1
       *NaMe3*
       *Name1*

    dict2:
      *NAME3*

If `gnatpp` is called with the following switches:

    gnatpp -nM -D dict1 -D dict2 test.adb

then we will get the following name casing in the `gnatpp` output:

    procedure Test is
       NAME1             : Integer := 1;
       Name4_NAME3_Name2 : Integer := 2;
       Name2_NAME3_Name4 : Boolean;
       Name1_Var         : Float;
    begin
       Name2_NAME3_Name4 := Name4_NAME3_Name2 > NAME1;
    end Test;

[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated by GNAT Mailserver on April, 17 2014 using texi2html