aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.2.1/gcc/ada/xr_tabls.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.2.1/gcc/ada/xr_tabls.adb')
-rw-r--r--gcc-4.2.1/gcc/ada/xr_tabls.adb1627
1 files changed, 0 insertions, 1627 deletions
diff --git a/gcc-4.2.1/gcc/ada/xr_tabls.adb b/gcc-4.2.1/gcc/ada/xr_tabls.adb
deleted file mode 100644
index 0b11a5697..000000000
--- a/gcc-4.2.1/gcc/ada/xr_tabls.adb
+++ /dev/null
@@ -1,1627 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT COMPILER COMPONENTS --
--- --
--- X R _ T A B L S --
--- --
--- B o d y --
--- --
--- Copyright (C) 1998-2006, 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 2, 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 COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
--- --
--- GNAT was originally developed by the GNAT team at New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc. --
--- --
-------------------------------------------------------------------------------
-
-with Types; use Types;
-with Osint;
-with Hostparm;
-
-with Ada.Unchecked_Conversion;
-with Ada.Unchecked_Deallocation;
-with Ada.Strings.Fixed;
-with Ada.Strings;
-with Ada.Text_IO;
-with Ada.Characters.Handling; use Ada.Characters.Handling;
-with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
-
-with GNAT.OS_Lib; use GNAT.OS_Lib;
-with GNAT.Directory_Operations; use GNAT.Directory_Operations;
-with GNAT.HTable; use GNAT.HTable;
-with GNAT.Heap_Sort_G;
-
-package body Xr_Tabls is
-
- type HTable_Headers is range 1 .. 10000;
-
- procedure Set_Next (E : File_Reference; Next : File_Reference);
- function Next (E : File_Reference) return File_Reference;
- function Get_Key (E : File_Reference) return Cst_String_Access;
- function Hash (F : Cst_String_Access) return HTable_Headers;
- function Equal (F1, F2 : Cst_String_Access) return Boolean;
- -- The five subprograms above are used to instanciate the static
- -- htable to store the files that should be processed.
-
- package File_HTable is new GNAT.HTable.Static_HTable
- (Header_Num => HTable_Headers,
- Element => File_Record,
- Elmt_Ptr => File_Reference,
- Null_Ptr => null,
- Set_Next => Set_Next,
- Next => Next,
- Key => Cst_String_Access,
- Get_Key => Get_Key,
- Hash => Hash,
- Equal => Equal);
- -- A hash table to store all the files referenced in the
- -- application. The keys in this htable are the name of the files
- -- themselves, therefore it is assumed that the source path
- -- doesn't contain twice the same source or ALI file name
-
- type Unvisited_Files_Record;
- type Unvisited_Files_Access is access Unvisited_Files_Record;
- type Unvisited_Files_Record is record
- File : File_Reference;
- Next : Unvisited_Files_Access;
- end record;
- -- A special list, in addition to File_HTable, that only stores
- -- the files that haven't been visited so far. Note that the File
- -- list points to some data in File_HTable, and thus should never be freed.
-
- function Next (E : Declaration_Reference) return Declaration_Reference;
- procedure Set_Next (E, Next : Declaration_Reference);
- function Get_Key (E : Declaration_Reference) return Cst_String_Access;
- -- The subprograms above are used to instanciate the static
- -- htable to store the entities that have been found in the application
-
- package Entities_HTable is new GNAT.HTable.Static_HTable
- (Header_Num => HTable_Headers,
- Element => Declaration_Record,
- Elmt_Ptr => Declaration_Reference,
- Null_Ptr => null,
- Set_Next => Set_Next,
- Next => Next,
- Key => Cst_String_Access,
- Get_Key => Get_Key,
- Hash => Hash,
- Equal => Equal);
- -- A hash table to store all the entities defined in the
- -- application. For each entity, we store a list of its reference
- -- locations as well.
- -- The keys in this htable should be created with Key_From_Ref,
- -- and are the file, line and column of the declaration, which are
- -- unique for every entity.
-
- Entities_Count : Natural := 0;
- -- Number of entities in Entities_HTable. This is used in the end
- -- when sorting the table.
-
- Longest_File_Name_In_Table : Natural := 0;
- Unvisited_Files : Unvisited_Files_Access := null;
- Directories : Project_File_Ptr;
- Default_Match : Boolean := False;
- -- The above need commenting ???
-
- function Parse_Gnatls_Src return String;
- -- Return the standard source directories (taking into account the
- -- ADA_INCLUDE_PATH environment variable, if Osint.Add_Default_Search_Dirs
- -- was called first).
-
- function Parse_Gnatls_Obj return String;
- -- Return the standard object directories (taking into account the
- -- ADA_OBJECTS_PATH environment variable).
-
- function Key_From_Ref
- (File_Ref : File_Reference;
- Line : Natural;
- Column : Natural)
- return String;
- -- Return a key for the symbol declared at File_Ref, Line,
- -- Column. This key should be used for lookup in Entity_HTable
-
- function Is_Less_Than (Decl1, Decl2 : Declaration_Reference) return Boolean;
- -- Compare two declarations (the comparison is case-insensitive)
-
- function Is_Less_Than (Ref1, Ref2 : Reference) return Boolean;
- -- Compare two references
-
- procedure Store_References
- (Decl : Declaration_Reference;
- Get_Writes : Boolean := False;
- Get_Reads : Boolean := False;
- Get_Bodies : Boolean := False;
- Get_Declaration : Boolean := False;
- Arr : in out Reference_Array;
- Index : in out Natural);
- -- Store in Arr, starting at Index, all the references to Decl. The Get_*
- -- parameters can be used to indicate which references should be stored.
- -- Constraint_Error will be raised if Arr is not big enough.
-
- procedure Sort (Arr : in out Reference_Array);
- -- Sort an array of references (Arr'First must be 1)
-
- --------------
- -- Set_Next --
- --------------
-
- procedure Set_Next (E : File_Reference; Next : File_Reference) is
- begin
- E.Next := Next;
- end Set_Next;
-
- procedure Set_Next
- (E : Declaration_Reference; Next : Declaration_Reference) is
- begin
- E.Next := Next;
- end Set_Next;
-
- -------------
- -- Get_Key --
- -------------
-
- function Get_Key (E : File_Reference) return Cst_String_Access is
- begin
- return E.File;
- end Get_Key;
-
- function Get_Key (E : Declaration_Reference) return Cst_String_Access is
- begin
- return E.Key;
- end Get_Key;
-
- ----------
- -- Hash --
- ----------
-
- function Hash (F : Cst_String_Access) return HTable_Headers is
- function H is new GNAT.HTable.Hash (HTable_Headers);
-
- begin
- return H (F.all);
- end Hash;
-
- -----------
- -- Equal --
- -----------
-
- function Equal (F1, F2 : Cst_String_Access) return Boolean is
- begin
- return F1.all = F2.all;
- end Equal;
-
- ------------------
- -- Key_From_Ref --
- ------------------
-
- function Key_From_Ref
- (File_Ref : File_Reference;
- Line : Natural;
- Column : Natural)
- return String
- is
- begin
- return File_Ref.File.all & Natural'Image (Line) & Natural'Image (Column);
- end Key_From_Ref;
-
- ---------------------
- -- Add_Declaration --
- ---------------------
-
- function Add_Declaration
- (File_Ref : File_Reference;
- Symbol : String;
- Line : Natural;
- Column : Natural;
- Decl_Type : Character;
- Remove_Only : Boolean := False;
- Symbol_Match : Boolean := True)
- return Declaration_Reference
- is
- procedure Unchecked_Free is new Ada.Unchecked_Deallocation
- (Declaration_Record, Declaration_Reference);
-
- Key : aliased constant String := Key_From_Ref (File_Ref, Line, Column);
-
- New_Decl : Declaration_Reference :=
- Entities_HTable.Get (Key'Unchecked_Access);
-
- Is_Parameter : Boolean := False;
-
- begin
- -- Insert the Declaration in the table. There might already be a
- -- declaration in the table if the entity is a parameter, so we
- -- need to check that first.
-
- if New_Decl /= null and then New_Decl.Symbol_Length = 0 then
- Is_Parameter := New_Decl.Is_Parameter;
- Entities_HTable.Remove (Key'Unrestricted_Access);
- Entities_Count := Entities_Count - 1;
- Free (New_Decl.Key);
- Unchecked_Free (New_Decl);
- New_Decl := null;
- end if;
-
- -- The declaration might also already be there for parent types. In
- -- this case, we should keep the entry, since some other entries are
- -- pointing to it.
-
- if New_Decl = null
- and then not Remove_Only
- then
- New_Decl :=
- new Declaration_Record'
- (Symbol_Length => Symbol'Length,
- Symbol => Symbol,
- Key => new String'(Key),
- Decl => new Reference_Record'
- (File => File_Ref,
- Line => Line,
- Column => Column,
- Source_Line => null,
- Next => null),
- Is_Parameter => Is_Parameter,
- Decl_Type => Decl_Type,
- Body_Ref => null,
- Ref_Ref => null,
- Modif_Ref => null,
- Match => Symbol_Match
- and then
- (Default_Match
- or else Match (File_Ref, Line, Column)),
- Par_Symbol => null,
- Next => null);
-
- Entities_HTable.Set (New_Decl);
- Entities_Count := Entities_Count + 1;
-
- if New_Decl.Match then
- Longest_File_Name_In_Table :=
- Natural'Max (File_Ref.File'Length, Longest_File_Name_In_Table);
- end if;
-
- elsif New_Decl /= null
- and then not New_Decl.Match
- then
- New_Decl.Match := Default_Match
- or else Match (File_Ref, Line, Column);
- end if;
-
- return New_Decl;
- end Add_Declaration;
-
- ----------------------
- -- Add_To_Xref_File --
- ----------------------
-
- function Add_To_Xref_File
- (File_Name : String;
- Visited : Boolean := True;
- Emit_Warning : Boolean := False;
- Gnatchop_File : String := "";
- Gnatchop_Offset : Integer := 0) return File_Reference
- is
- Base : aliased constant String := Base_Name (File_Name);
- Dir : constant String := Dir_Name (File_Name);
- Dir_Acc : GNAT.OS_Lib.String_Access := null;
- Ref : File_Reference;
-
- begin
- -- Do we have a directory name as well?
-
- if File_Name /= Base then
- Dir_Acc := new String'(Dir);
- end if;
-
- Ref := File_HTable.Get (Base'Unchecked_Access);
- if Ref = null then
- Ref := new File_Record'
- (File => new String'(Base),
- Dir => Dir_Acc,
- Lines => null,
- Visited => Visited,
- Emit_Warning => Emit_Warning,
- Gnatchop_File => new String'(Gnatchop_File),
- Gnatchop_Offset => Gnatchop_Offset,
- Next => null);
- File_HTable.Set (Ref);
-
- if not Visited then
-
- -- Keep a separate list for faster access
-
- Set_Unvisited (Ref);
- end if;
- end if;
- return Ref;
- end Add_To_Xref_File;
-
- --------------
- -- Add_Line --
- --------------
-
- procedure Add_Line
- (File : File_Reference;
- Line : Natural;
- Column : Natural)
- is
- begin
- File.Lines := new Ref_In_File'(Line => Line,
- Column => Column,
- Next => File.Lines);
- end Add_Line;
-
- ----------------
- -- Add_Parent --
- ----------------
-
- procedure Add_Parent
- (Declaration : in out Declaration_Reference;
- Symbol : String;
- Line : Natural;
- Column : Natural;
- File_Ref : File_Reference)
- is
- begin
- Declaration.Par_Symbol :=
- Add_Declaration
- (File_Ref, Symbol, Line, Column,
- Decl_Type => ' ',
- Symbol_Match => False);
- end Add_Parent;
-
- -------------------
- -- Add_Reference --
- -------------------
-
- procedure Add_Reference
- (Declaration : Declaration_Reference;
- File_Ref : File_Reference;
- Line : Natural;
- Column : Natural;
- Ref_Type : Character;
- Labels_As_Ref : Boolean)
- is
- New_Ref : Reference;
-
- begin
- case Ref_Type is
- when 'b' | 'c' | 'm' | 'r' | 'i' | ' ' | 'x' =>
- null;
-
- when 'l' | 'w' =>
- if not Labels_As_Ref then
- return;
- end if;
-
- when '=' | '<' | '>' | '^' =>
-
- -- Create a dummy declaration in the table to report it as a
- -- parameter. Note that the current declaration for the subprogram
- -- comes before the declaration of the parameter.
-
- declare
- Key : constant String :=
- Key_From_Ref (File_Ref, Line, Column);
- New_Decl : Declaration_Reference;
-
- begin
- New_Decl := new Declaration_Record'
- (Symbol_Length => 0,
- Symbol => "",
- Key => new String'(Key),
- Decl => null,
- Is_Parameter => True,
- Decl_Type => ' ',
- Body_Ref => null,
- Ref_Ref => null,
- Modif_Ref => null,
- Match => False,
- Par_Symbol => null,
- Next => null);
- Entities_HTable.Set (New_Decl);
- Entities_Count := Entities_Count + 1;
- end;
-
- when 'e' | 'z' | 't' | 'p' | 'P' | 'k' | 'd' =>
- return;
-
- when others =>
- Ada.Text_IO.Put_Line ("Unknown reference type: " & Ref_Type);
- return;
- end case;
-
- New_Ref := new Reference_Record'
- (File => File_Ref,
- Line => Line,
- Column => Column,
- Source_Line => null,
- Next => null);
-
- -- We can insert the reference in the list directly, since all
- -- the references will appear only once in the ALI file
- -- corresponding to the file where they are referenced.
- -- This saves a lot of time compared to checking the list to check
- -- if it exists.
-
- case Ref_Type is
- when 'b' | 'c' =>
- New_Ref.Next := Declaration.Body_Ref;
- Declaration.Body_Ref := New_Ref;
-
- when 'r' | 'i' | 'l' | ' ' | 'x' | 'w' =>
- New_Ref.Next := Declaration.Ref_Ref;
- Declaration.Ref_Ref := New_Ref;
-
- when 'm' =>
- New_Ref.Next := Declaration.Modif_Ref;
- Declaration.Modif_Ref := New_Ref;
-
- when others =>
- null;
- end case;
-
- if not Declaration.Match then
- Declaration.Match := Match (File_Ref, Line, Column);
- end if;
-
- if Declaration.Match then
- Longest_File_Name_In_Table :=
- Natural'Max (File_Ref.File'Length, Longest_File_Name_In_Table);
- end if;
- end Add_Reference;
-
- -------------------
- -- ALI_File_Name --
- -------------------
-
- function ALI_File_Name (Ada_File_Name : String) return String is
-
- -- ??? Should ideally be based on the naming scheme defined in
- -- project files.
-
- Index : constant Natural :=
- Ada.Strings.Fixed.Index
- (Ada_File_Name, ".", Going => Ada.Strings.Backward);
-
- begin
- if Index /= 0 then
- return Ada_File_Name (Ada_File_Name'First .. Index) & "ali";
- else
- return Ada_File_Name & ".ali";
- end if;
- end ALI_File_Name;
-
- ------------------
- -- Is_Less_Than --
- ------------------
-
- function Is_Less_Than (Ref1, Ref2 : Reference) return Boolean is
- begin
- if Ref1 = null then
- return False;
- elsif Ref2 = null then
- return True;
- end if;
-
- if Ref1.File.File.all < Ref2.File.File.all then
- return True;
-
- elsif Ref1.File.File.all = Ref2.File.File.all then
- return (Ref1.Line < Ref2.Line
- or else (Ref1.Line = Ref2.Line
- and then Ref1.Column < Ref2.Column));
- end if;
-
- return False;
- end Is_Less_Than;
-
- ------------------
- -- Is_Less_Than --
- ------------------
-
- function Is_Less_Than (Decl1, Decl2 : Declaration_Reference) return Boolean
- is
- -- We cannot store the data case-insensitive in the table,
- -- since we wouldn't be able to find the right casing for the
- -- display later on.
-
- S1 : constant String := To_Lower (Decl1.Symbol);
- S2 : constant String := To_Lower (Decl2.Symbol);
-
- begin
- if S1 < S2 then
- return True;
- elsif S1 > S2 then
- return False;
- end if;
-
- return Decl1.Key.all < Decl2.Key.all;
- end Is_Less_Than;
-
- -------------------------
- -- Create_Project_File --
- -------------------------
-
- procedure Create_Project_File (Name : String) is
- Obj_Dir : Unbounded_String := Null_Unbounded_String;
- Src_Dir : Unbounded_String := Null_Unbounded_String;
- Build_Dir : GNAT.OS_Lib.String_Access := new String'("");
-
- F : File_Descriptor;
- Len : Positive;
- File_Name : aliased String := Name & ASCII.NUL;
-
- begin
- -- Read the size of the file
-
- F := Open_Read (File_Name'Address, Text);
-
- -- Project file not found
-
- if F /= Invalid_FD then
- Len := Positive (File_Length (F));
-
- declare
- Buffer : String (1 .. Len);
- Index : Positive := Buffer'First;
- Last : Positive;
-
- begin
- Len := Read (F, Buffer'Address, Len);
- Close (F);
-
- -- First, look for Build_Dir, since all the source and object
- -- path are relative to it.
-
- while Index <= Buffer'Last loop
-
- -- Find the end of line
-
- Last := Index;
- while Last <= Buffer'Last
- and then Buffer (Last) /= ASCII.LF
- and then Buffer (Last) /= ASCII.CR
- loop
- Last := Last + 1;
- end loop;
-
- if Index <= Buffer'Last - 9
- and then Buffer (Index .. Index + 9) = "build_dir="
- then
- Index := Index + 10;
- while Index <= Last
- and then (Buffer (Index) = ' '
- or else Buffer (Index) = ASCII.HT)
- loop
- Index := Index + 1;
- end loop;
-
- Free (Build_Dir);
- Build_Dir := new String'(Buffer (Index .. Last - 1));
- end if;
-
- Index := Last + 1;
-
- -- In case we had a ASCII.CR/ASCII.LF end of line, skip the
- -- remaining symbol
-
- if Index <= Buffer'Last
- and then Buffer (Index) = ASCII.LF
- then
- Index := Index + 1;
- end if;
- end loop;
-
- -- Now parse the source and object paths
-
- Index := Buffer'First;
- while Index <= Buffer'Last loop
-
- -- Find the end of line
-
- Last := Index;
- while Last <= Buffer'Last
- and then Buffer (Last) /= ASCII.LF
- and then Buffer (Last) /= ASCII.CR
- loop
- Last := Last + 1;
- end loop;
-
- if Index <= Buffer'Last - 7
- and then Buffer (Index .. Index + 7) = "src_dir="
- then
- Append (Src_Dir, Normalize_Pathname
- (Name => Ada.Strings.Fixed.Trim
- (Buffer (Index + 8 .. Last - 1), Ada.Strings.Both),
- Directory => Build_Dir.all) & Path_Separator);
-
- elsif Index <= Buffer'Last - 7
- and then Buffer (Index .. Index + 7) = "obj_dir="
- then
- Append (Obj_Dir, Normalize_Pathname
- (Name => Ada.Strings.Fixed.Trim
- (Buffer (Index + 8 .. Last - 1), Ada.Strings.Both),
- Directory => Build_Dir.all) & Path_Separator);
- end if;
-
- -- In case we had a ASCII.CR/ASCII.LF end of line, skip the
- -- remaining symbol
- Index := Last + 1;
-
- if Index <= Buffer'Last
- and then Buffer (Index) = ASCII.LF
- then
- Index := Index + 1;
- end if;
- end loop;
- end;
- end if;
-
- Osint.Add_Default_Search_Dirs;
-
- declare
- Src : constant String := Parse_Gnatls_Src;
- Obj : constant String := Parse_Gnatls_Obj;
-
- begin
- Directories := new Project_File'
- (Src_Dir_Length => Length (Src_Dir) + Src'Length,
- Obj_Dir_Length => Length (Obj_Dir) + Obj'Length,
- Src_Dir => To_String (Src_Dir) & Src,
- Obj_Dir => To_String (Obj_Dir) & Obj,
- Src_Dir_Index => 1,
- Obj_Dir_Index => 1,
- Last_Obj_Dir_Start => 0);
- end;
-
- Free (Build_Dir);
- end Create_Project_File;
-
- ---------------------
- -- Current_Obj_Dir --
- ---------------------
-
- function Current_Obj_Dir return String is
- begin
- return Directories.Obj_Dir
- (Directories.Last_Obj_Dir_Start .. Directories.Obj_Dir_Index - 2);
- end Current_Obj_Dir;
-
- ----------------
- -- Get_Column --
- ----------------
-
- function Get_Column (Decl : Declaration_Reference) return String is
- begin
- return Ada.Strings.Fixed.Trim (Natural'Image (Decl.Decl.Column),
- Ada.Strings.Left);
- end Get_Column;
-
- function Get_Column (Ref : Reference) return String is
- begin
- return Ada.Strings.Fixed.Trim (Natural'Image (Ref.Column),
- Ada.Strings.Left);
- end Get_Column;
-
- ---------------------
- -- Get_Declaration --
- ---------------------
-
- function Get_Declaration
- (File_Ref : File_Reference;
- Line : Natural;
- Column : Natural)
- return Declaration_Reference
- is
- Key : aliased constant String := Key_From_Ref (File_Ref, Line, Column);
-
- begin
- return Entities_HTable.Get (Key'Unchecked_Access);
- end Get_Declaration;
-
- ----------------------
- -- Get_Emit_Warning --
- ----------------------
-
- function Get_Emit_Warning (File : File_Reference) return Boolean is
- begin
- return File.Emit_Warning;
- end Get_Emit_Warning;
-
- --------------
- -- Get_File --
- --------------
-
- function Get_File
- (Decl : Declaration_Reference;
- With_Dir : Boolean := False) return String
- is
- begin
- return Get_File (Decl.Decl.File, With_Dir);
- end Get_File;
-
- function Get_File
- (Ref : Reference;
- With_Dir : Boolean := False) return String
- is
- begin
- return Get_File (Ref.File, With_Dir);
- end Get_File;
-
- function Get_File
- (File : File_Reference;
- With_Dir : Boolean := False;
- Strip : Natural := 0) return String
- is
- Tmp : GNAT.OS_Lib.String_Access;
-
- function Internal_Strip (Full_Name : String) return String;
- -- Internal function to process the Strip parameter
-
- --------------------
- -- Internal_Strip --
- --------------------
-
- function Internal_Strip (Full_Name : String) return String is
- Unit_End : Natural;
- Extension_Start : Natural;
- S : Natural;
-
- begin
- if Strip = 0 then
- return Full_Name;
- end if;
-
- -- Isolate the file extension
-
- Extension_Start := Full_Name'Last;
- while Extension_Start >= Full_Name'First
- and then Full_Name (Extension_Start) /= '.'
- loop
- Extension_Start := Extension_Start - 1;
- end loop;
-
- -- Strip the right number of subunit_names
-
- S := Strip;
- Unit_End := Extension_Start - 1;
- while Unit_End >= Full_Name'First
- and then S > 0
- loop
- if Full_Name (Unit_End) = '-' then
- S := S - 1;
- end if;
-
- Unit_End := Unit_End - 1;
- end loop;
-
- if Unit_End < Full_Name'First then
- return "";
- else
- return Full_Name (Full_Name'First .. Unit_End)
- & Full_Name (Extension_Start .. Full_Name'Last);
- end if;
- end Internal_Strip;
-
- -- Start of processing for Get_File;
-
- begin
- -- If we do not want the full path name
-
- if not With_Dir then
- return Internal_Strip (File.File.all);
- end if;
-
- if File.Dir = null then
- if Ada.Strings.Fixed.Tail (File.File.all, 3) = "ali" then
- Tmp := Locate_Regular_File
- (Internal_Strip (File.File.all), Directories.Obj_Dir);
- else
- Tmp := Locate_Regular_File
- (File.File.all, Directories.Src_Dir);
- end if;
-
- if Tmp = null then
- File.Dir := new String'("");
- else
- File.Dir := new String'(Dir_Name (Tmp.all));
- Free (Tmp);
- end if;
- end if;
-
- return Internal_Strip (File.Dir.all & File.File.all);
- end Get_File;
-
- ------------------
- -- Get_File_Ref --
- ------------------
-
- function Get_File_Ref (Ref : Reference) return File_Reference is
- begin
- return Ref.File;
- end Get_File_Ref;
-
- -----------------------
- -- Get_Gnatchop_File --
- -----------------------
-
- function Get_Gnatchop_File
- (File : File_Reference;
- With_Dir : Boolean := False)
- return String
- is
- begin
- if File.Gnatchop_File.all = "" then
- return Get_File (File, With_Dir);
- else
- return File.Gnatchop_File.all;
- end if;
- end Get_Gnatchop_File;
-
- function Get_Gnatchop_File
- (Ref : Reference;
- With_Dir : Boolean := False)
- return String
- is
- begin
- return Get_Gnatchop_File (Ref.File, With_Dir);
- end Get_Gnatchop_File;
-
- function Get_Gnatchop_File
- (Decl : Declaration_Reference;
- With_Dir : Boolean := False)
- return String
- is
- begin
- return Get_Gnatchop_File (Decl.Decl.File, With_Dir);
- end Get_Gnatchop_File;
-
- --------------
- -- Get_Line --
- --------------
-
- function Get_Line (Decl : Declaration_Reference) return String is
- begin
- return Ada.Strings.Fixed.Trim (Natural'Image (Decl.Decl.Line),
- Ada.Strings.Left);
- end Get_Line;
-
- function Get_Line (Ref : Reference) return String is
- begin
- return Ada.Strings.Fixed.Trim (Natural'Image (Ref.Line),
- Ada.Strings.Left);
- end Get_Line;
-
- ----------------
- -- Get_Parent --
- ----------------
-
- function Get_Parent
- (Decl : Declaration_Reference)
- return Declaration_Reference
- is
- begin
- return Decl.Par_Symbol;
- end Get_Parent;
-
- ---------------------
- -- Get_Source_Line --
- ---------------------
-
- function Get_Source_Line (Ref : Reference) return String is
- begin
- if Ref.Source_Line /= null then
- return Ref.Source_Line.all;
- else
- return "";
- end if;
- end Get_Source_Line;
-
- function Get_Source_Line (Decl : Declaration_Reference) return String is
- begin
- if Decl.Decl.Source_Line /= null then
- return Decl.Decl.Source_Line.all;
- else
- return "";
- end if;
- end Get_Source_Line;
-
- ----------------
- -- Get_Symbol --
- ----------------
-
- function Get_Symbol (Decl : Declaration_Reference) return String is
- begin
- return Decl.Symbol;
- end Get_Symbol;
-
- --------------
- -- Get_Type --
- --------------
-
- function Get_Type (Decl : Declaration_Reference) return Character is
- begin
- return Decl.Decl_Type;
- end Get_Type;
-
- ----------
- -- Sort --
- ----------
-
- procedure Sort (Arr : in out Reference_Array) is
- Tmp : Reference;
-
- function Lt (Op1, Op2 : Natural) return Boolean;
- procedure Move (From, To : Natural);
- -- See GNAT.Heap_Sort_G
-
- --------
- -- Lt --
- --------
-
- function Lt (Op1, Op2 : Natural) return Boolean is
- begin
- if Op1 = 0 then
- return Is_Less_Than (Tmp, Arr (Op2));
- elsif Op2 = 0 then
- return Is_Less_Than (Arr (Op1), Tmp);
- else
- return Is_Less_Than (Arr (Op1), Arr (Op2));
- end if;
- end Lt;
-
- ----------
- -- Move --
- ----------
-
- procedure Move (From, To : Natural) is
- begin
- if To = 0 then
- Tmp := Arr (From);
- elsif From = 0 then
- Arr (To) := Tmp;
- else
- Arr (To) := Arr (From);
- end if;
- end Move;
-
- package Ref_Sort is new GNAT.Heap_Sort_G (Move, Lt);
-
- -- Start of processing for Sort
-
- begin
- Ref_Sort.Sort (Arr'Last);
- end Sort;
-
- -----------------------
- -- Grep_Source_Files --
- -----------------------
-
- procedure Grep_Source_Files is
- Length : Natural := 0;
- Decl : Declaration_Reference := Entities_HTable.Get_First;
- Arr : Reference_Array_Access;
- Index : Natural;
- End_Index : Natural;
- Current_File : File_Reference;
- Current_Line : Cst_String_Access;
- Buffer : GNAT.OS_Lib.String_Access;
- Ref : Reference;
- Line : Natural;
-
- begin
- -- Create a temporary array, where all references will be
- -- sorted by files. This way, we only have to read the source
- -- files once.
-
- while Decl /= null loop
-
- -- Add 1 for the declaration itself
-
- Length := Length + References_Count (Decl, True, True, True) + 1;
- Decl := Entities_HTable.Get_Next;
- end loop;
-
- Arr := new Reference_Array (1 .. Length);
- Index := Arr'First;
-
- Decl := Entities_HTable.Get_First;
- while Decl /= null loop
- Store_References (Decl, True, True, True, True, Arr.all, Index);
- Decl := Entities_HTable.Get_Next;
- end loop;
-
- Sort (Arr.all);
-
- -- Now traverse the whole array and find the appropriate source
- -- lines.
-
- for R in Arr'Range loop
- Ref := Arr (R);
-
- if Ref.File /= Current_File then
- Free (Buffer);
- begin
- Read_File (Get_File (Ref.File, With_Dir => True), Buffer);
- End_Index := Buffer'First - 1;
- Line := 0;
- exception
- when Ada.Text_IO.Name_Error | Ada.Text_IO.End_Error =>
- Line := Natural'Last;
- end;
- Current_File := Ref.File;
- end if;
-
- if Ref.Line > Line then
-
- -- Do not free Current_Line, it is referenced by the last
- -- Ref we processed.
-
- loop
- Index := End_Index + 1;
-
- loop
- End_Index := End_Index + 1;
- exit when End_Index > Buffer'Last
- or else Buffer (End_Index) = ASCII.LF;
- end loop;
-
- -- Skip spaces at beginning of line
-
- while Index < End_Index and then
- (Buffer (Index) = ' ' or else Buffer (Index) = ASCII.HT)
- loop
- Index := Index + 1;
- end loop;
-
- Line := Line + 1;
- exit when Ref.Line = Line;
- end loop;
-
- Current_Line := new String'(Buffer (Index .. End_Index - 1));
- end if;
-
- Ref.Source_Line := Current_Line;
- end loop;
-
- Free (Buffer);
- Free (Arr);
- end Grep_Source_Files;
-
- ---------------
- -- Read_File --
- ---------------
-
- procedure Read_File
- (File_Name : String;
- Contents : out GNAT.OS_Lib.String_Access)
- is
- Name_0 : constant String := File_Name & ASCII.NUL;
- FD : constant File_Descriptor := Open_Read (Name_0'Address, Binary);
- Length : Natural;
-
- begin
- if FD = Invalid_FD then
- raise Ada.Text_IO.Name_Error;
- end if;
-
- -- Include room for EOF char
-
- Length := Natural (File_Length (FD));
-
- declare
- Buffer : String (1 .. Length + 1);
- This_Read : Integer;
- Read_Ptr : Natural := 1;
-
- begin
- loop
- This_Read := Read (FD,
- A => Buffer (Read_Ptr)'Address,
- N => Length + 1 - Read_Ptr);
- Read_Ptr := Read_Ptr + Integer'Max (This_Read, 0);
- exit when This_Read <= 0;
- end loop;
-
- Buffer (Read_Ptr) := EOF;
- Contents := new String'(Buffer (1 .. Read_Ptr));
-
- -- Things are not simple on VMS due to the plethora of file types
- -- and organizations. It seems clear that there shouldn't be more
- -- bytes read than are contained in the file though.
-
- if (Hostparm.OpenVMS and then Read_Ptr > Length + 1)
- or else (not Hostparm.OpenVMS and then Read_Ptr /= Length + 1)
- then
- raise Ada.Text_IO.End_Error;
- end if;
-
- Close (FD);
- end;
- end Read_File;
-
- -----------------------
- -- Longest_File_Name --
- -----------------------
-
- function Longest_File_Name return Natural is
- begin
- return Longest_File_Name_In_Table;
- end Longest_File_Name;
-
- -----------
- -- Match --
- -----------
-
- function Match
- (File : File_Reference;
- Line : Natural;
- Column : Natural)
- return Boolean
- is
- Ref : Ref_In_File_Ptr := File.Lines;
-
- begin
- while Ref /= null loop
- if (Ref.Line = 0 or else Ref.Line = Line)
- and then (Ref.Column = 0 or else Ref.Column = Column)
- then
- return True;
- end if;
-
- Ref := Ref.Next;
- end loop;
-
- return False;
- end Match;
-
- -----------
- -- Match --
- -----------
-
- function Match (Decl : Declaration_Reference) return Boolean is
- begin
- return Decl.Match;
- end Match;
-
- ----------
- -- Next --
- ----------
-
- function Next (E : File_Reference) return File_Reference is
- begin
- return E.Next;
- end Next;
-
- function Next (E : Declaration_Reference) return Declaration_Reference is
- begin
- return E.Next;
- end Next;
-
- ------------------
- -- Next_Obj_Dir --
- ------------------
-
- function Next_Obj_Dir return String is
- First : constant Integer := Directories.Obj_Dir_Index;
- Last : Integer;
-
- begin
- Last := Directories.Obj_Dir_Index;
-
- if Last > Directories.Obj_Dir_Length then
- return String'(1 .. 0 => ' ');
- end if;
-
- while Directories.Obj_Dir (Last) /= Path_Separator loop
- Last := Last + 1;
- end loop;
-
- Directories.Obj_Dir_Index := Last + 1;
- Directories.Last_Obj_Dir_Start := First;
- return Directories.Obj_Dir (First .. Last - 1);
- end Next_Obj_Dir;
-
- -------------------------
- -- Next_Unvisited_File --
- -------------------------
-
- function Next_Unvisited_File return File_Reference is
- procedure Unchecked_Free is new Ada.Unchecked_Deallocation
- (Unvisited_Files_Record, Unvisited_Files_Access);
-
- Ref : File_Reference;
- Tmp : Unvisited_Files_Access;
-
- begin
- if Unvisited_Files = null then
- return Empty_File;
- else
- Tmp := Unvisited_Files;
- Ref := Unvisited_Files.File;
- Unvisited_Files := Unvisited_Files.Next;
- Unchecked_Free (Tmp);
- return Ref;
- end if;
- end Next_Unvisited_File;
-
- ----------------------
- -- Parse_Gnatls_Src --
- ----------------------
-
- function Parse_Gnatls_Src return String is
- Length : Natural;
-
- begin
- Length := 0;
- for J in 1 .. Osint.Nb_Dir_In_Src_Search_Path loop
- if Osint.Dir_In_Src_Search_Path (J)'Length = 0 then
- Length := Length + 2;
- else
- Length := Length + Osint.Dir_In_Src_Search_Path (J)'Length + 1;
- end if;
- end loop;
-
- declare
- Result : String (1 .. Length);
- L : Natural;
-
- begin
- L := Result'First;
- for J in 1 .. Osint.Nb_Dir_In_Src_Search_Path loop
- if Osint.Dir_In_Src_Search_Path (J)'Length = 0 then
- Result (L .. L + 1) := "." & Path_Separator;
- L := L + 2;
-
- else
- Result (L .. L + Osint.Dir_In_Src_Search_Path (J)'Length - 1) :=
- Osint.Dir_In_Src_Search_Path (J).all;
- L := L + Osint.Dir_In_Src_Search_Path (J)'Length;
- Result (L) := Path_Separator;
- L := L + 1;
- end if;
- end loop;
-
- return Result;
- end;
- end Parse_Gnatls_Src;
-
- ----------------------
- -- Parse_Gnatls_Obj --
- ----------------------
-
- function Parse_Gnatls_Obj return String is
- Length : Natural;
-
- begin
- Length := 0;
- for J in 1 .. Osint.Nb_Dir_In_Obj_Search_Path loop
- if Osint.Dir_In_Obj_Search_Path (J)'Length = 0 then
- Length := Length + 2;
- else
- Length := Length + Osint.Dir_In_Obj_Search_Path (J)'Length + 1;
- end if;
- end loop;
-
- declare
- Result : String (1 .. Length);
- L : Natural;
-
- begin
- L := Result'First;
- for J in 1 .. Osint.Nb_Dir_In_Obj_Search_Path loop
- if Osint.Dir_In_Obj_Search_Path (J)'Length = 0 then
- Result (L .. L + 1) := "." & Path_Separator;
- L := L + 2;
- else
- Result (L .. L + Osint.Dir_In_Obj_Search_Path (J)'Length - 1) :=
- Osint.Dir_In_Obj_Search_Path (J).all;
- L := L + Osint.Dir_In_Obj_Search_Path (J)'Length;
- Result (L) := Path_Separator;
- L := L + 1;
- end if;
- end loop;
-
- return Result;
- end;
- end Parse_Gnatls_Obj;
-
- -------------------
- -- Reset_Obj_Dir --
- -------------------
-
- procedure Reset_Obj_Dir is
- begin
- Directories.Obj_Dir_Index := 1;
- end Reset_Obj_Dir;
-
- -----------------------
- -- Set_Default_Match --
- -----------------------
-
- procedure Set_Default_Match (Value : Boolean) is
- begin
- Default_Match := Value;
- end Set_Default_Match;
-
- ----------
- -- Free --
- ----------
-
- procedure Free (Str : in out Cst_String_Access) is
- function Convert is new Ada.Unchecked_Conversion
- (Cst_String_Access, GNAT.OS_Lib.String_Access);
-
- S : GNAT.OS_Lib.String_Access := Convert (Str);
-
- begin
- Free (S);
- Str := null;
- end Free;
-
- ---------------------
- -- Reset_Directory --
- ---------------------
-
- procedure Reset_Directory (File : File_Reference) is
- begin
- Free (File.Dir);
- end Reset_Directory;
-
- -------------------
- -- Set_Unvisited --
- -------------------
-
- procedure Set_Unvisited (File_Ref : File_Reference) is
- F : constant String := Get_File (File_Ref, With_Dir => False);
-
- begin
- File_Ref.Visited := False;
-
- -- ??? Do not add a source file to the list. This is true at
- -- least for gnatxref, and probably for gnatfind as wel
-
- if F'Length > 4
- and then F (F'Last - 3 .. F'Last) = ".ali"
- then
- Unvisited_Files := new Unvisited_Files_Record'
- (File => File_Ref,
- Next => Unvisited_Files);
- end if;
- end Set_Unvisited;
-
- ----------------------
- -- Get_Declarations --
- ----------------------
-
- function Get_Declarations
- (Sorted : Boolean := True)
- return Declaration_Array_Access
- is
- Arr : constant Declaration_Array_Access :=
- new Declaration_Array (1 .. Entities_Count);
- Decl : Declaration_Reference := Entities_HTable.Get_First;
- Index : Natural := Arr'First;
- Tmp : Declaration_Reference;
-
- procedure Move (From : Natural; To : Natural);
- function Lt (Op1, Op2 : Natural) return Boolean;
- -- See GNAT.Heap_Sort_G
-
- --------
- -- Lt --
- --------
-
- function Lt (Op1, Op2 : Natural) return Boolean is
- begin
- if Op1 = 0 then
- return Is_Less_Than (Tmp, Arr (Op2));
- elsif Op2 = 0 then
- return Is_Less_Than (Arr (Op1), Tmp);
- else
- return Is_Less_Than (Arr (Op1), Arr (Op2));
- end if;
- end Lt;
-
- ----------
- -- Move --
- ----------
-
- procedure Move (From : Natural; To : Natural) is
- begin
- if To = 0 then
- Tmp := Arr (From);
- elsif From = 0 then
- Arr (To) := Tmp;
- else
- Arr (To) := Arr (From);
- end if;
- end Move;
-
- package Decl_Sort is new GNAT.Heap_Sort_G (Move, Lt);
-
- -- Start of processing for Get_Declarations
-
- begin
- while Decl /= null loop
- Arr (Index) := Decl;
- Index := Index + 1;
- Decl := Entities_HTable.Get_Next;
- end loop;
-
- if Sorted and then Arr'Length /= 0 then
- Decl_Sort.Sort (Entities_Count);
- end if;
-
- return Arr;
- end Get_Declarations;
-
- ----------------------
- -- References_Count --
- ----------------------
-
- function References_Count
- (Decl : Declaration_Reference;
- Get_Reads : Boolean := False;
- Get_Writes : Boolean := False;
- Get_Bodies : Boolean := False)
- return Natural
- is
- function List_Length (E : Reference) return Natural;
- -- Return the number of references in E
-
- -----------------
- -- List_Length --
- -----------------
-
- function List_Length (E : Reference) return Natural is
- L : Natural := 0;
- E1 : Reference := E;
-
- begin
- while E1 /= null loop
- L := L + 1;
- E1 := E1.Next;
- end loop;
-
- return L;
- end List_Length;
-
- Length : Natural := 0;
-
- -- Start of processing for References_Count
-
- begin
- if Get_Reads then
- Length := List_Length (Decl.Ref_Ref);
- end if;
-
- if Get_Writes then
- Length := Length + List_Length (Decl.Modif_Ref);
- end if;
-
- if Get_Bodies then
- Length := Length + List_Length (Decl.Body_Ref);
- end if;
-
- return Length;
- end References_Count;
-
- ----------------------
- -- Store_References --
- ----------------------
-
- procedure Store_References
- (Decl : Declaration_Reference;
- Get_Writes : Boolean := False;
- Get_Reads : Boolean := False;
- Get_Bodies : Boolean := False;
- Get_Declaration : Boolean := False;
- Arr : in out Reference_Array;
- Index : in out Natural)
- is
- procedure Add (List : Reference);
- -- Add all the references in List to Arr
-
- ---------
- -- Add --
- ---------
-
- procedure Add (List : Reference) is
- E : Reference := List;
- begin
- while E /= null loop
- Arr (Index) := E;
- Index := Index + 1;
- E := E.Next;
- end loop;
- end Add;
-
- -- Start of processing for Store_References
-
- begin
- if Get_Declaration then
- Add (Decl.Decl);
- end if;
-
- if Get_Reads then
- Add (Decl.Ref_Ref);
- end if;
-
- if Get_Writes then
- Add (Decl.Modif_Ref);
- end if;
-
- if Get_Bodies then
- Add (Decl.Body_Ref);
- end if;
- end Store_References;
-
- --------------------
- -- Get_References --
- --------------------
-
- function Get_References
- (Decl : Declaration_Reference;
- Get_Reads : Boolean := False;
- Get_Writes : Boolean := False;
- Get_Bodies : Boolean := False)
- return Reference_Array_Access
- is
- Length : constant Natural :=
- References_Count (Decl, Get_Reads, Get_Writes, Get_Bodies);
-
- Arr : constant Reference_Array_Access :=
- new Reference_Array (1 .. Length);
-
- Index : Natural := Arr'First;
-
- begin
- Store_References
- (Decl => Decl,
- Get_Writes => Get_Writes,
- Get_Reads => Get_Reads,
- Get_Bodies => Get_Bodies,
- Get_Declaration => False,
- Arr => Arr.all,
- Index => Index);
-
- if Arr'Length /= 0 then
- Sort (Arr.all);
- end if;
-
- return Arr;
- end Get_References;
-
- ----------
- -- Free --
- ----------
-
- procedure Free (Arr : in out Reference_Array_Access) is
- procedure Internal is new Ada.Unchecked_Deallocation
- (Reference_Array, Reference_Array_Access);
- begin
- Internal (Arr);
- end Free;
-
- ------------------
- -- Is_Parameter --
- ------------------
-
- function Is_Parameter (Decl : Declaration_Reference) return Boolean is
- begin
- return Decl.Is_Parameter;
- end Is_Parameter;
-
-end Xr_Tabls;