diff options
author | Geert Bosch <bosch@gnat.com> | 2002-03-08 23:49:35 +0100 |
---|---|---|
committer | Geert Bosch <bosch@gcc.gnu.org> | 2002-03-08 23:49:35 +0100 |
commit | 43ff454717964426d77fde0a0e94d29ac664a707 (patch) | |
tree | e1966bb24cb5ddb58313cbf62e39a664a3776d73 /gcc/ada/switch-m.adb | |
parent | 4ec59de224960b41e45d957802bc30f46c78418c (diff) | |
download | gcc-43ff454717964426d77fde0a0e94d29ac664a707.zip gcc-43ff454717964426d77fde0a0e94d29ac664a707.tar.gz gcc-43ff454717964426d77fde0a0e94d29ac664a707.tar.bz2 |
adadecode.c, [...]: New files.
* adadecode.c, adadecode.h, aux-io.c, s-traces.adb, s-traces.ads,
s-tratas.adb, s-tratas.ads, sinput-d.adb, sinput-d.ads,
switch-b.adb, switch-b.ads, switch-c.adb, switch-c.ads,
switch-m.adb, switch-m.ads : New files.
From-SVN: r50466
Diffstat (limited to 'gcc/ada/switch-m.adb')
-rw-r--r-- | gcc/ada/switch-m.adb | 591 |
1 files changed, 591 insertions, 0 deletions
diff --git a/gcc/ada/switch-m.adb b/gcc/ada/switch-m.adb new file mode 100644 index 0000000..ec08a6d --- /dev/null +++ b/gcc/ada/switch-m.adb @@ -0,0 +1,591 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S W I T C H - M -- +-- -- +-- B o d y -- +-- -- +-- $Revision$ +-- -- +-- Copyright (C) 2001-2002 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, 59 Temple Place - Suite 330, Boston, -- +-- MA 02111-1307, USA. -- +-- -- +-- 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). -- +-- -- +------------------------------------------------------------------------------ + +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.C.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 := ' '; + + First_Char : Integer := Ptr; + 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 : 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 + First_Char := Ptr; + 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 + + Add_Switch_Component (Switch_Chars); + return; + + when True => + + case C is + + -- One-letter switches + + when 'a' | 'A' | 'b' | 'c' | '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' => + -- None of the -gnate switches (-gnatec and -gnatem) + -- need to be store in an ALI file. + + 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; + + -- 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 : Integer := Switch_Chars'Last; + C : Character := ' '; + + begin + -- Skip past the initial character (must be the switch character) + + if Ptr = Max then + raise Bad_Switch; + + 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 + + while Ptr <= Max loop + 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; + + -- Processing for c switch + + when 'c' => + Ptr := Ptr + 1; + Compile_Only := True; + + -- Processing for C switch + + when 'C' => + Ptr := Ptr + 1; + Create_Mapping_File := True; + + -- 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 + raise Bad_Switch; + end if; + end loop; + + -- Make sure Zero_Cost_Exceptions is set if gnatdX set. This + -- is for backwards compatibility with old versions and usage. + + if Debug_Flag_XX then + Zero_Cost_Exceptions_Set := True; + Zero_Cost_Exceptions_Val := True; + end if; + + return; + + -- Processing for f switch + + when 'f' => + Ptr := Ptr + 1; + Force_Compilations := 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); + 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; + + 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 + raise Too_Many_Output_Files; + else + Output_File_Name_Present := True; + end if; + + -- Processing for q switch + + when 'q' => + Ptr := Ptr + 1; + Quiet_Output := True; + + -- Processing for s switch + + when 's' => + Ptr := Ptr + 1; + Check_Switches := True; + + -- Processing for v switch + + when 'v' => + Ptr := Ptr + 1; + Verbose_Mode := 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 => + raise Bad_Switch; + + 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"); + + end Scan_Make_Switches; + +end Switch.M; |