fixing pr42337
[official-gcc.git] / gcc / ada / switch-b.adb
blobe3e597bcadfb06c6b232137887ad838d93fa2b29
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-2008, 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 ------------------------------------------------------------------------------
26 with Debug; use Debug;
27 with Osint; use Osint;
28 with Opt; use Opt;
30 with System.WCh_Con; use System.WCh_Con;
32 package body Switch.B is
34 --------------------------
35 -- Scan_Binder_Switches --
36 --------------------------
38 procedure Scan_Binder_Switches (Switch_Chars : String) is
39 Max : constant Integer := Switch_Chars'Last;
40 Ptr : Integer := Switch_Chars'First;
41 C : Character := ' ';
43 function Get_Stack_Size (S : Character) return Int;
44 -- Used for -d and -D to scan stack size including handling k/m.
45 -- S is set to 'd' or 'D' to indicate the switch being scanned.
47 --------------------
48 -- Get_Stack_Size --
49 --------------------
51 function Get_Stack_Size (S : Character) return Int is
52 Result : Int;
54 begin
55 Scan_Pos (Switch_Chars, Max, Ptr, Result, S);
57 -- In the following code, we enable overflow checking since the
58 -- multiplication by K or M may cause overflow, which is an error.
60 declare
61 pragma Unsuppress (Overflow_Check);
63 begin
64 -- Check for additional character 'k' (for kilobytes) or 'm'
65 -- (for Megabytes), but only if we have not reached the end
66 -- of the switch string. Note that if this appears before the
67 -- end of the string we will get an error when we test to make
68 -- sure that the string is exhausted (at the end of the case).
70 if Ptr <= Max then
71 if Switch_Chars (Ptr) = 'k' then
72 Result := Result * 1024;
73 Ptr := Ptr + 1;
75 elsif Switch_Chars (Ptr) = 'm' then
76 Result := Result * (1024 * 1024);
77 Ptr := Ptr + 1;
78 end if;
79 end if;
81 exception
82 when Constraint_Error =>
83 Osint.Fail ("numeric value out of range for switch: " & S);
84 end;
86 return Result;
87 end Get_Stack_Size;
89 -- Start of processing for Scan_Binder_Switches
91 begin
92 -- Skip past the initial character (must be the switch character)
94 if Ptr = Max then
95 Bad_Switch (Switch_Chars);
96 else
97 Ptr := Ptr + 1;
98 end if;
100 -- A little check, "gnat" at the start of a switch is not allowed
101 -- except for the compiler
103 if Switch_Chars'Last >= Ptr + 3
104 and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
105 then
106 Osint.Fail ("invalid switch: """ & Switch_Chars & """"
107 & " (gnat not needed here)");
108 end if;
110 -- Loop to scan through switches given in switch string
112 Check_Switch : begin
113 C := Switch_Chars (Ptr);
115 case C is
117 -- Processing for a switch
119 when 'a' =>
120 Ptr := Ptr + 1;
121 Use_Pragma_Linker_Constructor := True;
123 -- Processing for A switch
125 when 'A' =>
126 Ptr := Ptr + 1;
127 Ada_Bind_File := True;
129 -- Processing for b switch
131 when 'b' =>
132 Ptr := Ptr + 1;
133 Brief_Output := True;
135 -- Processing for c switch
137 when 'c' =>
138 Ptr := Ptr + 1;
140 Check_Only := True;
142 -- Processing for C switch
144 when 'C' =>
145 Ptr := Ptr + 1;
147 Ada_Bind_File := False;
149 -- Processing for d switch
151 when 'd' =>
153 if Ptr = Max then
154 Bad_Switch (Switch_Chars);
155 end if;
157 Ptr := Ptr + 1;
158 C := Switch_Chars (Ptr);
160 -- Case where character after -d is a digit (default stack size)
162 if C in '0' .. '9' then
164 -- In this case, we process the default primary stack size
166 Default_Stack_Size := Get_Stack_Size ('d');
168 -- Case where character after -d is not digit (debug flags)
170 else
171 -- Note: for the debug switch, the remaining characters in this
172 -- switch field must all be debug flags, since all valid switch
173 -- characters are also valid debug characters. This switch is
174 -- not documented on purpose because it is only used by the
175 -- implementors.
177 -- Loop to scan out debug flags
179 loop
180 C := Switch_Chars (Ptr);
182 if C in 'a' .. 'z' or else C in 'A' .. 'Z' then
183 Set_Debug_Flag (C);
184 else
185 Bad_Switch (Switch_Chars);
186 end if;
188 Ptr := Ptr + 1;
189 exit when Ptr > Max;
190 end loop;
191 end if;
193 -- Processing for D switch
195 when 'D' =>
196 if Ptr = Max then
197 Bad_Switch (Switch_Chars);
198 end if;
200 Ptr := Ptr + 1;
201 Default_Sec_Stack_Size := Get_Stack_Size ('D');
203 -- Processing for e switch
205 when 'e' =>
206 Ptr := Ptr + 1;
207 Elab_Dependency_Output := True;
209 -- Processing for E switch
211 when 'E' =>
212 Ptr := Ptr + 1;
213 Exception_Tracebacks := True;
215 -- Processing for F switch
217 when 'F' =>
218 Ptr := Ptr + 1;
219 Force_Checking_Of_Elaboration_Flags := True;
221 -- Processing for g switch
223 when 'g' =>
224 Ptr := Ptr + 1;
226 if Ptr <= Max then
227 C := Switch_Chars (Ptr);
229 if C in '0' .. '3' then
230 Debugger_Level :=
231 Character'Pos
232 (Switch_Chars (Ptr)) - Character'Pos ('0');
233 Ptr := Ptr + 1;
234 end if;
236 else
237 Debugger_Level := 2;
238 end if;
240 -- Processing for h switch
242 when 'h' =>
243 Ptr := Ptr + 1;
244 Usage_Requested := True;
246 -- Processing for i switch
248 when 'i' =>
249 if Ptr = Max then
250 Bad_Switch (Switch_Chars);
251 end if;
253 Ptr := Ptr + 1;
254 C := Switch_Chars (Ptr);
256 if C in '1' .. '5'
257 or else C = '8'
258 or else C = 'p'
259 or else C = 'f'
260 or else C = 'n'
261 or else C = 'w'
262 then
263 Identifier_Character_Set := C;
264 Ptr := Ptr + 1;
265 else
266 Bad_Switch (Switch_Chars);
267 end if;
269 -- Processing for K switch
271 when 'K' =>
272 Ptr := Ptr + 1;
273 Output_Linker_Option_List := True;
275 -- Processing for l switch
277 when 'l' =>
278 Ptr := Ptr + 1;
279 Elab_Order_Output := True;
281 -- Processing for m switch
283 when 'm' =>
284 if Ptr = Max then
285 Bad_Switch (Switch_Chars);
286 end if;
288 Ptr := Ptr + 1;
289 Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Messages, C);
291 -- Processing for n switch
293 when 'n' =>
294 Ptr := Ptr + 1;
295 Bind_Main_Program := False;
297 -- Note: The -L option of the binder also implies -n, so
298 -- any change here must also be reflected in the processing
299 -- for -L that is found in Gnatbind.Scan_Bind_Arg.
301 -- Processing for o switch
303 when 'o' =>
304 Ptr := Ptr + 1;
306 if Output_File_Name_Present then
307 Osint.Fail ("duplicate -o switch");
309 else
310 Output_File_Name_Present := True;
311 end if;
313 -- Processing for O switch
315 when 'O' =>
316 Ptr := Ptr + 1;
317 Output_Object_List := True;
319 -- Processing for p switch
321 when 'p' =>
322 Ptr := Ptr + 1;
323 Pessimistic_Elab_Order := True;
325 -- Processing for q switch
327 when 'q' =>
328 Ptr := Ptr + 1;
329 Quiet_Output := True;
331 -- Processing for r switch
333 when 'r' =>
334 Ptr := Ptr + 1;
335 List_Restrictions := True;
337 -- Processing for R switch
339 when 'R' =>
340 Ptr := Ptr + 1;
341 Check_Only := True;
342 List_Closure := True;
344 -- Processing for s switch
346 when 's' =>
347 Ptr := Ptr + 1;
348 All_Sources := True;
349 Check_Source_Files := True;
351 -- Processing for t switch
353 when 't' =>
354 Ptr := Ptr + 1;
355 Tolerate_Consistency_Errors := True;
357 -- Processing for T switch
359 when 'T' =>
360 if Ptr = Max then
361 Bad_Switch (Switch_Chars);
362 end if;
364 Ptr := Ptr + 1;
365 Time_Slice_Set := True;
366 Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value, C);
367 Time_Slice_Value := Time_Slice_Value * 1_000;
369 -- Processing for u switch
371 when 'u' =>
372 if Ptr = Max then
373 Bad_Switch (Switch_Chars);
374 end if;
376 Ptr := Ptr + 1;
377 Dynamic_Stack_Measurement := True;
378 Scan_Nat
379 (Switch_Chars,
380 Max,
381 Ptr,
382 Dynamic_Stack_Measurement_Array_Size,
385 -- Processing for v switch
387 when 'v' =>
388 Ptr := Ptr + 1;
389 Verbose_Mode := True;
391 -- Processing for w switch
393 when 'w' =>
394 if Ptr = Max then
395 Bad_Switch (Switch_Chars);
396 end if;
398 -- For the binder we only allow suppress/error cases
400 Ptr := Ptr + 1;
402 case Switch_Chars (Ptr) is
404 when 'e' =>
405 Warning_Mode := Treat_As_Error;
407 when 's' =>
408 Warning_Mode := Suppress;
410 when others =>
411 Bad_Switch (Switch_Chars);
412 end case;
414 Ptr := Ptr + 1;
416 -- Processing for W switch
418 when 'W' =>
419 Ptr := Ptr + 1;
421 if Ptr > Max then
422 Bad_Switch (Switch_Chars);
423 end if;
425 begin
426 Wide_Character_Encoding_Method :=
427 Get_WC_Encoding_Method (Switch_Chars (Ptr));
428 exception
429 when Constraint_Error =>
430 Bad_Switch (Switch_Chars);
431 end;
433 Wide_Character_Encoding_Method_Specified := True;
435 Upper_Half_Encoding :=
436 Wide_Character_Encoding_Method in
437 WC_Upper_Half_Encoding_Method;
439 Ptr := Ptr + 1;
441 -- Processing for x switch
443 when 'x' =>
444 Ptr := Ptr + 1;
445 All_Sources := False;
446 Check_Source_Files := False;
448 -- Processing for X switch
450 when 'X' =>
451 if Ptr = Max then
452 Bad_Switch (Switch_Chars);
453 end if;
455 Ptr := Ptr + 1;
456 Scan_Pos (Switch_Chars, Max, Ptr, Default_Exit_Status, C);
458 -- Processing for y switch
460 when 'y' =>
461 Ptr := Ptr + 1;
462 Leap_Seconds_Support := True;
464 -- Processing for z switch
466 when 'z' =>
467 Ptr := Ptr + 1;
468 No_Main_Subprogram := True;
470 -- Processing for Z switch
472 when 'Z' =>
473 Ptr := Ptr + 1;
474 Zero_Formatting := True;
476 -- Processing for --RTS
478 when '-' =>
480 if Ptr + 4 <= Max and then
481 Switch_Chars (Ptr + 1 .. Ptr + 3) = "RTS"
482 then
483 Ptr := Ptr + 4;
485 if Switch_Chars (Ptr) /= '=' or else Ptr = Max then
486 Osint.Fail ("missing path for --RTS");
488 else
489 -- valid --RTS switch
491 Opt.No_Stdinc := True;
492 Opt.RTS_Switch := True;
494 declare
495 Src_Path_Name : constant String_Ptr :=
496 Get_RTS_Search_Dir
497 (Switch_Chars
498 (Ptr + 1 .. Switch_Chars'Last),
499 Include);
500 Lib_Path_Name : constant String_Ptr :=
501 Get_RTS_Search_Dir
502 (Switch_Chars
503 (Ptr + 1 .. Switch_Chars'Last),
504 Objects);
506 begin
507 if Src_Path_Name /= null and then
508 Lib_Path_Name /= null
509 then
510 -- Set the RTS_*_Path_Name variables, so that the
511 -- correct directories will be set when
512 -- Osint.Add_Default_Search_Dirs will be called later.
514 RTS_Src_Path_Name := Src_Path_Name;
515 RTS_Lib_Path_Name := Lib_Path_Name;
517 Ptr := Max + 1;
519 elsif Src_Path_Name = null
520 and then Lib_Path_Name = null
521 then
522 Osint.Fail ("RTS path not valid: missing " &
523 "adainclude and adalib directories");
524 elsif Src_Path_Name = null then
525 Osint.Fail ("RTS path not valid: missing " &
526 "adainclude directory");
527 elsif Lib_Path_Name = null then
528 Osint.Fail ("RTS path not valid: missing " &
529 "adalib directory");
530 end if;
531 end;
532 end if;
534 else
535 Bad_Switch (Switch_Chars);
536 end if;
538 -- Anything else is an error (illegal switch character)
540 when others =>
541 Bad_Switch (Switch_Chars);
542 end case;
544 if Ptr <= Max then
545 Bad_Switch (Switch_Chars);
546 end if;
547 end Check_Switch;
548 end Scan_Binder_Switches;
550 end Switch.B;