OSDN Git Service

2010-01-26 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / scn.adb
index b83be64..9848550 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2005 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2009, 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. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
 
 with Atree;    use Atree;
 with Csets;    use Csets;
+with Hostparm; use Hostparm;
 with Namet;    use Namet;
 with Opt;      use Opt;
+with Output;   use Output;
 with Restrict; use Restrict;
 with Rident;   use Rident;
 with Scans;    use Scans;
@@ -35,18 +36,26 @@ with Sinfo;    use Sinfo;
 with Sinput;   use Sinput;
 with Uintp;    use Uintp;
 
+with GNAT.Byte_Order_Mark; use GNAT.Byte_Order_Mark;
+
+with System.WCh_Con; use System.WCh_Con;
+
 package body Scn is
 
    use ASCII;
 
+   Obsolescent_Check_Flag : Boolean := True;
+   --  Obsolescent check activation. Set to False during integrated
+   --  preprocessing.
+
    Used_As_Identifier : array (Token_Type) of Boolean;
    --  Flags set True if a given keyword is used as an identifier (used to
    --  make sure that we only post an error message for incorrect use of a
    --  keyword as an identifier once for a given keyword).
 
    procedure Check_End_Of_Line;
-   --  Called when end of line encountered. Checks that line is not
-   --  too long, and that other style checks for the end of line are met.
+   --  Called when end of line encountered. Checks that line is not too long,
+   --  and that other style checks for the end of line are met.
 
    function Determine_License return License_Type;
    --  Scan header of file and check that it has an appropriate GNAT-style
@@ -56,45 +65,6 @@ package body Scn is
    procedure Error_Long_Line;
    --  Signal error of excessively long line
 
-   ---------------
-   -- Post_Scan --
-   ---------------
-
-   procedure Post_Scan is
-   begin
-      case Token is
-         when Tok_Char_Literal =>
-            Token_Node := New_Node (N_Character_Literal, Token_Ptr);
-            Set_Char_Literal_Value (Token_Node, UI_From_CC (Character_Code));
-            Set_Chars (Token_Node, Token_Name);
-
-         when Tok_Identifier =>
-            Token_Node := New_Node (N_Identifier, Token_Ptr);
-            Set_Chars (Token_Node, Token_Name);
-
-         when Tok_Real_Literal =>
-            Token_Node := New_Node (N_Real_Literal, Token_Ptr);
-            Set_Realval (Token_Node, Real_Literal_Value);
-
-         when Tok_Integer_Literal =>
-            Token_Node := New_Node (N_Integer_Literal, Token_Ptr);
-            Set_Intval (Token_Node, Int_Literal_Value);
-
-         when Tok_String_Literal =>
-            Token_Node := New_Node (N_String_Literal, Token_Ptr);
-            Set_Has_Wide_Character (Token_Node, Wide_Character_Found);
-            Set_Strval (Token_Node, String_Literal_Id);
-
-         when Tok_Operator_Symbol =>
-            Token_Node := New_Node (N_Operator_Symbol, Token_Ptr);
-            Set_Chars (Token_Node, Token_Name);
-            Set_Strval (Token_Node, String_Literal_Id);
-
-         when others =>
-            null;
-      end case;
-   end Post_Scan;
-
    -----------------------
    -- Check_End_Of_Line --
    -----------------------
@@ -104,7 +74,7 @@ package body Scn is
    begin
       if Style_Check then
          Style.Check_Line_Terminator (Len);
-      elsif Len > Opt.Max_Line_Length then
+      elsif Len > Max_Line_Length then
          Error_Long_Line;
       end if;
    end Check_End_Of_Line;
@@ -266,7 +236,7 @@ package body Scn is
    begin
       Error_Msg
         ("this line is too long",
-         Current_Line_Start + Source_Ptr (Opt.Max_Line_Length));
+         Current_Line_Start + Source_Ptr (Max_Line_Length));
    end Error_Long_Line;
 
    ------------------------
@@ -280,7 +250,13 @@ package body Scn is
       GNAT_Hedr : constant Text_Buffer (1 .. 78) := (others => '-');
 
    begin
-      Scanner.Initialize_Scanner (Unit, Index);
+      Scanner.Initialize_Scanner (Index);
+
+      if Index /= Internal_Source_File then
+         Set_Unit (Index, Unit);
+      end if;
+
+      Current_Source_Unit := Unit;
 
       --  Set default for Comes_From_Source (except if we are going to process
       --  an artificial string internally created within the compiler and
@@ -299,6 +275,46 @@ package body Scn is
          Set_License (Current_Source_File, Determine_License);
       end if;
 
+      --  Check for BOM
+
+      declare
+         BOM : BOM_Kind;
+         Len : Natural;
+         Tst : String (1 .. 5);
+
+      begin
+         for J in 1 .. 5 loop
+            Tst (J) := Source (Scan_Ptr + Source_Ptr (J) - 1);
+         end loop;
+
+         Read_BOM (Tst, Len, BOM, False);
+
+         case BOM is
+            when UTF8_All =>
+               Scan_Ptr := Scan_Ptr + Source_Ptr (Len);
+               Wide_Character_Encoding_Method := WCEM_UTF8;
+               Upper_Half_Encoding := True;
+
+            when UTF16_LE | UTF16_BE =>
+               Set_Standard_Error;
+               Write_Line ("UTF-16 encoding format not recognized");
+               Set_Standard_Output;
+               raise Unrecoverable_Error;
+
+            when UTF32_LE | UTF32_BE =>
+               Set_Standard_Error;
+               Write_Line ("UTF-32 encoding format not recognized");
+               Set_Standard_Output;
+               raise Unrecoverable_Error;
+
+            when Unknown =>
+               null;
+
+            when others =>
+               raise Program_Error;
+         end case;
+      end;
+
       --  Because of the License stuff above, Scng.Initialize_Scanner cannot
       --  call Scan. Scan initial token (note this initializes Prev_Token,
       --  Prev_Token_Ptr).
@@ -317,7 +333,7 @@ package body Scn is
          Scan;
       end if;
 
-      --  Clear flags for reserved words used as indentifiers
+      --  Clear flags for reserved words used as identifiers
 
       for J in Token_Type loop
          Used_As_Identifier (J) := False;
@@ -330,14 +346,59 @@ package body Scn is
 
    procedure Obsolescent_Check (S : Source_Ptr) is
    begin
-      --  This is a pain in the neck case, since we normally need a node to
-      --  call Check_Restrictions, and all we have is a source pointer. The
-      --  easiest thing is to construct a dummy node. A bit kludgy, but this
-      --  is a marginal case. It's not worth trying to do things more cleanly.
-
-      Check_Restriction (No_Obsolescent_Features, New_Node (N_Empty, S));
+      if Obsolescent_Check_Flag then
+         --  This is a pain in the neck case, since we normally need a node to
+         --  call Check_Restrictions, and all we have is a source pointer. The
+         --  easiest thing is to construct a dummy node. A bit kludgy, but this
+         --  is a marginal case. It's not worth trying to do things more
+         --  cleanly.
+
+         Check_Restriction (No_Obsolescent_Features, New_Node (N_Empty, S));
+      end if;
    end Obsolescent_Check;
 
+   ---------------
+   -- Post_Scan --
+   ---------------
+
+   procedure Post_Scan is
+   begin
+      case Token is
+         when Tok_Char_Literal =>
+            Token_Node := New_Node (N_Character_Literal, Token_Ptr);
+            Set_Char_Literal_Value (Token_Node, UI_From_CC (Character_Code));
+            Set_Chars (Token_Node, Token_Name);
+
+         when Tok_Identifier =>
+            Token_Node := New_Node (N_Identifier, Token_Ptr);
+            Set_Chars (Token_Node, Token_Name);
+
+         when Tok_Real_Literal =>
+            Token_Node := New_Node (N_Real_Literal, Token_Ptr);
+            Set_Realval (Token_Node, Real_Literal_Value);
+
+         when Tok_Integer_Literal =>
+            Token_Node := New_Node (N_Integer_Literal, Token_Ptr);
+            Set_Intval (Token_Node, Int_Literal_Value);
+
+         when Tok_String_Literal =>
+            Token_Node := New_Node (N_String_Literal, Token_Ptr);
+            Set_Has_Wide_Character
+              (Token_Node, Wide_Character_Found);
+            Set_Has_Wide_Wide_Character
+              (Token_Node, Wide_Wide_Character_Found);
+            Set_Strval (Token_Node, String_Literal_Id);
+
+         when Tok_Operator_Symbol =>
+            Token_Node := New_Node (N_Operator_Symbol, Token_Ptr);
+            Set_Chars (Token_Node, Token_Name);
+            Set_Strval (Token_Node, String_Literal_Id);
+
+         when others =>
+            null;
+      end case;
+   end Post_Scan;
+
    ------------------------------
    -- Scan_Reserved_Identifier --
    ------------------------------
@@ -369,4 +430,13 @@ package body Scn is
       Set_Chars (Token_Node, Token_Name);
    end Scan_Reserved_Identifier;
 
+   ---------------------------
+   -- Set_Obsolescent_Check --
+   ---------------------------
+
+   procedure Set_Obsolescent_Check (Value : Boolean) is
+   begin
+      Obsolescent_Check_Flag := Value;
+   end Set_Obsolescent_Check;
+
 end Scn;