GNAT GPL User's Guide: The Cross-Referencing Tools gnatxref and gnatfind

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

# 13. The Cross-Referencing Tools `gnatxref` and `gnatfind`

The compiler generates cross-referencing information (unless you set the ``-gnatx'` switch), which are saved in the ``.ali'` files. This information indicates where in the source each entity is declared and referenced. Note that entities in package Standard are not included, but entities in all other predefined units are included in the output.

Before using any of these two tools, you need to compile successfully your application, so that GNAT gets a chance to generate the cross-referencing information.

The two tools `gnatxref` and `gnatfind` take advantage of this information to provide the user with the capability to easily locate the declaration and references to an entity. These tools are quite similar, the difference being that `gnatfind` is intended for locating definitions and/or references to a specified entity or entities, whereas `gnatxref` is oriented to generating a full report of all cross-references.

To use these tools, you must not compile your application using the ``-gnatx'` switch on the `gnatmake` command line (see section 6. The GNAT Make Program `gnatmake`). Otherwise, cross-referencing information will not be generated.

Note: to invoke `gnatxref` or `gnatfind` with a project file, use the `gnat` driver (see 12.2 The GNAT Driver and Project Files).

> 13.1 `gnatxref` Switches |  |
> 13.2 `gnatfind` Switches |  |
> 13.3 Project Files for `gnatxref` and `gnatfind` |  |
> 13.4 Regular Expressions in `gnatfind` and `gnatxref` |  |
> 13.5 Examples of `gnatxref` Usage |  |
> 13.6 Examples of `gnatfind` Usage |  |

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

## 13.1 `gnatxref` Switches

The command invocation for `gnatxref` is:

    $ gnatxref [switches] sourcefile1 [sourcefile2 ...]

where

sourcefile1
sourcefile2
  identifies the source files for which a report is to be generated. The "with"ed units will be processed too. You must provide at least one file.

  These file names are considered to be regular expressions, so for instance specifying ``source*.adb'` is the same as giving every file in the current directory whose name starts with ``source'` and whose extension is ``adb'`.

  You shouldn't specify any directory name, just base names. `gnatxref` and `gnatfind` will be able to locate these files by themselves using the source path. If you specify directories, no result is produced.

The switches can be:

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

``--help'`
  If ``--version'` was not used, display usage, then exit disregarding all other options.

``-a'`
  If this switch is present, `gnatfind` and `gnatxref` will parse the read-only files found in the library search path. Otherwise, these files will be ignored. This option can be used to protect Gnat sources or your own libraries from being parsed, thus making `gnatfind` and `gnatxref` much faster, and their output much smaller. Read-only here refers to access or permissions status in the file system for the current user.

``-aIDIR'`
  When looking for source files also look in directory DIR. The order in which source file search is undertaken is the same as for `gnatmake`.

``-aODIR'`
  When searching for library and object files, look in directory DIR. The order in which library files are searched is the same as for `gnatmake`.

``-nostdinc'`
  Do not look for sources in the system default directory.

``-nostdlib'`
  Do not look for library files in the system default directory.

``--ext=extension'`
  Specify an alternate ali file extension. The default is `ali` and other extensions (e.g. `gli` for C/C++ sources when using ``-fdump-xref'`) may be specified via this switch. Note that if this switch overrides the default, which means that only the new extension will be considered.

``--RTS=rts-path'`
  Specifies the default location of the runtime library. Same meaning as the equivalent `gnatmake` flag (see section 6.2 Switches for `gnatmake`).

``-d'`
  If this switch is set `gnatxref` will output the parent type reference for each matching derived types.

``-f'`
  If this switch is set, the output file names will be preceded by their directory (if the file was found in the search path). If this switch is not set, the directory will not be printed.

``-g'`
  If this switch is set, information is output only for library-level entities, ignoring local entities. The use of this switch may accelerate `gnatfind` and `gnatxref`.

``-IDIR'`
  Equivalent to ``-aODIR -aIDIR'`.

``-pFILE'`
  Specify a project file to use See section 11. GNAT Project Manager. If you need to use the ``.gpr'` project files, you should use gnatxref through the GNAT driver (`gnat xref -Pproject`).

  By default, `gnatxref` and `gnatfind` will try to locate a project file in the current directory.

  If a project file is either specified or found by the tools, then the content of the source directory and object directory lines are added as if they had been specified respectively by ``-aI'` and ``-aO'`.

``-u'`
  Output only unused symbols. This may be really useful if you give your main compilation unit on the command line, as `gnatxref` will then display every unused entity and 'with'ed package.

``-v'`
  Instead of producing the default output, `gnatxref` will generate a ``tags'` file that can be used by vi. For examples how to use this feature, see 13.5 Examples of `gnatxref` Usage. The tags file is output to the standard output, thus you will have to redirect it to a file.

All these switches may be in any order on the command line, and may even appear after the file names. They need not be separated by spaces, thus you can say ``gnatxref -ag'` instead of ``gnatxref -a -g'`.

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

## 13.2 `gnatfind` Switches

The command line for `gnatfind` is:

    $ gnatfind [switches] pattern[:sourcefile[:line[:column]]]
          [file1 file2 ...]

where

pattern
  An entity will be output only if it matches the regular expression found in pattern, see 13.4 Regular Expressions in `gnatfind` and `gnatxref`.

  Omitting the pattern is equivalent to specifying ``*'`, which will match any entity. Note that if you do not provide a pattern, you have to provide both a sourcefile and a line.

  Entity names are given in Latin-1, with uppercase/lowercase equivalence for matching purposes. At the current time there is no support for 8-bit codes other than Latin-1, or for wide characters in identifiers.

sourcefile
  `gnatfind` will look for references, bodies or declarations of symbols referenced in ``sourcefile'`, at line line and column column. See 13.6 Examples of `gnatfind` Usage for syntax examples.

line
  is a decimal integer identifying the line number containing the reference to the entity (or entities) to be located.

column
  is a decimal integer identifying the exact location on the line of the first character of the identifier for the entity reference. Columns are numbered from 1.

file1 file2 ...
  The search will be restricted to these source files. If none are given, then the search will be done for every library file in the search path. These file must appear only after the pattern or sourcefile.

  These file names are considered to be regular expressions, so for instance specifying ``source*.adb'` is the same as giving every file in the current directory whose name starts with ``source'` and whose extension is ``adb'`.

  The location of the spec of the entity will always be displayed, even if it isn't in one of ``file1'`, ``file2'`,.... The occurrences of the entity in the separate units of the ones given on the command line will also be displayed.

  Note that if you specify at least one file in this part, `gnatfind` may sometimes not be able to find the body of the subprograms.

At least one of 'sourcefile' or 'pattern' has to be present on the command line.

The following switches are available:

Display Copyright and version, then exit disregarding all other options.
``--help'`
  If ``--version'` was not used, display usage, then exit disregarding all other options.

``-a'`
  If this switch is present, `gnatfind` and `gnatxref` will parse the read-only files found in the library search path. Otherwise, these files will be ignored. This option can be used to protect Gnat sources or your own libraries from being parsed, thus making `gnatfind` and `gnatxref` much faster, and their output much smaller. Read-only here refers to access or permission status in the file system for the current user.

``-aIDIR'`
  When looking for source files also look in directory DIR. The order in which source file search is undertaken is the same as for `gnatmake`.

``-aODIR'`
  When searching for library and object files, look in directory DIR. The order in which library files are searched is the same as for `gnatmake`.

``-nostdinc'`
  Do not look for sources in the system default directory.

``-nostdlib'`
  Do not look for library files in the system default directory.

``--ext=extension'`
  Specify an alternate ali file extension. The default is `ali` and other extensions (e.g. `gli` for C/C++ sources when using ``-fdump-xref'`) may be specified via this switch. Note that if this switch overrides the default, which means that only the new extension will be considered.

``--RTS=rts-path'`
  Specifies the default location of the runtime library. Same meaning as the equivalent `gnatmake` flag (see section 6.2 Switches for `gnatmake`).

``-d'`
  If this switch is set, then `gnatfind` will output the parent type reference for each matching derived types.

``-e'`
  By default, `gnatfind` accept the simple regular expression set for ``pattern'`. If this switch is set, then the pattern will be considered as full Unix-style regular expression.

``-f'`
  If this switch is set, the output file names will be preceded by their directory (if the file was found in the search path). If this switch is not set, the directory will not be printed.

``-g'`
  If this switch is set, information is output only for library-level entities, ignoring local entities. The use of this switch may accelerate `gnatfind` and `gnatxref`.

``-IDIR'`
  Equivalent to ``-aODIR -aIDIR'`.

``-pFILE'`
  Specify a project file (see section 11. GNAT Project Manager) to use. By default, `gnatxref` and `gnatfind` will try to locate a project file in the current directory.

  If a project file is either specified or found by the tools, then the content of the source directory and object directory lines are added as if they had been specified respectively by ``-aI'` and ``-aO'`.

``-r'`
  By default, `gnatfind` will output only the information about the declaration, body or type completion of the entities. If this switch is set, the `gnatfind` will locate every reference to the entities in the files specified on the command line (or in every file in the search path if no file is given on the command line).

``-s'`
  If this switch is set, then `gnatfind` will output the content of the Ada source file lines were the entity was found.

``-t'`
  If this switch is set, then `gnatfind` will output the type hierarchy for the specified type. It act like -d option but recursively from parent type to parent type. When this switch is set it is not possible to specify more than one file.

All these switches may be in any order on the command line, and may even appear after the file names. They need not be separated by spaces, thus you can say ``gnatxref -ag'` instead of ``gnatxref -a -g'`.

As stated previously, gnatfind will search in every directory in the search path. You can force it to look only in the current directory if you specify `*` at the end of the command line.

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

## 13.3 Project Files for `gnatxref` and `gnatfind`

Project files allow a programmer to specify how to compile its application, where to find sources, etc. These files are used primarily by GPS, but they can also be used by the two tools `gnatxref` and `gnatfind`.

A project file name must end with ``.gpr'`. If a single one is present in the current directory, then `gnatxref` and `gnatfind` will extract the information from it. If multiple project files are found, none of them is read, and you have to use the ``-p'` switch to specify the one you want to use.

The following lines can be included, even though most of them have default values which can be used in most cases. The lines can be entered in any order in the file. Except for ``src_dir'` and ``obj_dir'`, you can only have one instance of each line. If you have multiple instances, only the last one is taken into account.

`src_dir=DIR`
  [default: `"./"`] specifies a directory where to look for source files. Multiple `src_dir` lines can be specified and they will be searched in the order they are specified.

`obj_dir=DIR`
  [default: `"./"`] specifies a directory where to look for object and library files. Multiple `obj_dir` lines can be specified, and they will be searched in the order they are specified

`comp_opt=SWITCHES`
  [default: `""`] creates a variable which can be referred to subsequently by using the `${comp_opt}` notation. This is intended to store the default switches given to `gnatmake` and `gcc`.

`bind_opt=SWITCHES`
  [default: `""`] creates a variable which can be referred to subsequently by using the ``${bind_opt}'` notation. This is intended to store the default switches given to `gnatbind`.

`link_opt=SWITCHES`
  [default: `""`] creates a variable which can be referred to subsequently by using the ``${link_opt}'` notation. This is intended to store the default switches given to `gnatlink`.

`main=EXECUTABLE`
  [default: `""`] specifies the name of the executable for the application. This variable can be referred to in the following lines by using the ``${main}'` notation.

`comp_cmd=COMMAND`
  [default: `"gcc -c -I${src_dir} -g -gnatq"`] specifies the command used to compile a single file in the application.

`make_cmd=COMMAND`
  [default: `"gnatmake ${main} -aI${src_dir} -aO${obj_dir} -g -gnatq -cargs ${comp_opt} -bargs ${bind_opt} -largs ${link_opt}"`] specifies the command used to recompile the whole application.

`run_cmd=COMMAND`
  [default: `"${main}"`] specifies the command used to run the application.

`debug_cmd=COMMAND`
  [default: `"gdb ${main}"`] specifies the command used to debug the application

`gnatxref` and `gnatfind` only take into account the `src_dir` and `obj_dir` lines, and ignore the others.

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

## 13.4 Regular Expressions in `gnatfind` and `gnatxref`

As specified in the section about `gnatfind`, the pattern can be a regular expression. Actually, there are to set of regular expressions which are recognized by the program:

`globbing patterns`
  These are the most usual regular expression. They are the same that you generally used in a Unix shell command line, or in a DOS session.

  Here is a more formal grammar:

      regexp ::= term
      term   ::= elmt            -- matches elmt
      term   ::= elmt elmt       -- concatenation (elmt then elmt)
      term   ::= *               -- any string of 0 or more characters
      term   ::= ?               -- matches any character
      term   ::= [char {char}]   -- matches any character listed
      term   ::= [char - char]   -- matches any character in range

`full regular expression`
  The second set of regular expressions is much more powerful. This is the type of regular expressions recognized by utilities such a ``grep'`.

  The following is the form of a regular expression, expressed in Ada reference manual style BNF is as follows

      regexp ::= term {| term}   -- alternation (term or term ...)

      term ::= item {item}       -- concatenation (item then item)

      item ::= elmt              -- match elmt
      item ::= elmt *            -- zero or more elmt's
      item ::= elmt +            -- one or more elmt's
      item ::= elmt ?            -- matches elmt or nothing
      elmt ::= nschar            -- matches given character
      elmt ::= [nschar {nschar}]   -- matches any character listed
      elmt ::= [^ nschar {nschar}] -- matches any character not listed
      elmt ::= [char - char]     -- matches chars in given range
      elmt ::= \ char            -- matches given character
      elmt ::= .                 -- matches any single character
      elmt ::= ( regexp )        -- parens used for grouping

      char ::= any character, including special characters
      nschar ::= any character except ()[].*+?^

  Following are a few examples:

  ``abcde|fghi'`
    will match any of the two strings ``abcde'` and ``fghi'`,

  ``abc*d'`
    will match any string like ``abd'`, ``abcd'`, ``abccd'`, ``abcccd'`, and so on,

  ``[a-z]+'`
    will match any string which has only lowercase characters in it (and at least one character.

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

## 13.5 Examples of `gnatxref` Usage

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

### 13.5.1 General Usage

For the following examples, we will consider the following units:

    main.ads:
    1: with Bar;
    2: package Main is
    3:     procedure Foo (B : in Integer);
    4:     C : Integer;
    5: private
    6:     D : Integer;
    7: end Main;

    main.adb:
    1: package body Main is
    2:     procedure Foo (B : in Integer) is
    3:     begin
    4:        C := B;
    5:        D := B;
    6:        Bar.Print (B);
    7:        Bar.Print (C);
    8:     end Foo;
    9: end Main;

    bar.ads:
    1: package Bar is
    2:     procedure Print (B : Integer);
    3: end bar;

The first thing to do is to recompile your application (for instance, in that case just by doing a ``gnatmake main'`, so that GNAT generates the cross-referencing information. You can then issue any of the following commands:
`gnatxref main.adb`
  `gnatxref` generates cross-reference information for main.adb and every unit 'with'ed by main.adb.

  The output would be:

      B                                                      Type: Integer
        Decl: bar.ads           2:22
      B                                                      Type: Integer
        Decl: main.ads          3:20
        Body: main.adb          2:20
        Ref:  main.adb          4:13     5:13     6:19
      Bar                                                    Type: Unit
        Decl: bar.ads           1:9
        Ref:  main.adb          6:8      7:8
             main.ads           1:6
      C                                                      Type: Integer
        Decl: main.ads          4:5
        Modi: main.adb          4:8
        Ref:  main.adb          7:19
      D                                                      Type: Integer
        Decl: main.ads          6:5
        Modi: main.adb          5:8
      Foo                                                    Type: Unit
        Decl: main.ads          3:15
        Body: main.adb          2:15
      Main                                                    Type: Unit
        Decl: main.ads          2:9
        Body: main.adb          1:14
      Print                                                   Type: Unit
        Decl: bar.ads           2:15
        Ref:  main.adb          6:12     7:12

  that is the entity `Main` is declared in main.ads, line 2, column 9, its body is in main.adb, line 1, column 14 and is not referenced any where.

  The entity `Print` is declared in bar.ads, line 2, column 15 and it is referenced in main.adb, line 6 column 12 and line 7 column 12.

`gnatxref package1.adb package2.ads`
  `gnatxref` will generates cross-reference information for package1.adb, package2.ads and any other package 'with'ed by any of these.

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

### 13.5.2 Using gnatxref with vi

`gnatxref` can generate a tags file output, which can be used directly from `vi`. Note that the standard version of `vi` will not work properly with overloaded symbols. Consider using another free implementation of `vi`, such as `vim`.

    $ gnatxref -v gnatfind.adb > tags

will generate the tags file for `gnatfind` itself (if the sources are in the search path!).

From `vi`, you can then use the command ``:tag entity'` (replacing entity by whatever you are looking for), and vi will display a new file with the corresponding declaration of entity.

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

## 13.6 Examples of `gnatfind` Usage

`gnatfind -f xyz:main.adb`
  Find declarations for all entities xyz referenced at least once in main.adb. The references are search in every library file in the search path.

  The directories will be printed as well (as the ``-f'` switch is set)

  The output will look like:

      directory/main.ads:106:14: xyz <= declaration
      directory/main.adb:24:10: xyz <= body
      directory/foo.ads:45:23: xyz <= declaration

  that is to say, one of the entities xyz found in main.adb is declared at line 12 of main.ads (and its body is in main.adb), and another one is declared at line 45 of foo.ads

`gnatfind -fs xyz:main.adb`
  This is the same command as the previous one, instead `gnatfind` will display the content of the Ada source file lines.

  The output will look like:

      directory/main.ads:106:14: xyz <= declaration
         procedure xyz;
      directory/main.adb:24:10: xyz <= body
         procedure xyz is
      directory/foo.ads:45:23: xyz <= declaration
         xyz : Integer;

  This can make it easier to find exactly the location your are looking for.

`gnatfind -r "*x*":main.ads:123 foo.adb`
  Find references to all entities containing an x that are referenced on line 123 of main.ads. The references will be searched only in main.ads and foo.adb.

`gnatfind main.ads:123`
  Find declarations and bodies for all entities that are referenced on line 123 of main.ads.

  This is the same as `gnatfind "*":main.adb:123`.

`gnatfind mydir/main.adb:123:45`
  Find the declaration for the entity referenced at column 45 in line 123 of file main.adb in directory mydir. Note that it is usual to omit the identifier name when the column is given, since the column position identifies a unique reference.

  The column has to be the beginning of the identifier, and should not point to any character in the middle of the identifier.

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

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