OSDN Git Service

2005-06-14 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / switch-b.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             S W I T C H - B                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 2001-2005 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
27 with Debug; use Debug;
28 with Osint; use Osint;
29 with Opt;   use Opt;
30
31 with System.WCh_Con; use System.WCh_Con;
32
33 package body Switch.B is
34
35    --------------------------
36    -- Scan_Binder_Switches --
37    --------------------------
38
39    procedure Scan_Binder_Switches (Switch_Chars : String) is
40       Max : constant Integer := Switch_Chars'Last;
41       Ptr : Integer          := Switch_Chars'First;
42       C   : Character        := ' ';
43
44    begin
45       --  Skip past the initial character (must be the switch character)
46
47       if Ptr = Max then
48          raise Bad_Switch;
49       else
50          Ptr := Ptr + 1;
51       end if;
52
53       --  A little check, "gnat" at the start of a switch is not allowed
54       --  except for the compiler
55
56       if Switch_Chars'Last >= Ptr + 3
57         and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
58       then
59          Osint.Fail ("invalid switch: """, Switch_Chars, """"
60             & " (gnat not needed here)");
61       end if;
62
63       --  Loop to scan through switches given in switch string
64
65       while Ptr <= Max loop
66          C := Switch_Chars (Ptr);
67
68          case C is
69
70          --  Processing for A switch
71
72          when 'A' =>
73             Ptr := Ptr + 1;
74
75             Ada_Bind_File := True;
76
77          --  Processing for b switch
78
79          when 'b' =>
80             Ptr := Ptr + 1;
81             Brief_Output := True;
82
83          --  Processing for c switch
84
85          when 'c' =>
86             Ptr := Ptr + 1;
87
88             Check_Only := True;
89
90          --  Processing for C switch
91
92          when 'C' =>
93             Ptr := Ptr + 1;
94
95             Ada_Bind_File := False;
96
97          --  Processing for d switch
98
99          when 'd' =>
100
101             --  Note: for the debug switch, the remaining characters in this
102             --  switch field must all be debug flags, since all valid switch
103             --  characters are also valid debug characters. This switch is not
104             --  documented on purpose because it is only used by the
105             --  implementors.
106
107             --  Loop to scan out debug flags
108
109             while Ptr < Max loop
110                Ptr := Ptr + 1;
111                C := Switch_Chars (Ptr);
112                exit when C = ASCII.NUL or else C = '/' or else C = '-';
113
114                if C in '1' .. '9' or else
115                   C in 'a' .. 'z' or else
116                   C in 'A' .. 'Z'
117                then
118                   Set_Debug_Flag (C);
119                else
120                   raise Bad_Switch;
121                end if;
122             end loop;
123
124             --  Make sure Zero_Cost_Exceptions is set if gnatdX set. This
125             --  is for backwards compatibility with old versions and usage.
126
127             if Debug_Flag_XX then
128                Zero_Cost_Exceptions_Set := True;
129                Zero_Cost_Exceptions_Val := True;
130             end if;
131
132             return;
133
134          --  Processing for D switch
135
136          when 'D' =>
137             Ptr := Ptr + 1;
138             Scan_Pos (Switch_Chars, Max, Ptr, Default_Sec_Stack_Size);
139
140          --  Processing for e switch
141
142          when 'e' =>
143             Ptr := Ptr + 1;
144             Elab_Dependency_Output := True;
145
146          --  Processing for E switch
147
148          when 'E' =>
149             Ptr := Ptr + 1;
150             Exception_Tracebacks := True;
151
152          --  Processing for F switch
153
154          when 'F' =>
155             Ptr := Ptr + 1;
156             Force_Checking_Of_Elaboration_Flags := True;
157
158          --  Processing for g switch
159
160          when 'g' =>
161             Ptr := Ptr + 1;
162
163             if Ptr <= Max then
164                C := Switch_Chars (Ptr);
165
166                if C in '0' .. '3' then
167                   Debugger_Level :=
168                     Character'Pos
169                       (Switch_Chars (Ptr)) - Character'Pos ('0');
170                   Ptr := Ptr + 1;
171                end if;
172
173             else
174                Debugger_Level := 2;
175             end if;
176
177          --  Processing for h switch
178
179          when 'h' =>
180             Ptr := Ptr + 1;
181             Usage_Requested := True;
182
183          --  Processing for i switch
184
185          when 'i' =>
186             if Ptr = Max then
187                raise Bad_Switch;
188             end if;
189
190             Ptr := Ptr + 1;
191             C := Switch_Chars (Ptr);
192
193             if C in  '1' .. '5'
194               or else C = '8'
195               or else C = 'p'
196               or else C = 'f'
197               or else C = 'n'
198               or else C = 'w'
199             then
200                Identifier_Character_Set := C;
201                Ptr := Ptr + 1;
202             else
203                raise Bad_Switch;
204             end if;
205
206          --  Processing for K switch
207
208          when 'K' =>
209             Ptr := Ptr + 1;
210             Output_Linker_Option_List := True;
211
212          --  Processing for l switch
213
214          when 'l' =>
215             Ptr := Ptr + 1;
216             Elab_Order_Output := True;
217
218          --  Processing for m switch
219
220          when 'm' =>
221             Ptr := Ptr + 1;
222             Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
223
224          --  Processing for n switch
225
226          when 'n' =>
227             Ptr := Ptr + 1;
228             Bind_Main_Program := False;
229
230             --  Note: The -L option of the binder also implies -n, so
231             --  any change here must also be reflected in the processing
232             --  for -L that is found in Gnatbind.Scan_Bind_Arg.
233
234          --  Processing for o switch
235
236          when 'o' =>
237             Ptr := Ptr + 1;
238
239             if Output_File_Name_Present then
240                raise Too_Many_Output_Files;
241
242             else
243                Output_File_Name_Present := True;
244             end if;
245
246          --  Processing for O switch
247
248          when 'O' =>
249             Ptr := Ptr + 1;
250             Output_Object_List := True;
251
252          --  Processing for p switch
253
254          when 'p' =>
255             Ptr := Ptr + 1;
256             Pessimistic_Elab_Order := True;
257
258          --  Processing for q switch
259
260          when 'q' =>
261             Ptr := Ptr + 1;
262             Quiet_Output := True;
263
264          --  Processing for r switch
265
266          when 'r' =>
267             Ptr := Ptr + 1;
268             List_Restrictions := True;
269
270          --  Processing for s switch
271
272          when 's' =>
273             Ptr := Ptr + 1;
274             All_Sources := True;
275             Check_Source_Files := True;
276
277          --  Processing for t switch
278
279          when 't' =>
280             Ptr := Ptr + 1;
281             Tolerate_Consistency_Errors := True;
282
283          --  Processing for T switch
284
285          when 'T' =>
286             Ptr := Ptr + 1;
287             Time_Slice_Set := True;
288             Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value);
289             Time_Slice_Value := Time_Slice_Value * 1_000;
290
291          --  Processing for v switch
292
293          when 'v' =>
294             Ptr := Ptr + 1;
295             Verbose_Mode := True;
296
297          --  Processing for w switch
298
299          when 'w' =>
300
301             --  For the binder we only allow suppress/error cases
302
303             Ptr := Ptr + 1;
304
305             case Switch_Chars (Ptr) is
306
307                when 'e' =>
308                   Warning_Mode  := Treat_As_Error;
309
310                when 's' =>
311                   Warning_Mode  := Suppress;
312
313                when others =>
314                   raise Bad_Switch;
315             end case;
316
317             Ptr := Ptr + 1;
318
319          --  Processing for W switch
320
321          when 'W' =>
322             Ptr := Ptr + 1;
323
324             for J in WC_Encoding_Method loop
325                if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
326                   Wide_Character_Encoding_Method := J;
327                   exit;
328
329                elsif J = WC_Encoding_Method'Last then
330                   raise Bad_Switch;
331                end if;
332             end loop;
333
334             Upper_Half_Encoding :=
335               Wide_Character_Encoding_Method in
336                 WC_Upper_Half_Encoding_Method;
337
338             Ptr := Ptr + 1;
339
340          --  Processing for x switch
341
342          when 'x' =>
343             Ptr := Ptr + 1;
344             All_Sources := False;
345             Check_Source_Files := False;
346
347          --  Processing for X switch
348
349          when 'X' =>
350             Ptr := Ptr + 1;
351             Scan_Pos (Switch_Chars, Max, Ptr, Default_Exit_Status);
352
353          --  Processing for z switch
354
355          when 'z' =>
356             Ptr := Ptr + 1;
357             No_Main_Subprogram := True;
358
359          --  Ignore extra switch character
360
361          when '/'  =>
362             Ptr := Ptr + 1;
363
364          --  Ignore '-' extra switch caracter, only if it isn't followed by
365          --  'RTS'. If it is, then we must process the 'RTS' switch
366
367          when '-' =>
368
369             if Ptr + 3 <= Max and then
370               Switch_Chars (Ptr + 1 .. Ptr + 3) = "RTS"
371             then
372                Ptr := Ptr + 1;
373
374                if Switch_Chars (Ptr + 3) /= '=' or else
375                  (Switch_Chars (Ptr + 3) = '='
376                   and then Ptr + 4 > Max)
377                then
378                   Osint.Fail ("missing path for --RTS");
379                else
380
381                   --  valid --RTS switch
382                   Opt.No_Stdinc := True;
383                   Opt.RTS_Switch := True;
384
385                   declare
386                      Src_Path_Name : constant String_Ptr :=
387                                        Get_RTS_Search_Dir
388                                          (Switch_Chars
389                                            (Ptr + 4 .. Switch_Chars'Last),
390                                           Include);
391                      Lib_Path_Name : constant String_Ptr :=
392                                        Get_RTS_Search_Dir
393                                          (Switch_Chars
394                                            (Ptr + 4 .. Switch_Chars'Last),
395                                           Objects);
396
397                   begin
398                      if Src_Path_Name /= null and then
399                        Lib_Path_Name /= null
400                      then
401                         --  Set the RTS_*_Path_Name variables, so that the
402                         --  correct directories will be set when
403                         --  Osint.Add_Default_Search_Dirs will be called later.
404
405                         RTS_Src_Path_Name := Src_Path_Name;
406                         RTS_Lib_Path_Name := Lib_Path_Name;
407
408                         --  We can exit as there can not be another switch
409                         --  after --RTS
410
411                         exit;
412
413                      elsif  Src_Path_Name = null
414                        and then Lib_Path_Name = null
415                      then
416                         Osint.Fail ("RTS path not valid: missing " &
417                                     "adainclude and adalib directories");
418                      elsif Src_Path_Name = null then
419                         Osint.Fail ("RTS path not valid: missing " &
420                                     "adainclude directory");
421                      elsif  Lib_Path_Name = null then
422                         Osint.Fail ("RTS path not valid: missing " &
423                                     "adalib directory");
424                      end if;
425                   end;
426                end if;
427
428             else
429                Ptr := Ptr + 1;
430             end if;
431
432          --  Anything else is an error (illegal switch character)
433
434          when others =>
435             raise Bad_Switch;
436          end case;
437       end loop;
438
439    exception
440       when Bad_Switch =>
441          Osint.Fail ("invalid switch: ", (1 => C));
442
443       when Bad_Switch_Value =>
444          Osint.Fail ("numeric value out of range for switch: ", (1 => C));
445
446       when Missing_Switch_Value =>
447          Osint.Fail ("missing numeric value for switch: ", (1 => C));
448
449       when Too_Many_Output_Files =>
450          Osint.Fail ("duplicate -o switch");
451    end Scan_Binder_Switches;
452
453 end Switch.B;