OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [ada/] [switch-m.adb] - Rev 16

Go to most recent revision | Compare with Previous | Blame | View Log

------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S W I T C H - M                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2001-2005 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- --
-- 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,  51  Franklin  Street,  Fifth  Floor, --
-- Boston, MA 02110-1301, USA.                                              --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------
 
with Debug;    use Debug;
with Osint;    use Osint;
with Opt;      use Opt;
with Table;
 
package body Switch.M is
 
   package Normalized_Switches is new Table.Table
     (Table_Component_Type => String_Access,
      Table_Index_Type     => Integer,
      Table_Low_Bound      => 1,
      Table_Initial        => 20,
      Table_Increment      => 100,
      Table_Name           => "Switch.M.Normalized_Switches");
   --  This table is used to keep the normalized switches, so that they may be
   --  reused for subsequent invocations of Normalize_Compiler_Switches with
   --  similar switches.
 
   Initial_Number_Of_Switches : constant := 10;
 
   Global_Switches : Argument_List_Access := null;
   --  Used by function Normalize_Compiler_Switches
 
   ---------------------------------
   -- Normalize_Compiler_Switches --
   ---------------------------------
 
   procedure Normalize_Compiler_Switches
     (Switch_Chars : String;
      Switches     : in out Argument_List_Access;
      Last         : out Natural)
   is
      Switch_Starts_With_Gnat : Boolean;
 
      Ptr : Integer := Switch_Chars'First;
      Max : constant Integer := Switch_Chars'Last;
      C   : Character := ' ';
 
      Storing      : String := Switch_Chars;
      First_Stored : Positive := Ptr + 1;
      Last_Stored  : Positive := First_Stored;
 
      procedure Add_Switch_Component (S : String);
      --  Add a new String_Access component in Switches. If a string equal
      --  to S is already stored in the table Normalized_Switches, use it.
      --  Other wise add a new component to the table.
 
      --------------------------
      -- Add_Switch_Component --
      --------------------------
 
      procedure Add_Switch_Component (S : String) is
      begin
         --  If Switches is null, allocate a new array
 
         if Switches = null then
            Switches := new Argument_List (1 .. Initial_Number_Of_Switches);
 
         --  otherwise, if Switches is full, extend it
 
         elsif Last = Switches'Last then
            declare
               New_Switches : constant Argument_List_Access :=
                                new Argument_List
                                      (1 .. Switches'Length + Switches'Length);
            begin
               New_Switches (1 .. Switches'Length) := Switches.all;
               Last := Switches'Length;
               Switches := New_Switches;
            end;
         end if;
 
         --  If this is the first switch, Last designates the first component
 
         if Last = 0 then
            Last := Switches'First;
         else
            Last := Last + 1;
         end if;
 
         --  Look into the table Normalized_Switches for a similar string.
         --  If one is found, put it at the added component, and return.
 
         for Index in 1 .. Normalized_Switches.Last loop
            if S = Normalized_Switches.Table (Index).all then
               Switches (Last) := Normalized_Switches.Table (Index);
               return;
            end if;
         end loop;
 
         --  No string equal to S was found in the table Normalized_Switches.
         --  Add a new component in the table.
 
         Switches (Last) := new String'(S);
         Normalized_Switches.Increment_Last;
         Normalized_Switches.Table (Normalized_Switches.Last) :=
           Switches (Last);
      end Add_Switch_Component;
 
   --  Start of processing for Normalize_Compiler_Switches
 
   begin
      Last := 0;
 
      if Ptr = Max or else Switch_Chars (Ptr) /= '-' then
         return;
      end if;
 
      Ptr := Ptr + 1;
 
      Switch_Starts_With_Gnat :=
         Ptr + 3 <= Max and then Switch_Chars (Ptr .. Ptr + 3) = "gnat";
 
      if Switch_Starts_With_Gnat then
         Ptr := Ptr + 4;
         First_Stored := Ptr;
      end if;
 
      while Ptr <= Max loop
         C := Switch_Chars (Ptr);
 
         --  Processing for a switch
 
         case Switch_Starts_With_Gnat is
 
            when False =>
 
               --  All switches that don't start with -gnat stay as is,
               --  except -v and -pg
 
               if Switch_Chars = "-pg" then
 
                  --  The gcc driver converts -pg to -p, so that is what
                  --  is stored in the ALI file.
 
                  Add_Switch_Component ("-p");
 
               elsif C /= 'v' then
                  Add_Switch_Component (Switch_Chars);
               end if;
 
               return;
 
            when True =>
 
               case C is
 
                  --  One-letter switches
 
                  when 'a' | 'A' | 'b' | 'c' | 'D' | 'E' | 'f' |
                    'F' | 'g' | 'h' | 'H' | 'k' | 'l' | 'L' | 'n' | 'N' |
                    'o' | 'O' | 'p' | 'P' | 'q' | 'Q' | 'r' | 's' | 't' |
                    'u' | 'U' | 'v' | 'x' | 'X' | 'Z' =>
                     Storing (First_Stored) := C;
                     Add_Switch_Component
                       (Storing (Storing'First .. First_Stored));
                     Ptr := Ptr + 1;
 
                  --  One-letter switches followed by a positive number
 
                  when 'm' | 'T' =>
                     Storing (First_Stored) := C;
                     Last_Stored := First_Stored;
 
                     loop
                        Ptr := Ptr + 1;
                        exit when Ptr > Max
                          or else Switch_Chars (Ptr) not in '0' .. '9';
                        Last_Stored := Last_Stored + 1;
                        Storing (Last_Stored) := Switch_Chars (Ptr);
                     end loop;
 
                     Add_Switch_Component
                       (Storing (Storing'First .. Last_Stored));
 
                  when 'd' =>
                     Storing (First_Stored) := 'd';
 
                     while Ptr < Max loop
                        Ptr := Ptr + 1;
                        C := Switch_Chars (Ptr);
                        exit when C = ASCII.NUL or else C = '/'
                          or else C = '-';
 
                        if C in '1' .. '9' or else
                           C in 'a' .. 'z' or else
                           C in 'A' .. 'Z'
                        then
                           Storing (First_Stored + 1) := C;
                           Add_Switch_Component
                             (Storing (Storing'First .. First_Stored + 1));
 
                        else
                           Last := 0;
                           return;
                        end if;
                     end loop;
 
                     return;
 
                  when 'e' =>
 
                     --  Only -gnateD and -gnatep= need storing in ALI file
 
                     Storing (First_Stored) := 'e';
                     Ptr := Ptr + 1;
 
                     if Ptr > Max
                       or else (Switch_Chars (Ptr) /= 'D'
                                  and then Switch_Chars (Ptr) /= 'p')
                     then
                        Last := 0;
                        return;
                     end if;
 
                     --  Processing for -gnateD
 
                     if Switch_Chars (Ptr) = 'D' then
                        Storing (First_Stored + 1 ..
                                 First_Stored + Max - Ptr + 1) :=
                          Switch_Chars (Ptr .. Max);
                        Add_Switch_Component
                          (Storing (Storing'First ..
                                      First_Stored + Max - Ptr + 1));
 
                     --  Processing for -gnatep=
 
                     else
                        Ptr := Ptr + 1;
 
                        if Ptr = Max then
                           Last := 0;
                           return;
                        end if;
 
                        if Switch_Chars (Ptr) = '=' then
                           Ptr := Ptr + 1;
                        end if;
 
                        --  To normalize, always put a '=' after -gnatep.
                        --  Because that could lengthen the switch string,
                        --  declare a local variable.
 
                        declare
                           To_Store : String (1 .. Max - Ptr + 9);
                        begin
                           To_Store (1 .. 8) := "-gnatep=";
                           To_Store (9 .. Max - Ptr + 9) :=
                             Switch_Chars (Ptr .. Max);
                           Add_Switch_Component (To_Store);
                        end;
                     end if;
 
                     return;
 
                  when 'i' =>
                     Storing (First_Stored) := 'i';
 
                     Ptr := Ptr + 1;
 
                     if Ptr > Max then
                        Last := 0;
                        return;
                     end if;
 
                     C := Switch_Chars (Ptr);
 
                     if C in '1' .. '5'
                       or else C = '8'
                       or else C = 'p'
                       or else C = 'f'
                       or else C = 'n'
                       or else C = 'w'
                     then
                        Storing (First_Stored + 1) := C;
                        Add_Switch_Component
                          (Storing (Storing'First .. First_Stored + 1));
                        Ptr := Ptr + 1;
 
                     else
                        Last := 0;
                        return;
                     end if;
 
                  --  -gnatR may be followed by '0', '1', '2' or '3',
                  --  then by 's'
 
                  when 'R' =>
                     Last_Stored := First_Stored;
                     Storing (Last_Stored) := 'R';
                     Ptr := Ptr + 1;
 
                     if Ptr <= Max
                       and then Switch_Chars (Ptr) in '0' .. '9'
                     then
                        C := Switch_Chars (Ptr);
 
                        if C in '4' .. '9' then
                           Last := 0;
                           return;
 
                        else
                           Last_Stored := Last_Stored + 1;
                           Storing (Last_Stored) := C;
                           Ptr := Ptr + 1;
 
                           if Ptr <= Max
                             and then Switch_Chars (Ptr) = 's' then
                              Last_Stored := Last_Stored + 1;
                              Storing (Last_Stored) := 's';
                              Ptr := Ptr + 1;
                           end if;
                        end if;
                     end if;
 
                     Add_Switch_Component
                       (Storing (Storing'First .. Last_Stored));
 
                  --  Multiple switches
 
                  when 'V' | 'w' | 'y' =>
                     Storing (First_Stored) := C;
                     Ptr := Ptr + 1;
 
                     if Ptr > Max then
                        if C = 'y' then
                           Add_Switch_Component
                             (Storing (Storing'First .. First_Stored));
 
                        else
                           Last := 0;
                           return;
                        end if;
                     end if;
 
                     while Ptr <= Max loop
                        C := Switch_Chars (Ptr);
                        Ptr := Ptr + 1;
 
                        --  'w' should be skipped in -gnatw
 
                        if C /= 'w' or else Storing (First_Stored) /= 'w' then
 
                           --  -gnatyMxxx
 
                           if C = 'M'
                             and then Storing (First_Stored) = 'y' then
                              Last_Stored := First_Stored + 1;
                              Storing (Last_Stored) := 'M';
 
                              while Ptr <= Max loop
                                 C := Switch_Chars (Ptr);
                                 exit when C not in '0' .. '9';
                                 Last_Stored := Last_Stored + 1;
                                 Storing (Last_Stored) := C;
                                 Ptr := Ptr + 1;
                              end loop;
 
                              --  If there is no digit after -gnatyM,
                              --  the switch is invalid.
 
                              if Last_Stored = First_Stored + 1 then
                                 Last := 0;
                                 return;
 
                              else
                                 Add_Switch_Component
                                   (Storing (Storing'First .. Last_Stored));
                              end if;
 
                           --  All other switches are -gnatxx
 
                           else
                              Storing (First_Stored + 1) := C;
                              Add_Switch_Component
                                (Storing (Storing'First .. First_Stored + 1));
                           end if;
                        end if;
                     end loop;
 
                  --  -gnat95 -gnat05
 
                  when '0' | '9' =>
                     Last_Stored := First_Stored;
                     Storing (Last_Stored) := C;
                     Ptr := Ptr + 1;
 
                     if Ptr /= Max or else Switch_Chars (Ptr) /= '5' then
 
                        --  Invalid switch
 
                        Last := 0;
                        return;
 
                     else
                        Last_Stored := Last_Stored + 1;
                        Storing (Last_Stored) := '5';
                        Add_Switch_Component
                          (Storing (Storing'First .. Last_Stored));
                        Ptr := Ptr + 1;
                     end if;
 
                  --  -gnat83
 
                  when '8' =>
                     Last_Stored := First_Stored;
                     Storing (Last_Stored) := '8';
                     Ptr := Ptr + 1;
 
                     if Ptr /= Max or else Switch_Chars (Ptr) /= '3' then
 
                        --  Invalid switch
 
                        Last := 0;
                        return;
 
                     else
                        Last_Stored := Last_Stored + 1;
                        Storing (Last_Stored) := '3';
                        Add_Switch_Component
                          (Storing (Storing'First .. Last_Stored));
                        Ptr := Ptr + 1;
                     end if;
 
                  --  Not a valid switch
 
                  when others =>
                     Last := 0;
                     return;
 
               end case;
 
         end case;
      end loop;
   end Normalize_Compiler_Switches;
 
   function Normalize_Compiler_Switches
     (Switch_Chars : String)
      return         Argument_List
   is
      Last : Natural;
 
   begin
      Normalize_Compiler_Switches (Switch_Chars, Global_Switches, Last);
 
      if Last = 0 then
         return (1 .. 0 => null);
 
      else
         return Global_Switches (Global_Switches'First .. Last);
      end if;
 
   end Normalize_Compiler_Switches;
 
   ------------------------
   -- Scan_Make_Switches --
   ------------------------
 
   procedure Scan_Make_Switches (Switch_Chars : String) is
      Ptr : Integer          := Switch_Chars'First;
      Max : constant Integer := Switch_Chars'Last;
      C   : Character        := ' ';
 
   begin
      --  Skip past the initial character (must be the switch character)
 
      if Ptr = Max then
         Bad_Switch (C);
 
      else
         Ptr := Ptr + 1;
      end if;
 
      --  A little check, "gnat" at the start of a switch is not allowed
      --  except for the compiler (where it was already removed)
 
      if Switch_Chars'Length >= Ptr + 3
        and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
      then
         Osint.Fail
           ("invalid switch: """, Switch_Chars, """ (gnat not needed here)");
      end if;
 
      --  Loop to scan through switches given in switch string
 
      Check_Switch : begin
         C := Switch_Chars (Ptr);
 
         --  Processing for a switch
 
         case C is
 
         when 'a' =>
            Ptr := Ptr + 1;
            Check_Readonly_Files := True;
 
         --  Processing for b switch
 
         when 'b' =>
            Ptr := Ptr + 1;
            Bind_Only  := True;
            Make_Steps := True;
 
         --  Processing for B switch
 
         when 'B' =>
            Ptr := Ptr + 1;
            Build_Bind_And_Link_Full_Project := True;
 
         --  Processing for c switch
 
         when 'c' =>
            Ptr := Ptr + 1;
            Compile_Only := True;
            Make_Steps   := True;
 
         --  Processing for C switch
 
         when 'C' =>
            Ptr := Ptr + 1;
            Create_Mapping_File := True;
 
         --  Processing for D switch
 
         when 'D' =>
            Ptr := Ptr + 1;
 
            if Object_Directory_Present then
               Osint.Fail ("duplicate -D switch");
 
            else
               Object_Directory_Present := True;
            end if;
 
         --  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.
 
            --  Loop to scan out debug flags
 
            while Ptr < Max loop
               Ptr := Ptr + 1;
               C := Switch_Chars (Ptr);
               exit when C = ASCII.NUL or else C = '/' or else C = '-';
 
               if C in '1' .. '9' or else
                  C in 'a' .. 'z' or else
                  C in 'A' .. 'Z'
               then
                  Set_Debug_Flag (C);
               else
                  Bad_Switch (C);
               end if;
            end loop;
 
            return;
 
         --  Processing for e switch
 
         when 'e' =>
            Ptr := Ptr + 1;
 
            if Ptr > Max then
               Bad_Switch (C);
            end if;
 
            case Switch_Chars (Ptr) is
 
               --  processing for eI switch
 
               when 'I' =>
                  Ptr := Ptr + 1;
                  Scan_Pos (Switch_Chars, Max, Ptr, Main_Index, C);
 
               --  processing for eL switch
 
               when 'L' =>
                  Ptr := Ptr + 1;
                  Follow_Links := True;
 
               when others =>
                  Bad_Switch (C);
            end case;
 
         --  Processing for f switch
 
         when 'f' =>
            Ptr := Ptr + 1;
            Force_Compilations := True;
 
         --  Processing for F switch
 
         when 'F' =>
            Ptr := Ptr + 1;
            Full_Path_Name_For_Brief_Errors := True;
 
         --  Processing for h switch
 
         when 'h' =>
            Ptr := Ptr + 1;
            Usage_Requested := True;
 
         --  Processing for i switch
 
         when 'i' =>
            Ptr := Ptr + 1;
            In_Place_Mode := True;
 
         --  Processing for j switch
 
         when 'j' =>
            Ptr := Ptr + 1;
 
            declare
               Max_Proc : Pos;
            begin
               Scan_Pos (Switch_Chars, Max, Ptr, Max_Proc, C);
               Maximum_Processes := Positive (Max_Proc);
            end;
 
         --  Processing for k switch
 
         when 'k' =>
            Ptr := Ptr + 1;
            Keep_Going := True;
 
         --  Processing for l switch
 
         when 'l' =>
            Ptr := Ptr + 1;
            Link_Only  := True;
            Make_Steps := True;
 
         when 'M' =>
            Ptr := Ptr + 1;
            List_Dependencies := True;
 
         --  Processing for n switch
 
         when 'n' =>
            Ptr := Ptr + 1;
            Do_Not_Execute := True;
 
         --  Processing for o switch
 
         when 'o' =>
            Ptr := Ptr + 1;
 
            if Output_File_Name_Present then
               Osint.Fail ("duplicate -o switch");
            else
               Output_File_Name_Present := True;
            end if;
 
         --  Processing for q switch
 
         when 'q' =>
            Ptr := Ptr + 1;
            Quiet_Output := True;
 
         --  Processing for R switch
 
         when 'R' =>
            Ptr := Ptr + 1;
            Run_Path_Option := False;
 
         --  Processing for s switch
 
         when 's' =>
            Ptr := Ptr + 1;
            Check_Switches := True;
 
         --  Processing for v switch
 
         when 'v' =>
            Ptr := Ptr + 1;
            Verbose_Mode := True;
            Verbosity_Level := Opt.High;
 
            if Ptr <= Max then
               case Switch_Chars (Ptr) is
                  when 'l' =>
                     Verbosity_Level := Opt.Low;
 
                  when 'm' =>
                     Verbosity_Level := Opt.Medium;
 
                  when 'h' =>
                     Verbosity_Level := Opt.High;
 
                  when others =>
                     Osint.Fail ("invalid switch: ", Switch_Chars);
               end case;
 
               Ptr := Ptr + 1;
            end if;
 
         --  Processing for x switch
 
         when 'x' =>
            Ptr := Ptr + 1;
            External_Unit_Compilation_Allowed := True;
 
         --  Processing for z switch
 
         when 'z' =>
            Ptr := Ptr + 1;
            No_Main_Subprogram := True;
 
         --  Ignore extra switch character
 
         when '/' | '-' =>
            Ptr := Ptr + 1;
 
         --  Anything else is an error (illegal switch character)
 
         when others =>
            Bad_Switch (C);
 
         end case;
 
         if Ptr <= Max then
            Osint.Fail ("invalid switch: ", Switch_Chars);
         end if;
 
      end Check_Switch;
 
   end Scan_Make_Switches;
 
end Switch.M;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.