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

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
         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 -- CODEFIX
           ("PROCEDURE expected");
         Token := T;
         return True;

      --  A special check for an illegal abbreviation

      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 -- CODFIX
           (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 RM_Column_Check and then Token_Is_At_Start_Of_Line
        and then Start_Column <= Scopes (Scope.Last).Ecol
      then
         Error_Msg_BC -- CODEFIX
           ("(style) incorrect layout");
      end if;
   end Check_Bad_Layout;

   --------------------------
   -- Check_Future_Keyword --
   --------------------------

   procedure Check_Future_Keyword is
   begin
      --  Ada 2005 (AI-284): Compiling in Ada 95 mode we warn that INTERFACE,
      --  OVERRIDING, and SYNCHRONIZED are new reserved words.

      if Ada_Version = Ada_95
        and then Warn_On_Ada_2005_Compatibility
      then
         if Token_Name in Name_Overriding | Name_Synchronized
           or else (Token_Name = Name_Interface
                     and then Prev_Token /= Tok_Pragma)
         then
            Error_Msg_N ("& is a reserved word in Ada 2005?y?", Token_Node);
         end if;
      end if;

      --  Similarly, warn about Ada 2012 reserved words

      if Ada_Version in Ada_95 .. Ada_2005
        and then Warn_On_Ada_2012_Compatibility
      then
         if Token_Name = Name_Some then
            Error_Msg_N ("& is a reserved word in Ada 2012?y?", Token_Node);
         end if;
      end if;

      --  Note: we deliberately do not emit these warnings when operating in
      --  Ada 83 mode because in that case we assume the user is building
      --  legacy code anyway and is not interested in updating Ada versions.

   end Check_Future_Keyword;

   --------------------------
   -- 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_N ("subtype mark expected", 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.
      --  Ditto for a right bracket in Ada 2022.

      elsif Token = Tok_Right_Paren
        or else (Token = Tok_Right_Bracket and then Ada_Version >= Ada_2022)
      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 -- CODEFIX
              ("|"";"" should be "",""");
            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
      while Token = T loop
         if T = Tok_Comma then
            Error_Msg_SC -- CODEFIX
              ("|extra "","" ignored");

         elsif T = Tok_Left_Paren then
            Error_Msg_SC -- CODEFIX
              ("|extra ""("" ignored");

         --  Note: the following error used to be labeled as a non-serious
         --  error like the other similar messages here (with a | at the start
         --  of the message). But this caused some annoying cascaded errors
         --  that were confusing, as shown by this example:

         --          A : array (1 .. 9) of Integer :=
         --            ((1 .. 2) => 0,
         --             1  2   3
         --       >>> positional aggregate cannot have one component
         --       >>> named association cannot follow positional association
         --       >>> extra ")" ignored

         --  So we decided to label it as serious after all

         elsif T = Tok_Right_Paren then
            Error_Msg_SC -- CODEFIX
              ("extra "")"" ignored");

         elsif T = Tok_Semicolon then
            Error_Msg_SC -- CODEFIX
              ("|extra "";"" ignored");

         elsif T = Tok_Colon then
            Error_Msg_SC -- CODEFIX
              ("|extra "":"" ignored");

         else
            declare
               Tname : constant String := Token_Type'Image (Token);
            begin
               Error_Msg_SC ("|extra " & Tname (5 .. Tname'Last) & " ignored");
            end;
         end if;

         Scan; -- Scan past ignored token
      end loop;
   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;

   -------------------------------
   -- Missing_Semicolon_On_When --
   -------------------------------

   function Missing_Semicolon_On_When return Boolean is
      State : Saved_Scan_State;

   begin
      if not Token_Is_At_Start_Of_Line then
         return False;

      elsif Scopes (Scope.Last).Etyp /= E_Case then
         return False;

      else
         Save_Scan_State (State);
         Scan; -- past WHEN
         Scan; -- past token after WHEN

         if Token = Tok_Arrow then
            Restore_Scan_State (State);
            return True;
         else
            Restore_Scan_State (State);
            return False;
         end if;
      end if;
   end Missing_Semicolon_On_When;

   -------------------
   -- Next_Token_Is --
   -------------------

   function Next_Token_Is (Tok : Token_Type) return Boolean is
      Scan_State : Saved_Scan_State;
      Result     : Boolean;
   begin
      Save_Scan_State (Scan_State);
      Scan;
      Result := (Token = Tok);
      Restore_Scan_State (Scan_State);
      return Result;
   end Next_Token_Is;

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

   procedure No_Constraint is
   begin
      --  If we have a token that could start a constraint on the same line
      --  then cnsider this an illegal constraint. It seems unlikely it could
      --  be anything else if it is on the same line.

      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;

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

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

      if Include_Subprogram_In_Messages
        and then Scopes (Scope.Last).Labl /= Error
      then
         Current_Node := Scopes (Scope.Last).Labl;
      end if;

      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;

      Scopes (Scope.Last).Junk := False;
      Scopes (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
      Bad_Attribute (Token_Node, Token_Name, Warn => False);
   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;

   -----------------------------------
   -- Warn_If_Standard_Redefinition --
   -----------------------------------

   procedure Warn_If_Standard_Redefinition (N : Node_Id) is
   begin
      if Warn_On_Standard_Redefinition then
         declare
            C : constant Entity_Id := Current_Entity (N);
         begin
            if Present (C) and then Sloc (C) = Standard_Location then
               Error_Msg_N ("redefinition of entity& in Standard?.k?", N);
            end if;
         end;
      end if;
   end Warn_If_Standard_Redefinition;

end Util;
