1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- X R _ T A B L S -- 6-- -- 7-- S p e c -- 8-- -- 9-- Copyright (C) 1998-2003 Free Software Foundation, Inc. -- 10-- -- 11-- GNAT is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 2, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- 17-- for more details. You should have received a copy of the GNU General -- 18-- Public License distributed with GNAT; see file COPYING. If not, write -- 19-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- 20-- MA 02111-1307, USA. -- 21-- -- 22-- GNAT was originally developed by the GNAT team at New York University. -- 23-- Extensive contributions were provided by Ada Core Technologies Inc. -- 24-- -- 25------------------------------------------------------------------------------ 26 27with GNAT.OS_Lib; 28 29package Xr_Tabls is 30 31 ------------------- 32 -- Project files -- 33 ------------------- 34 35 function ALI_File_Name (Ada_File_Name : String) return String; 36 -- Returns the ali file name corresponding to Ada_File_Name. 37 38 procedure Create_Project_File (Name : String); 39 -- Open and parse a new project file. If the file Name could not be 40 -- opened or is not a valid project file, then a project file associated 41 -- with the standard default directories is returned 42 43 function Next_Obj_Dir return String; 44 -- Returns the next directory to visit to find related ali files 45 -- If there are no more such directories, returns a null string. 46 47 function Current_Obj_Dir return String; 48 -- Returns the obj_dir which was returned by the last Next_Obj_Dir call 49 50 procedure Reset_Obj_Dir; 51 -- Reset the iterator for Obj_Dir 52 53 ------------ 54 -- Tables -- 55 ------------ 56 57 type Declaration_Reference is private; 58 Empty_Declaration : constant Declaration_Reference; 59 60 type Declaration_Array is array (Natural range <>) of Declaration_Reference; 61 type Declaration_Array_Access is access Declaration_Array; 62 63 type File_Reference is private; 64 Empty_File : constant File_Reference; 65 66 type Reference is private; 67 Empty_Reference : constant Reference; 68 69 type Reference_Array is array (Natural range <>) of Reference; 70 type Reference_Array_Access is access Reference_Array; 71 72 procedure Free (Arr : in out Reference_Array_Access); 73 74 function Add_Declaration 75 (File_Ref : File_Reference; 76 Symbol : String; 77 Line : Natural; 78 Column : Natural; 79 Decl_Type : Character; 80 Remove_Only : Boolean := False; 81 Symbol_Match : Boolean := True) 82 return Declaration_Reference; 83 -- Add a new declaration in the table and return the index to it. 84 -- Decl_Type is the type of the entity Any previous instance of this 85 -- entity in the htable is removed. If Remove_Only is True, then any 86 -- previous instance is removed, but the new entity is never inserted. 87 -- Symbol_Match should be set to False if the name of the symbol doesn't 88 -- match the pattern from the command line. In that case, the entity will 89 -- not be output by gnatfind. If Symbol_Match is True, the entity will only 90 -- be output if the file name itself matches. 91 92 procedure Add_Parent 93 (Declaration : in out Declaration_Reference; 94 Symbol : String; 95 Line : Natural; 96 Column : Natural; 97 File_Ref : File_Reference); 98 -- The parent declaration (Symbol in file File_Ref at position Line and 99 -- Column) information is added to Declaration. 100 101 function Add_To_Xref_File 102 (File_Name : String; 103 Visited : Boolean := True; 104 Emit_Warning : Boolean := False; 105 Gnatchop_File : String := ""; 106 Gnatchop_Offset : Integer := 0) 107 return File_Reference; 108 -- Add a new reference to a file in the table. Ref is used to return the 109 -- index in the table where this file is stored. Visited is the value which 110 -- will be used in the table (if True, the file will not be returned by 111 -- Next_Unvisited_File). If Emit_Warning is True and the ali file does 112 -- not exist or does not have cross-referencing information, then a 113 -- warning will be emitted. Gnatchop_File is the name of the file that 114 -- File_Name was extracted from through a call to "gnatchop -r" (using 115 -- pragma Source_Reference). Gnatchop_Offset should be the index of the 116 -- first line of File_Name within the Gnatchop_File. 117 118 procedure Add_Line 119 (File : File_Reference; 120 Line : Natural; 121 Column : Natural); 122 -- Add a new reference in a file, which the user has provided on the 123 -- command line. This is used for an optimized matching algorithm. 124 125 procedure Add_Reference 126 (Declaration : Declaration_Reference; 127 File_Ref : File_Reference; 128 Line : Natural; 129 Column : Natural; 130 Ref_Type : Character; 131 Labels_As_Ref : Boolean); 132 -- Add a new reference (Ref_Type = 'r'), body (Ref_Type = 'b') or 133 -- modification (Ref_Type = 'm') to an entity. If Labels_As_Ref is True, 134 -- then the references to the entity after the end statements ("end Foo") 135 -- are counted as actual references. This means that the entity will never 136 -- be reported as unreferenced (for instance in the case of gnatxref -u). 137 138 function Get_Declarations 139 (Sorted : Boolean := True) 140 return Declaration_Array_Access; 141 -- Return a sorted list of all the declarations in the application. 142 -- Freeing this array is the responsability of the caller, however it 143 -- shouldn't free the actual contents of the array, which are pointers 144 -- to internal data 145 146 function References_Count 147 (Decl : Declaration_Reference; 148 Get_Reads : Boolean := False; 149 Get_Writes : Boolean := False; 150 Get_Bodies : Boolean := False) 151 return Natural; 152 -- Return the number of references in Decl for the categories specified 153 -- by the Get_* parameters (read-only accesses, write accesses and bodies) 154 155 function Get_References 156 (Decl : Declaration_Reference; 157 Get_Reads : Boolean := False; 158 Get_Writes : Boolean := False; 159 Get_Bodies : Boolean := False) 160 return Reference_Array_Access; 161 -- Return a sorted list of all references to the entity in decl. 162 -- The parameters Get_* are used to specify what kind of references 163 -- should be merged and returned (read-only accesses, write accesses 164 -- and bodies). 165 166 function Get_Column (Decl : Declaration_Reference) return String; 167 function Get_Column (Ref : Reference) return String; 168 169 function Get_Declaration 170 (File_Ref : File_Reference; 171 Line : Natural; 172 Column : Natural) 173 return Declaration_Reference; 174 -- Returns reference to the declaration found in file File_Ref at the 175 -- given Line and Column 176 177 function Get_Parent 178 (Decl : Declaration_Reference) 179 return Declaration_Reference; 180 -- Returns reference to Decl's parent declaration 181 182 function Get_Emit_Warning (File : File_Reference) return Boolean; 183 -- Returns the Emit_Warning field of the structure 184 185 function Get_Gnatchop_File 186 (File : File_Reference; 187 With_Dir : Boolean := False) 188 return String; 189 function Get_Gnatchop_File 190 (Ref : Reference; 191 With_Dir : Boolean := False) 192 return String; 193 function Get_Gnatchop_File 194 (Decl : Declaration_Reference; 195 With_Dir : Boolean := False) 196 return String; 197 -- Return the name of the file that File was extracted from through a 198 -- call to "gnatchop -r". The file name for File is returned if File 199 -- was not extracted from such a file. The directory will be given only 200 -- if With_Dir is True. 201 202 function Get_File 203 (Decl : Declaration_Reference; 204 With_Dir : Boolean := False) return String; 205 pragma Inline (Get_File); 206 -- Extract column number or file name from reference 207 208 function Get_File 209 (Ref : Reference; 210 With_Dir : Boolean := False) return String; 211 pragma Inline (Get_File); 212 213 function Get_File 214 (File : File_Reference; 215 With_Dir : Boolean := False; 216 Strip : Natural := 0) return String; 217 -- Returns the file name (and its directory if With_Dir is True or the 218 -- user has used the -f switch on the command line. If Strip is not 0, 219 -- then the last Strip-th "-..." substrings are removed first. For 220 -- instance, with Strip=2, a file name "parent-child1-child2-child3.ali" 221 -- would be returned as "parent-child1.ali". This is used when looking 222 -- for the ALI file to use for a package, since for separates with have 223 -- to use the parent's ALI. The null string is returned if there is no 224 -- such parent unit. 225 -- 226 -- Note that this version of Get_File is not inlined 227 228 function Get_File_Ref (Ref : Reference) return File_Reference; 229 function Get_Line (Decl : Declaration_Reference) return String; 230 function Get_Line (Ref : Reference) return String; 231 function Get_Symbol (Decl : Declaration_Reference) return String; 232 function Get_Type (Decl : Declaration_Reference) return Character; 233 function Is_Parameter (Decl : Declaration_Reference) return Boolean; 234 -- Functions that return the contents of a declaration 235 236 function Get_Source_Line (Ref : Reference) return String; 237 function Get_Source_Line (Decl : Declaration_Reference) return String; 238 -- Return the source line associated with the reference 239 240 procedure Grep_Source_Files; 241 -- Parse all the source files which have at least one reference, 242 -- and grep the appropriate source lines so that we'll be able to 243 -- display them. This function should be called once all the .ali 244 -- files have been parsed, and only if the appropriate user switch 245 -- has been used (gnatfind -s). 246 -- 247 -- Note: To save memory, the strings for the source lines are shared. 248 -- Thus it is no longer possible to free the references, or we would 249 -- free the same chunk multiple times. It doesn't matter, though, since 250 -- this is only called once, prior to exiting gnatfind. 251 252 function Longest_File_Name return Natural; 253 -- Returns the longest file name found 254 255 function Match (Decl : Declaration_Reference) return Boolean; 256 -- Return True if the declaration matches 257 258 function Match 259 (File : File_Reference; 260 Line : Natural; 261 Column : Natural) 262 return Boolean; 263 -- Returns True if File:Line:Column was given on the command line 264 -- by the user 265 266 function Next_Unvisited_File return File_Reference; 267 -- Returns the next unvisited library file in the list 268 -- If there is no more unvisited file, return Empty_File. 269 -- Two calls to this subprogram will return different files. 270 271 procedure Set_Default_Match (Value : Boolean); 272 -- Set the default value for match in declarations. 273 -- This is used so that if no file was provided in the 274 -- command line, then every file match 275 276 procedure Reset_Directory (File : File_Reference); 277 -- Reset the cached directory for file. Next time Get_File is 278 -- called, the directory willl be recomputed. 279 280 procedure Set_Unvisited (File_Ref : File_Reference); 281 -- Set File_Ref as unvisited. So Next_Unvisited_File will return it. 282 283 procedure Read_File 284 (File_Name : String; 285 Contents : out GNAT.OS_Lib.String_Access); 286 -- Reads File_Name into the newly allocated strig Contents. A 287 -- Types.EOF character will be added to the returned Contents to 288 -- simplify parsing. Name_Error is raised if the file was not found. 289 -- End_Error is raised if the file could not be read correctly. For 290 -- most systems correct reading means that the number of bytes read 291 -- is equal to the file size. The exception is OpenVMS where correct 292 -- reading means that the number of bytes read is less than or equal 293 -- to the file size. 294 295private 296 type Project_File (Src_Dir_Length, Obj_Dir_Length : Natural) is record 297 Src_Dir : String (1 .. Src_Dir_Length); 298 Src_Dir_Index : Integer; 299 300 Obj_Dir : String (1 .. Obj_Dir_Length); 301 Obj_Dir_Index : Integer; 302 Last_Obj_Dir_Start : Natural; 303 end record; 304 305 type Project_File_Ptr is access all Project_File; 306 -- This is actually a list of all the directories to be searched, 307 -- either for source files or for library files 308 309 type Ref_In_File; 310 type Ref_In_File_Ptr is access all Ref_In_File; 311 312 type Ref_In_File is record 313 Line : Natural; 314 Column : Natural; 315 Next : Ref_In_File_Ptr := null; 316 end record; 317 318 type File_Record; 319 type File_Reference is access all File_Record; 320 321 Empty_File : constant File_Reference := null; 322 type Cst_String_Access is access constant String; 323 324 procedure Free (Str : in out Cst_String_Access); 325 326 type File_Record is record 327 File : Cst_String_Access; 328 Dir : GNAT.OS_Lib.String_Access; 329 Lines : Ref_In_File_Ptr := null; 330 Visited : Boolean := False; 331 Emit_Warning : Boolean := False; 332 Gnatchop_File : GNAT.OS_Lib.String_Access := null; 333 Gnatchop_Offset : Integer := 0; 334 Next : File_Reference := null; 335 end record; 336 -- Holds a reference to a source file, that was referenced in at least one 337 -- ALI file. Gnatchop_File will contain the name of the file that File was 338 -- extracted From. Gnatchop_Offset contains the index of the first line of 339 -- File within Gnatchop_File. These two fields are used to properly support 340 -- gnatchop files and pragma Source_Reference. 341 -- 342 -- Lines is used for files that were given on the command line, to 343 -- memorize the lines and columns that the user specified. 344 345 type Reference_Record; 346 type Reference is access all Reference_Record; 347 348 Empty_Reference : constant Reference := null; 349 350 type Reference_Record is record 351 File : File_Reference; 352 Line : Natural; 353 Column : Natural; 354 Source_Line : Cst_String_Access; 355 Next : Reference := null; 356 end record; 357 -- File is a reference to the Ada source file 358 -- Source_Line is the Line as it appears in the source file. This 359 -- field is only used when the switch is set on the command line of 360 -- gnatfind. 361 362 type Declaration_Record; 363 type Declaration_Reference is access all Declaration_Record; 364 365 Empty_Declaration : constant Declaration_Reference := null; 366 367 type Declaration_Record (Symbol_Length : Natural) is record 368 Key : Cst_String_Access; 369 Symbol : String (1 .. Symbol_Length); 370 Decl : Reference; 371 Is_Parameter : Boolean := False; -- True if entity is subprog param 372 Decl_Type : Character; 373 Body_Ref : Reference := null; 374 Ref_Ref : Reference := null; 375 Modif_Ref : Reference := null; 376 Match : Boolean := False; 377 Par_Symbol : Declaration_Reference := null; 378 Next : Declaration_Reference := null; 379 end record; 380 -- The lists of referenced (Body_Ref, Ref_Ref and Modif_Ref) are 381 -- kept unsorted until the results needs to be printed. This saves 382 -- lots of time while the internal tables are created. 383 384 pragma Inline (Get_Column); 385 pragma Inline (Get_Emit_Warning); 386 pragma Inline (Get_File_Ref); 387 pragma Inline (Get_Line); 388 pragma Inline (Get_Symbol); 389 pragma Inline (Get_Type); 390 pragma Inline (Longest_File_Name); 391end Xr_Tabls; 392