File: gnatelim-driver.adb

package info (click to toggle)
asis 2005-5
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 6,424 kB
  • ctags: 27
  • sloc: ada: 73,883; makefile: 201
file content (351 lines) | stat: -rw-r--r-- 10,935 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
------------------------------------------------------------------------------
--                                                                          --
--                           GNATELIM COMPONENTS                            --
--                                                                          --
--                      G N A T E L I M . D R I V E R                       --
--                                                                          --
--                       P r o c e d u r e   B o d y                        --
--                                                                          --
--            Copyright (C) 1998-2005 Ada Core Technologies, Inc.           --
--                                                                          --
-- GNATELIM  is  free software;  you can  redistribute it and/or  modify it --
-- under the terms of the  GNU  General Public License  as published by the --
-- Free Software Foundation; either version 2 or (at your option) any later --
-- version. GNATELIM is distributed in the hope that it will be useful, but --
-- WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABI- --
-- LITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Li- --
-- cense 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,  59 Temple Place - Suite 330, --
-- Boston, MA 02111-1307, USA.                                              --
--                                                                          --
-- The original version  of  Gnatelim  was developed by  Alain  Le  Guennec --
-- It is now maintained by Ada Core Technologies Inc  (http://www.gnat.com) --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Characters.Handling;   use Ada.Characters.Handling;
with Ada.Exceptions;            use Ada.Exceptions;
with Ada.Strings.Fixed;         use Ada.Strings.Fixed;
with Ada.Wide_Text_IO;          use Ada.Wide_Text_IO;
with Ada.Command_Line;          use Ada.Command_Line;

with GNAT.OS_Lib;               use GNAT.OS_Lib;
with GNAT.Directory_Operations; use GNAT.Directory_Operations;
with GNAT.Command_Line;         use GNAT.Command_Line;

with ASIS_UL.Compiler_Options;  use ASIS_UL.Compiler_Options;

with Gnatelim.Analyze;
with Gnatelim.Bind_File;
with Gnatelim.Nodes;            use Gnatelim.Nodes;
with Gnatelim.Output;           use Gnatelim.Output;
with Gnatelim.Errors;           use Gnatelim.Errors;

procedure Gnatelim.Driver is

   Bindfile, Main_Proc : String_Access;
   --  Storage for bindfile and main procedure names

   Main : Node;
   --  ???

   -------------------------
   --  Local subprograms  --
   -------------------------

   procedure Brief_Help;
   --  Prints brief help information to stdout.

   function Detect_Target return String;
   --  Detects if this is a cross version of the tool by analysing its name.
   --  In case if it is a cross version, returns the prefix of the name
   --  detecting the specific cross version, othervise returns an empty
   --  string   (in case of gnaampelim, returns "AAMP")

   function Compiler_To_Call return String;
   --  Detects the name of the compiler to call

   function Gnatmake_To_Call return String;
   --  Detects the name of gnatmake to call

   procedure Locate_Main_Unit (Par : String);
   --  This procedure tries to locate the file containing the main procedure
   --  name and to set full normalized name of this file as the value of
   --  Main_Proc. In case if it is impossible because of any reason, this
   --  procesure assigns to Main_Proc the reference to a Par string as it is
   --  passed to the procedure

   ----------------
   -- Brief_Help --
   ----------------

   procedure Brief_Help is
   begin

      Put_Gnatelim_Version;
      Put_Line ("");
      Put_Line ("Usage: gnatelim [options] name [gcc_switches]");
      Put_Line ("  name     the name of the source file containing the main");
      Put_Line ("           subprogram of a program (partition)");
      Put_Line ("gnatelim options:");
      Put_Line ("  -v       verbose mode");
      Put_Line ("  -a       also analyze RTL components used by a program");
      Put_Line ("  -b<file> process specific bind file");
      Put_Line ("  -q       quiet mode");
      Put_Line ("  -I<dir>  look in this dir for source files; can be repeated"
                & " any number");
      Put_Line ("           of times. Specify -I- to exclude current dir.");
      Put_Line ("  -C<file> file that contains configuration pragmas. Must be"
                & " with full path.");
      Put_Line ("  --GCC=<file> use this GCC instead of the one on the path");
      Put_Line ("  --GNATMAKE=<file> "
                & "use this GNATMAKE instead of the one on the path");
      Put      ("  gcc_switches  '-cargs switches' where 'switches' is ");
      Put_Line ("a list of of switches");
      Put_Line ("                that are valid switches for gcc");
   end Brief_Help;

   ----------------------
   -- Compiler_To_Call --
   ----------------------

   function Compiler_To_Call return String is
      Target : constant String := Detect_Target;
   begin

      if Target = "AAMP" then
         return "gnaamp";
      else
         return Target & "gcc";
      end if;

   end Compiler_To_Call;

   -------------------
   -- Detect_Target --
   -------------------

   function Detect_Target return String is
      Name     : constant String  :=
        To_Lower (Base_Name (Normalize_Pathname (Command_Name)));
      Tgt_Last : constant Integer := Index (Name, "gnatelim") - 1;
   begin

      if Name = "gnaampelim" then
         return "AAMP";
      elsif Tgt_Last > Name'First then
         return Name (Name'First .. Tgt_Last);
      else
         return "";
      end if;

   exception
      when others =>
         return "";

   end Detect_Target;

   ----------------------
   -- Gnatmake_To_Call --
   ----------------------

   function Gnatmake_To_Call return String is
      Target : constant String := Detect_Target;
   begin

      if Target = "AAMP" then
         return "gnaampmake";
      else
         return Target & "gnatmake";
      end if;

   end Gnatmake_To_Call;

   ----------------------
   -- Locate_Main_Unit --
   ----------------------

   procedure Locate_Main_Unit (Par : String) is
   begin

      if Is_Regular_File (Par) then
         Main_Proc := new String'(Normalize_Pathname (Par));
      elsif Is_Regular_File (Par & ".adb") then
         Main_Proc := new String'(Normalize_Pathname (Par & ".adb"));
      elsif Is_Regular_File (Par & ".ads") then
         Main_Proc := new String'(Normalize_Pathname (Par & ".ads"));
      end if;

      if Main_Proc = null then
         Main_Proc := new String'(Par);
      end if;

   end Locate_Main_Unit;

begin  --  Gnatelim.Driver's body.

   --  Parse command-line arguments.

   Initialize_Option_Scan
     (Stop_At_First_Non_Switch => True,
      Section_Delimiters       => "cargs");

   loop
      case Getopt ("-help -GCC=: -GNATMAKE=: a b: m q v C: I: d dv dh v") is

         when ASCII.Nul =>
            exit;

         when 'a' =>
            Gnatelim.Eliminate_In_RTL := True;

         when 'b' =>
            Bindfile := new String'(Parameter);

         when 'm' =>
            null; --  Obsolete switch, for backwards compatibility

         when 'q' =>
            Gnatelim.Quiet_Mode := True;

         when 'v' =>
            Gnatelim.Verbose_Mode := True;

         when 'C' =>
            Store_gnatec_Option (Parameter);

         when 'I' =>
            Store_I_Option (Parameter);

         when '-' =>
            if Full_Switch = "-help" then
               Brief_Help;
               OS_Exit (1);

            elsif Full_Switch = "-GCC=" then
               Gcc := new String'(Parameter);

            elsif Full_Switch = "-GNATMAKE=" then
               Gnatmake := new String'(Parameter);
            end if;

         when 'd' =>
            --  Debug switches

            if Full_Switch = "dv" then
               Gnatelim.Output_Debug_Information := True;

            elsif Full_Switch = "dh" then
               Gnatelim.Eliminate_Homonyms_By_Profile := True;

            elsif Full_Switch = "d" then
               Gnatelim.Progress_Indicator_Mode := True;

            end if;

         when others =>
            null;

      end case;

   end loop;

   if Bindfile = null then
      Bindfile := new String'("");
   end if;

   if Gnatmake = null then
      Gnatmake := Locate_Exec_On_Path (Gnatmake_To_Call);
   end if;

   if Gnatmake = null then
      Error (To_Wide_String (Gnatmake_To_Call) & " not found on the path");
   end if;

   if Gcc = null then
      Gcc := Locate_Exec_On_Path (Compiler_To_Call);
   end if;

   if Gcc = null then
      Error (To_Wide_String (Compiler_To_Call) & " not found on the path");
   end if;

   --  Clear environment variables that set objects path for gnatmake, as
   --  gnatelim will define its own
   Setenv ("ADA_PRJ_OBJECTS_FILE", "");
   Setenv ("ADA_OBJECTS_PATH", "");

   Locate_Main_Unit (Get_Argument);

   if Main_Proc = null or else Main_Proc.all = "" then
      Error ("gnatelim: can not locate the main unit");
   end if;

   Process_cargs_Section;

   Set_Arg_List;

   if Main_Proc.all = "" then
      Brief_Help;
      OS_Exit (1);
   end if;

   if Verbose_Mode then
      Put ("--  ");
      Put_Gnatelim_Version;
      New_Line;
      Put_Line ("--  Copyright 1997-2003, Free Software Foundation, Inc.");
      New_Line;
   end if;

   Warning ("Processing bind file...");
   Gnatelim.Bind_File.Process_Bind_File
     (Main_Proc.all, Bindfile.all);

   Warning ("Registering subprograms...");
   Main := Gnatelim.Analyze (Main_Proc);

   Main.Flags (FLAG_USED) := True;
   Register_Node (Main);

   Warning ("Analyzing usage...");

   Gnatelim.Nodes.Transitive_Closure;

   Warning ("Generating pragmas...");
   Gnatelim.Output.Report_Unused_Subprograms;

exception

   when Fatal_Error =>
      OS_Exit (1);

   when Invalid_Switch =>
      Brief_Help;
      New_Line;
      Put_Line ("Unknown switch: -" & To_Wide_String (Full_Switch));

   when Ex : others =>
      Set_Output (Standard_Error);
      New_Line;

      Put ("Unexpected exception in ");
      Put_Gnatelim_Version;
      New_Line;
      Put (To_Wide_String (Exception_Name (Ex)));
      Put (" was raised: ");

      if Exception_Message (Ex)'Length = 0 then
         Put_Line ("(no exception message)");
      else
         Put_Line (To_Wide_String (Exception_Message (Ex)));
      end if;

      Put_Line ("Please report to report@gnat.com");

      --  Exit cleanly.
      Set_Output (Standard_Output);
      OS_Exit (1);

end Gnatelim.Driver;