------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             P A R . U T I L                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2004, 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 Csets;   use Csets;
with Stylesw; use Stylesw;
with Uintp;   use Uintp;

with GNAT.Spelling_Checker; use GNAT.Spelling_Checker;

separate (Par)
package body Util is

   ---------------------
   -- Bad_Spelling_Of --
   ---------------------

   function Bad_Spelling_Of (T : Token_Type) return Boolean is
      Tname : constant String := Token_Type'Image (T);
      --  Characters of token name

      S : String (1 .. Tname'Last - 4);
      --  Characters of token name folded to lower case, omitting TOK_ at start

      M1 : String (1 .. 42) := "incorrect spelling of keyword ************";
      M2 : String (1 .. 44) := "illegal abbreviation of keyword ************";
      --  Buffers used to construct error message

      P1 : constant := 30;
      P2 : constant := 32;
      --  Starting subscripts in M1, M2 for keyword name

      SL : constant Natural := S'Length;
      --  Length of expected token name excluding TOK_ at start

   begin
      if Token /= Tok_Identifier then
         return False;
      end if;

      for J in S'Range loop
         --  LLVM local
         S (J) := Fold_Lower (Tname (J + 4));
      end loop;

      Get_Name_String (Token_Name);

      --  A special check for case of PROGRAM used for PROCEDURE

      if T = Tok_Procedure
        and then Name_Len = 7
        and then Name_Buffer (1 .. 7) = "program"
      then
         Error_Msg_SC ("PROCEDURE expected");
         Token := T;
         return True;

      --  A special check for an illegal abbrevation

      elsif Name_Len < S'Length
        and then Name_Len >= 4
        and then Name_Buffer (1 .. Name_Len) = S (1 .. Name_Len)
      then
         for J in 1 .. S'Last loop
            M2 (P2 + J - 1) := Fold_Upper (S (J));
         end loop;

         Error_Msg_SC (M2 (1 .. P2 - 1 + S'Last));
         Token := T;
         return True;
      end if;

      --  Now we go into the full circuit to check for a misspelling

      --  Never consider something a misspelling if either the actual or
      --  expected string is less than 3 characters (before this check we
      --  used to consider i to be a misspelled if in some cases!)

      if SL < 3 or else Name_Len < 3 then
         return False;

      --  Special case: prefix matches, i.e. the leading characters of the
      --  token that we have exactly match the required keyword. If there
      --  are at least two characters left over, assume that we have a case
      --  of two keywords joined together which should not be joined.

      elsif Name_Len > SL + 1
        and then S = Name_Buffer (1 .. SL)
      then
         Scan_Ptr := Token_Ptr + S'Length;
         Error_Msg_S ("missing space");
         Token := T;
         return True;
      end if;

      if Is_Bad_Spelling_Of (Name_Buffer (1 .. Name_Len), S) then
         for J in 1 .. S'Last loop
            M1 (P1 + J - 1) := Fold_Upper (S (J));
         end loop;

         Error_Msg_SC (M1 (1 .. P1 - 1 + S'Last));
         Token := T;
         return True;

      else
         return False;
      end if;
   end Bad_Spelling_Of;

   ----------------------
   -- Check_95_Keyword --
   ----------------------

   --  On entry, the caller has checked that current token is an identifier
   --  whose name matches the name of the 95 keyword New_Tok.

   procedure Check_95_Keyword (Token_95, Next : Token_Type) is
      Scan_State : Saved_Scan_State;

   begin
      Save_Scan_State (Scan_State); -- at identifier/keyword
      Scan; -- past identifier/keyword

      if Token = Next then
         Restore_Scan_State (Scan_State); -- to identifier
         Error_Msg_Name_1 := Token_Name;
         Error_Msg_SC ("(Ada 83) keyword* cannot be used!");
         Token := Token_95;
      else
         Restore_Scan_State (Scan_State); -- to identifier
      end if;
   end Check_95_Keyword;

   ----------------------
   -- Check_Bad_Layout --
   ----------------------

   procedure Check_Bad_Layout is
   begin
      if Style.RM_Column_Check and then Token_Is_At_Start_Of_Line
        and then Start_Column <= Scope.Table (Scope.Last).Ecol
      then
         Error_Msg_BC ("(style) incorrect layout");
      end if;
   end Check_Bad_Layout;

   --------------------------
   -- Check_Misspelling_Of --
   --------------------------

   procedure Check_Misspelling_Of (T : Token_Type) is
   begin
      if Bad_Spelling_Of (T) then
         null;
      end if;
   end Check_Misspelling_Of;

   -----------------------------
   -- Check_Simple_Expression --
   -----------------------------

   procedure Check_Simple_Expression (E : Node_Id) is
   begin
      if Expr_Form = EF_Non_Simple then
         Error_Msg_N ("this expression must be parenthesized", E);
      end if;
   end Check_Simple_Expression;

   ---------------------------------------
   -- Check_Simple_Expression_In_Ada_83 --
   ---------------------------------------

   procedure Check_Simple_Expression_In_Ada_83 (E : Node_Id) is
   begin
      if Expr_Form = EF_Non_Simple then
         if Ada_Version = Ada_83 then
            Error_Msg_N ("(Ada 83) this expression must be parenthesized!", E);
         end if;
      end if;
   end Check_Simple_Expression_In_Ada_83;

   ------------------------
   -- Check_Subtype_Mark --
   ------------------------

   function Check_Subtype_Mark (Mark : Node_Id) return Node_Id is
   begin
      if Nkind (Mark) = N_Identifier
        or else Nkind (Mark) = N_Selected_Component
        or else (Nkind (Mark) = N_Attribute_Reference
                  and then Is_Type_Attribute_Name (Attribute_Name (Mark)))
        or else Mark = Error
      then
         return Mark;
      else
         Error_Msg ("subtype mark expected", Sloc (Mark));
         return Error;
      end if;
   end Check_Subtype_Mark;

   -------------------
   -- Comma_Present --
   -------------------

   function Comma_Present return Boolean is
      Scan_State  : Saved_Scan_State;
      Paren_Count : Nat;

   begin
      --  First check, if a comma is present, then a comma is present!

      if Token = Tok_Comma then
         T_Comma;
         return True;

      --  If we have a right paren, then that is taken as ending the list
      --  i.e. no comma is present.

      elsif Token = Tok_Right_Paren then
         return False;

      --  If pragmas, then get rid of them and make a recursive call
      --  to process what follows these pragmas.

      elsif Token = Tok_Pragma then
         P_Pragmas_Misplaced;
         return Comma_Present;

      --  At this stage we have an error, and the goal is to decide on whether
      --  or not we should diagnose an error and report a (non-existent)
      --  comma as being present, or simply to report no comma is present

      --  If we are a semicolon, then the question is whether we have a missing
      --  right paren, or whether the semicolon should have been a comma. To
      --  guess the right answer, we scan ahead keeping track of the paren
      --  level, looking for a clue that helps us make the right decision.

      --  This approach is highly accurate in the single error case, and does
      --  not make bad mistakes in the multiple error case (indeed we can't
      --  really make a very bad decision at this point in any case).

      elsif Token = Tok_Semicolon then
         Save_Scan_State (Scan_State);
         Scan; -- past semicolon

         --  Check for being followed by identifier => which almost certainly
         --  means we are still in a parameter list and the comma should have
         --  been a semicolon (such a sequence could not follow a semicolon)

         if Token = Tok_Identifier then
            Scan;

            if Token = Tok_Arrow then
               goto Assume_Comma;
            end if;
         end if;

         --  If that test didn't work, loop ahead looking for a comma or
         --  semicolon at the same parenthesis level. Always remember that
         --  we can't go badly wrong in an error situation like this!

         Paren_Count := 0;

         --  Here is the look ahead loop, Paren_Count tells us whether the
         --  token we are looking at is at the same paren level as the
         --  suspicious semicolon that we are trying to figure out.

         loop

            --  If we hit another semicolon or an end of file, and we have
            --  not seen a right paren or another comma on the way, then
            --  probably the semicolon did end the list. Indeed that is
            --  certainly the only single error correction possible here.

            if Token = Tok_Semicolon or else Token = Tok_EOF then
               Restore_Scan_State (Scan_State);
               return False;

            --  A comma at the same paren level as the semicolon is a strong
            --  indicator that the semicolon should have been a comma, indeed
            --  again this is the only possible single error correction.

            elsif Token = Tok_Comma then
               exit when Paren_Count = 0;

            --  A left paren just bumps the paren count

            elsif Token = Tok_Left_Paren then
               Paren_Count := Paren_Count + 1;

            --  A right paren that is at the same paren level as the semicolon
            --  also means that the only possible single error correction is
            --  to assume that the semicolon should have been a comma. If we
            --  are not at the same paren level, then adjust the paren level.

            elsif Token = Tok_Right_Paren then
               exit when Paren_Count = 0;
               Paren_Count := Paren_Count - 1;
            end if;

            --  Keep going, we haven't made a decision yet

            Scan;
         end loop;

         --  If we fall through the loop, it means that we found a terminating
         --  right paren or another comma. In either case it is reasonable to
         --  assume that the semicolon was really intended to be a comma. Also
         --  come here for the identifier arrow case.

         <<Assume_Comma>>
            Restore_Scan_State (Scan_State);
            Error_Msg_SC (""";"" illegal here, replaced by "",""");
            Scan; -- past the semicolon
            return True;

      --  If we are not at semicolon or a right paren, then we base the
      --  decision on whether or not the next token can be part of an
      --  expression. If not, then decide that no comma is present (the
      --  caller will eventually generate a missing right parent message)

      elsif Token in Token_Class_Eterm then
         return False;

      --  Otherwise we assume a comma is present, even if none is present,
      --  since the next token must be part of an expression, so if we were
      --  at the end of the list, then there is more than one error present.

      else
         T_Comma; -- to give error
         return True;
      end if;
   end Comma_Present;

   -----------------------
   -- Discard_Junk_List --
   -----------------------

   procedure Discard_Junk_List (L : List_Id) is
      pragma Warnings (Off, L);
   begin
      null;
   end Discard_Junk_List;

   -----------------------
   -- Discard_Junk_Node --
   -----------------------

   procedure Discard_Junk_Node (N : Node_Id) is
      pragma Warnings (Off, N);
   begin
      null;
   end Discard_Junk_Node;

   ------------
   -- Ignore --
   ------------

   procedure Ignore (T : Token_Type) is
   begin
      if Token = T then
         if T = Tok_Comma then
            Error_Msg_SC ("unexpected "","" ignored");

         elsif T = Tok_Left_Paren then
            Error_Msg_SC ("unexpected ""("" ignored");

         elsif T = Tok_Right_Paren then
            Error_Msg_SC ("unexpected "")"" ignored");

         elsif T = Tok_Semicolon then
            Error_Msg_SC ("unexpected "";"" ignored");

         else
            declare
               Tname : constant String := Token_Type'Image (Token);
               Msg   : String := "unexpected keyword ????????????????????????";

            begin
               --  Loop to copy characters of keyword name (ignoring Tok_)

               for J in 5 .. Tname'Last loop
                  Msg (J + 14) := Fold_Upper (Tname (J));
               end loop;

               Msg (Tname'Last + 15 .. Tname'Last + 22) := " ignored";
               Error_Msg_SC (Msg (1 .. Tname'Last + 22));
            end;
         end if;

         Scan; -- Scan past ignored token
      end if;
   end Ignore;

   ----------------------------
   -- Is_Reserved_Identifier --
   ----------------------------

   function Is_Reserved_Identifier (C : Id_Check := None) return Boolean is
   begin
      if not Is_Reserved_Keyword (Token) then
         return False;

      else
         declare
            Ident_Casing : constant Casing_Type :=
                             Identifier_Casing (Current_Source_File);

            Key_Casing   : constant Casing_Type :=
                             Keyword_Casing (Current_Source_File);

         begin
            --  If the casing of identifiers and keywords is different in
            --  this source file, and the casing of this token matches the
            --  keyword casing, then we return False, since it is pretty
            --  clearly intended to be a keyword.

            if Ident_Casing = Unknown
              or else Key_Casing = Unknown
              or else Ident_Casing = Key_Casing
              or else Determine_Token_Casing /= Key_Casing
            then
               return True;

            --  Here we have a keyword written clearly with keyword casing.
            --  In default mode, we would not be willing to consider this as
            --  a reserved identifier, but if C is set, we may still accept it

            elsif C /= None then
               declare
                  Scan_State  : Saved_Scan_State;
                  OK_Next_Tok : Boolean;

               begin
                  Save_Scan_State (Scan_State);
                  Scan;

                  if Token_Is_At_Start_Of_Line then
                     return False;
                  end if;

                  case C is
                     when None =>
                        raise Program_Error;

                     when C_Comma_Right_Paren =>
                        OK_Next_Tok :=
                          Token = Tok_Comma or else Token = Tok_Right_Paren;

                     when C_Comma_Colon =>
                        OK_Next_Tok :=
                          Token = Tok_Comma or else Token = Tok_Colon;

                     when C_Do =>
                        OK_Next_Tok :=
                          Token = Tok_Do;

                     when C_Dot =>
                        OK_Next_Tok :=
                          Token = Tok_Dot;

                     when C_Greater_Greater =>
                        OK_Next_Tok :=
                          Token = Tok_Greater_Greater;

                     when C_In =>
                        OK_Next_Tok :=
                          Token = Tok_In;

                     when C_Is =>
                        OK_Next_Tok :=
                          Token = Tok_Is;

                     when C_Left_Paren_Semicolon =>
                        OK_Next_Tok :=
                          Token = Tok_Left_Paren or else Token = Tok_Semicolon;

                     when C_Use =>
                        OK_Next_Tok :=
                          Token = Tok_Use;

                     when C_Vertical_Bar_Arrow =>
                        OK_Next_Tok :=
                          Token = Tok_Vertical_Bar or else Token = Tok_Arrow;
                  end case;

                  Restore_Scan_State (Scan_State);

                  if OK_Next_Tok then
                     return True;
                  end if;
               end;
            end if;
         end;
      end if;

      --  If we fall through it is not a reserved identifier

      return False;
   end Is_Reserved_Identifier;

   ----------------------
   -- Merge_Identifier --
   ----------------------

   procedure Merge_Identifier (Prev : Node_Id; Nxt : Token_Type) is
   begin
      if Token /= Tok_Identifier then
         return;
      end if;

      declare
         S : Saved_Scan_State;
         T : Token_Type;

      begin
         Save_Scan_State (S);
         Scan;
         T := Token;
         Restore_Scan_State (S);

         if T /= Nxt then
            return;
         end if;
      end;

      --  Check exactly one space between identifiers

      if Source (Token_Ptr - 1) /= ' '
        or else Int (Token_Ptr) /=
                  Int (Prev_Token_Ptr) + Length_Of_Name (Chars (Prev)) + 1
      then
         return;
      end if;

      --  Do the merge

      Get_Name_String (Chars (Token_Node));

      declare
         Buf : constant String (1 .. Name_Len) :=
                 Name_Buffer (1 .. Name_Len);

      begin
         Get_Name_String (Chars (Prev));
         Add_Char_To_Name_Buffer ('_');
         Add_Str_To_Name_Buffer (Buf);
         Set_Chars (Prev, Name_Find);
      end;

      Error_Msg_Node_1 := Prev;
      Error_Msg_SC
        ("unexpected identifier, possibly & was meant here");
      Scan;
   end Merge_Identifier;

   -------------------
   -- No_Constraint --
   -------------------

   procedure No_Constraint is
   begin
      if Token in Token_Class_Consk then
         Error_Msg_SC ("constraint not allowed here");
         Discard_Junk_Node (P_Constraint_Opt);
      end if;
   end No_Constraint;

   --------------------
   -- No_Right_Paren --
   --------------------

   function No_Right_Paren (Expr : Node_Id) return Node_Id is
   begin
      if Token = Tok_Right_Paren then
         Error_Msg_SC ("unexpected right parenthesis");
         Resync_Expression;
         return Error;
      else
         return Expr;
      end if;
   end No_Right_Paren;

   ---------------------
   -- Pop_Scope_Stack --
   ---------------------

   procedure Pop_Scope_Stack is
   begin
      pragma Assert (Scope.Last > 0);
      Scope.Decrement_Last;

      if Debug_Flag_P then
         Error_Msg_Uint_1 := UI_From_Int (Scope.Last);
         Error_Msg_SC ("decrement scope stack ptr, new value = ^!");
      end if;
   end Pop_Scope_Stack;

   ----------------------
   -- Push_Scope_Stack --
   ----------------------

   procedure Push_Scope_Stack is
   begin
      Scope.Increment_Last;

      if Style_Check_Max_Nesting_Level
        and then Scope.Last = Style_Max_Nesting_Level + 1
      then
         Error_Msg
           ("(style) maximum nesting level exceeded",
            First_Non_Blank_Location);
      end if;

      Scope.Table (Scope.Last).Junk := False;
      Scope.Table (Scope.Last).Node := Empty;

      if Debug_Flag_P then
         Error_Msg_Uint_1 := UI_From_Int (Scope.Last);
         Error_Msg_SC ("increment scope stack ptr, new value = ^!");
      end if;
   end Push_Scope_Stack;

   ----------------------
   -- Separate_Present --
   ----------------------

   function Separate_Present return Boolean is
      Scan_State : Saved_Scan_State;

   begin
      if Token = Tok_Separate then
         return True;

      elsif Token /= Tok_Identifier then
         return False;

      else
         Save_Scan_State (Scan_State);
         Scan; -- past identifier

         if Token = Tok_Semicolon then
            Restore_Scan_State (Scan_State);
            return Bad_Spelling_Of (Tok_Separate);

         else
            Restore_Scan_State (Scan_State);
            return False;
         end if;
      end if;
   end Separate_Present;

   --------------------------
   -- Signal_Bad_Attribute --
   --------------------------

   procedure Signal_Bad_Attribute is
   begin
      Error_Msg_N ("unrecognized attribute&", Token_Node);

      --  Check for possible misspelling

      Get_Name_String (Token_Name);

      declare
         AN : constant String := Name_Buffer (1 .. Name_Len);

      begin
         Error_Msg_Name_1 := First_Attribute_Name;
         while Error_Msg_Name_1 <= Last_Attribute_Name loop
            Get_Name_String (Error_Msg_Name_1);

            if Is_Bad_Spelling_Of
                 (AN, Name_Buffer (1 .. Name_Len))
            then
               Error_Msg_N
                 ("\possible misspelling of %", Token_Node);
               exit;
            end if;

            Error_Msg_Name_1 := Error_Msg_Name_1 + 1;
         end loop;
      end;
   end Signal_Bad_Attribute;

   -----------------------------
   -- Token_Is_At_End_Of_Line --
   -----------------------------

   function Token_Is_At_End_Of_Line return Boolean is
      S : Source_Ptr;

   begin
      --  Skip past blanks and horizontal tabs

      S := Scan_Ptr;
      while Source (S) = ' ' or else Source (S) = ASCII.HT loop
         S := S + 1;
      end loop;

      --  We are at end of line if at a control character (CR/LF/VT/FF/EOF)
      --  or if we are at the start of an end of line comment sequence.

      return Source (S) < ' '
        or else (Source (S) = '-' and then Source (S + 1) = '-');
   end Token_Is_At_End_Of_Line;

   -------------------------------
   -- Token_Is_At_Start_Of_Line --
   -------------------------------

   function Token_Is_At_Start_Of_Line return Boolean is
   begin
      return (Token_Ptr = First_Non_Blank_Location or else Token = Tok_EOF);
   end Token_Is_At_Start_Of_Line;

end Util;
