------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             X R E F _ L I B                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1998-2019, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Osint;
with Output; use Output;
with Types;  use Types;

with Unchecked_Deallocation;

with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Text_IO;

with GNAT.Command_Line; use GNAT.Command_Line;
with GNAT.IO_Aux;       use GNAT.IO_Aux;

package body Xref_Lib is

   Type_Position : constant := 50;
   --  Column for label identifying type of entity

   ---------------------
   -- Local Variables --
   ---------------------

   Pipe : constant Character := '|';
   --  First character on xref lines in the .ali file

   No_Xref_Information : exception;
   --  Exception raised when there is no cross-referencing information in
   --  the .ali files.

   procedure Parse_EOL
     (Source                 : not null access String;
      Ptr                    : in out Positive;
      Skip_Continuation_Line : Boolean := False);
   --  On return Source (Ptr) is the first character of the next line
   --  or EOF. Source.all must be terminated by EOF.
   --
   --  If Skip_Continuation_Line is True, this subprogram skips as many
   --  lines as required when the second or more lines starts with '.'
   --  (continuation lines in ALI files).

   function Current_Xref_File (File : ALI_File) return File_Reference;
   --  Return the file matching the last 'X' line we found while parsing
   --  the ALI file.

   function File_Name (File : ALI_File; Num : Positive) return File_Reference;
   --  Returns the dependency file name number Num

   function Get_Full_Type (Decl : Declaration_Reference) return String;
   --  Returns the full type corresponding to a type letter as found in
   --  the .ali files.

   procedure Open
     (Name         : String;
      File         : in out ALI_File;
      Dependencies : Boolean := False);
   --  Open a new ALI file. If Dependencies is True, the insert every library
   --  file 'with'ed in the files database (used for gnatxref)

   procedure Parse_Identifier_Info
     (Pattern       : Search_Pattern;
      File          : in out ALI_File;
      Local_Symbols : Boolean;
      Der_Info      : Boolean := False;
      Type_Tree     : Boolean := False;
      Wide_Search   : Boolean := True;
      Labels_As_Ref : Boolean := True);
   --  Output the file and the line where the identifier was referenced,
   --  If Local_Symbols is False then only the publicly visible symbols
   --  will be processed.
   --
   --  If Labels_As_Ref is true, then the references to the entities after
   --  the end statements ("end Foo") will be counted as actual references.
   --  The entity will never be reported as unreferenced by gnatxref -u

   procedure Parse_Token
     (Source    : not null access String;
      Ptr       : in out Positive;
      Token_Ptr : out Positive);
   --  Skips any separators and stores the start of the token in Token_Ptr.
   --  Then stores the position of the next separator in Ptr. On return
   --  Source (Token_Ptr .. Ptr - 1) is the token. Separators are space
   --  and ASCII.HT. Parse_Token will never skip to the next line.

   procedure Parse_Number
     (Source : not null access String;
      Ptr    : in out Positive;
      Number : out Natural);
   --  Skips any separators and parses Source up to the first character that
   --  is not a decimal digit. Returns value of parsed digits or 0 if none.

   procedure Parse_X_Filename (File : in out ALI_File);
   --  Reads and processes "X..." lines in the ALI file
   --  and updates the File.X_File information.

   procedure Skip_To_First_X_Line
     (File    : in out ALI_File;
      D_Lines : Boolean;
      W_Lines : Boolean);
   --  Skip the lines in the ALI file until the first cross-reference line
   --  (^X...) is found. Search is started from the beginning of the file.
   --  If not such line is found, No_Xref_Information is raised.
   --  If W_Lines is false, then the lines "^W" are not parsed.
   --  If D_Lines is false, then the lines "^D" are not parsed.

   ----------------
   -- Add_Entity --
   ----------------

   procedure Add_Entity
     (Pattern : in out Search_Pattern;
      Entity  : String;
      Glob    : Boolean := False)
   is
      File_Start : Natural;
      Line_Start : Natural;
      Col_Start  : Natural;
      Line_Num   : Natural := 0;
      Col_Num    : Natural := 0;

      File_Ref : File_Reference := Empty_File;
      pragma Warnings (Off, File_Ref);

   begin
      --  Find the end of the first item in Entity (pattern or file?)
      --  If there is no ':', we only have a pattern

      File_Start := Index (Entity, ":");

      --  If the regular expression is invalid, just consider it as a string

      if File_Start = 0 then
         begin
            Pattern.Entity := Compile (Entity, Glob, False);
            Pattern.Initialized := True;

         exception
            when Error_In_Regexp =>

               --  The basic idea is to insert a \ before every character

               declare
                  Tmp_Regexp : String (1 .. 2 * Entity'Length);
                  Index      : Positive := 1;

               begin
                  for J in Entity'Range loop
                     Tmp_Regexp (Index) := '\';
                     Tmp_Regexp (Index + 1) := Entity (J);
                     Index := Index + 2;
                  end loop;

                  Pattern.Entity := Compile (Tmp_Regexp, True, False);
                  Pattern.Initialized := True;
               end;
         end;

         Set_Default_Match (True);
         return;
      end if;

      --  If there is a dot in the pattern, then it is a file name

      if (Glob and then
           Index (Entity (Entity'First .. File_Start - 1), ".") /= 0)
             or else
              (not Glob
                 and then Index (Entity (Entity'First .. File_Start - 1),
                                   "\.") /= 0)
      then
         Pattern.Entity      := Compile (".*", False);
         Pattern.Initialized := True;
         File_Start          := Entity'First;

      else
         --  If the regular expression is invalid, just consider it as a string

         begin
            Pattern.Entity :=
              Compile (Entity (Entity'First .. File_Start - 1), Glob, False);
            Pattern.Initialized := True;

         exception
            when Error_In_Regexp =>

               --  The basic idea is to insert a \ before every character

               declare
                  Tmp_Regexp : String (1 .. 2 * (File_Start - Entity'First));
                  Index      : Positive := 1;

               begin
                  for J in Entity'First .. File_Start - 1 loop
                     Tmp_Regexp (Index) := '\';
                     Tmp_Regexp (Index + 1) := Entity (J);
                     Index := Index + 2;
                  end loop;

                  Pattern.Entity := Compile (Tmp_Regexp, True, False);
                  Pattern.Initialized := True;
               end;
         end;

         File_Start := File_Start + 1;
      end if;

      --  Parse the file name

      Line_Start := Index (Entity (File_Start .. Entity'Last), ":");

      --  Check if it was a disk:\directory item (for Windows)

      if File_Start = Line_Start - 1
        and then Line_Start < Entity'Last
        and then Entity (Line_Start + 1) = '\'
      then
         Line_Start := Index (Entity (Line_Start + 1 .. Entity'Last), ":");
      end if;

      if Line_Start = 0 then
         Line_Start := Entity'Length + 1;

      elsif Line_Start /= Entity'Last then
         Col_Start := Index (Entity (Line_Start + 1 .. Entity'Last), ":");

         if Col_Start = 0 then
            Col_Start := Entity'Last + 1;
         end if;

         if Col_Start > Line_Start + 1 then
            begin
               Line_Num := Natural'Value
                 (Entity (Line_Start + 1 .. Col_Start - 1));

            exception
               when Constraint_Error =>
                  raise Invalid_Argument;
            end;
         end if;

         if Col_Start < Entity'Last then
            begin
               Col_Num := Natural'Value (Entity
                                         (Col_Start + 1 .. Entity'Last));

            exception
               when Constraint_Error => raise Invalid_Argument;
            end;
         end if;
      end if;

      declare
         File_Name : String := Entity (File_Start .. Line_Start - 1);

      begin
         Osint.Canonical_Case_File_Name (File_Name);
         File_Ref := Add_To_Xref_File (File_Name, Visited => True);
         Pattern.File_Ref := File_Ref;

         Add_Line (Pattern.File_Ref, Line_Num, Col_Num);

         File_Ref :=
           Add_To_Xref_File
             (ALI_File_Name (File_Name),
              Visited      => False,
              Emit_Warning => True);
      end;
   end Add_Entity;

   -------------------
   -- Add_Xref_File --
   -------------------

   procedure Add_Xref_File (File : String) is
      File_Ref : File_Reference := Empty_File;
      pragma Unreferenced (File_Ref);

      Iterator : Expansion_Iterator;

      procedure Add_Xref_File_Internal (File : String);
      --  Do the actual addition of the file

      ----------------------------
      -- Add_Xref_File_Internal --
      ----------------------------

      procedure Add_Xref_File_Internal (File : String) is
      begin
         --  Case where we have an ALI file, accept it even though this is
         --  not official usage, since the intention is obvious

         if Tail (File, 4) = "." & Osint.ALI_Suffix.all then
            File_Ref := Add_To_Xref_File
                          (File, Visited => False, Emit_Warning => True);

         --  Normal non-ali file case

         else
            File_Ref := Add_To_Xref_File (File, Visited => True);

            File_Ref := Add_To_Xref_File
                         (ALI_File_Name (File),
                          Visited => False, Emit_Warning => True);
         end if;
      end Add_Xref_File_Internal;

   --  Start of processing for Add_Xref_File

   begin
      --  Check if we need to do the expansion

      if Ada.Strings.Fixed.Index (File, "*") /= 0
        or else Ada.Strings.Fixed.Index (File, "?") /= 0
      then
         Start_Expansion (Iterator, File);

         loop
            declare
               S : constant String := Expansion (Iterator);

            begin
               exit when S'Length = 0;
               Add_Xref_File_Internal (S);
            end;
         end loop;

      else
         Add_Xref_File_Internal (File);
      end if;
   end Add_Xref_File;

   -----------------------
   -- Current_Xref_File --
   -----------------------

   function Current_Xref_File (File : ALI_File) return File_Reference is
   begin
      return File.X_File;
   end Current_Xref_File;

   --------------------------
   -- Default_Project_File --
   --------------------------

   function Default_Project_File (Dir_Name : String) return String is
      My_Dir  : Dir_Type;
      Dir_Ent : File_Name_String;
      Last    : Natural;

   begin
      Open (My_Dir, Dir_Name);

      loop
         Read (My_Dir, Dir_Ent, Last);
         exit when Last = 0;

         if Tail (Dir_Ent (1 .. Last), 4) = ".adp" then

            --  The first project file found is the good one

            Close (My_Dir);
            return Dir_Ent (1 .. Last);
         end if;
      end loop;

      Close (My_Dir);
      return String'(1 .. 0 => ' ');

   exception
      when Directory_Error => return String'(1 .. 0 => ' ');
   end Default_Project_File;

   ---------------
   -- File_Name --
   ---------------

   function File_Name
     (File : ALI_File;
      Num  : Positive) return File_Reference
   is
      Table : Table_Type renames File.Dep.Table (1 .. Last (File.Dep));
   begin
      return Table (Num);
   end File_Name;

   --------------------
   -- Find_ALI_Files --
   --------------------

   procedure Find_ALI_Files is
      My_Dir  : Rec_DIR;
      Dir_Ent : File_Name_String;
      Last    : Natural;

      File_Ref : File_Reference;
      pragma Unreferenced (File_Ref);

      function Open_Next_Dir return Boolean;
      --  Tries to open the next object directory, and return False if
      --  the directory cannot be opened.

      -------------------
      -- Open_Next_Dir --
      -------------------

      function Open_Next_Dir return Boolean is
      begin
         --  Until we are able to open a new directory

         loop
            declare
               Obj_Dir : constant String := Next_Obj_Dir;

            begin
               --  Case of no more Obj_Dir lines

               if Obj_Dir'Length = 0 then
                  return False;
               end if;

               Open (My_Dir.Dir, Obj_Dir);
               exit;

            exception

               --  Could not open the directory

               when Directory_Error => null;
            end;
         end loop;

         return True;
      end Open_Next_Dir;

   --  Start of processing for Find_ALI_Files

   begin
      Reset_Obj_Dir;

      if Open_Next_Dir then
         loop
            Read (My_Dir.Dir, Dir_Ent, Last);

            if Last = 0 then
               Close (My_Dir.Dir);

               if not Open_Next_Dir then
                  return;
               end if;

            elsif Last > 4
              and then Dir_Ent (Last - 3 .. Last) = "." & Osint.ALI_Suffix.all
            then
               File_Ref :=
                 Add_To_Xref_File (Dir_Ent (1 .. Last), Visited => False);
            end if;
         end loop;
      end if;
   end Find_ALI_Files;

   -------------------
   -- Get_Full_Type --
   -------------------

   function Get_Full_Type (Decl : Declaration_Reference) return String is

      function Param_String return String;
      --  Return the string to display depending on whether Decl is a parameter

      ------------------
      -- Param_String --
      ------------------

      function Param_String return String is
      begin
         if Is_Parameter (Decl) then
            return "parameter ";
         else
            return "";
         end if;
      end Param_String;

   --  Start of processing for Get_Full_Type

   begin
      case Get_Type (Decl) is
         when 'A' => return "array type";
         when 'B' => return "boolean type";
         when 'C' => return "class-wide type";
         when 'D' => return "decimal type";
         when 'E' => return "enumeration type";
         when 'F' => return "float type";
         when 'H' => return "abstract type";
         when 'I' => return "integer type";
         when 'M' => return "modular type";
         when 'O' => return "fixed type";
         when 'P' => return "access type";
         when 'R' => return "record type";
         when 'S' => return "string type";
         when 'T' => return "task type";
         when 'W' => return "protected type";

         when 'a' => return Param_String & "array object";
         when 'b' => return Param_String & "boolean object";
         when 'c' => return Param_String & "class-wide object";
         when 'd' => return Param_String & "decimal object";
         when 'e' => return Param_String & "enumeration object";
         when 'f' => return Param_String & "float object";
         when 'i' => return Param_String & "integer object";
         when 'j' => return Param_String & "class object";
         when 'm' => return Param_String & "modular object";
         when 'o' => return Param_String & "fixed object";
         when 'p' => return Param_String & "access object";
         when 'r' => return Param_String & "record object";
         when 's' => return Param_String & "string object";
         when 't' => return Param_String & "task object";
         when 'w' => return Param_String & "protected object";
         when 'x' => return Param_String & "abstract procedure";
         when 'y' => return Param_String & "abstract function";

         when 'h' => return "interface";
         when 'g' => return "macro";
         when 'G' => return "function macro";
         when 'J' => return "class";
         when 'K' => return "package";
         when 'k' => return "generic package";
         when 'L' => return "statement label";
         when 'l' => return "loop label";
         when 'N' => return "named number";
         when 'n' => return "enumeration literal";
         when 'q' => return "block label";
         when 'Q' => return "include file";
         when 'U' => return "procedure";
         when 'u' => return "generic procedure";
         when 'V' => return "function";
         when 'v' => return "generic function";
         when 'X' => return "exception";
         when 'Y' => return "entry";

         when '+' => return "private type";
         when '*' => return "private variable";

         --  The above should be the only possibilities, but for this kind
         --  of informational output, we don't want to bomb if we find
         --  something else, so just return three question marks when we
         --  have an unknown Abbrev value

         when others =>
            if Is_Parameter (Decl) then
               return "parameter";
            else
               return "??? (" & Get_Type (Decl) & ")";
            end if;
      end case;
   end Get_Full_Type;

   --------------------------
   -- Skip_To_First_X_Line --
   --------------------------

   procedure Skip_To_First_X_Line
     (File    : in out ALI_File;
      D_Lines : Boolean;
      W_Lines : Boolean)
   is
      Ali              : String_Access renames File.Buffer;
      Token            : Positive;
      Ptr              : Positive := Ali'First;
      Num_Dependencies : Natural  := 0;
      File_Start       : Positive;
      File_End         : Positive;
      Gnatchop_Offset  : Integer;
      Gnatchop_Name    : Positive;

      File_Ref : File_Reference;
      pragma Unreferenced (File_Ref);

   begin
      --  Read all the lines possibly processing with-clauses and dependency
      --  information and exit on finding the first Xref line.
      --  A fall-through of the loop means that there is no xref information
      --  which is an error condition.

      while Ali (Ptr) /= EOF loop
         if D_Lines and then Ali (Ptr) = 'D' then

            --  Found dependency information. Format looks like:
            --  D src-nam time-stmp checksum [subunit-name] [line:file-name]

            --  Skip the D and parse the filenam

            Ptr := Ptr + 1;
            Parse_Token (Ali, Ptr, Token);
            File_Start := Token;
            File_End := Ptr - 1;

            Num_Dependencies := Num_Dependencies + 1;
            Set_Last (File.Dep, Num_Dependencies);

            Parse_Token (Ali, Ptr, Token); --  Skip time-stamp
            Parse_Token (Ali, Ptr, Token); --  Skip checksum
            Parse_Token (Ali, Ptr, Token); --  Read next entity on the line

            if not (Ali (Token) in '0' .. '9') then
               Parse_Token (Ali, Ptr, Token); --  Was a subunit name
            end if;

            --  Did we have a gnatchop-ed file with a pragma Source_Reference ?

            Gnatchop_Offset := 0;

            if Ali (Token) in '0' .. '9' then
               Gnatchop_Name := Token;
               while Ali (Gnatchop_Name) /= ':' loop
                  Gnatchop_Name := Gnatchop_Name + 1;
               end loop;

               Gnatchop_Offset :=
                 2 - Natural'Value (Ali (Token .. Gnatchop_Name - 1));
               Token := Gnatchop_Name + 1;
            end if;

            declare
               Table : Table_Type renames
                         File.Dep.Table (1 .. Last (File.Dep));
            begin
               Table (Num_Dependencies) := Add_To_Xref_File
                 (Ali (File_Start .. File_End),
                  Gnatchop_File => Ali (Token .. Ptr - 1),
                  Gnatchop_Offset => Gnatchop_Offset);
            end;

         elsif W_Lines and then Ali (Ptr) = 'W' then

            --  Found with-clause information. Format looks like:
            --     "W debug%s               debug.adb               debug.ali"

            --  Skip the W and parse the .ali filename (3rd token)

            Parse_Token (Ali, Ptr, Token);
            Parse_Token (Ali, Ptr, Token);
            Parse_Token (Ali, Ptr, Token);

            File_Ref :=
              Add_To_Xref_File (Ali (Token .. Ptr - 1), Visited => False);

         elsif Ali (Ptr) = 'X' then

            --  Found a cross-referencing line - stop processing

            File.Current_Line := Ptr;
            File.Xref_Line    := Ptr;
            return;
         end if;

         Parse_EOL (Ali, Ptr);
      end loop;

      raise No_Xref_Information;
   end Skip_To_First_X_Line;

   ----------
   -- Open --
   ----------

   procedure Open
     (Name         : String;
      File         : in out ALI_File;
      Dependencies : Boolean := False)
   is
      Ali : String_Access renames File.Buffer;
      pragma Warnings (Off, Ali);

   begin
      if File.Buffer /= null then
         Free (File.Buffer);
      end if;

      Init (File.Dep);

      begin
         Read_File (Name, Ali);

      exception
         when Ada.Text_IO.Name_Error | Ada.Text_IO.End_Error =>
            raise No_Xref_Information;
      end;

      Skip_To_First_X_Line (File, D_Lines => True, W_Lines => Dependencies);
   end Open;

   ---------------
   -- Parse_EOL --
   ---------------

   procedure Parse_EOL
     (Source                 : not null access String;
      Ptr                    : in out Positive;
      Skip_Continuation_Line : Boolean := False)
   is
   begin
      loop
         --  Skip to end of line

         while Source (Ptr) /= ASCII.CR and then Source (Ptr) /= ASCII.LF
           and then Source (Ptr) /= EOF
         loop
            Ptr := Ptr + 1;
         end loop;

         --  Skip CR or LF if not at end of file

         if Source (Ptr) /= EOF then
            Ptr := Ptr + 1;
         end if;

         --  Skip past CR/LF or LF/CR combination

         if (Source (Ptr) = ASCII.CR or else Source (Ptr) = ASCII.LF)
           and then Source (Ptr) /= Source (Ptr - 1)
         then
            Ptr := Ptr + 1;
         end if;

         exit when not Skip_Continuation_Line or else Source (Ptr) /= '.';
      end loop;
   end Parse_EOL;

   ---------------------------
   -- Parse_Identifier_Info --
   ---------------------------

   procedure Parse_Identifier_Info
     (Pattern       : Search_Pattern;
      File          : in out ALI_File;
      Local_Symbols : Boolean;
      Der_Info      : Boolean := False;
      Type_Tree     : Boolean := False;
      Wide_Search   : Boolean := True;
      Labels_As_Ref : Boolean := True)
   is
      Ptr      : Positive renames File.Current_Line;
      Ali      : String_Access renames File.Buffer;

      E_Line   : Natural;   --  Line number of current entity
      E_Col    : Natural;   --  Column number of current entity
      E_Type   : Character; --  Type of current entity
      E_Name   : Positive;  --  Pointer to begin of entity name
      E_Global : Boolean;   --  True iff entity is global

      R_Line   : Natural;   --  Line number of current reference
      R_Col    : Natural;   --  Column number of current reference
      R_Type   : Character; --  Type of current reference

      Decl_Ref : Declaration_Reference;
      File_Ref : File_Reference := Current_Xref_File (File);

      function Get_Symbol_Name (Eun, Line, Col : Natural) return String;
      --  Returns the symbol name for the entity defined at the specified
      --  line and column in the dependent unit number Eun. For this we need
      --  to parse the ali file again because the parent entity is not in
      --  the declaration table if it did not match the search pattern.

      procedure Skip_To_Matching_Closing_Bracket;
      --  When Ptr points to an opening square bracket, moves it to the
      --  character following the matching closing bracket

      ---------------------
      -- Get_Symbol_Name --
      ---------------------

      function Get_Symbol_Name (Eun, Line, Col : Natural) return String is
         Ptr    : Positive := 1;
         E_Eun  : Positive;   --  Unit number of current entity
         E_Line : Natural;    --  Line number of current entity
         E_Col  : Natural;    --  Column number of current entity
         E_Name : Positive;   --  Pointer to begin of entity name

      begin
         --  Look for the X lines corresponding to unit Eun

         loop
            if Ali (Ptr) = 'X' then
               Ptr := Ptr + 1;
               Parse_Number (Ali, Ptr, E_Eun);
               exit when E_Eun = Eun;
            end if;

            Parse_EOL (Ali, Ptr, Skip_Continuation_Line => True);
         end loop;

         --  Here we are in the right Ali section, we now look for the entity
         --  declared at position (Line, Col).

         loop
            Parse_Number (Ali, Ptr, E_Line);
            exit when Ali (Ptr) = EOF;
            Ptr := Ptr + 1;
            Parse_Number (Ali, Ptr, E_Col);
            exit when Ali (Ptr) = EOF;
            Ptr := Ptr + 1;

            if Line = E_Line and then Col = E_Col then
               Parse_Token (Ali, Ptr, E_Name);
               return Ali (E_Name .. Ptr - 1);
            end if;

            Parse_EOL (Ali, Ptr, Skip_Continuation_Line => True);
            exit when Ali (Ptr) = EOF;
         end loop;

         --  We were not able to find the symbol, this should not happen but
         --  since we don't want to stop here we return a string of three
         --  question marks as the symbol name.

         return "???";
      end Get_Symbol_Name;

      --------------------------------------
      -- Skip_To_Matching_Closing_Bracket --
      --------------------------------------

      procedure Skip_To_Matching_Closing_Bracket is
         Num_Brackets : Natural;

      begin
         Num_Brackets := 1;
         while Num_Brackets /= 0 loop
            Ptr := Ptr + 1;
            if Ali (Ptr) = '[' then
               Num_Brackets := Num_Brackets + 1;
            elsif Ali (Ptr) = ']' then
               Num_Brackets := Num_Brackets - 1;
            end if;
         end loop;

         Ptr := Ptr + 1;
      end Skip_To_Matching_Closing_Bracket;

      Table : Table_Type renames File.Dep.Table (1 .. Last (File.Dep));

   --  Start of processing for Parse_Identifier_Info

   begin
      --  The identifier info looks like:
      --     "38U9*Debug 12|36r6 36r19"

      --  Extract the line, column and entity name information

      Parse_Number (Ali, Ptr, E_Line);

      if Ali (Ptr) > ' ' then
         E_Type := Ali (Ptr);
         Ptr := Ptr + 1;
      end if;

      --  Ignore some of the entities (labels,...)

      case E_Type is
         when 'l' | 'L' | 'q' =>
            Parse_EOL (Ali, Ptr, Skip_Continuation_Line => True);
            return;

         when others =>
            null;
      end case;

      Parse_Number (Ali, Ptr, E_Col);

      E_Global := False;
      if Ali (Ptr) >= ' ' then
         E_Global := (Ali (Ptr) = '*');
         Ptr := Ptr + 1;
      end if;

      Parse_Token (Ali, Ptr, E_Name);

      --  Exit if the symbol does not match or if we have a local symbol and we
      --  do not want it or if the file is unknown.

      if File.X_File = Empty_File then
         return;
      end if;

      if (not Local_Symbols and not E_Global)
        or else (Pattern.Initialized
                  and then not Match (Ali (E_Name .. Ptr - 1), Pattern.Entity))
        or else (E_Name >= Ptr)
      then
         Decl_Ref := Add_Declaration
           (File.X_File, Ali (E_Name .. Ptr - 1), E_Line, E_Col, E_Type,
            Remove_Only => True);
         Parse_EOL (Ali, Ptr, Skip_Continuation_Line => True);
         return;
      end if;

      --  Insert the declaration in the table

      Decl_Ref := Add_Declaration
        (File.X_File, Ali (E_Name .. Ptr - 1), E_Line, E_Col, E_Type);

      if Ali (Ptr) = '[' then
         Skip_To_Matching_Closing_Bracket;
      end if;

      --  Skip any renaming indication

      if Ali (Ptr) = '=' then
         declare
            P_Line, P_Column : Natural;
            pragma Warnings (Off, P_Line);
            pragma Warnings (Off, P_Column);
         begin
            Ptr := Ptr + 1;
            Parse_Number (Ali, Ptr, P_Line);
            Ptr := Ptr + 1;
            Parse_Number (Ali, Ptr, P_Column);
         end;
      end if;

      while Ptr <= Ali'Last
         and then (Ali (Ptr) = '<'
                   or else Ali (Ptr) = '('
                   or else Ali (Ptr) = '{')
      loop
         --  Here we have a type derivation information. The format is
         --  <3|12I45> which means that the current entity is derived from the
         --  type defined in unit number 3, line 12 column 45. The pipe and
         --  unit number is optional. It is specified only if the parent type
         --  is not defined in the current unit.

         --  We also have the format for generic instantiations, as in
         --  7a5*Uid(3|5I8[4|2]) 2|4r74

         --  We could also have something like
         --  16I9*I<integer>
         --  that indicates that I derives from the predefined type integer.

         Ptr := Ptr + 1;

         if Ali (Ptr) in '0' .. '9' then
            Parse_Derived_Info : declare
               P_Line   : Natural;          --  parent entity line
               P_Column : Natural;          --  parent entity column
               P_Eun    : Positive;         --  parent entity file number

            begin
               Parse_Number (Ali, Ptr, P_Line);

               --  If we have a pipe then the first number was the unit number

               if Ali (Ptr) = '|' then
                  P_Eun := P_Line;
                  Ptr := Ptr + 1;

                  --  Now we have the line number

                  Parse_Number (Ali, Ptr, P_Line);

               else
                  --  We don't have a unit number specified, so we set P_Eun to
                  --  the current unit.

                  for K in Table'Range loop
                     P_Eun := K;
                     exit when Table (K) = File_Ref;
                  end loop;
               end if;

               --  Then parse the type and column number

               Ptr := Ptr + 1;
               Parse_Number (Ali, Ptr, P_Column);

               --  Skip the information for generics instantiations

               if Ali (Ptr) = '[' then
                  Skip_To_Matching_Closing_Bracket;
               end if;

               --  Skip '>', or ')' or '>'

               Ptr := Ptr + 1;

               --  The derived info is needed only is the derived info mode is
               --  on or if we want to output the type hierarchy

               if Der_Info or else Type_Tree then
                  declare
                     Symbol : constant String :=
                                Get_Symbol_Name (P_Eun, P_Line, P_Column);
                  begin
                     if Symbol /= "???" then
                        Add_Parent
                          (Decl_Ref,
                           Symbol,
                           P_Line,
                           P_Column,
                           Table (P_Eun));
                     end if;
                  end;
               end if;

               if Type_Tree
                 and then (Pattern.File_Ref = Empty_File
                             or else
                           Pattern.File_Ref = Current_Xref_File (File))
               then
                  Search_Parent_Tree : declare
                     Pattern         : Search_Pattern;  --  Parent type pattern
                     File_Pos_Backup : Positive;

                  begin
                     Add_Entity
                       (Pattern,
                        Get_Symbol_Name (P_Eun, P_Line, P_Column)
                        & ':' & Get_Gnatchop_File (Table (P_Eun))
                        & ':' & Get_Line (Get_Parent (Decl_Ref))
                        & ':' & Get_Column (Get_Parent (Decl_Ref)),
                        False);

                     --  No default match is needed to look for the parent type
                     --  since we are using the fully qualified symbol name:
                     --  symbol:file:line:column

                     Set_Default_Match (False);

                     --  The parent hierarchy is defined in the same unit as
                     --  the derived type. So we want to revisit the unit.

                     File_Pos_Backup   := File.Current_Line;

                     Skip_To_First_X_Line
                       (File, D_Lines => False, W_Lines => False);

                     while File.Buffer (File.Current_Line) /= EOF loop
                        Parse_X_Filename (File);
                        Parse_Identifier_Info
                          (Pattern       => Pattern,
                           File          => File,
                           Local_Symbols => False,
                           Der_Info      => Der_Info,
                           Type_Tree     => True,
                           Wide_Search   => False,
                           Labels_As_Ref => Labels_As_Ref);
                     end loop;

                     File.Current_Line := File_Pos_Backup;
                  end Search_Parent_Tree;
               end if;
            end Parse_Derived_Info;

         else
            while Ali (Ptr) /= '>'
              and then Ali (Ptr) /= ')'
              and then Ali (Ptr) /= '}'
            loop
               Ptr := Ptr + 1;
            end loop;
            Ptr := Ptr + 1;
         end if;
      end loop;

      --  To find the body, we will have to parse the file too

      if Wide_Search then
         declare
            File_Name : constant String := Get_Gnatchop_File (File.X_File);
            Ignored : File_Reference;
         begin
            Ignored := Add_To_Xref_File (ALI_File_Name (File_Name), False);
         end;
      end if;

      --  Parse references to this entity.
      --  Ptr points to next reference with leading blanks

      loop
         --  Process references on current line

         while Ali (Ptr) = ' ' or else Ali (Ptr) = ASCII.HT loop

            --  For every reference read the line, type and column,
            --  optionally preceded by a file number and a pipe symbol.

            Parse_Number (Ali, Ptr, R_Line);

            if Ali (Ptr) = Pipe then
               Ptr := Ptr + 1;
               File_Ref := File_Name (File, R_Line);

               Parse_Number (Ali, Ptr, R_Line);
            end if;

            if Ali (Ptr) > ' ' then
               R_Type := Ali (Ptr);
               Ptr := Ptr + 1;
            end if;

            --  Imported entities may have an indication specifying information
            --  about the corresponding external name:
            --    5U14*Foo2 5>20 6b<c,myfoo2>22   # Imported entity
            --    5U14*Foo2 5>20 6i<c,myfoo2>22   # Exported entity

            if (R_Type = 'b' or else R_Type = 'i')
              and then Ali (Ptr) = '<'
            then
               while Ptr <= Ali'Last
                 and then Ali (Ptr) /= '>'
               loop
                  Ptr := Ptr + 1;
               end loop;
               Ptr := Ptr + 1;
            end if;

            Parse_Number (Ali, Ptr, R_Col);

            --  Insert the reference or body in the table

            Add_Reference
              (Decl_Ref, File_Ref, R_Line, R_Col, R_Type, Labels_As_Ref);

            --  Skip generic information, if any

            if Ali (Ptr) = '[' then
               declare
                  Num_Nested : Integer := 1;

               begin
                  Ptr := Ptr + 1;
                  while Num_Nested /= 0 loop
                     if Ali (Ptr) = ']' then
                        Num_Nested := Num_Nested - 1;
                     elsif Ali (Ptr) = '[' then
                        Num_Nested := Num_Nested + 1;
                     end if;

                     Ptr := Ptr + 1;
                  end loop;
               end;
            end if;

         end loop;

         Parse_EOL (Ali, Ptr);

         --   Loop until new line is no continuation line

         exit when Ali (Ptr) /= '.';
         Ptr := Ptr + 1;
      end loop;
   end Parse_Identifier_Info;

   ------------------
   -- Parse_Number --
   ------------------

   procedure Parse_Number
     (Source : not null access String;
      Ptr    : in out Positive;
      Number : out Natural)
   is
   begin
      --  Skip separators

      while Source (Ptr) = ' ' or else Source (Ptr) = ASCII.HT loop
         Ptr := Ptr + 1;
      end loop;

      Number := 0;
      while Source (Ptr) in '0' .. '9' loop
         Number :=
           10 * Number + (Character'Pos (Source (Ptr)) - Character'Pos ('0'));
         Ptr := Ptr + 1;
      end loop;
   end Parse_Number;

   -----------------
   -- Parse_Token --
   -----------------

   procedure Parse_Token
     (Source    : not null access String;
      Ptr       : in out Positive;
      Token_Ptr : out Positive)
   is
      In_Quotes : Character := ASCII.NUL;

   begin
      --  Skip separators

      while Source (Ptr) = ' ' or else Source (Ptr) = ASCII.HT loop
         Ptr := Ptr + 1;
      end loop;

      Token_Ptr := Ptr;

      --  Find end-of-token

      while (In_Quotes /= ASCII.NUL or else
               not (Source (Ptr) = ' '
                     or else Source (Ptr) = ASCII.HT
                     or else Source (Ptr) = '<'
                     or else Source (Ptr) = '{'
                     or else Source (Ptr) = '['
                     or else Source (Ptr) = '='
                     or else Source (Ptr) = '('))
        and then Source (Ptr) >= ' '
      loop
         --  Double-quotes are used for operators
         --  Simple-quotes are used for character constants, for instance when
         --  they are found in an enumeration type "type A is ('+', '-');"

         case Source (Ptr) is
            when '"' | ''' =>
               if In_Quotes = Source (Ptr) then
                  In_Quotes := ASCII.NUL;
               elsif In_Quotes = ASCII.NUL then
                  In_Quotes := Source (Ptr);
               end if;

            when others =>
               null;
         end case;

         Ptr := Ptr + 1;
      end loop;
   end Parse_Token;

   ----------------------
   -- Parse_X_Filename --
   ----------------------

   procedure Parse_X_Filename (File : in out ALI_File) is
      Ali     : String_Access renames File.Buffer;
      Ptr     : Positive renames File.Current_Line;
      File_Nr : Natural;

      Table : Table_Type renames File.Dep.Table (1 .. Last (File.Dep));

   begin
      while Ali (Ptr) = 'X' loop

         --  The current line is the start of a new Xref file section,
         --  whose format looks like:

         --     " X 1 debug.ads"

         --  Skip the X and read the file number for the new X_File

         Ptr := Ptr + 1;
         Parse_Number (Ali, Ptr, File_Nr);

         --  If the referenced file is unknown, we simply ignore it

         if File_Nr in Table'Range then
            File.X_File := Table (File_Nr);
         else
            File.X_File := Empty_File;
         end if;

         Parse_EOL (Ali, Ptr);
      end loop;
   end Parse_X_Filename;

   --------------------
   -- Print_Gnatfind --
   --------------------

   procedure Print_Gnatfind
     (References     : Boolean;
      Full_Path_Name : Boolean)
   is
      Decls : constant Declaration_Array_Access := Get_Declarations;
      Decl  : Declaration_Reference;
      Arr   : Reference_Array_Access;

      procedure Print_Ref
        (Ref : Reference;
         Msg : String := "      ");
      --  Print a reference, according to the extended tag of the output

      ---------------
      -- Print_Ref --
      ---------------

      procedure Print_Ref
        (Ref : Reference;
         Msg : String := "      ")
      is
         F : String_Access :=
               Osint.To_Host_File_Spec
                (Get_Gnatchop_File (Ref, Full_Path_Name));

         Buffer : constant String :=
                    F.all &
                    ":" & Get_Line (Ref)   &
                    ":" & Get_Column (Ref) &
                    ": ";

         Num_Blanks : Integer := Longest_File_Name + 10 - Buffer'Length;

      begin
         Free (F);
         Num_Blanks := Integer'Max (0, Num_Blanks);
         Write_Line
           (Buffer
            & String'(1 .. Num_Blanks => ' ')
            & Msg & " " & Get_Symbol (Decl));

         if Get_Source_Line (Ref)'Length /= 0 then
            Write_Line ("   " & Get_Source_Line (Ref));
         end if;
      end Print_Ref;

   --  Start of processing for Print_Gnatfind

   begin
      for D in Decls'Range loop
         Decl := Decls (D);

         if Match (Decl) then

            --  Output the declaration

            declare
               Parent : constant Declaration_Reference := Get_Parent (Decl);

               F : String_Access :=
                     Osint.To_Host_File_Spec
                      (Get_Gnatchop_File (Decl, Full_Path_Name));

               Buffer : constant String :=
                          F.all &
                          ":" & Get_Line (Decl)   &
                          ":" & Get_Column (Decl) &
                          ": ";

               Num_Blanks : Integer := Longest_File_Name + 10 - Buffer'Length;

            begin
               Free (F);
               Num_Blanks := Integer'Max (0, Num_Blanks);
               Write_Line
                 (Buffer & String'(1 .. Num_Blanks => ' ')
                  & "(spec) " & Get_Symbol (Decl));

               if Parent /= Empty_Declaration then
                  F := Osint.To_Host_File_Spec (Get_Gnatchop_File (Parent));
                  Write_Line
                    (Buffer & String'(1 .. Num_Blanks => ' ')
                     & "   derived from " & Get_Symbol (Parent)
                     & " ("
                     & F.all
                     & ':' & Get_Line (Parent)
                     & ':' & Get_Column (Parent) & ')');
                  Free (F);
               end if;
            end;

            if Get_Source_Line (Decl)'Length /= 0 then
               Write_Line ("   " & Get_Source_Line (Decl));
            end if;

            --  Output the body (sorted)

            Arr := Get_References (Decl, Get_Bodies => True);

            for R in Arr'Range loop
               Print_Ref (Arr (R), "(body)");
            end loop;

            Free (Arr);

            if References then
               Arr := Get_References
                 (Decl, Get_Writes => True, Get_Reads => True);

               for R in Arr'Range loop
                  Print_Ref (Arr (R));
               end loop;

               Free (Arr);
            end if;
         end if;
      end loop;
   end Print_Gnatfind;

   ------------------
   -- Print_Unused --
   ------------------

   procedure Print_Unused (Full_Path_Name : Boolean) is
      Decls : constant Declaration_Array_Access := Get_Declarations;
      Decl  : Declaration_Reference;
      Arr   : Reference_Array_Access;
      F     : String_Access;

   begin
      for D in Decls'Range loop
         Decl := Decls (D);

         if References_Count
             (Decl, Get_Reads => True, Get_Writes => True) = 0
         then
            F := Osint.To_Host_File_Spec
              (Get_Gnatchop_File (Decl, Full_Path_Name));
            Write_Str (Get_Symbol (Decl)
                        & " ("
                        & Get_Full_Type (Decl)
                        & ") "
                        & F.all
                        & ':'
                        & Get_Line (Decl)
                        & ':'
                        & Get_Column (Decl));
            Free (F);

            --  Print the body if any

            Arr := Get_References (Decl, Get_Bodies => True);

            for R in Arr'Range loop
               F := Osint.To_Host_File_Spec
                      (Get_Gnatchop_File (Arr (R), Full_Path_Name));
               Write_Str (' '
                           & F.all
                           & ':' & Get_Line (Arr (R))
                           & ':' & Get_Column (Arr (R)));
               Free (F);
            end loop;

            Write_Eol;
            Free (Arr);
         end if;
      end loop;
   end Print_Unused;

   --------------
   -- Print_Vi --
   --------------

   procedure Print_Vi (Full_Path_Name : Boolean) is
      Tab   : constant Character := ASCII.HT;
      Decls : constant Declaration_Array_Access :=
                Get_Declarations (Sorted => False);
      Decl  : Declaration_Reference;
      Arr   : Reference_Array_Access;
      F     : String_Access;

   begin
      for D in Decls'Range loop
         Decl := Decls (D);

         F := Osint.To_Host_File_Spec (Get_File (Decl, Full_Path_Name));
         Write_Line (Get_Symbol (Decl) & Tab & F.all & Tab & Get_Line (Decl));
         Free (F);

         --  Print the body if any

         Arr := Get_References (Decl, Get_Bodies => True);

         for R in Arr'Range loop
            F := Osint.To_Host_File_Spec (Get_File (Arr (R), Full_Path_Name));
            Write_Line
              (Get_Symbol (Decl) & Tab & F.all & Tab  & Get_Line (Arr (R)));
            Free (F);
         end loop;

         Free (Arr);

         --  Print the modifications

         Arr := Get_References (Decl, Get_Writes => True, Get_Reads => True);

         for R in Arr'Range loop
            F := Osint.To_Host_File_Spec (Get_File (Arr (R), Full_Path_Name));
            Write_Line
              (Get_Symbol (Decl) & Tab & F.all & Tab & Get_Line (Arr (R)));
            Free (F);
         end loop;

         Free (Arr);
      end loop;
   end Print_Vi;

   ----------------
   -- Print_Xref --
   ----------------

   procedure Print_Xref (Full_Path_Name : Boolean) is
      Decls : constant Declaration_Array_Access := Get_Declarations;
      Decl : Declaration_Reference;

      Margin : constant := 10;
      --  Column where file names start

      procedure New_Line80;
      --  Go to start of new line

      procedure Print80 (S : String);
      --  Print the text, respecting the 80 columns rule

      procedure Print_Ref (Line, Column : String);
      --  The beginning of the output is aligned on a column multiple of 9

      procedure Print_List
        (Decl       : Declaration_Reference;
         Msg        : String;
         Get_Reads  : Boolean := False;
         Get_Writes : Boolean := False;
         Get_Bodies : Boolean := False);
      --  Print a list of references. If the list is not empty, Msg will
      --  be printed prior to the list.

      ----------------
      -- New_Line80 --
      ----------------

      procedure New_Line80 is
      begin
         Write_Eol;
         Write_Str (String'(1 .. Margin - 1 => ' '));
      end New_Line80;

      -------------
      -- Print80 --
      -------------

      procedure Print80 (S : String) is
         Align : Natural := Margin - (Integer (Column) mod Margin);

      begin
         if Align = Margin then
            Align := 0;
         end if;

         Write_Str (String'(1 .. Align => ' ') & S);
      end Print80;

      ---------------
      -- Print_Ref --
      ---------------

      procedure Print_Ref (Line, Column : String) is
         Line_Align : constant Integer := 4 - Line'Length;

         S : constant String := String'(1 .. Line_Align => ' ')
                                  & Line & ':' & Column;

         Align : Natural := Margin - (Integer (Output.Column) mod Margin);

      begin
         if Align = Margin then
            Align := 0;
         end if;

         if Integer (Output.Column) + Align + S'Length > 79 then
            New_Line80;
            Align := 0;
         end if;

         Write_Str (String'(1 .. Align => ' ') & S);
      end Print_Ref;

      ----------------
      -- Print_List --
      ----------------

      procedure Print_List
        (Decl       : Declaration_Reference;
         Msg        : String;
         Get_Reads  : Boolean := False;
         Get_Writes : Boolean := False;
         Get_Bodies : Boolean := False)
      is
         Arr : Reference_Array_Access :=
                 Get_References
                   (Decl,
                    Get_Writes => Get_Writes,
                    Get_Reads  => Get_Reads,
                    Get_Bodies => Get_Bodies);
         File : File_Reference := Empty_File;
         F    : String_Access;

      begin
         if Arr'Length /= 0 then
            Write_Eol;
            Write_Str (Msg);
         end if;

         for R in Arr'Range loop
            if Get_File_Ref (Arr (R)) /= File then
               if File /= Empty_File then
                  New_Line80;
               end if;

               File := Get_File_Ref (Arr (R));
               F := Osint.To_Host_File_Spec
                 (Get_Gnatchop_File (Arr (R), Full_Path_Name));

               if F = null then
                  Write_Str ("<unknown> ");
               else
                  Write_Str (F.all & ' ');
                  Free (F);
               end if;
            end if;

            Print_Ref (Get_Line (Arr (R)), Get_Column (Arr (R)));
         end loop;

         Free (Arr);
      end Print_List;

      F : String_Access;

   --  Start of processing for Print_Xref

   begin
      for D in Decls'Range loop
         Decl := Decls (D);

         Write_Str (Get_Symbol (Decl));

         --  Put the declaration type in column Type_Position, but if the
         --  declaration name is too long, put at least one space between its
         --  name and its type.

         while Column < Type_Position - 1 loop
            Write_Char (' ');
         end loop;

         Write_Char (' ');

         Write_Line (Get_Full_Type (Decl));

         Write_Parent_Info : declare
            Parent : constant Declaration_Reference := Get_Parent (Decl);

         begin
            if Parent /= Empty_Declaration then
               Write_Str ("  Ptype: ");
               F := Osint.To_Host_File_Spec (Get_Gnatchop_File (Parent));
               Print80 (F.all);
               Free (F);
               Print_Ref (Get_Line (Parent), Get_Column (Parent));
               Print80 ("  " & Get_Symbol (Parent));
               Write_Eol;
            end if;
         end Write_Parent_Info;

         Write_Str ("  Decl:  ");
         F := Osint.To_Host_File_Spec
               (Get_Gnatchop_File (Decl, Full_Path_Name));

         if F = null then
            Print80 ("<unknown> ");
         else
            Print80 (F.all & ' ');
            Free (F);
         end if;

         Print_Ref (Get_Line (Decl), Get_Column (Decl));

         Print_List
           (Decl, "  Body:  ", Get_Bodies => True);
         Print_List
           (Decl, "  Modi:  ", Get_Writes => True);
         Print_List
           (Decl, "  Ref:   ", Get_Reads => True);
         Write_Eol;
      end loop;
   end Print_Xref;

   ------------
   -- Search --
   ------------

   procedure Search
     (Pattern       : Search_Pattern;
      Local_Symbols : Boolean;
      Wide_Search   : Boolean;
      Read_Only     : Boolean;
      Der_Info      : Boolean;
      Type_Tree     : Boolean)
   is
      type String_Access is access String;
      procedure Free is new Unchecked_Deallocation (String, String_Access);

      ALIfile   : ALI_File;
      File_Ref  : File_Reference;
      Strip_Num : Natural := 0;
      Ali_Name  : String_Access;

   begin
      --  If we want all the .ali files, then find them

      if Wide_Search then
         Find_ALI_Files;
      end if;

      loop
         --  Get the next unread ali file

         File_Ref := Next_Unvisited_File;

         exit when File_Ref = Empty_File;

         --  Find the ALI file to use. Most of the time, it will be the unit
         --  name, with a different extension. However, when dealing with
         --  separates the ALI file is in fact the parent's ALI file (and this
         --  is recursive, in case the parent itself is a separate).

         Strip_Num := 0;
         loop
            Free (Ali_Name);
            Ali_Name := new String'
              (Get_File (File_Ref, With_Dir => True, Strip => Strip_Num));

            --  Stripped too many things...

            if Ali_Name.all = "" then
               if Get_Emit_Warning (File_Ref) then
                  Set_Standard_Error;
                  Write_Line
                    ("warning : file " & Get_File (File_Ref, With_Dir => True)
                     & " not found");
                  Set_Standard_Output;
               end if;
               Free (Ali_Name);
               exit;

            --  If not found, try the parent's ALI file (this is needed for
            --  separate units and subprograms).

            --  Reset the cached directory first, in case the separate's
            --  ALI file is not in the same directory.

            elsif not File_Exists (Ali_Name.all) then
               Strip_Num := Strip_Num + 1;
               Reset_Directory (File_Ref);

            --  Else we finally found it

            else
               exit;
            end if;
         end loop;

         --  If we had to get the parent's ALI, insert it in the list as usual.
         --  This is to avoid parsing it twice in case it has already been
         --  parsed.

         if Ali_Name /= null and then Strip_Num /= 0 then
            File_Ref := Add_To_Xref_File
              (File_Name => Ali_Name.all,
               Visited   => False);

         --  Now that we have a file name, parse it to find any reference to
         --  the entity.

         elsif Ali_Name /= null
           and then (Read_Only or else Is_Writable_File (Ali_Name.all))
         then
            begin
               Open (Ali_Name.all, ALIfile);

               --  The cross-reference section in the ALI file may be followed
               --  by other sections, which can be identified by the starting
               --  character of every line, which should neither be 'X' nor a
               --  figure in '1' .. '9'.

               --  The loop tests below also take into account the end-of-file
               --  possibility.

               while ALIfile.Buffer (ALIfile.Current_Line) = 'X' loop
                  Parse_X_Filename (ALIfile);

                  while ALIfile.Buffer (ALIfile.Current_Line) in '1' .. '9'
                  loop
                     Parse_Identifier_Info
                       (Pattern, ALIfile, Local_Symbols, Der_Info, Type_Tree,
                        Wide_Search, Labels_As_Ref => True);
                  end loop;
               end loop;

            exception
               when No_Xref_Information   =>
                  if Get_Emit_Warning (File_Ref) then
                     Set_Standard_Error;
                     Write_Line
                       ("warning : No cross-referencing information in  "
                        & Ali_Name.all);
                     Set_Standard_Output;
                  end if;
            end;
         end if;
      end loop;

      Free (Ali_Name);
   end Search;

   -----------------
   -- Search_Xref --
   -----------------

   procedure Search_Xref
     (Local_Symbols : Boolean;
      Read_Only     : Boolean;
      Der_Info      : Boolean)
   is
      ALIfile      : ALI_File;
      File_Ref     : File_Reference;
      Null_Pattern : Search_Pattern;

   begin
      Null_Pattern.Initialized := False;

      loop
         --  Find the next unvisited file

         File_Ref := Next_Unvisited_File;
         exit when File_Ref = Empty_File;

         --  Search the object directories for the .ali file

         declare
            F : constant String := Get_File (File_Ref, With_Dir => True);

         begin
            if Read_Only or else Is_Writable_File (F) then
               Open (F, ALIfile, True);

               --  The cross-reference section in the ALI file may be followed
               --  by other sections, which can be identified by the starting
               --  character of every line, which should neither be 'X' nor a
               --  figure in '1' .. '9'.

               --  The loop tests below also take into account the end-of-file
               --  possibility.

               while ALIfile.Buffer (ALIfile.Current_Line) = 'X' loop
                  Parse_X_Filename (ALIfile);

                  while ALIfile.Buffer (ALIfile.Current_Line) in '1' .. '9'
                  loop
                     Parse_Identifier_Info
                       (Null_Pattern, ALIfile, Local_Symbols, Der_Info,
                        Labels_As_Ref => False);
                  end loop;
               end loop;
            end if;

         exception
            when No_Xref_Information =>  null;
         end;
      end loop;
   end Search_Xref;

end Xref_Lib;
