1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2018, Free Software Foundation, Inc. --
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. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
29 with ALI
.Util
; use ALI
.Util
;
30 with Binderr
; use Binderr
;
31 with Butil
; use Butil
;
33 with Fname
; use Fname
;
34 with Gnatvsn
; use Gnatvsn
;
35 with Make_Util
; use Make_Util
;
36 with Namet
; use Namet
;
38 with Osint
; use Osint
;
39 with Osint
.L
; use Osint
.L
;
40 with Output
; use Output
;
41 with Rident
; use Rident
;
45 with Switch
; use Switch
;
46 with Types
; use Types
;
48 with GNAT
.Case_Util
; use GNAT
.Case_Util
;
49 with GNAT
.Command_Line
; use GNAT
.Command_Line
;
50 with GNAT
.Directory_Operations
; use GNAT
.Directory_Operations
;
51 with GNAT
.OS_Lib
; use GNAT
.OS_Lib
;
54 pragma Ident
(Gnat_Static_Version_String
);
56 -- NOTE : The following string may be used by other tools, such as GPS. So
57 -- it can only be modified if these other uses are checked and coordinated.
59 Project_Search_Path
: constant String := "Project Search Path:";
60 -- Label displayed in verbose mode before the directories in the project
61 -- search path. Do not modify without checking NOTE above.
63 Prj_Path
: String_Access
;
65 Max_Column
: constant := 80;
67 No_Obj
: aliased String := "<no_obj>";
69 No_Runtime
: Boolean := False;
70 -- Set to True if there is no default runtime and --RTS= is not specified
73 OK
, -- matching timestamp
74 Checksum_OK
, -- only matching checksum
75 Not_Found
, -- file not found on source PATH
76 Not_Same
, -- neither checksum nor timestamp matching
77 Not_First_On_PATH
); -- matching file hidden by Not_Same file on path
80 type Dir_Ref
is access Dir_Data
;
82 type Dir_Data
is record
83 Value
: String_Access
;
86 -- Simply linked list of dirs
88 First_Source_Dir
: Dir_Ref
;
89 Last_Source_Dir
: Dir_Ref
;
90 -- The list of source directories from the command line.
91 -- These directories are added using Osint.Add_Src_Search_Dir
92 -- after those of the GNAT Project File, if any.
94 First_Lib_Dir
: Dir_Ref
;
95 Last_Lib_Dir
: Dir_Ref
;
96 -- The list of object directories from the command line.
97 -- These directories are added using Osint.Add_Lib_Search_Dir
98 -- after those of the GNAT Project File, if any.
100 Main_File
: File_Name_Type
;
101 Ali_File
: File_Name_Type
;
102 Text
: Text_Buffer_Ptr
;
105 Too_Long
: Boolean := False;
106 -- When True, lines are too long for multi-column output and each
107 -- item of information is on a different line.
109 Selective_Output
: Boolean := False;
110 Print_Usage
: Boolean := False;
111 Print_Unit
: Boolean := True;
112 Print_Source
: Boolean := True;
113 Print_Object
: Boolean := True;
114 -- Flags controlling the form of the output
116 Also_Predef
: Boolean := False; -- -a
117 Dependable
: Boolean := False; -- -d
118 License
: Boolean := False; -- -l
119 Very_Verbose_Mode
: Boolean := False; -- -V
120 -- Command line flags
122 Unit_Start
: Integer;
124 Source_Start
: Integer;
125 Source_End
: Integer;
126 Object_Start
: Integer;
127 Object_End
: Integer;
128 -- Various column starts and ends
130 Spaces
: constant String (1 .. Max_Column
) := (others => ' ');
132 RTS_Specified
: String_Access
:= null;
133 -- Used to detect multiple use of --RTS= switch
135 Exit_Status
: Exit_Code_Type
:= E_Success
;
136 -- Reset to E_Fatal if bad error found
138 -----------------------
139 -- Local Subprograms --
140 -----------------------
142 procedure Add_Lib_Dir
(Dir
: String);
143 -- Add an object directory in the list First_Lib_Dir-Last_Lib_Dir
145 procedure Add_Source_Dir
(Dir
: String);
146 -- Add a source directory in the list First_Source_Dir-Last_Source_Dir
148 procedure Find_General_Layout
;
149 -- Determine the structure of the output (multi columns or not, etc)
151 procedure Find_Status
152 (FS
: in out File_Name_Type
;
153 Stamp
: Time_Stamp_Type
;
155 Status
: out File_Status
);
156 -- Determine the file status (Status) of the file represented by FS with
157 -- the expected Stamp and checksum given as argument. FS will be updated
158 -- to the full file name if available.
160 function Corresponding_Sdep_Entry
(A
: ALI_Id
; U
: Unit_Id
) return Sdep_Id
;
161 -- Give the Sdep entry corresponding to the unit U in ali record A
163 procedure Output_Object
(O
: File_Name_Type
);
164 -- Print out the name of the object when requested
166 procedure Output_Source
(Sdep_I
: Sdep_Id
);
167 -- Print out the name and status of the source corresponding to this
170 procedure Output_Status
(FS
: File_Status
; Verbose
: Boolean);
171 -- Print out FS either in a coded form if verbose is false or in an
172 -- expanded form otherwise.
174 procedure Output_Unit
(ALI
: ALI_Id
; U_Id
: Unit_Id
);
175 -- Print out information on the unit when requested
177 procedure Reset_Print
;
178 -- Reset Print flags properly when selective output is chosen
180 procedure Scan_Ls_Arg
(Argv
: String);
181 -- Scan and process user specific arguments (Argv is a single argument)
183 procedure Search_RTS
(Name
: String);
184 -- Find include and objects path for the RTS name.
187 -- Print usage message
189 procedure Output_License_Information
;
190 pragma No_Return
(Output_License_Information
);
191 -- Output license statement, and if not found, output reference to COPYING
193 function Image
(Restriction
: Restriction_Id
) return String;
194 -- Returns the capitalized image of Restriction
196 function Normalize
(Path
: String) return String;
197 -- Returns a normalized path name. On Windows, the directory separators are
198 -- set to '\' in Normalize_Pathname.
200 ------------------------------------------
201 -- GNATDIST specific output subprograms --
202 ------------------------------------------
206 -- Any modification to this subunit requires synchronization with the
209 procedure Output_ALI
(A
: ALI_Id
);
210 -- Comment required saying what this routine does ???
212 procedure Output_No_ALI
(Afile
: File_Name_Type
);
213 -- Comments required saying what this routine does ???
217 ------------------------------
218 -- Support for project path --
219 ------------------------------
223 procedure Initialize_Default_Project_Path
224 (Self
: in out String_Access
;
225 Target_Name
: String;
226 Runtime_Name
: String := "");
227 -- Initialize Self. It will then contain the default project path on
228 -- the given target and runtime (including directories specified by the
229 -- environment variables GPR_PROJECT_PATH_FILE, GPR_PROJECT_PATH and
230 -- ADA_PROJECT_PATH). If one of the directory or Target_Name is "-",
231 -- then the path contains only those directories specified by the
232 -- environment variables (except "-"). This does nothing if Self has
233 -- already been initialized.
235 procedure Add_Directories
236 (Self
: in out String_Access
;
238 Prepend
: Boolean := False);
239 -- Add one or more directories to the path. Directories added with this
240 -- procedure are added in order after the current directory and before
241 -- the path given by the environment variable GPR_PROJECT_PATH. A value
242 -- of "-" will remove the default project directory from the project
245 -- Calls to this subprogram must be performed before the first call to
246 -- Find_Project below, or PATH will be added at the end of the search
249 function Get_Runtime_Path
250 (Self
: String_Access
;
251 Path
: String) return String_Access
;
252 -- Compute the full path for the project-based runtime name.
253 -- Path is simply searched on the project path.
261 procedure Add_Lib_Dir
(Dir
: String) is
263 if First_Lib_Dir
= null then
266 (Value => new String'(Dir
),
268 Last_Lib_Dir
:= First_Lib_Dir
;
273 (Value => new String'(Dir
),
275 Last_Lib_Dir
:= Last_Lib_Dir
.Next
;
283 procedure Add_Source_Dir
(Dir
: String) is
285 if First_Source_Dir
= null then
288 (Value => new String'(Dir
),
290 Last_Source_Dir
:= First_Source_Dir
;
293 Last_Source_Dir
.Next
:=
295 (Value => new String'(Dir
),
297 Last_Source_Dir
:= Last_Source_Dir
.Next
;
301 ------------------------------
302 -- Corresponding_Sdep_Entry --
303 ------------------------------
305 function Corresponding_Sdep_Entry
307 U
: Unit_Id
) return Sdep_Id
310 for D
in ALIs
.Table
(A
).First_Sdep
.. ALIs
.Table
(A
).Last_Sdep
loop
311 if Sdep
.Table
(D
).Sfile
= Units
.Table
(U
).Sfile
then
316 Error_Msg_Unit_1
:= Units
.Table
(U
).Uname
;
317 Error_Msg_File_1
:= ALIs
.Table
(A
).Afile
;
319 Error_Msg
("wrong ALI format, can't find dependency line for $ in {");
320 Exit_Program
(E_Fatal
);
322 end Corresponding_Sdep_Entry
;
324 -------------------------
325 -- Find_General_Layout --
326 -------------------------
328 procedure Find_General_Layout
is
329 Max_Unit_Length
: Integer := 11;
330 Max_Src_Length
: Integer := 11;
331 Max_Obj_Length
: Integer := 11;
337 -- Compute maximum of each column
339 for Id
in ALIs
.First
.. ALIs
.Last
loop
340 Get_Name_String
(Units
.Table
(ALIs
.Table
(Id
).First_Unit
).Uname
);
341 if Also_Predef
or else not Is_Internal_Unit
then
345 Max_Unit_Length
:= Integer'Max (Max_Unit_Length
, Len
);
349 FS
:= Full_Source_Name
(ALIs
.Table
(Id
).Sfile
);
352 Get_Name_String
(ALIs
.Table
(Id
).Sfile
);
353 Name_Len
:= Name_Len
+ 13;
355 Get_Name_String
(FS
);
358 Max_Src_Length
:= Integer'Max (Max_Src_Length
, Name_Len
+ 1);
362 if ALIs
.Table
(Id
).No_Object
then
364 Integer'Max (Max_Obj_Length
, No_Obj
'Length);
366 Get_Name_String
(ALIs
.Table
(Id
).Ofile_Full_Name
);
367 Max_Obj_Length
:= Integer'Max (Max_Obj_Length
, Name_Len
+ 1);
373 -- Verify is output is not wider than maximum number of columns
378 (Max_Unit_Length
+ Max_Src_Length
+ Max_Obj_Length
) > Max_Column
;
380 -- Set start and end of columns
383 Object_End
:= Object_Start
- 1;
386 Object_End
:= Object_Start
+ Max_Obj_Length
;
389 Unit_Start
:= Object_End
+ 1;
390 Unit_End
:= Unit_Start
- 1;
393 Unit_End
:= Unit_Start
+ Max_Unit_Length
;
396 Source_Start
:= Unit_End
+ 1;
398 if Source_Start
> Spaces
'Last then
399 Source_Start
:= Spaces
'Last;
402 Source_End
:= Source_Start
- 1;
405 Source_End
:= Source_Start
+ Max_Src_Length
;
407 end Find_General_Layout
;
413 procedure Find_Status
414 (FS
: in out File_Name_Type
;
415 Stamp
: Time_Stamp_Type
;
417 Status
: out File_Status
)
419 Tmp1
: File_Name_Type
;
420 Tmp2
: File_Name_Type
;
423 Tmp1
:= Full_Source_Name
(FS
);
425 if Tmp1
= No_File
then
428 elsif File_Stamp
(Tmp1
) = Stamp
then
432 elsif Checksums_Match
(Get_File_Checksum
(FS
), Checksum
) then
434 Status
:= Checksum_OK
;
437 Tmp2
:= Matching_Full_Source_Name
(FS
, Stamp
);
439 if Tmp2
= No_File
then
444 Status
:= Not_First_On_PATH
;
454 package body GNATDIST
is
457 N_Indents
: Natural := 0;
488 Image
: constant array (Token_Type
) of String_Access
:=
489 (T_No_ALI
=> new String'("No_ALI"),
490 T_ALI => new String'("ALI"),
491 T_Unit
=> new String'("Unit"),
492 T_With => new String'("With"),
493 T_Source
=> new String'("Source"),
494 T_Afile => new String'("Afile"),
495 T_Ofile
=> new String'("Ofile"),
496 T_Sfile => new String'("Sfile"),
497 T_Name
=> new String'("Name"),
498 T_Main => new String'("Main"),
499 T_Kind
=> new String'("Kind"),
500 T_Flags => new String'("Flags"),
501 T_Preelaborated
=> new String'("Preelaborated"),
502 T_Pure => new String'("Pure"),
503 T_Has_RACW
=> new String'("Has_RACW"),
504 T_Remote_Types => new String'("Remote_Types"),
505 T_Shared_Passive
=> new String'("Shared_Passive"),
506 T_RCI => new String'("RCI"),
507 T_Predefined
=> new String'("Predefined"),
508 T_Internal => new String'("Internal"),
509 T_Is_Generic
=> new String'("Is_Generic"),
510 T_Procedure => new String'("procedure"),
511 T_Function
=> new String'("function"),
512 T_Package => new String'("package"),
513 T_Subprogram
=> new String'("subprogram"),
514 T_Spec => new String'("spec"),
515 T_Body
=> new String'("body"));
517 procedure Output_Name (N : Name_Id);
518 -- Remove any encoding info (%b and %s) and output N
520 procedure Output_Afile (A : File_Name_Type);
521 procedure Output_Ofile (O : File_Name_Type);
522 procedure Output_Sfile (S : File_Name_Type);
523 -- Output various names. Check that the name is different from no name.
524 -- Otherwise, skip the output.
526 procedure Output_Token (T : Token_Type);
527 -- Output token using specific format. That is several indentations and:
529 -- T_No_ALI .. T_With : <token> & " =>" & NL
530 -- T_Source .. T_Kind : <token> & " => "
531 -- T_Flags : <token> & " =>"
532 -- T_Preelab .. T_Body : " " & <token>
534 procedure Output_Sdep (S : Sdep_Id);
535 procedure Output_Unit (U : Unit_Id);
536 procedure Output_With (W : With_Id);
537 -- Output this entry as a global section (like ALIs)
543 procedure Output_Afile (A : File_Name_Type) is
546 Output_Token (T_Afile);
556 procedure Output_ALI (A : ALI_Id) is
558 Output_Token (T_ALI);
559 N_Indents := N_Indents + 1;
561 Output_Afile (ALIs.Table (A).Afile);
562 Output_Ofile (ALIs.Table (A).Ofile_Full_Name);
563 Output_Sfile (ALIs.Table (A).Sfile);
567 if ALIs.Table (A).Main_Program /= None then
568 Output_Token (T_Main);
570 if ALIs.Table (A).Main_Program = Proc then
571 Output_Token (T_Procedure);
573 Output_Token (T_Function);
581 for U in ALIs.Table (A).First_Unit .. ALIs.Table (A).Last_Unit loop
587 for S in ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep loop
591 N_Indents := N_Indents - 1;
598 procedure Output_No_ALI (Afile : File_Name_Type) is
600 Output_Token (T_No_ALI);
601 N_Indents := N_Indents + 1;
602 Output_Afile (Afile);
603 N_Indents := N_Indents - 1;
610 procedure Output_Name (N : Name_Id) is
612 -- Remove any encoding info (%s or %b)
617 and then Name_Buffer (Name_Len - 1) = '%'
619 Name_Len := Name_Len - 2;
622 Output_Token (T_Name);
623 Write_Str (Name_Buffer (1 .. Name_Len));
631 procedure Output_Ofile (O : File_Name_Type) is
634 Output_Token (T_Ofile);
644 procedure Output_Sdep (S : Sdep_Id) is
646 Output_Token (T_Source);
647 Write_Name (Sdep.Table (S).Sfile);
655 procedure Output_Sfile (S : File_Name_Type) is
656 FS : File_Name_Type := S;
659 if FS /= No_File then
661 -- We want to output the full source name
663 FS := Full_Source_Name (FS);
665 -- There is no full source name. This occurs for instance when a
666 -- withed unit has a spec file but no body file. This situation is
667 -- not a problem for GNATDIST since the unit may be located on a
668 -- partition we do not want to build. However, we need to locate
669 -- the spec file and to find its full source name. Replace the
670 -- body file name with the spec file name used to compile the
671 -- current unit when possible.
677 and then Name_Buffer (Name_Len - 3 .. Name_Len) = ".adb"
679 Name_Buffer (Name_Len) := 's
';
680 FS := Full_Source_Name (Name_Find);
685 if FS /= No_File then
686 Output_Token (T_Sfile);
696 procedure Output_Token (T : Token_Type) is
699 when T_No_ALI .. T_Flags =>
700 for J in 1 .. N_Indents loop
704 Write_Str (Image (T).all);
706 for J in Image (T)'Length .. 12 loop
712 if T in T_No_ALI .. T_With then
714 elsif T in T_Source .. T_Name then
718 when T_Preelaborated .. T_Body =>
719 if T in T_Preelaborated .. T_Is_Generic then
721 Output_Token (T_Flags);
724 N_Flags := N_Flags + 1;
728 Write_Str (Image (T).all);
736 procedure Output_Unit (U : Unit_Id) is
738 Output_Token (T_Unit);
739 N_Indents := N_Indents + 1;
743 Output_Name (Name_Id (Units.Table (U).Uname));
747 Output_Token (T_Kind);
749 if Units.Table (U).Unit_Kind = 'p
' then
750 Output_Token (T_Package);
752 Output_Token (T_Subprogram);
755 if Name_Buffer (Name_Len) = 's
' then
756 Output_Token (T_Spec);
758 Output_Token (T_Body);
763 -- Output source file name
765 Output_Sfile (Units.Table (U).Sfile);
771 if Units.Table (U).Preelab then
772 Output_Token (T_Preelaborated);
775 if Units.Table (U).Pure then
776 Output_Token (T_Pure);
779 if Units.Table (U).Has_RACW then
780 Output_Token (T_Has_RACW);
783 if Units.Table (U).Remote_Types then
784 Output_Token (T_Remote_Types);
787 if Units.Table (U).Shared_Passive then
788 Output_Token (T_Shared_Passive);
791 if Units.Table (U).RCI then
792 Output_Token (T_RCI);
795 if Units.Table (U).Predefined then
796 Output_Token (T_Predefined);
799 if Units.Table (U).Internal then
800 Output_Token (T_Internal);
803 if Units.Table (U).Is_Generic then
804 Output_Token (T_Is_Generic);
813 for W in Units.Table (U).First_With .. Units.Table (U).Last_With loop
817 N_Indents := N_Indents - 1;
824 procedure Output_With (W : With_Id) is
826 Output_Token (T_With);
827 N_Indents := N_Indents + 1;
829 Output_Name (Name_Id (Withs.Table (W).Uname));
833 Output_Token (T_Kind);
835 if Name_Buffer (Name_Len) = 's
' then
836 Output_Token (T_Spec);
838 Output_Token (T_Body);
843 Output_Afile (Withs.Table (W).Afile);
844 Output_Sfile (Withs.Table (W).Sfile);
846 N_Indents := N_Indents - 1;
855 function Image (Restriction : Restriction_Id) return String is
856 Result : String := Restriction'Img;
857 Skip : Boolean := True;
860 for J in Result'Range loop
863 Result (J) := To_Upper (Result (J));
865 elsif Result (J) = '_
' then
869 Result (J) := To_Lower (Result (J));
880 function Normalize (Path : String) return String is
882 return Normalize_Pathname (Path);
885 --------------------------------
886 -- Output_License_Information --
887 --------------------------------
889 procedure Output_License_Information is
893 Write_Str ("Please refer to file COPYING in your distribution"
894 & " for license terms.");
898 Exit_Program (E_Success);
899 end Output_License_Information;
905 procedure Output_Object (O : File_Name_Type) is
906 Object_Name : String_Access;
912 Object_Name := To_Host_File_Spec (Name_Buffer (1 .. Name_Len));
914 Object_Name := No_Obj'Unchecked_Access;
917 Write_Str (Object_Name.all);
919 if Print_Source or else Print_Unit then
925 (Object_Start + Object_Name'Length .. Object_End));
935 procedure Output_Source (Sdep_I : Sdep_Id) is
936 Stamp : Time_Stamp_Type;
939 Status : File_Status;
940 Object_Name : String_Access;
943 if Sdep_I = No_Sdep_Id then
947 Stamp := Sdep.Table (Sdep_I).Stamp;
948 Checksum := Sdep.Table (Sdep_I).Checksum;
949 FS := Sdep.Table (Sdep_I).Sfile;
952 Find_Status (FS, Stamp, Checksum, Status);
953 Get_Name_String (FS);
955 Object_Name := To_Host_File_Spec (Name_Buffer (1 .. Name_Len));
958 Write_Str (" Source => ");
959 Write_Str (Object_Name.all);
963 (Spaces (Source_Start + Object_Name'Length .. Source_End));
966 Output_Status (Status, Verbose => True);
971 if not Selective_Output then
972 Output_Status (Status, Verbose => False);
975 Write_Str (Object_Name.all);
984 procedure Output_Status (FS : File_Status; Verbose : Boolean) is
989 Write_Str (" unchanged");
992 Write_Str (" slightly modified");
995 Write_Str (" file not found");
998 Write_Str (" modified");
1000 when Not_First_On_PATH =>
1001 Write_Str (" unchanged version not first on PATH");
1010 Write_Str (" MOK ");
1013 Write_Str (" ??? ");
1016 Write_Str (" DIF ");
1018 when Not_First_On_PATH =>
1019 Write_Str (" HID ");
1028 procedure Output_Unit (ALI : ALI_Id; U_Id : Unit_Id) is
1030 U : Unit_Record renames Units.Table (U_Id);
1034 Get_Name_String (U.Uname);
1035 Kind := Name_Buffer (Name_Len);
1036 Name_Len := Name_Len - 2;
1038 if not Verbose_Mode then
1039 Write_Str (Name_Buffer (1 .. Name_Len));
1042 Write_Str ("Unit => ");
1044 Write_Str (" Name => ");
1045 Write_Str (Name_Buffer (1 .. Name_Len));
1047 Write_Str (" Kind => ");
1049 if Units.Table (U_Id).Unit_Kind = 'p
' then
1050 Write_Str ("package ");
1052 Write_Str ("subprogram ");
1062 if Verbose_Mode then
1063 if U.Preelab or else
1066 U.Dynamic_Elab or else
1068 U.Remote_Types or else
1069 U.Shared_Passive or else
1071 U.Predefined or else
1073 U.Is_Generic or else
1074 U.Init_Scalars or else
1075 U.SAL_Interface or else
1076 U.Body_Needed_For_SAL or else
1080 Write_Str (" Flags =>");
1083 Write_Str (" Preelaborable");
1087 Write_Str (" No_Elab_Code");
1091 Write_Str (" Pure");
1094 if U.Dynamic_Elab then
1095 Write_Str (" Dynamic_Elab");
1099 Write_Str (" Has_RACW");
1102 if U.Remote_Types then
1103 Write_Str (" Remote_Types");
1106 if U.Shared_Passive then
1107 Write_Str (" Shared_Passive");
1114 if U.Predefined then
1115 Write_Str (" Predefined");
1119 Write_Str (" Internal");
1122 if U.Is_Generic then
1123 Write_Str (" Is_Generic");
1126 if U.Init_Scalars then
1127 Write_Str (" Init_Scalars");
1130 if U.SAL_Interface then
1131 Write_Str (" SAL_Interface");
1134 if U.Body_Needed_For_SAL then
1135 Write_Str (" Body_Needed_For_SAL");
1138 if U.Elaborate_Body then
1139 Write_Str (" Elaborate Body");
1142 if U.Remote_Types then
1143 Write_Str (" Remote_Types");
1146 if U.Shared_Passive then
1147 Write_Str (" Shared_Passive");
1150 if U.Predefined then
1151 Write_Str (" Predefined");
1156 Restrictions : constant Restrictions_Info :=
1157 ALIs.Table (ALI).Restrictions;
1160 -- If the source was compiled with pragmas Restrictions,
1161 -- Display these restrictions.
1163 if Restrictions.Set /= (All_Restrictions => False) then
1165 Write_Str (" pragma Restrictions =>");
1167 -- For boolean restrictions, just display the name of the
1168 -- restriction; for valued restrictions, also display the
1169 -- restriction value.
1171 for Restriction in All_Restrictions loop
1172 if Restrictions.Set (Restriction) then
1175 Write_Str (Image (Restriction));
1177 if Restriction in All_Parameter_Restrictions then
1179 Write_Str (Restrictions.Value (Restriction)'Img);
1185 -- If the unit violates some Restrictions, display the list of
1186 -- these restrictions.
1188 if Restrictions.Violated /= (All_Restrictions => False) then
1190 Write_Str (" Restrictions violated =>");
1192 -- For boolean restrictions, just display the name of the
1193 -- restriction. For valued restrictions, also display the
1194 -- restriction value.
1196 for Restriction in All_Restrictions loop
1197 if Restrictions.Violated (Restriction) then
1200 Write_Str (Image (Restriction));
1202 if Restriction in All_Parameter_Restrictions then
1203 if Restrictions.Count (Restriction) > 0 then
1206 if Restrictions.Unknown (Restriction) then
1207 Write_Str (" at least");
1210 Write_Str (Restrictions.Count (Restriction)'Img);
1219 if Print_Source then
1224 Write_Str (Spaces (Unit_Start + Name_Len + 1 .. Unit_End));
1230 package body Prj_Env is
1232 Uninitialized_Prefix : constant String := '#
' & Path_Separator;
1233 -- Prefix to indicate that the project path has not been initialized
1234 -- yet. Must be two characters long.
1236 ---------------------
1237 -- Add_Directories --
1238 ---------------------
1240 procedure Add_Directories
1241 (Self : in out String_Access;
1243 Prepend : Boolean := False)
1245 Tmp : String_Access;
1249 Self := new String'(Uninitialized_Prefix
& Path
);
1253 Self
:= new String'(Path & Path_Separator & Tmp.all);
1255 Self := new String'(Tmp
.all & Path_Separator
& Path
);
1259 end Add_Directories
;
1261 -------------------------------------
1262 -- Initialize_Default_Project_Path --
1263 -------------------------------------
1265 procedure Initialize_Default_Project_Path
1266 (Self
: in out String_Access
;
1267 Target_Name
: String;
1268 Runtime_Name
: String := "")
1270 Add_Default_Dir
: Boolean := Target_Name
/= "-";
1274 Ada_Project_Path
: constant String := "ADA_PROJECT_PATH";
1275 Gpr_Project_Path
: constant String := "GPR_PROJECT_PATH";
1276 Gpr_Project_Path_File
: constant String := "GPR_PROJECT_PATH_FILE";
1277 -- Names of alternate env. variables that contain path name(s) of
1278 -- directories where project files may reside. They are taken into
1279 -- account in this order: GPR_PROJECT_PATH_FILE, GPR_PROJECT_PATH,
1280 -- ADA_PROJECT_PATH.
1282 Gpr_Prj_Path_File
: String_Access
;
1283 Gpr_Prj_Path
: String_Access
;
1284 Ada_Prj_Path
: String_Access
;
1285 -- The path name(s) of directories where project files may reside.
1288 Prefix
: String_Ptr
;
1289 Runtime
: String_Ptr
;
1291 procedure Add_Target
(Suffix
: String);
1292 -- Add :<prefix>/<target>/Suffix to the project path
1294 FD
: File_Descriptor
;
1301 procedure Add_Target
(Suffix
: String) is
1302 Extra_Sep
: constant String :=
1303 (if Target_Name
(Target_Name
'Last) = '/' then
1306 (1 => Directory_Separator
));
1307 -- Note: Target_Name has a trailing / when it comes from Sdefault
1310 Add_Str_To_Name_Buffer
1311 (Path_Separator
& Prefix
.all & Target_Name
& Extra_Sep
& Suffix
);
1314 -- Start of processing for Initialize_Default_Project_Path
1318 and then (Self
'Length = 0
1319 or else Self
(Self
'First) /= '#')
1324 -- The current directory is always first in the search path. Since
1325 -- the Project_Path currently starts with '#:' as a sign that it is
1326 -- not initialized, we simply replace '#' with '.'
1329 Self
:= new String'('.' & Path_Separator);
1331 Self (Self'First) := '.';
1334 -- Then the reset of the project path (if any) currently contains the
1335 -- directories added through Add_Search_Project_Directory
1337 -- If environment variables are defined and not empty, add their
1340 Gpr_Prj_Path_File := Getenv (Gpr_Project_Path_File);
1341 Gpr_Prj_Path := Getenv (Gpr_Project_Path);
1342 Ada_Prj_Path := Getenv (Ada_Project_Path);
1344 if Gpr_Prj_Path_File.all /= "" then
1345 FD := Open_Read (Gpr_Prj_Path_File.all, GNAT.OS_Lib.Text);
1347 if FD = Invalid_FD then
1349 ("warning: could not read project path file """
1350 & Gpr_Prj_Path_File.all & """");
1353 Len := Integer (File_Length (FD));
1356 Buffer : String (1 .. Len);
1357 Index : Positive := 1;
1359 Tmp : String_Access;
1364 Len := Read (FD, Buffer (1)'Address, Len);
1367 -- Scan the file line by line
1369 while Index < Buffer'Last loop
1371 -- Find the end of line
1374 while Last <= Buffer'Last
1375 and then Buffer (Last) /= ASCII.LF
1376 and then Buffer (Last) /= ASCII.CR
1381 -- Ignore empty lines
1383 if Last > Index then
1387 (Tmp
.all & Path_Separator
&
1388 Buffer
(Index
.. Last
- 1));
1392 -- Find the beginning of the next line
1395 while Buffer
(Index
) = ASCII
.CR
or else
1396 Buffer
(Index
) = ASCII
.LF
1405 if Gpr_Prj_Path
.all /= "" then
1406 Add_Directories
(Self
, Gpr_Prj_Path
.all);
1409 Free
(Gpr_Prj_Path
);
1411 if Ada_Prj_Path
.all /= "" then
1412 Add_Directories
(Self
, Ada_Prj_Path
.all);
1415 Free
(Ada_Prj_Path
);
1417 -- Copy to Name_Buffer, since we will need to manipulate the path
1419 Name_Len
:= Self
'Length;
1420 Name_Buffer
(1 .. Name_Len
) := Self
.all;
1422 -- Scan the directory path to see if "-" is one of the directories.
1423 -- Remove each occurrence of "-" and set Add_Default_Dir to False.
1424 -- Also resolve relative paths and symbolic links.
1428 while First
<= Name_Len
1429 and then (Name_Buffer
(First
) = Path_Separator
)
1434 exit when First
> Name_Len
;
1438 while Last
< Name_Len
1439 and then Name_Buffer
(Last
+ 1) /= Path_Separator
1444 -- If the directory is "-", set Add_Default_Dir to False and
1445 -- remove from path.
1447 if Name_Buffer
(First
.. Last
) = "-" then
1448 Add_Default_Dir
:= False;
1450 for J
in Last
+ 1 .. Name_Len
loop
1451 Name_Buffer
(J
- 2) := Name_Buffer
(J
);
1454 Name_Len
:= Name_Len
- 2;
1456 -- After removing the '-', go back one character to get the
1457 -- next directory correctly.
1463 New_Dir
: constant String :=
1465 (Name_Buffer
(First
.. Last
),
1466 Resolve_Links
=> Opt
.Follow_Links_For_Dirs
);
1468 New_Last
: Positive;
1471 -- If the absolute path was resolved and is different from
1472 -- the original, replace original with the resolved path.
1474 if New_Dir
/= Name_Buffer
(First
.. Last
)
1475 and then New_Dir
'Length /= 0
1477 New_Len
:= Name_Len
+ New_Dir
'Length - (Last
- First
+ 1);
1478 New_Last
:= First
+ New_Dir
'Length - 1;
1479 Name_Buffer
(New_Last
+ 1 .. New_Len
) :=
1480 Name_Buffer
(Last
+ 1 .. Name_Len
);
1481 Name_Buffer
(First
.. New_Last
) := New_Dir
;
1482 Name_Len
:= New_Len
;
1493 -- Set the initial value of Current_Project_Path
1495 if Add_Default_Dir
then
1496 if Sdefault
.Search_Dir_Prefix
= null then
1500 Prefix
:= new String'(Executable_Prefix_Path);
1503 Prefix := new String'(Sdefault
.Search_Dir_Prefix
.all
1504 & ".." & Dir_Separator
1505 & ".." & Dir_Separator
1506 & ".." & Dir_Separator
1507 & ".." & Dir_Separator
);
1510 if Prefix
.all /= "" then
1511 if Target_Name
/= "" then
1513 if Runtime_Name
/= "" then
1514 if Base_Name
(Runtime_Name
) = Runtime_Name
then
1516 -- $prefix/$target/$runtime/lib/gnat
1519 (Runtime_Name
& Directory_Separator
&
1520 "lib" & Directory_Separator
& "gnat");
1522 -- $prefix/$target/$runtime/share/gpr
1525 (Runtime_Name
& Directory_Separator
&
1526 "share" & Directory_Separator
& "gpr");
1530 new String'(Normalize_Pathname (Runtime_Name));
1532 -- $runtime_dir/lib/gnat
1534 Add_Str_To_Name_Buffer
1535 (Path_Separator & Runtime.all & Directory_Separator &
1536 "lib" & Directory_Separator & "gnat");
1538 -- $runtime_dir/share/gpr
1540 Add_Str_To_Name_Buffer
1541 (Path_Separator & Runtime.all & Directory_Separator &
1542 "share" & Directory_Separator & "gpr");
1546 -- $prefix/$target/lib/gnat
1549 ("lib" & Directory_Separator & "gnat");
1551 -- $prefix/$target/share/gpr
1554 ("share" & Directory_Separator & "gpr");
1557 -- $prefix/share/gpr
1559 Add_Str_To_Name_Buffer
1560 (Path_Separator & Prefix.all & "share"
1561 & Directory_Separator & "gpr");
1565 Add_Str_To_Name_Buffer
1566 (Path_Separator & Prefix.all & "lib"
1567 & Directory_Separator & "gnat");
1573 Self := new String'(Name_Buffer
(1 .. Name_Len
));
1574 end Initialize_Default_Project_Path
;
1576 -----------------------
1577 -- Get_Runtime_Path --
1578 -----------------------
1580 function Get_Runtime_Path
1581 (Self
: String_Access
;
1582 Path
: String) return String_Access
1589 if Is_Absolute_Path
(Path
) then
1590 if Is_Directory
(Path
) then
1591 return new String'(Path);
1597 -- Because we do not want to resolve symbolic links, we cannot
1598 -- use Locate_Regular_File. Instead we try each possible path
1601 First := Self'First;
1602 while First <= Self'Last loop
1603 while First <= Self'Last
1604 and then Self (First) = Path_Separator
1609 exit when First > Self'Last;
1612 while Last < Self'Last
1613 and then Self (Last + 1) /= Path_Separator
1620 if not Is_Absolute_Path (Self (First .. Last)) then
1621 Add_Str_To_Name_Buffer (Get_Current_Dir); -- ??? System call
1622 Add_Char_To_Name_Buffer (Directory_Separator);
1625 Add_Str_To_Name_Buffer (Self (First .. Last));
1626 Add_Char_To_Name_Buffer (Directory_Separator);
1627 Add_Str_To_Name_Buffer (Path);
1629 if Is_Directory (Name_Buffer (1 .. Name_Len)) then
1630 return new String'(Name_Buffer
(1 .. Name_Len
));
1638 end Get_Runtime_Path
;
1646 procedure Reset_Print
is
1648 if not Selective_Output
then
1649 Selective_Output
:= True;
1650 Print_Source
:= False;
1651 Print_Object
:= False;
1652 Print_Unit
:= False;
1660 procedure Search_RTS
(Name
: String) is
1661 Src_Path
: String_Ptr
;
1662 Lib_Path
: String_Ptr
;
1663 -- Paths for source and include subdirs
1665 Rts_Full_Path
: String_Access
;
1666 -- Full path for RTS project
1669 -- Try to find the RTS
1671 Src_Path
:= Get_RTS_Search_Dir
(Name
, Include
);
1672 Lib_Path
:= Get_RTS_Search_Dir
(Name
, Objects
);
1674 -- For non-project RTS, both the include and the objects directories
1677 if Src_Path
/= null and then Lib_Path
/= null then
1678 Add_Search_Dirs
(Src_Path
, Include
);
1679 Add_Search_Dirs
(Lib_Path
, Objects
);
1680 Prj_Env
.Initialize_Default_Project_Path
1682 Target_Name
=> Sdefault
.Target_Name
.all,
1683 Runtime_Name
=> Name
);
1687 if Lib_Path
/= null then
1688 Osint
.Fail
("RTS path not valid: missing adainclude directory");
1689 elsif Src_Path
/= null then
1690 Osint
.Fail
("RTS path not valid: missing adalib directory");
1693 -- Try to find the RTS on the project path. First setup the project path
1695 Prj_Env
.Initialize_Default_Project_Path
1697 Target_Name
=> Sdefault
.Target_Name
.all,
1698 Runtime_Name
=> Name
);
1700 Rts_Full_Path
:= Prj_Env
.Get_Runtime_Path
(Prj_Path
, Name
);
1702 if Rts_Full_Path
/= null then
1704 -- Directory name was found on the project path. Look for the
1705 -- include subdirectory(s).
1707 Src_Path
:= Get_RTS_Search_Dir
(Rts_Full_Path
.all, Include
);
1709 if Src_Path
/= null then
1710 Add_Search_Dirs
(Src_Path
, Include
);
1712 -- Add the lib subdirectory if it exists
1714 Lib_Path
:= Get_RTS_Search_Dir
(Rts_Full_Path
.all, Objects
);
1716 if Lib_Path
/= null then
1717 Add_Search_Dirs
(Lib_Path
, Objects
);
1725 ("RTS path not valid: missing adainclude and adalib directories");
1732 procedure Scan_Ls_Arg
(Argv
: String) is
1733 FD
: File_Descriptor
;
1738 pragma Assert
(Argv
'First = 1);
1740 if Argv
'Length = 0 then
1745 if Argv
(1) = '-' then
1746 if Argv
'Length = 1 then
1747 Fail
("switch character cannot be followed by a blank");
1749 -- Processing for -I-
1751 elsif Argv
(2 .. Argv
'Last) = "I-" then
1752 Opt
.Look_In_Primary_Dir
:= False;
1754 -- Forbid -?- or -??- where ? is any character
1756 elsif (Argv
'Length = 3 and then Argv
(3) = '-')
1757 or else (Argv
'Length = 4 and then Argv
(4) = '-')
1759 Fail
("Trailing ""-"" at the end of " & Argv
& " forbidden.");
1761 -- Processing for -Idir
1763 elsif Argv
(2) = 'I' then
1764 Add_Source_Dir
(Argv
(3 .. Argv
'Last));
1765 Add_Lib_Dir
(Argv
(3 .. Argv
'Last));
1767 -- Processing for -aIdir (to gcc this is like a -I switch)
1769 elsif Argv
'Length >= 3 and then Argv
(2 .. 3) = "aI" then
1770 Add_Source_Dir
(Argv
(4 .. Argv
'Last));
1772 -- Processing for -aOdir
1774 elsif Argv
'Length >= 3 and then Argv
(2 .. 3) = "aO" then
1775 Add_Lib_Dir
(Argv
(4 .. Argv
'Last));
1777 -- Processing for -aLdir (to gnatbind this is like a -aO switch)
1779 elsif Argv
'Length >= 3 and then Argv
(2 .. 3) = "aL" then
1780 Add_Lib_Dir
(Argv
(4 .. Argv
'Last));
1782 -- Processing for -aP<dir>
1784 elsif Argv
'Length > 3 and then Argv
(1 .. 3) = "-aP" then
1785 Prj_Env
.Add_Directories
(Prj_Path
, Argv
(4 .. Argv
'Last));
1787 -- Processing for -nostdinc
1789 elsif Argv
(2 .. Argv
'Last) = "nostdinc" then
1790 Opt
.No_Stdinc
:= True;
1792 -- Processing for one character switches
1794 elsif Argv
'Length = 2 then
1796 when 'a' => Also_Predef
:= True;
1797 when 'h' => Print_Usage
:= True;
1798 when 'u' => Reset_Print
; Print_Unit
:= True;
1799 when 's' => Reset_Print
; Print_Source
:= True;
1800 when 'o' => Reset_Print
; Print_Object
:= True;
1801 when 'v' => Verbose_Mode
:= True;
1802 when 'd' => Dependable
:= True;
1803 when 'l' => License
:= True;
1804 when 'V' => Very_Verbose_Mode
:= True;
1806 when others => OK
:= False;
1809 -- Processing for -files=file
1811 elsif Argv
'Length > 7 and then Argv
(1 .. 7) = "-files=" then
1812 FD
:= Open_Read
(Argv
(8 .. Argv
'Last), GNAT
.OS_Lib
.Text
);
1814 if FD
= Invalid_FD
then
1815 Osint
.Fail
("could not find text file """ &
1816 Argv
(8 .. Argv
'Last) & '"');
1819 Len
:= Integer (File_Length
(FD
));
1822 Buffer
: String (1 .. Len
+ 1);
1823 Index
: Positive := 1;
1829 Len
:= Read
(FD
, Buffer
(1)'Address, Len
);
1830 Buffer
(Buffer
'Last) := ASCII
.NUL
;
1833 -- Scan the file line by line
1835 while Index
< Buffer
'Last loop
1837 -- Find the end of line
1840 while Last
<= Buffer
'Last
1841 and then Buffer
(Last
) /= ASCII
.LF
1842 and then Buffer
(Last
) /= ASCII
.CR
1847 -- Ignore empty lines
1849 if Last
> Index
then
1850 Add_File
(Buffer
(Index
.. Last
- 1));
1853 -- Find the beginning of the next line
1856 while Buffer
(Index
) = ASCII
.CR
or else
1857 Buffer
(Index
) = ASCII
.LF
1864 -- Processing for --RTS=path
1866 elsif Argv
'Length >= 5 and then Argv
(1 .. 5) = "--RTS" then
1867 if Argv
'Length <= 6 or else Argv
(6) /= '='then
1868 Osint
.Fail
("missing path for --RTS");
1871 -- Check that it is the first time we see this switch or, if
1872 -- it is not the first time, the same path is specified.
1874 if RTS_Specified
= null then
1875 RTS_Specified
:= new String'(Argv (7 .. Argv'Last));
1877 elsif RTS_Specified.all /= Argv (7 .. Argv'Last) then
1878 Osint.Fail ("--RTS cannot be specified multiple times");
1881 -- Valid --RTS switch
1883 Opt.No_Stdinc := True;
1884 Opt.RTS_Switch := True;
1891 -- If not a switch, it must be a file name
1898 Write_Str ("warning: unknown switch """);
1913 Write_Str ("Usage: ");
1914 Osint.Write_Program_Name;
1915 Write_Str (" switches [list of object files]");
1921 Write_Str ("switches:");
1924 Display_Usage_Version_And_Help;
1928 Write_Str (" -a also output relevant predefined units");
1933 Write_Str (" -u output only relevant unit names");
1938 Write_Str (" -h output this help message");
1943 Write_Str (" -s output only relevant source names");
1948 Write_Str (" -o output only relevant object names");
1953 Write_Str (" -d output sources on which specified units " &
1959 Write_Str (" -l output license information");
1964 Write_Str (" -v verbose output, full path and unit " &
1971 Write_Str (" -files=fil files are listed in text file 'fil
'");
1974 -- Line for -aI switch
1976 Write_Str (" -aIdir specify source files search path");
1979 -- Line for -aO switch
1981 Write_Str (" -aOdir specify object files search path");
1984 -- Line for -aP switch
1986 Write_Str (" -aPdir specify project search path");
1989 -- Line for -I switch
1991 Write_Str (" -Idir like -aIdir -aOdir");
1994 -- Line for -I- switch
1996 Write_Str (" -I- do not look for sources & object files");
1997 Write_Str (" in the default directory");
2000 -- Line for -nostdinc
2002 Write_Str (" -nostdinc do not look for source files");
2003 Write_Str (" in the system default directory");
2008 Write_Str (" --RTS=dir specify the default source and object search"
2012 -- File Status explanation
2015 Write_Str (" file status can be:");
2018 for ST in File_Status loop
2020 Output_Status (ST, Verbose => False);
2021 Write_Str (" ==> ");
2022 Output_Status (ST, Verbose => True);
2027 procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage);
2029 -- Start of processing for Gnatls
2032 -- Initialize standard packages
2038 -- First check for --version or --help
2040 Check_Version_And_Help ("GNATLS", "1992");
2042 -- Loop to scan out arguments
2045 Scan_Args : while Next_Arg < Arg_Count loop
2047 Next_Argv : String (1 .. Len_Arg (Next_Arg));
2049 Fill_Arg (Next_Argv'Address, Next_Arg);
2050 Scan_Ls_Arg (Next_Argv);
2053 Next_Arg := Next_Arg + 1;
2056 -- If -l (output license information) is given, it must be the only switch
2059 if Arg_Count = 2 then
2060 Output_License_Information;
2061 Exit_Program (E_Success);
2065 Write_Str ("Can't use -l with another switch");
2068 Exit_Program (E_Fatal);
2072 -- Handle --RTS switch
2074 if RTS_Specified /= null then
2075 Search_RTS (RTS_Specified.all);
2078 -- Add the source and object directories specified on the command line, if
2079 -- any, to the searched directories.
2081 while First_Source_Dir /= null loop
2082 Add_Src_Search_Dir (First_Source_Dir.Value.all);
2083 First_Source_Dir := First_Source_Dir.Next;
2086 while First_Lib_Dir /= null loop
2087 Add_Lib_Search_Dir (First_Lib_Dir.Value.all);
2088 First_Lib_Dir := First_Lib_Dir.Next;
2091 -- Finally, add the default directories
2093 Osint.Add_Default_Search_Dirs;
2095 -- If --RTS= is not specified, check if there is a default runtime
2097 if RTS_Specified = null then
2099 FD : File_Descriptor;
2100 Text : Source_Buffer_Ptr;
2104 Name_Buffer (1 .. 10) := "system.ads";
2107 Read_Source_File (Name_Find, 0, Hi, Text, FD);
2109 if Null_Source_Buffer_Ptr (Text) then
2115 if Verbose_Mode then
2117 Display_Version ("GNATLS", "1997");
2122 ("Default runtime not available. Use --RTS= with a valid runtime");
2125 Exit_Status := E_Warnings;
2128 Write_Str ("Source Search Path:");
2131 for J in 1 .. Nb_Dir_In_Src_Search_Path loop
2134 if Dir_In_Src_Search_Path (J)'Length = 0 then
2135 Write_Str ("<Current_Directory>");
2138 elsif not No_Runtime then
2142 (Dir_In_Src_Search_Path (J).all, True).all));
2149 Write_Str ("Object Search Path:");
2152 for J in 1 .. Nb_Dir_In_Obj_Search_Path loop
2155 if Dir_In_Obj_Search_Path (J)'Length = 0 then
2156 Write_Str ("<Current_Directory>");
2159 elsif not No_Runtime then
2163 (Dir_In_Obj_Search_Path (J).all, True).all));
2170 Write_Str (Project_Search_Path);
2172 Write_Str (" <Current_Directory>");
2175 Prj_Env.Initialize_Default_Project_Path
2176 (Prj_Path, Target_Name => Sdefault.Target_Name.all);
2184 if Prj_Path.all /= "" then
2185 First := Prj_Path'First;
2187 while First <= Prj_Path'Last
2188 and then (Prj_Path (First) = Path_Separator)
2193 exit when First > Prj_Path'Last;
2196 while Last < Prj_Path'Last
2197 and then Prj_Path (Last + 1) /= Path_Separator
2202 if First /= Last or else Prj_Path (First) /= '.' then
2204 -- If the directory is ".", skip it as it is the current
2205 -- directory and it is already the first directory in the
2212 (Prj_Path (First .. Last), True).all));
2224 -- Output usage information when requested
2230 if not More_Lib_Files then
2231 if not Print_Usage and then not Verbose_Mode then
2232 if Arg_Count = 1 then
2236 Exit_Status := E_Fatal;
2240 Exit_Program (Exit_Status);
2244 Initialize_ALI_Source;
2246 -- Print out all libraries for which no ALI files can be located
2248 while More_Lib_Files loop
2249 Main_File := Next_Main_Lib_File;
2250 Ali_File := Full_Lib_File_Name (Lib_File_Name (Main_File));
2252 if Ali_File = No_File then
2253 if Very_Verbose_Mode then
2254 GNATDIST.Output_No_ALI (Lib_File_Name (Main_File));
2258 Write_Str ("Can't find library info for ");
2259 Get_Name_String (Main_File);
2260 Write_Char ('"'); -- "
2261 Write_Str
(Name_Buffer
(1 .. Name_Len
));
2262 Write_Char
('"'); -- "
2264 Exit_Status
:= E_Fatal
;
2268 Ali_File
:= Strip_Directory
(Ali_File
);
2270 if Get_Name_Table_Int
(Ali_File
) = 0 then
2271 Text
:= Read_Library_Info
(Ali_File
, True);
2282 Ignore_Errors
=> True);
2290 -- Reset default output file descriptor, if needed
2292 Set_Standard_Output
;
2294 if Very_Verbose_Mode
then
2295 for A
in ALIs
.First
.. ALIs
.Last
loop
2296 GNATDIST
.Output_ALI
(A
);
2302 Find_General_Layout
;
2304 for Id
in ALIs
.First
.. ALIs
.Last
loop
2309 Get_Name_String
(Units
.Table
(ALIs
.Table
(Id
).First_Unit
).Uname
);
2311 if Also_Predef
or else not Is_Internal_Unit
then
2312 if ALIs
.Table
(Id
).No_Object
then
2313 Output_Object
(No_File
);
2315 Output_Object
(ALIs
.Table
(Id
).Ofile_Full_Name
);
2318 -- In verbose mode print all main units in the ALI file, otherwise
2319 -- just print the first one to ease columnwise printout
2321 if Verbose_Mode
then
2322 Last_U
:= ALIs
.Table
(Id
).Last_Unit
;
2324 Last_U
:= ALIs
.Table
(Id
).First_Unit
;
2327 for U
in ALIs
.Table
(Id
).First_Unit
.. Last_U
loop
2328 if U
/= ALIs
.Table
(Id
).First_Unit
2329 and then Selective_Output
2335 Output_Unit
(Id
, U
);
2337 -- Output source now, unless if it will be done as part of
2338 -- outputing dependencies.
2340 if not (Dependable
and then Print_Source
) then
2341 Output_Source
(Corresponding_Sdep_Entry
(Id
, U
));
2345 -- Print out list of units on which this unit depends (D lines)
2347 if Dependable
and then Print_Source
then
2348 if Verbose_Mode
then
2349 Write_Str
("depends upon");
2357 ALIs
.Table
(Id
).First_Sdep
.. ALIs
.Table
(Id
).Last_Sdep
2360 or else not Is_Internal_File_Name
(Sdep
.Table
(D
).Sfile
)
2362 if Verbose_Mode
then
2372 Write_Str
(Spaces
(1 .. Source_Start
- 2));
2385 -- All done. Set proper exit status
2388 Exit_Program
(Exit_Status
);