1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- G N A T X R E F -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 1998-2011, 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 3, 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 COPYING3. If not, go to -- 19-- http://www.gnu.org/licenses for a complete copy of the license. -- 20-- -- 21-- GNAT was originally developed by the GNAT team at New York University. -- 22-- Extensive contributions were provided by Ada Core Technologies Inc. -- 23-- -- 24------------------------------------------------------------------------------ 25 26with Opt; 27with Osint; use Osint; 28with Types; use Types; 29with Switch; use Switch; 30with Xr_Tabls; use Xr_Tabls; 31with Xref_Lib; use Xref_Lib; 32 33with Ada.Strings.Fixed; use Ada.Strings.Fixed; 34with Ada.Text_IO; use Ada.Text_IO; 35 36with GNAT.Command_Line; use GNAT.Command_Line; 37 38with System.Strings; use System.Strings; 39 40procedure Gnatxref is 41 Search_Unused : Boolean := False; 42 Local_Symbols : Boolean := True; 43 Prj_File : File_Name_String; 44 Prj_File_Length : Natural := 0; 45 Usage_Error : exception; 46 Full_Path_Name : Boolean := False; 47 Vi_Mode : Boolean := False; 48 Read_Only : Boolean := False; 49 Have_File : Boolean := False; 50 Der_Info : Boolean := False; 51 52 RTS_Specified : String_Access := null; 53 -- Used to detect multiple use of --RTS= switch 54 55 EXT_Specified : String_Access := null; 56 -- Used to detect multiple use of --ext= switch 57 58 procedure Parse_Cmd_Line; 59 -- Parse every switch on the command line 60 61 procedure Usage; 62 -- Display the usage 63 64 procedure Write_Usage; 65 -- Print a small help page for program usage 66 67 -------------------- 68 -- Parse_Cmd_Line -- 69 -------------------- 70 71 procedure Parse_Cmd_Line is 72 73 procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage); 74 75 -- Start of processing for Parse_Cmd_Line 76 77 begin 78 -- First check for --version or --help 79 80 Check_Version_And_Help ("GNATXREF", "1998"); 81 82 loop 83 case 84 GNAT.Command_Line.Getopt 85 ("a aI: aO: d f g h I: nostdinc nostdlib p: u v -RTS= -ext=") 86 is 87 when ASCII.NUL => 88 exit; 89 90 when 'a' => 91 if GNAT.Command_Line.Full_Switch = "a" then 92 Read_Only := True; 93 94 elsif GNAT.Command_Line.Full_Switch = "aI" then 95 Osint.Add_Src_Search_Dir (GNAT.Command_Line.Parameter); 96 97 else 98 Osint.Add_Lib_Search_Dir (GNAT.Command_Line.Parameter); 99 end if; 100 101 when 'd' => 102 Der_Info := True; 103 104 when 'f' => 105 Full_Path_Name := True; 106 107 when 'g' => 108 Local_Symbols := False; 109 110 when 'h' => 111 Write_Usage; 112 113 when 'I' => 114 Osint.Add_Src_Search_Dir (GNAT.Command_Line.Parameter); 115 Osint.Add_Lib_Search_Dir (GNAT.Command_Line.Parameter); 116 117 when 'n' => 118 if GNAT.Command_Line.Full_Switch = "nostdinc" then 119 Opt.No_Stdinc := True; 120 elsif GNAT.Command_Line.Full_Switch = "nostdlib" then 121 Opt.No_Stdlib := True; 122 end if; 123 124 when 'p' => 125 declare 126 S : constant String := GNAT.Command_Line.Parameter; 127 begin 128 Prj_File_Length := S'Length; 129 Prj_File (1 .. Prj_File_Length) := S; 130 end; 131 132 when 'u' => 133 Search_Unused := True; 134 Vi_Mode := False; 135 136 when 'v' => 137 Vi_Mode := True; 138 Search_Unused := False; 139 140 -- The only switch starting with -- recognized is --RTS 141 142 when '-' => 143 144 -- Check that it is the first time we see this switch 145 146 if Full_Switch = "-RTS" then 147 if RTS_Specified = null then 148 RTS_Specified := new String'(GNAT.Command_Line.Parameter); 149 150 elsif RTS_Specified.all /= GNAT.Command_Line.Parameter then 151 Osint.Fail ("--RTS cannot be specified multiple times"); 152 end if; 153 154 Opt.No_Stdinc := True; 155 Opt.RTS_Switch := True; 156 157 declare 158 Src_Path_Name : constant String_Ptr := 159 Get_RTS_Search_Dir 160 (GNAT.Command_Line.Parameter, 161 Include); 162 163 Lib_Path_Name : constant String_Ptr := 164 Get_RTS_Search_Dir 165 (GNAT.Command_Line.Parameter, 166 Objects); 167 168 begin 169 if Src_Path_Name /= null 170 and then Lib_Path_Name /= null 171 then 172 Add_Search_Dirs (Src_Path_Name, Include); 173 Add_Search_Dirs (Lib_Path_Name, Objects); 174 175 elsif Src_Path_Name = null 176 and then Lib_Path_Name = null 177 then 178 Osint.Fail ("RTS path not valid: missing " & 179 "adainclude and adalib directories"); 180 181 elsif Src_Path_Name = null then 182 Osint.Fail ("RTS path not valid: missing " & 183 "adainclude directory"); 184 185 elsif Lib_Path_Name = null then 186 Osint.Fail ("RTS path not valid: missing " & 187 "adalib directory"); 188 end if; 189 end; 190 191 elsif GNAT.Command_Line.Full_Switch = "-ext" then 192 193 -- Check that it is the first time we see this switch 194 195 if EXT_Specified = null then 196 EXT_Specified := new String'(GNAT.Command_Line.Parameter); 197 198 elsif EXT_Specified.all /= GNAT.Command_Line.Parameter then 199 Osint.Fail ("--ext cannot be specified multiple times"); 200 end if; 201 202 if EXT_Specified'Length 203 = Osint.ALI_Default_Suffix'Length 204 then 205 Osint.ALI_Suffix := EXT_Specified.all'Access; 206 else 207 Osint.Fail ("--ext argument must have 3 characters"); 208 end if; 209 end if; 210 211 when others => 212 Write_Usage; 213 end case; 214 end loop; 215 216 -- Get the other arguments 217 218 loop 219 declare 220 S : constant String := GNAT.Command_Line.Get_Argument; 221 222 begin 223 exit when S'Length = 0; 224 225 if Ada.Strings.Fixed.Index (S, ":") /= 0 then 226 Ada.Text_IO.Put_Line 227 ("Only file names are allowed on the command line"); 228 Write_Usage; 229 end if; 230 231 Add_Xref_File (S); 232 Have_File := True; 233 end; 234 end loop; 235 236 exception 237 when GNAT.Command_Line.Invalid_Switch => 238 Ada.Text_IO.Put_Line ("Invalid switch : " 239 & GNAT.Command_Line.Full_Switch); 240 Write_Usage; 241 242 when GNAT.Command_Line.Invalid_Parameter => 243 Ada.Text_IO.Put_Line ("Parameter missing for : " 244 & GNAT.Command_Line.Full_Switch); 245 Write_Usage; 246 end Parse_Cmd_Line; 247 248 ----------- 249 -- Usage -- 250 ----------- 251 252 procedure Usage is 253 begin 254 Put_Line ("Usage: gnatxref [switches] file1 file2 ..."); 255 New_Line; 256 Put_Line (" file ... list of source files to xref, " & 257 "including with'ed units"); 258 New_Line; 259 Put_Line ("gnatxref switches:"); 260 Display_Usage_Version_And_Help; 261 Put_Line (" -a Consider all files, even when the ali file is" 262 & " readonly"); 263 Put_Line (" -aIdir Specify source files search path"); 264 Put_Line (" -aOdir Specify library/object files search path"); 265 Put_Line (" -d Output derived type information"); 266 Put_Line (" -f Output full path name"); 267 Put_Line (" -g Output information only for global symbols"); 268 Put_Line (" -Idir Like -aIdir -aOdir"); 269 Put_Line (" -nostdinc Don't look for sources in the system default" 270 & " directory"); 271 Put_Line (" -nostdlib Don't look for library files in the system" 272 & " default directory"); 273 Put_Line (" --ext=xxx Specify alternate ali file extension"); 274 Put_Line (" --RTS=dir specify the default source and object search" 275 & " path"); 276 Put_Line (" -p file Use file as the default project file"); 277 Put_Line (" -u List unused entities"); 278 Put_Line (" -v Print a 'tags' file for vi"); 279 New_Line; 280 281 end Usage; 282 283 ----------------- 284 -- Write_Usage -- 285 ----------------- 286 287 procedure Write_Usage is 288 begin 289 Display_Version ("GNATXREF", "1998"); 290 New_Line; 291 Usage; 292 raise Usage_Error; 293 end Write_Usage; 294 295begin 296 Parse_Cmd_Line; 297 298 if not Have_File then 299 Write_Usage; 300 end if; 301 302 Xr_Tabls.Set_Default_Match (True); 303 304 -- Find the project file 305 306 if Prj_File_Length = 0 then 307 Xr_Tabls.Create_Project_File 308 (Default_Project_File (Osint.To_Host_Dir_Spec (".", False).all)); 309 else 310 Xr_Tabls.Create_Project_File (Prj_File (1 .. Prj_File_Length)); 311 end if; 312 313 -- Fill up the table 314 315 Search_Xref (Local_Symbols, Read_Only, Der_Info); 316 317 if Search_Unused then 318 Print_Unused (Full_Path_Name); 319 elsif Vi_Mode then 320 Print_Vi (Full_Path_Name); 321 else 322 Print_Xref (Full_Path_Name); 323 end if; 324 325exception 326 when Usage_Error => 327 null; 328end Gnatxref; 329