2010-07-22 Andi Kleen <ak@linux.intel.com>
[official-gcc.git] / gcc / ada / switch-b.adb
blobb41296b2cc987bc5e1b1d83743fcc710bef239ab
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-2010, 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;
29 with Output; use Output;
31 with System.WCh_Con; use System.WCh_Con;
33 package body Switch.B is
35 --------------------------
36 -- Scan_Binder_Switches --
37 --------------------------
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 := ' ';
44 function Get_Optional_Filename return String_Ptr;
45 -- If current character is '=', return a newly allocated string that
46 -- contains the remainder of the current switch (after the '='), else
47 -- return null.
49 function Get_Stack_Size (S : Character) return Int;
50 -- Used for -d and -D to scan stack size including handling k/m. S is
51 -- set to 'd' or 'D' to indicate the switch being scanned.
53 ---------------------------
54 -- Get_Optional_Filename --
55 ---------------------------
57 function Get_Optional_Filename return String_Ptr is
58 Result : String_Ptr;
60 begin
61 if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
62 if Ptr = Max then
63 Bad_Switch (Switch_Chars);
64 else
65 Result := new String'(Switch_Chars (Ptr + 1 .. Max));
66 Ptr := Max + 1;
67 return Result;
68 end if;
69 end if;
71 return null;
72 end Get_Optional_Filename;
74 --------------------
75 -- Get_Stack_Size --
76 --------------------
78 function Get_Stack_Size (S : Character) return Int is
79 Result : Int;
81 begin
82 Scan_Pos (Switch_Chars, Max, Ptr, Result, S);
84 -- In the following code, we enable overflow checking since the
85 -- multiplication by K or M may cause overflow, which is an error.
87 declare
88 pragma Unsuppress (Overflow_Check);
90 begin
91 -- Check for additional character 'k' (for kilobytes) or 'm' (for
92 -- Megabytes), but only if we have not reached the end of the
93 -- switch string. Note that if this appears before the end of the
94 -- string we will get an error when we test to make sure that the
95 -- string is exhausted (at the end of the case).
97 if Ptr <= Max then
98 if Switch_Chars (Ptr) = 'k' then
99 Result := Result * 1024;
100 Ptr := Ptr + 1;
102 elsif Switch_Chars (Ptr) = 'm' then
103 Result := Result * (1024 * 1024);
104 Ptr := Ptr + 1;
105 end if;
106 end if;
108 exception
109 when Constraint_Error =>
110 Osint.Fail ("numeric value out of range for switch: " & S);
111 end;
113 return Result;
114 end Get_Stack_Size;
116 -- Start of processing for Scan_Binder_Switches
118 begin
119 -- Skip past the initial character (must be the switch character)
121 if Ptr = Max then
122 Bad_Switch (Switch_Chars);
123 else
124 Ptr := Ptr + 1;
125 end if;
127 -- A little check, "gnat" at the start of a switch is not allowed except
128 -- for the compiler
130 if Switch_Chars'Last >= Ptr + 3
131 and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
132 then
133 Osint.Fail ("invalid switch: """ & Switch_Chars & """"
134 & " (gnat not needed here)");
135 end if;
137 -- Loop to scan through switches given in switch string
139 Check_Switch : begin
140 C := Switch_Chars (Ptr);
142 case C is
144 -- Processing for a switch
146 when 'a' =>
147 Ptr := Ptr + 1;
148 Use_Pragma_Linker_Constructor := True;
150 -- Processing for A switch
152 when 'A' =>
153 Ptr := Ptr + 1;
154 Output_ALI_List := True;
155 ALI_List_Filename := Get_Optional_Filename;
157 -- Processing for b switch
159 when 'b' =>
160 Ptr := Ptr + 1;
161 Brief_Output := True;
163 -- Processing for c switch
165 when 'c' =>
166 Ptr := Ptr + 1;
167 Check_Only := True;
169 -- Processing for C switch
171 when 'C' =>
172 Ptr := Ptr + 1;
173 Ada_Bind_File := False;
175 Write_Line ("warning: gnatbind switch -C is obsolescent");
177 -- Processing for d switch
179 when 'd' =>
181 if Ptr = Max then
182 Bad_Switch (Switch_Chars);
183 end if;
185 Ptr := Ptr + 1;
186 C := Switch_Chars (Ptr);
188 -- Case where character after -d is a digit (default stack size)
190 if C in '0' .. '9' then
192 -- In this case, we process the default primary stack size
194 Default_Stack_Size := Get_Stack_Size ('d');
196 -- Case where character after -d is not digit (debug flags)
198 else
199 -- Note: for the debug switch, the remaining characters in this
200 -- switch field must all be debug flags, since all valid switch
201 -- characters are also valid debug characters. This switch is
202 -- not documented on purpose because it is only used by the
203 -- implementors.
205 -- Loop to scan out debug flags
207 loop
208 C := Switch_Chars (Ptr);
210 if C in 'a' .. 'z' or else C in 'A' .. 'Z' then
211 Set_Debug_Flag (C);
212 else
213 Bad_Switch (Switch_Chars);
214 end if;
216 Ptr := Ptr + 1;
217 exit when Ptr > Max;
218 end loop;
219 end if;
221 -- Processing for D switch
223 when 'D' =>
224 if Ptr = Max then
225 Bad_Switch (Switch_Chars);
226 end if;
228 Ptr := Ptr + 1;
229 Default_Sec_Stack_Size := Get_Stack_Size ('D');
231 -- Processing for e switch
233 when 'e' =>
234 Ptr := Ptr + 1;
235 Elab_Dependency_Output := True;
237 -- Processing for E switch
239 when 'E' =>
240 Ptr := Ptr + 1;
241 Exception_Tracebacks := True;
243 -- Processing for F switch
245 when 'F' =>
246 Ptr := Ptr + 1;
247 Force_Checking_Of_Elaboration_Flags := True;
249 -- Processing for g switch
251 when 'g' =>
252 Ptr := Ptr + 1;
254 if Ptr <= Max then
255 C := Switch_Chars (Ptr);
257 if C in '0' .. '3' then
258 Debugger_Level :=
259 Character'Pos
260 (Switch_Chars (Ptr)) - Character'Pos ('0');
261 Ptr := Ptr + 1;
262 end if;
264 else
265 Debugger_Level := 2;
266 end if;
268 -- Processing for h switch
270 when 'h' =>
271 Ptr := Ptr + 1;
272 Usage_Requested := True;
274 -- Processing for H switch
276 when 'H' =>
277 if Ptr = Max then
278 Bad_Switch (Switch_Chars);
279 end if;
281 Ptr := Ptr + 1;
282 Scan_Nat (Switch_Chars, Max, Ptr, Heap_Size, C);
284 if Heap_Size /= 32 and then Heap_Size /= 64 then
285 Bad_Switch (Switch_Chars);
286 end if;
288 -- Processing for i switch
290 when 'i' =>
291 if Ptr = Max then
292 Bad_Switch (Switch_Chars);
293 end if;
295 Ptr := Ptr + 1;
296 C := Switch_Chars (Ptr);
298 if C in '1' .. '5'
299 or else C = '8'
300 or else C = 'p'
301 or else C = 'f'
302 or else C = 'n'
303 or else C = 'w'
304 then
305 Identifier_Character_Set := C;
306 Ptr := Ptr + 1;
307 else
308 Bad_Switch (Switch_Chars);
309 end if;
311 -- Processing for K switch
313 when 'K' =>
314 Ptr := Ptr + 1;
315 Output_Linker_Option_List := True;
317 -- Processing for l switch
319 when 'l' =>
320 Ptr := Ptr + 1;
321 Elab_Order_Output := True;
323 -- Processing for m switch
325 when 'm' =>
326 if Ptr = Max then
327 Bad_Switch (Switch_Chars);
328 end if;
330 Ptr := Ptr + 1;
331 Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Messages, C);
333 -- Processing for n switch
335 when 'n' =>
336 Ptr := Ptr + 1;
337 Bind_Main_Program := False;
339 -- Note: The -L option of the binder also implies -n, so
340 -- any change here must also be reflected in the processing
341 -- for -L that is found in Gnatbind.Scan_Bind_Arg.
343 -- Processing for o switch
345 when 'o' =>
346 Ptr := Ptr + 1;
348 if Output_File_Name_Present then
349 Osint.Fail ("duplicate -o switch");
350 else
351 Output_File_Name_Present := True;
352 end if;
354 -- Processing for O switch
356 when 'O' =>
357 Ptr := Ptr + 1;
358 Output_Object_List := True;
359 Object_List_Filename := Get_Optional_Filename;
361 -- Processing for p switch
363 when 'p' =>
364 Ptr := Ptr + 1;
365 Pessimistic_Elab_Order := True;
367 -- Processing for q switch
369 when 'q' =>
370 Ptr := Ptr + 1;
371 Quiet_Output := True;
373 -- Processing for r switch
375 when 'r' =>
376 Ptr := Ptr + 1;
377 List_Restrictions := True;
379 -- Processing for R switch
381 when 'R' =>
382 Ptr := Ptr + 1;
383 List_Closure := True;
385 -- Processing for s switch
387 when 's' =>
388 Ptr := Ptr + 1;
389 All_Sources := True;
390 Check_Source_Files := True;
392 -- Processing for t switch
394 when 't' =>
395 Ptr := Ptr + 1;
396 Tolerate_Consistency_Errors := True;
398 -- Processing for T switch
400 when 'T' =>
401 if Ptr = Max then
402 Bad_Switch (Switch_Chars);
403 end if;
405 Ptr := Ptr + 1;
406 Time_Slice_Set := True;
407 Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value, C);
408 Time_Slice_Value := Time_Slice_Value * 1_000;
410 -- Processing for u switch
412 when 'u' =>
413 if Ptr = Max then
414 Bad_Switch (Switch_Chars);
415 end if;
417 Ptr := Ptr + 1;
418 Dynamic_Stack_Measurement := True;
419 Scan_Nat
420 (Switch_Chars,
421 Max,
422 Ptr,
423 Dynamic_Stack_Measurement_Array_Size,
426 -- Processing for v switch
428 when 'v' =>
429 Ptr := Ptr + 1;
430 Verbose_Mode := True;
432 -- Processing for w switch
434 when 'w' =>
435 if Ptr = Max then
436 Bad_Switch (Switch_Chars);
437 end if;
439 -- For the binder we only allow suppress/error cases
441 Ptr := Ptr + 1;
443 case Switch_Chars (Ptr) is
444 when 'e' =>
445 Warning_Mode := Treat_As_Error;
447 when 's' =>
448 Warning_Mode := Suppress;
450 when others =>
451 Bad_Switch (Switch_Chars);
452 end case;
454 Ptr := Ptr + 1;
456 -- Processing for W switch
458 when 'W' =>
459 Ptr := Ptr + 1;
461 if Ptr > Max then
462 Bad_Switch (Switch_Chars);
463 end if;
465 begin
466 Wide_Character_Encoding_Method :=
467 Get_WC_Encoding_Method (Switch_Chars (Ptr));
468 exception
469 when Constraint_Error =>
470 Bad_Switch (Switch_Chars);
471 end;
473 Wide_Character_Encoding_Method_Specified := True;
475 Upper_Half_Encoding :=
476 Wide_Character_Encoding_Method in WC_Upper_Half_Encoding_Method;
478 Ptr := Ptr + 1;
480 -- Processing for x switch
482 when 'x' =>
483 Ptr := Ptr + 1;
484 All_Sources := False;
485 Check_Source_Files := False;
487 -- Processing for X switch
489 when 'X' =>
490 if Ptr = Max then
491 Bad_Switch (Switch_Chars);
492 end if;
494 Ptr := Ptr + 1;
495 Scan_Pos (Switch_Chars, Max, Ptr, Default_Exit_Status, C);
497 -- Processing for y switch
499 when 'y' =>
500 Ptr := Ptr + 1;
501 Leap_Seconds_Support := True;
503 -- Processing for z switch
505 when 'z' =>
506 Ptr := Ptr + 1;
507 No_Main_Subprogram := True;
509 -- Processing for Z switch
511 when 'Z' =>
512 Ptr := Ptr + 1;
513 Zero_Formatting := True;
515 -- Processing for --RTS
517 when '-' =>
519 if Ptr + 4 <= Max and then
520 Switch_Chars (Ptr + 1 .. Ptr + 3) = "RTS"
521 then
522 Ptr := Ptr + 4;
524 if Switch_Chars (Ptr) /= '=' or else Ptr = Max then
525 Osint.Fail ("missing path for --RTS");
527 else
528 -- Valid --RTS switch
530 Opt.No_Stdinc := True;
531 Opt.RTS_Switch := True;
533 declare
534 Src_Path_Name : constant String_Ptr :=
535 Get_RTS_Search_Dir
536 (Switch_Chars
537 (Ptr + 1 .. Switch_Chars'Last),
538 Include);
539 Lib_Path_Name : constant String_Ptr :=
540 Get_RTS_Search_Dir
541 (Switch_Chars
542 (Ptr + 1 .. Switch_Chars'Last),
543 Objects);
545 begin
546 if Src_Path_Name /= null and then
547 Lib_Path_Name /= null
548 then
549 -- Set the RTS_*_Path_Name variables, so that the
550 -- correct directories will be set when a subsequent
551 -- call Osint.Add_Default_Search_Dirs is made.
553 RTS_Src_Path_Name := Src_Path_Name;
554 RTS_Lib_Path_Name := Lib_Path_Name;
556 Ptr := Max + 1;
558 elsif Src_Path_Name = null
559 and then Lib_Path_Name = null
560 then
561 Osint.Fail ("RTS path not valid: missing " &
562 "adainclude and adalib directories");
563 elsif Src_Path_Name = null then
564 Osint.Fail ("RTS path not valid: missing " &
565 "adainclude directory");
566 elsif Lib_Path_Name = null then
567 Osint.Fail ("RTS path not valid: missing " &
568 "adalib directory");
569 end if;
570 end;
571 end if;
573 else
574 Bad_Switch (Switch_Chars);
575 end if;
577 -- Anything else is an error (illegal switch character)
579 when others =>
580 Bad_Switch (Switch_Chars);
581 end case;
583 if Ptr <= Max then
584 Bad_Switch (Switch_Chars);
585 end if;
586 end Check_Switch;
587 end Scan_Binder_Switches;
589 end Switch.B;