OSDN Git Service

2010-10-05 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / switch-b.adb
index c442e6a..b41296b 100644 (file)
@@ -6,29 +6,27 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                            $Revision$
---                                                                          --
---          Copyright (C) 2001-2002 Free Software Foundation, Inc.          --
+--          Copyright (C) 2001-2010, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- 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.                                                      --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
--- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with Debug;    use Debug;
-with Osint;    use Osint;
-with Opt;      use Opt;
+with Debug;  use Debug;
+with Osint;  use Osint;
+with Opt;    use Opt;
+with Output; use Output;
 
 with System.WCh_Con; use System.WCh_Con;
 
@@ -39,43 +37,122 @@ package body Switch.B is
    --------------------------
 
    procedure Scan_Binder_Switches (Switch_Chars : String) is
-      Ptr : Integer := Switch_Chars'First;
-      Max : Integer := Switch_Chars'Last;
-      C   : Character := ' ';
+      Max : constant Integer := Switch_Chars'Last;
+      Ptr : Integer          := Switch_Chars'First;
+      C   : Character        := ' ';
+
+      function Get_Optional_Filename return String_Ptr;
+      --  If current character is '=', return a newly allocated string that
+      --  contains the remainder of the current switch (after the '='), else
+      --  return null.
+
+      function Get_Stack_Size (S : Character) return Int;
+      --  Used for -d and -D to scan stack size including handling k/m. S is
+      --  set to 'd' or 'D' to indicate the switch being scanned.
+
+      ---------------------------
+      -- Get_Optional_Filename --
+      ---------------------------
+
+      function Get_Optional_Filename return String_Ptr is
+         Result : String_Ptr;
+
+      begin
+         if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            else
+               Result := new String'(Switch_Chars (Ptr + 1 .. Max));
+               Ptr := Max + 1;
+               return Result;
+            end if;
+         end if;
+
+         return null;
+      end Get_Optional_Filename;
+
+      --------------------
+      -- Get_Stack_Size --
+      --------------------
+
+      function Get_Stack_Size (S : Character) return Int is
+         Result : Int;
+
+      begin
+         Scan_Pos (Switch_Chars, Max, Ptr, Result, S);
+
+         --  In the following code, we enable overflow checking since the
+         --  multiplication by K or M may cause overflow, which is an error.
+
+         declare
+            pragma Unsuppress (Overflow_Check);
+
+         begin
+            --  Check for additional character 'k' (for kilobytes) or 'm' (for
+            --  Megabytes), but only if we have not reached the end of the
+            --  switch string. Note that if this appears before the end of the
+            --  string we will get an error when we test to make sure that the
+            --  string is exhausted (at the end of the case).
+
+            if Ptr <= Max then
+               if Switch_Chars (Ptr) = 'k' then
+                  Result := Result * 1024;
+                  Ptr := Ptr + 1;
+
+               elsif Switch_Chars (Ptr) = 'm' then
+                  Result := Result * (1024 * 1024);
+                  Ptr := Ptr + 1;
+               end if;
+            end if;
+
+         exception
+            when Constraint_Error =>
+               Osint.Fail ("numeric value out of range for switch: " & S);
+         end;
+
+         return Result;
+      end Get_Stack_Size;
+
+   --  Start of processing for Scan_Binder_Switches
 
    begin
       --  Skip past the initial character (must be the switch character)
 
       if Ptr = Max then
-         raise Bad_Switch;
+         Bad_Switch (Switch_Chars);
       else
          Ptr := Ptr + 1;
       end if;
 
-      --  A little check, "gnat" at the start of a switch is not allowed
-      --  except for the compiler
+      --  A little check, "gnat" at the start of a switch is not allowed except
+      --  for the compiler
 
       if Switch_Chars'Last >= Ptr + 3
         and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
       then
-         Osint.Fail ("invalid switch: """, Switch_Chars, """"
-            & " (gnat not needed here)");
-
+         Osint.Fail ("invalid switch: """ & Switch_Chars & """"
+                     & " (gnat not needed here)");
       end if;
 
       --  Loop to scan through switches given in switch string
 
-      while Ptr <= Max loop
+      Check_Switch : begin
          C := Switch_Chars (Ptr);
 
          case C is
 
+         --  Processing for a switch
+
+         when 'a' =>
+            Ptr := Ptr + 1;
+            Use_Pragma_Linker_Constructor := True;
+
          --  Processing for A switch
 
          when 'A' =>
             Ptr := Ptr + 1;
-
-            Ada_Bind_File := True;
+            Output_ALI_List := True;
+            ALI_List_Filename := Get_Optional_Filename;
 
          --  Processing for b switch
 
@@ -87,52 +164,69 @@ package body Switch.B is
 
          when 'c' =>
             Ptr := Ptr + 1;
-
             Check_Only := True;
 
          --  Processing for C switch
 
          when 'C' =>
             Ptr := Ptr + 1;
-
             Ada_Bind_File := False;
 
+            Write_Line ("warning: gnatbind switch -C is obsolescent");
+
          --  Processing for d switch
 
          when 'd' =>
 
-            --  Note: for the debug switch, the remaining characters in this
-            --  switch field must all be debug flags, since all valid switch
-            --  characters are also valid debug characters. This switch is not
-            --  documented on purpose because it is only used by the
-            --  implementors.
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            end if;
 
-            --  Loop to scan out debug flags
+            Ptr := Ptr + 1;
+            C := Switch_Chars (Ptr);
 
-            while Ptr < Max loop
-               Ptr := Ptr + 1;
-               C := Switch_Chars (Ptr);
-               exit when C = ASCII.NUL or else C = '/' or else C = '-';
+            --  Case where character after -d is a digit (default stack size)
 
-               if C in '1' .. '9' or else
-                  C in 'a' .. 'z' or else
-                  C in 'A' .. 'Z'
-               then
-                  Set_Debug_Flag (C);
-               else
-                  raise Bad_Switch;
-               end if;
-            end loop;
+            if C in '0' .. '9' then
+
+               --  In this case, we process the default primary stack size
+
+               Default_Stack_Size := Get_Stack_Size ('d');
+
+            --  Case where character after -d is not digit (debug flags)
+
+            else
+               --  Note: for the debug switch, the remaining characters in this
+               --  switch field must all be debug flags, since all valid switch
+               --  characters are also valid debug characters. This switch is
+               --  not documented on purpose because it is only used by the
+               --  implementors.
 
-            --  Make sure Zero_Cost_Exceptions is set if gnatdX set. This
-            --  is for backwards compatibility with old versions and usage.
+               --  Loop to scan out debug flags
 
-            if Debug_Flag_XX then
-               Zero_Cost_Exceptions_Set := True;
-               Zero_Cost_Exceptions_Val := True;
+               loop
+                  C := Switch_Chars (Ptr);
+
+                  if C in 'a' .. 'z' or else C in 'A' .. 'Z' then
+                     Set_Debug_Flag (C);
+                  else
+                     Bad_Switch (Switch_Chars);
+                  end if;
+
+                  Ptr := Ptr + 1;
+                  exit when Ptr > Max;
+               end loop;
             end if;
 
-            return;
+         --  Processing for D switch
+
+         when 'D' =>
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            end if;
+
+            Ptr := Ptr + 1;
+            Default_Sec_Stack_Size := Get_Stack_Size ('D');
 
          --  Processing for e switch
 
@@ -146,11 +240,11 @@ package body Switch.B is
             Ptr := Ptr + 1;
             Exception_Tracebacks := True;
 
-         --  Processing for f switch
+         --  Processing for F switch
 
-         when 'f' =>
+         when 'F' =>
             Ptr := Ptr + 1;
-            Force_RM_Elaboration_Order := True;
+            Force_Checking_Of_Elaboration_Flags := True;
 
          --  Processing for g switch
 
@@ -177,17 +271,31 @@ package body Switch.B is
             Ptr := Ptr + 1;
             Usage_Requested := True;
 
+         --  Processing for H switch
+
+         when 'H' =>
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            end if;
+
+            Ptr := Ptr + 1;
+            Scan_Nat (Switch_Chars, Max, Ptr, Heap_Size, C);
+
+            if Heap_Size /= 32 and then Heap_Size /= 64 then
+               Bad_Switch (Switch_Chars);
+            end if;
+
          --  Processing for i switch
 
          when 'i' =>
             if Ptr = Max then
-               raise Bad_Switch;
+               Bad_Switch (Switch_Chars);
             end if;
 
             Ptr := Ptr + 1;
             C := Switch_Chars (Ptr);
 
-            if C in  '1' .. '5'
+            if C in '1' .. '5'
               or else C = '8'
               or else C = 'p'
               or else C = 'f'
@@ -197,7 +305,7 @@ package body Switch.B is
                Identifier_Character_Set := C;
                Ptr := Ptr + 1;
             else
-               raise Bad_Switch;
+               Bad_Switch (Switch_Chars);
             end if;
 
          --  Processing for K switch
@@ -215,8 +323,12 @@ package body Switch.B is
          --  Processing for m switch
 
          when 'm' =>
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            end if;
+
             Ptr := Ptr + 1;
-            Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
+            Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Messages, C);
 
          --  Processing for n switch
 
@@ -234,8 +346,7 @@ package body Switch.B is
             Ptr := Ptr + 1;
 
             if Output_File_Name_Present then
-               raise Too_Many_Output_Files;
-
+               Osint.Fail ("duplicate -o switch");
             else
                Output_File_Name_Present := True;
             end if;
@@ -245,6 +356,7 @@ package body Switch.B is
          when 'O' =>
             Ptr := Ptr + 1;
             Output_Object_List := True;
+            Object_List_Filename := Get_Optional_Filename;
 
          --  Processing for p switch
 
@@ -264,6 +376,12 @@ package body Switch.B is
             Ptr := Ptr + 1;
             List_Restrictions := True;
 
+         --  Processing for R switch
+
+         when 'R' =>
+            Ptr := Ptr + 1;
+            List_Closure := True;
+
          --  Processing for s switch
 
          when 's' =>
@@ -280,9 +398,30 @@ package body Switch.B is
          --  Processing for T switch
 
          when 'T' =>
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            end if;
+
             Ptr := Ptr + 1;
             Time_Slice_Set := True;
-            Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value);
+            Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value, C);
+            Time_Slice_Value := Time_Slice_Value * 1_000;
+
+         --  Processing for u switch
+
+         when 'u' =>
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            end if;
+
+            Ptr := Ptr + 1;
+            Dynamic_Stack_Measurement := True;
+            Scan_Nat
+              (Switch_Chars,
+               Max,
+               Ptr,
+               Dynamic_Stack_Measurement_Array_Size,
+               C);
 
          --  Processing for v switch
 
@@ -293,21 +432,23 @@ package body Switch.B is
          --  Processing for w switch
 
          when 'w' =>
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            end if;
 
             --  For the binder we only allow suppress/error cases
 
             Ptr := Ptr + 1;
 
             case Switch_Chars (Ptr) is
-
                when 'e' =>
-                  Warning_Mode  := Treat_As_Error;
+                  Warning_Mode := Treat_As_Error;
 
                when 's' =>
-                  Warning_Mode  := Suppress;
+                  Warning_Mode := Suppress;
 
                when others =>
-                  raise Bad_Switch;
+                  Bad_Switch (Switch_Chars);
             end case;
 
             Ptr := Ptr + 1;
@@ -317,19 +458,22 @@ package body Switch.B is
          when 'W' =>
             Ptr := Ptr + 1;
 
-            for J in WC_Encoding_Method loop
-               if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
-                  Wide_Character_Encoding_Method := J;
-                  exit;
+            if Ptr > Max then
+               Bad_Switch (Switch_Chars);
+            end if;
 
-               elsif J = WC_Encoding_Method'Last then
-                  raise Bad_Switch;
-               end if;
-            end loop;
+            begin
+               Wide_Character_Encoding_Method :=
+                 Get_WC_Encoding_Method (Switch_Chars (Ptr));
+            exception
+               when Constraint_Error =>
+                  Bad_Switch (Switch_Chars);
+            end;
+
+            Wide_Character_Encoding_Method_Specified := True;
 
             Upper_Half_Encoding :=
-              Wide_Character_Encoding_Method in
-                WC_Upper_Half_Encoding_Method;
+              Wide_Character_Encoding_Method in WC_Upper_Half_Encoding_Method;
 
             Ptr := Ptr + 1;
 
@@ -340,54 +484,80 @@ package body Switch.B is
             All_Sources := False;
             Check_Source_Files := False;
 
+         --  Processing for X switch
+
+         when 'X' =>
+            if Ptr = Max then
+               Bad_Switch (Switch_Chars);
+            end if;
+
+            Ptr := Ptr + 1;
+            Scan_Pos (Switch_Chars, Max, Ptr, Default_Exit_Status, C);
+
+         --  Processing for y switch
+
+         when 'y' =>
+            Ptr := Ptr + 1;
+            Leap_Seconds_Support := True;
+
          --  Processing for z switch
 
          when 'z' =>
             Ptr := Ptr + 1;
             No_Main_Subprogram := True;
 
-         --  Ignore extra switch character
+         --  Processing for Z switch
 
-         when '/'  =>
+         when 'Z' =>
             Ptr := Ptr + 1;
+            Zero_Formatting := True;
 
-         --  Ignore '-' extra switch caracter, only if it isn't followed by
-         --  'RTS'. If it is, then we must process the 'RTS' switch
+         --  Processing for --RTS
 
          when '-' =>
 
-            if Ptr + 3 <= Max and then
+            if Ptr + 4 <= Max and then
               Switch_Chars (Ptr + 1 .. Ptr + 3) = "RTS"
             then
-               Ptr := Ptr + 1;
+               Ptr := Ptr + 4;
 
-               if Switch_Chars (Ptr + 3) /= '=' or else
-                 (Switch_Chars (Ptr + 3) = '='
-                  and then Ptr + 4 > Max)
-               then
+               if Switch_Chars (Ptr) /= '=' or else Ptr = Max then
                   Osint.Fail ("missing path for --RTS");
+
                else
+                  --  Valid --RTS switch
 
-                  --  valid --RTS switch
                   Opt.No_Stdinc := True;
                   Opt.RTS_Switch := True;
 
                   declare
-                     Src_Path_Name : String_Ptr := Get_RTS_Search_Dir
-                       (Switch_Chars (Ptr + 4 .. Switch_Chars'Last), Include);
-                     Lib_Path_Name : String_Ptr := Get_RTS_Search_Dir
-                       (Switch_Chars (Ptr + 4 .. Switch_Chars'Last), Objects);
+                     Src_Path_Name : constant String_Ptr :=
+                                       Get_RTS_Search_Dir
+                                         (Switch_Chars
+                                           (Ptr + 1 .. Switch_Chars'Last),
+                                          Include);
+                     Lib_Path_Name : constant String_Ptr :=
+                                       Get_RTS_Search_Dir
+                                         (Switch_Chars
+                                           (Ptr + 1 .. Switch_Chars'Last),
+                                          Objects);
+
                   begin
                      if Src_Path_Name /= null and then
                        Lib_Path_Name /= null
                      then
-                        Add_Search_Dirs (Src_Path_Name, Include);
-                        Add_Search_Dirs (Lib_Path_Name, Objects);
-                        --  we can exit as there can not be another switch
-                        --  after --RTS
-                        exit;
+                        --  Set the RTS_*_Path_Name variables, so that the
+                        --  correct directories will be set when a subsequent
+                        --  call Osint.Add_Default_Search_Dirs is made.
+
+                        RTS_Src_Path_Name := Src_Path_Name;
+                        RTS_Lib_Path_Name := Lib_Path_Name;
+
+                        Ptr := Max + 1;
+
                      elsif  Src_Path_Name = null
-                       and Lib_Path_Name = null then
+                       and then Lib_Path_Name = null
+                     then
                         Osint.Fail ("RTS path not valid: missing " &
                                     "adainclude and adalib directories");
                      elsif Src_Path_Name = null then
@@ -401,28 +571,19 @@ package body Switch.B is
                end if;
 
             else
-               Ptr := Ptr + 1;
+               Bad_Switch (Switch_Chars);
             end if;
 
          --  Anything else is an error (illegal switch character)
 
          when others =>
-            raise Bad_Switch;
+            Bad_Switch (Switch_Chars);
          end case;
-      end loop;
-
-   exception
-      when Bad_Switch =>
-         Osint.Fail ("invalid switch: ", (1 => C));
-
-      when Bad_Switch_Value =>
-         Osint.Fail ("numeric value too big for switch: ", (1 => C));
-
-      when Missing_Switch_Value =>
-         Osint.Fail ("missing numeric value for switch: ", (1 => C));
 
-      when Too_Many_Output_Files =>
-         Osint.Fail ("duplicate -o switch");
+         if Ptr <= Max then
+            Bad_Switch (Switch_Chars);
+         end if;
+      end Check_Switch;
    end Scan_Binder_Switches;
 
 end Switch.B;