------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                               S T Y L E G                                --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2023, 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.      --
--                                                                          --
------------------------------------------------------------------------------

--  This version of the Style package implements the standard GNAT style
--  checking rules. For documentation of these rules, see comments on the
--  individual procedures.

with Atree;          use Atree;
with Casing;         use Casing;
with Csets;          use Csets;
with Einfo;          use Einfo;
with Einfo.Utils;    use Einfo.Utils;
with Err_Vars;       use Err_Vars;
with Errout;
with Opt;            use Opt;
with Scans;          use Scans;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinput;         use Sinput;
with Stylesw;        use Stylesw;

package body Styleg is

   use ASCII;

   Blank_Lines : Nat := 0;
   --  Counts number of empty lines seen. Reset to zero if a non-empty line
   --  is encountered. Used to check for trailing blank lines in Check_EOF,
   --  and for multiple blank lines.

   Blank_Line_Location : Source_Ptr;
   --  Remembers location of first blank line in a series. Used to issue an
   --  appropriate diagnostic if subsequent blank lines or the end of file
   --  is encountered.

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Check_No_Space_After;
   --  Checks that there is a non-white space character after the current
   --  token, or white space followed by a comment, or the end of line.
   --  Issue error message if not.

   procedure Check_No_Space_Before;
   --  Check that token is first token on line, or else is not preceded
   --  by white space. Signal error of space not allowed if not.

   procedure Check_Separate_Stmt_Lines_Cont;
   --  Non-inlined continuation of Check_Separate_Stmt_Lines

   function Determine_Token_Casing return Casing_Type;
   --  Determine casing of current token

   procedure Error_Space_Not_Allowed (S : Source_Ptr);
   --  Posts an error message indicating that a space is not allowed
   --  at the given source location.

   procedure Error_Space_Required (S : Source_Ptr);
   --  Posts an error message indicating that a space is required at
   --  the given source location.

   function Is_White_Space (C : Character) return Boolean;
   pragma Inline (Is_White_Space);
   --  Returns True for space or HT, False otherwise

   procedure Require_Following_Space;
   pragma Inline (Require_Following_Space);
   --  Require token to be followed by white space. Used only if in GNAT
   --  style checking mode.

   procedure Require_Preceding_Space;
   pragma Inline (Require_Preceding_Space);
   --  Require token to be preceded by white space. Used only if in GNAT
   --  style checking mode.

   ----------------------
   -- Check_Abs_Or_Not --
   ----------------------

   --  In check token mode (-gnatyt), ABS/NOT must be followed by a space or
   --  a line feed.

   procedure Check_Abs_Not is
   begin
      if Style_Check_Tokens then
         if Source (Scan_Ptr) not in ' ' | ASCII.CR | ASCII.LF then
            Error_Space_Required (Scan_Ptr);
         end if;
      end if;
   end Check_Abs_Not;

   ----------------------
   -- Check_Apostrophe --
   ----------------------

   --  Do not allow space after apostrophe

   procedure Check_Apostrophe is
   begin
      if Style_Check_Tokens then
         Check_No_Space_After;
      end if;
   end Check_Apostrophe;

   -----------------
   -- Check_Arrow --
   -----------------

   --  In check tokens mode (-gnatys), arrow must be surrounded by spaces,
   --  except that within the argument of a Depends or Refined_Depends aspect
   --  or pragma the required format is "=>+ " rather than "=> +").

   procedure Check_Arrow (Inside_Depends : Boolean := False) is
   begin
      if Style_Check_Tokens then
         Require_Preceding_Space;

         --  Special handling for Depends and Refined_Depends

         if Inside_Depends then
            if Source (Scan_Ptr) = ' '
              and then Source (Scan_Ptr + 1) = '+'
            then
               Error_Space_Not_Allowed (Scan_Ptr);

            elsif Source (Scan_Ptr) /= ' '
              and then Source (Scan_Ptr) /= '+'
            then
               Require_Following_Space;
            end if;

         --  Normal case

         else
            Require_Following_Space;
         end if;
      end if;
   end Check_Arrow;

   --------------------------
   -- Check_Attribute_Name --
   --------------------------

   --  In check attribute casing mode (-gnatya), attribute names must be
   --  mixed case, i.e. start with an upper case letter, and otherwise
   --  lower case, except after an underline character.

   procedure Check_Attribute_Name (Reserved : Boolean) is
      pragma Warnings (Off, Reserved);
   begin
      if Style_Check_Attribute_Casing then
         if Determine_Token_Casing /= Mixed_Case then
            Error_Msg_SC -- CODEFIX
              ("(style) bad capitalization, mixed case required?a?");
         end if;
      end if;
   end Check_Attribute_Name;

   ---------------------------
   -- Check_Binary_Operator --
   ---------------------------

   --  In check token mode (-gnatyt), binary operators other than the special
   --  case of exponentiation require surrounding space characters.

   procedure Check_Binary_Operator is
   begin
      if Style_Check_Tokens then
         Require_Preceding_Space;
         Require_Following_Space;
      end if;
   end Check_Binary_Operator;

   ----------------------------
   -- Check_Boolean_Operator --
   ----------------------------

   procedure Check_Boolean_Operator (Node : Node_Id) is

      function OK_Boolean_Operand (N : Node_Id) return Boolean;
      --  Returns True for simple variable, or "not X1" or "X1 and X2" or
      --  "X1 or X2" where X1, X2 are recursively OK_Boolean_Operand's.

      ------------------------
      -- OK_Boolean_Operand --
      ------------------------

      function OK_Boolean_Operand (N : Node_Id) return Boolean is
      begin
         if Nkind (N) in N_Identifier | N_Expanded_Name then
            return True;

         elsif Nkind (N) = N_Op_Not then
            return OK_Boolean_Operand (Original_Node (Right_Opnd (N)));

         elsif Nkind (N) in N_Op_And | N_Op_Or then
            return OK_Boolean_Operand (Original_Node (Left_Opnd (N)))
                     and then
                   OK_Boolean_Operand (Original_Node (Right_Opnd (N)));

         else
            return False;
         end if;
      end OK_Boolean_Operand;

   --  Start of processing for Check_Boolean_Operator

   begin
      if Style_Check_Boolean_And_Or
        and then Comes_From_Source (Node)
      then
         declare
            Orig : constant Node_Id := Original_Node (Node);

         begin
            if Nkind (Orig) in N_Op_And | N_Op_Or then
               declare
                  L : constant Node_Id := Original_Node (Left_Opnd  (Orig));
                  R : constant Node_Id := Original_Node (Right_Opnd (Orig));

               begin
                  --  First OK case, simple boolean constants/identifiers

                  if OK_Boolean_Operand (L)
                       and then
                     OK_Boolean_Operand (R)
                  then
                     return;

                  --  Second OK case, modular types

                  elsif Is_Modular_Integer_Type (Etype (Node)) then
                     return;

                  --  Third OK case, array types

                  elsif Is_Array_Type (Etype (Node)) then
                     return;

                  --  Otherwise we have an error

                  elsif Nkind (Orig) = N_Op_And then
                     Error_Msg -- CODEFIX
                       ("(style) `AND THEN` required?B?", Sloc (Orig));
                  else
                     Error_Msg -- CODEFIX
                       ("(style) `OR ELSE` required?B?", Sloc (Orig));
                  end if;
               end;
            end if;
         end;
      end if;
   end Check_Boolean_Operator;

   ---------------
   -- Check_Box --
   ---------------

   --  In check token mode (-gnatyt), box must be preceded by a space or by
   --  a left parenthesis. Spacing checking on the surrounding tokens takes
   --  care of the remaining checks.

   procedure Check_Box is
   begin
      if Style_Check_Tokens then
         if Prev_Token /= Tok_Left_Paren then
            Require_Preceding_Space;
         end if;
      end if;
   end Check_Box;

   -----------------
   -- Check_Colon --
   -----------------

   --  In check token mode (-gnatyt), colon must be surrounded by spaces

   procedure Check_Colon is
   begin
      if Style_Check_Tokens then
         Require_Preceding_Space;
         Require_Following_Space;
      end if;
   end Check_Colon;

   -----------------------
   -- Check_Colon_Equal --
   -----------------------

   --  In check token mode (-gnatyt), := must be surrounded by spaces

   procedure Check_Colon_Equal is
   begin
      if Style_Check_Tokens then
         Require_Preceding_Space;
         Require_Following_Space;
      end if;
   end Check_Colon_Equal;

   -----------------
   -- Check_Comma --
   -----------------

   --  In check token mode (-gnatyt), comma must be either the first
   --  token on a line, or be preceded by a non-blank character.
   --  It must also always be followed by a blank.

   procedure Check_Comma is
   begin
      if Style_Check_Tokens then
         Check_No_Space_Before;

         if Source (Scan_Ptr) > ' ' then
            Error_Space_Required (Scan_Ptr);
         end if;
      end if;
   end Check_Comma;

   -------------------
   -- Check_Comment --
   -------------------

   --  In check comment mode (-gnatyc) there are several requirements on the
   --  format of comments. The following are permissible comment formats:

   --    1. Any comment that is not at the start of a line, i.e. where the
   --       initial minuses are not the first non-blank characters on the
   --       line must have at least one blank after the second minus or a
   --       special character as defined in rule 5.

   --    2. A row of all minuses of any length is permitted (see procedure
   --       box above in the source of this routine).

   --    3. A comment line starting with two minuses and a space, and ending
   --       with a space and two minuses. Again see the procedure title box
   --       immediately above in the source.

   --    4. A full line comment where two spaces follow the two minus signs.
   --       This is the normal comment format in GNAT style, as typified by
   --       the comments you are reading now.

   --    5. A full line comment where the first character after the second
   --       minus is a special character, i.e. a character in the ASCII
   --       range 16#21#..16#2F# or 16#3A#..16#3F#. This allows special
   --       comments, such as those generated by gnatprep, or those that
   --       appear in the SPARK annotation language to be accepted.

   --       Note: for GNAT internal files (-gnatg switch set on for the
   --       compilation), the only special sequence recognized and allowed
   --       is --! as generated by gnatprep.

   --    6. In addition, the comment must be properly indented if comment
   --       indentation checking is active (Style_Check_Indentation non-zero).
   --       Either the start column must be a multiple of this indentation,
   --       or the indentation must match that of the next non-blank line,
   --       or must match the indentation of the immediately preciding line
   --       if it is non-blank.

   procedure Check_Comment is
      S : Source_Ptr;
      C : Character;

      function Is_Box_Comment return Boolean;
      --  Returns True if the last two characters on the line are -- which
      --  characterizes a box comment (as for example follows this spec).

      function Is_Special_Character (C : Character) return Boolean;
      --  Determines if C is a special character (see rule 5 above)

      function Same_Column_As_Next_Non_Blank_Line return Boolean;
      --  Called for a full line comment. If the indentation of this comment
      --  matches that of the next non-blank line in the source, then True is
      --  returned, otherwise False.

      function Same_Column_As_Previous_Line return Boolean;
      --  Called for a full line comment. If the previous line is blank, then
      --  returns False. Otherwise, if the indentation of this comment matches
      --  that of the previous line in the source, then True is returned,
      --  otherwise False.

      --------------------
      -- Is_Box_Comment --
      --------------------

      function Is_Box_Comment return Boolean is
         S : Source_Ptr;

      begin
         --  Do we need to worry about UTF_32 line terminators here ???

         S := Scan_Ptr + 3;
         while Source (S) not in Line_Terminator loop
            S := S + 1;
         end loop;

         return Source (S - 1) = '-' and then Source (S - 2) = '-';
      end Is_Box_Comment;

      --------------------------
      -- Is_Special_Character --
      --------------------------

      function Is_Special_Character (C : Character) return Boolean is
      begin
         if GNAT_Mode then
            return C = '!';
         else
            return
              Character'Pos (C) in 16#21# .. 16#2F#
                or else
              Character'Pos (C) in 16#3A# .. 16#3F#;
         end if;
      end Is_Special_Character;

      ----------------------------------------
      -- Same_Column_As_Next_Non_Blank_Line --
      ----------------------------------------

      function Same_Column_As_Next_Non_Blank_Line return Boolean is
         P : Source_Ptr;

      begin
         --  Step to end of line

         P := Scan_Ptr + 2;
         while Source (P) not in Line_Terminator loop
            P := P + 1;
         end loop;

         --  Step past blanks, and line terminators (UTF_32 case???)

         while Source (P) <= ' ' and then Source (P) /= EOF loop
            P := P + 1;
         end loop;

         --  Compare columns

         return Get_Column_Number (Scan_Ptr) = Get_Column_Number (P);
      end Same_Column_As_Next_Non_Blank_Line;

      ----------------------------------
      -- Same_Column_As_Previous_Line --
      ----------------------------------

      function Same_Column_As_Previous_Line return Boolean is
         S, P : Source_Ptr;

      begin
         --  Point S to start of this line, and P to start of previous line

         S := Line_Start (Scan_Ptr);
         P := S;
         Backup_Line (P);

         --  Step P to first non-blank character on line

         loop
            --  If we get back to start of current line, then the previous line
            --  was blank, and we always return False in that situation.

            if P = S then
               return False;
            end if;

            exit when Source (P) /= ' ' and then Source (P) /= ASCII.HT;
            P := P + 1;
         end loop;

         --  Compare columns

         return Get_Column_Number (Scan_Ptr) = Get_Column_Number (P);
      end Same_Column_As_Previous_Line;

   --  Start of processing for Check_Comment

   begin
      --  Can never have a non-blank character preceding the first minus.
      --  The "+ 3" is to leave room for a possible byte order mark (BOM);
      --  we want to avoid a warning for a comment at the start of the
      --  file just after the BOM.

      if Style_Check_Comments then
         if Scan_Ptr > Source_First (Current_Source_File) + 3
           and then Source (Scan_Ptr - 1) > ' '
         then
            Error_Msg_S -- CODEFIX
              ("(style) space required?c?");
         end if;
      end if;

      --  For a comment that is not at the start of the line, the only
      --  requirement is that we cannot have a non-blank character after
      --  the second minus sign or a special character.

      if Scan_Ptr /= First_Non_Blank_Location then
         if Style_Check_Comments then
            if Source (Scan_Ptr + 2) > ' '
              and then not Is_Special_Character (Source (Scan_Ptr + 2))
            then
               Error_Msg -- CODEFIX
                 ("(style) space required?c?", Scan_Ptr + 2);
            end if;
         end if;

         return;

      --  Case of a comment that is at the start of a line

      else
         --  First check, must be in appropriately indented column

         if Style_Check_Indentation /= 0 then
            if Start_Column rem Style_Check_Indentation /= 0 then
               if not Same_Column_As_Next_Non_Blank_Line
                 and then not Same_Column_As_Previous_Line
               then
                  Error_Msg_S -- CODEFIX
                    ("(style) bad column?0?");
               end if;

               return;
            end if;
         end if;

         --  If we are not checking comments, nothing more to do

         if not Style_Check_Comments then
            return;
         end if;

         --  Case of not followed by a blank. Usually wrong, but there are
         --  some exceptions that we permit.

         if Source (Scan_Ptr + 2) /= ' ' then
            C := Source (Scan_Ptr + 2);

            --  Case of -- all on its own on a line is OK

            if C < ' ' then
               return;
            end if;

            --  Case of --x, x special character is OK (gnatprep/SPARK/etc.)
            --  This is not permitted in internal GNAT implementation units
            --  except for the case of --! as used by gnatprep output.

            if Is_Special_Character (C) then
               return;
            end if;

            --  The only other case in which we allow a character after
            --  the -- other than a space is when we have a row of minus
            --  signs (case of header lines for a box comment for example).

            S := Scan_Ptr + 2;
            while Source (S) >= ' ' loop
               if Source (S) /= '-' then
                  if Is_Box_Comment
                    or else Style_Check_Comments_Spacing = 1
                  then
                     Error_Space_Required (Scan_Ptr + 2);
                  else
                     Error_Msg -- CODEFIX
                       ("(style) two spaces required?c?", Scan_Ptr + 2);
                  end if;

                  return;
               end if;

               S := S + 1;
            end loop;

         --  If we are followed by a blank, then the comment is OK if the
         --  character following this blank is another blank or a format
         --  effector, or if the required comment spacing is 1.

         elsif Source (Scan_Ptr + 3) <= ' '
           or else Style_Check_Comments_Spacing = 1
         then
            return;

         --  Here is the case where we only have one blank after the two minus
         --  signs, with Style_Check_Comments_Spacing set to 2, which is an
         --  error unless the line ends with two minus signs, the case of a
         --  box comment.

         elsif not Is_Box_Comment then
            Error_Space_Required (Scan_Ptr + 3);
         end if;
      end if;
   end Check_Comment;

   --------------------------------------
   -- Check_Defining_Identifier_Casing --
   --------------------------------------

   procedure Check_Defining_Identifier_Casing is
   begin
      if Style_Check_Mixed_Case_Decls then
         case Determine_Token_Casing is
            when All_Lower_Case
               | All_Upper_Case
            =>
               Error_Msg_SC -- CODEFIX
                 ("(style) bad capitalization, mixed case required?D?");

            --  The Unknown case is something like A_B_C, which is both all
            --  caps and mixed case.

            when Mixed_Case
               | Unknown
            =>
               null; -- OK
         end case;
      end if;
   end Check_Defining_Identifier_Casing;

   -------------------
   -- Check_Dot_Dot --
   -------------------

   --  In check token mode (-gnatyt), ".." must be surrounded by spaces

   procedure Check_Dot_Dot is
   begin
      if Style_Check_Tokens then
         Require_Preceding_Space;
         Require_Following_Space;
      end if;
   end Check_Dot_Dot;

   ---------------
   -- Check_EOF --
   ---------------

   --  In check blanks at end mode, check no blank lines precede the EOF

   procedure Check_EOF is
   begin
      if Style_Check_Blank_Lines then

         --  We expect one blank line, from the EOF, but no more than one

         if Blank_Lines = 2 then
            Error_Msg -- CODEFIX
              ("(style) blank line not allowed at end of file?u?",
               Blank_Line_Location);

         elsif Blank_Lines >= 3 then
            Error_Msg -- CODEFIX
              ("(style) blank lines not allowed at end of file?u?",
               Blank_Line_Location);
         end if;
      end if;
   end Check_EOF;

   -----------------------------------
   -- Check_Exponentiation_Operator --
   -----------------------------------

   --  No spaces are required for the ** operator in GNAT style check mode

   procedure Check_Exponentiation_Operator is
   begin
      null;
   end Check_Exponentiation_Operator;

   --------------
   -- Check_HT --
   --------------

   --  In check horizontal tab mode (-gnatyh), tab characters are not allowed

   procedure Check_HT is
   begin
      if Style_Check_Horizontal_Tabs then
         Error_Msg_S -- CODEFIX
           ("(style) horizontal tab not allowed?h?");
      end if;
   end Check_HT;

   -----------------------
   -- Check_Indentation --
   -----------------------

   --  In check indentation mode (-gnaty? for ? a digit), a new statement or
   --  declaration is required to start in a column that is a multiple of the
   --  indentation amount.

   procedure Check_Indentation is
   begin
      if Style_Check_Indentation /= 0 then
         if Token_Ptr = First_Non_Blank_Location
           and then Start_Column rem Style_Check_Indentation /= 0
         then
            Error_Msg_SC -- CODEFIX
              ("(style) bad indentation?0?");
         end if;
      end if;
   end Check_Indentation;

   -------------------------------------
   -- Check_Left_Paren_Square_Bracket --
   -------------------------------------

   --  In check token mode (-gnatyt), left paren must not be preceded by an
   --  identifier character or digit (a separating space is required) and may
   --  never be followed by a space.
   --  Same applies for the left square bracket starting from Ada version 2022.

   procedure Check_Left_Paren_Square_Bracket is
   begin
      if Style_Check_Tokens then
         if Token_Ptr > Source_First (Current_Source_File)
           and then Identifier_Char (Source (Token_Ptr - 1))
         then
            Error_Space_Required (Token_Ptr);
         end if;

         Check_No_Space_After;
      end if;
   end Check_Left_Paren_Square_Bracket;

   ---------------------------
   -- Check_Line_Max_Length --
   ---------------------------

   --  In check max line length mode (-gnatym), the line length must
   --  not exceed the permitted maximum value.

   procedure Check_Line_Max_Length (Len : Nat) is
   begin
      if Style_Check_Max_Line_Length then
         if Len > Style_Max_Line_Length then
            Error_Msg
              ("(style) this line is too long?M?",
               Current_Line_Start + Source_Ptr (Style_Max_Line_Length));
         end if;
      end if;
   end Check_Line_Max_Length;

   ---------------------------
   -- Check_Line_Terminator --
   ---------------------------

   --  In check blanks at end mode (-gnatyb), lines may not end with a
   --  trailing space.

   --  In check form feeds mode (-gnatyf), the line terminator may not
   --  be either of the characters FF or VT.

   --  In check DOS line terminators node (-gnatyd), the line terminator
   --  must be a single LF, without a following CR.

   procedure Check_Line_Terminator (Len : Nat) is
      S : Source_Ptr;

      L : Nat := Len;
      --  Length of line (adjusted down for blanks at end of line)

   begin
      --  Reset count of blank lines if first line

      if Get_Logical_Line_Number (Scan_Ptr) = 1 then
         Blank_Lines := 0;
      end if;

      --  Check FF/VT terminators

      if Style_Check_Form_Feeds then
         if Source (Scan_Ptr) = ASCII.FF then
            Error_Msg_S -- CODEFIX
              ("(style) form feed not allowed?f?");
         elsif Source (Scan_Ptr) = ASCII.VT then
            Error_Msg_S -- CODEFIX
              ("(style) vertical tab not allowed?f?");
         end if;
      end if;

      --  Check DOS line terminator

      if Style_Check_DOS_Line_Terminator then

         --  Ignore EOF, since we only get called with an EOF if it is the last
         --  character in the buffer (and was therefore not in the source
         --  file), since the terminating EOF is added to stop the scan.

         if Source (Scan_Ptr) = EOF then
            null;

         --  Bad terminator if we don't have an LF

         elsif Source (Scan_Ptr) /= LF then
            Error_Msg_S ("(style) incorrect line terminator?d?");
         end if;
      end if;

      --  Remove trailing spaces

      S := Scan_Ptr;
      while L > 0 and then Is_White_Space (Source (S - 1)) loop
         S := S - 1;
         L := L - 1;
      end loop;

      --  Issue message for blanks at end of line if option enabled

      if Style_Check_Blanks_At_End and then L < Len then
         Error_Msg -- CODEFIX
           ("(style) trailing spaces not permitted?b?", S);
      end if;

      --  Deal with empty (blank) line

      if L = 0 then

         --  Increment blank line count

         Blank_Lines := Blank_Lines + 1;

         --  If first blank line, record location for later error message

         if Blank_Lines = 1 then
            Blank_Line_Location := Scan_Ptr;
         end if;

      --  Non-blank line, check for previous multiple blank lines

      else
         if Style_Check_Blank_Lines and then Blank_Lines > 1 then
            Error_Msg -- CODEFIX
              ("(style) multiple blank lines?u?", Blank_Line_Location);
         end if;

         --  And reset blank line count

         Blank_Lines := 0;
      end if;
   end Check_Line_Terminator;

   ------------------
   -- Check_Not_In --
   ------------------

   --  In check tokens mode, only one space between NOT and IN

   procedure Check_Not_In is
   begin
      if Style_Check_Tokens then
         if Source (Token_Ptr - 1) /= ' '
           or else Token_Ptr - Prev_Token_Ptr /= 4
         then -- CODEFIX?
            Error_Msg
              ("(style) single space must separate NOT and IN?t?",
               Token_Ptr - 1);
         end if;
      end if;
   end Check_Not_In;

   --------------------------
   -- Check_No_Space_After --
   --------------------------

   procedure Check_No_Space_After is
      S : Source_Ptr;

   begin
      if Is_White_Space (Source (Scan_Ptr)) then

         --  Allow one or more spaces if followed by comment

         S := Scan_Ptr + 1;
         loop
            if Source (S) = '-' and then Source (S + 1) = '-' then
               return;

            elsif Is_White_Space (Source (S)) then
               S := S + 1;

            else
               exit;
            end if;
         end loop;

         Error_Space_Not_Allowed (Scan_Ptr);
      end if;
   end Check_No_Space_After;

   ---------------------------
   -- Check_No_Space_Before --
   ---------------------------

   procedure Check_No_Space_Before is
   begin
      if Token_Ptr > First_Non_Blank_Location
         and then Source (Token_Ptr - 1) <= ' '
      then
         Error_Space_Not_Allowed (Token_Ptr - 1);
      end if;
   end Check_No_Space_Before;

   -----------------------
   -- Check_Pragma_Name --
   -----------------------

   --  In check pragma casing mode (-gnatyp), pragma names must be mixed
   --  case, i.e. start with an upper case letter, and otherwise lower case,
   --  except after an underline character.

   procedure Check_Pragma_Name is
   begin
      if Style_Check_Pragma_Casing then
         if Determine_Token_Casing /= Mixed_Case then
            Error_Msg_SC -- CODEFIX
              ("(style) bad capitalization, mixed case required?p?");
         end if;
      end if;
   end Check_Pragma_Name;

   -----------------------
   -- Check_Right_Paren --
   -----------------------

   --  In check token mode (-gnatyt), right paren must not be immediately
   --  followed by an identifier character, and must never be preceded by
   --  a space unless it is the initial non-blank character on the line.

   procedure Check_Right_Paren is
   begin
      if Style_Check_Tokens then
         if Identifier_Char (Source (Token_Ptr + 1)) then
            Error_Space_Required (Token_Ptr + 1);
         end if;

         Check_No_Space_Before;
      end if;
   end Check_Right_Paren;

   ---------------------
   -- Check_Semicolon --
   ---------------------

   --  In check token mode (-gnatyt), semicolon does not permit a preceding
   --  space and a following space is required.

   procedure Check_Semicolon is
   begin
      if Style_Check_Tokens then
         Check_No_Space_Before;

         if Source (Scan_Ptr) > ' ' then
            Error_Space_Required (Scan_Ptr);
         end if;
      end if;
   end Check_Semicolon;

   -------------------------------
   -- Check_Separate_Stmt_Lines --
   -------------------------------

   procedure Check_Separate_Stmt_Lines is
   begin
      if Style_Check_Separate_Stmt_Lines then
         Check_Separate_Stmt_Lines_Cont;
      end if;
   end Check_Separate_Stmt_Lines;

   ------------------------------------
   -- Check_Separate_Stmt_Lines_Cont --
   ------------------------------------

   procedure Check_Separate_Stmt_Lines_Cont is
      S : Source_Ptr;

   begin
      --  Skip past white space

      S := Scan_Ptr;
      while Is_White_Space (Source (S)) loop
         S := S + 1;
      end loop;

      --  Line terminator is OK

      if Source (S) in Line_Terminator then
         return;

      --  Comment is OK

      elsif Source (S) = '-' and then Source (S + 1) = '-' then
         return;

      --  ABORT keyword is OK after THEN (THEN ABORT case)

      elsif Token = Tok_Then
        and then (Source (S + 0) = 'a' or else Source (S + 0) = 'A')
        and then (Source (S + 1) = 'b' or else Source (S + 1) = 'B')
        and then (Source (S + 2) = 'o' or else Source (S + 2) = 'O')
        and then (Source (S + 3) = 'r' or else Source (S + 3) = 'R')
        and then (Source (S + 4) = 't' or else Source (S + 4) = 'T')
        and then (Source (S + 5) in Line_Terminator
                   or else Is_White_Space (Source (S + 5)))
      then
         return;

      --  PRAGMA keyword is OK after ELSE

      elsif Token = Tok_Else
        and then (Source (S + 0) = 'p' or else Source (S + 0) = 'P')
        and then (Source (S + 1) = 'r' or else Source (S + 1) = 'R')
        and then (Source (S + 2) = 'a' or else Source (S + 2) = 'A')
        and then (Source (S + 3) = 'g' or else Source (S + 3) = 'G')
        and then (Source (S + 4) = 'm' or else Source (S + 4) = 'M')
        and then (Source (S + 5) = 'a' or else Source (S + 5) = 'A')
        and then (Source (S + 6) in Line_Terminator
                   or else Is_White_Space (Source (S + 6)))
      then
         return;

         --  Otherwise we have the style violation we are looking for

      else
         if Token = Tok_Then then
            Error_Msg -- CODEFIX
              ("(style) no statements may follow THEN on same line?S?", S);
         else
            Error_Msg
              ("(style) no statements may follow ELSE on same line?S?", S);
         end if;
      end if;
   end Check_Separate_Stmt_Lines_Cont;

   ----------------
   -- Check_Then --
   ----------------

   --  In check if then layout mode (-gnatyi), we expect a THEN keyword to
   --  appear either on the same line as the IF, or on a separate line if
   --  the IF statement extends for more than one line.

   procedure Check_Then (If_Loc : Source_Ptr) is
   begin
      if Style_Check_If_Then_Layout then
         declare
            If_Line   : constant Physical_Line_Number :=
              Get_Physical_Line_Number (If_Loc);
            Then_Line : constant Physical_Line_Number :=
              Get_Physical_Line_Number (Token_Ptr);
         begin
            if If_Line = Then_Line then
               null;
            elsif Token_Ptr /= First_Non_Blank_Location then
               Error_Msg_SC ("(style) misplaced THEN?i?");
            end if;
         end;
      end if;
   end Check_Then;

   -------------------------------
   -- Check_Unary_Plus_Or_Minus --
   -------------------------------

   --  In check token mode (-gnatyt), unary plus or minus must not be
   --  followed by a space.

   --  Annoying exception: if we have the sequence =>+ within a Depends or
   --  Refined_Depends pragma or aspect, then we insist on a space rather
   --  than forbidding it.

   procedure Check_Unary_Plus_Or_Minus (Inside_Depends : Boolean := False) is
   begin
      if Style_Check_Tokens then
         if Inside_Depends then
            Require_Following_Space;
         else
            Check_No_Space_After;
         end if;
      end if;
   end Check_Unary_Plus_Or_Minus;

   ------------------------
   -- Check_Vertical_Bar --
   ------------------------

   --  In check token mode (-gnatyt), vertical bar must be surrounded by spaces

   procedure Check_Vertical_Bar is
   begin
      if Style_Check_Tokens then
         Require_Preceding_Space;
         Require_Following_Space;
      end if;
   end Check_Vertical_Bar;

   -----------------------
   -- Check_Xtra_Parens --
   -----------------------

   procedure Check_Xtra_Parens (N : Node_Id) is
   begin
      if Style_Check_Xtra_Parens
        and then
          Paren_Count (N) >
            (if Nkind (N) in N_Case_Expression
                           | N_Expression_With_Actions
                           | N_If_Expression
                           | N_Quantified_Expression
                           | N_Raise_Expression
             then 1
             else 0)
      then
         Error_Msg -- CODEFIX
           ("(style) redundant parentheses?x?", Errout.First_Sloc (N));
      end if;
   end Check_Xtra_Parens;

   ----------------------------------
   -- Check_Xtra_Parens_Precedence --
   ----------------------------------

   procedure Check_Xtra_Parens_Precedence (N : Node_Id) is
   begin
      if Style_Check_Xtra_Parens_Precedence
        and then
          Paren_Count (N) >
            (if Nkind (N) in N_Case_Expression
                           | N_Expression_With_Actions
                           | N_If_Expression
                           | N_Quantified_Expression
                           | N_Raise_Expression
             then 1
             else 0)
      then
         Error_Msg -- CODEFIX
           ("(style) redundant parentheses?z?", Errout.First_Sloc (N));
      end if;
   end Check_Xtra_Parens_Precedence;

   ----------------------------
   -- Determine_Token_Casing --
   ----------------------------

   function Determine_Token_Casing return Casing_Type is
   begin
      return Determine_Casing (Source (Token_Ptr .. Scan_Ptr - 1));
   end Determine_Token_Casing;

   -----------------------------
   -- Error_Space_Not_Allowed --
   -----------------------------

   procedure Error_Space_Not_Allowed (S : Source_Ptr) is
   begin
      Error_Msg -- CODEFIX
        ("(style) space not allowed?t?", S);
   end Error_Space_Not_Allowed;

   --------------------------
   -- Error_Space_Required --
   --------------------------

   procedure Error_Space_Required (S : Source_Ptr) is
   begin
      Error_Msg -- CODEFIX
        ("(style) space required?t?", S);
   end Error_Space_Required;

   --------------------
   -- Is_White_Space --
   --------------------

   function Is_White_Space (C : Character) return Boolean is
   begin
      return C = ' ' or else C = HT;
   end Is_White_Space;

   -------------------
   -- Mode_In_Check --
   -------------------

   function Mode_In_Check return Boolean is
   begin
      return Style_Check and Style_Check_Mode_In;
   end Mode_In_Check;

   -----------------
   -- No_End_Name --
   -----------------

   --  In check end/exit labels mode (-gnatye), always require the name of
   --  a subprogram or package to be present on the END, so this is an error.

   procedure No_End_Name (Name : Node_Id) is
   begin
      if Style_Check_End_Labels then
         Error_Msg_Node_1 := Name;
         Error_Msg_SP -- CODEFIX
           ("(style) `END &` required?e?");
      end if;
   end No_End_Name;

   ------------------
   -- No_Exit_Name --
   ------------------

   --  In check end/exit labels mode (-gnatye), always require the name of
   --  the loop to be present on the EXIT when exiting a named loop.

   procedure No_Exit_Name (Name : Node_Id) is
   begin
      if Style_Check_End_Labels then
         Error_Msg_Node_1 := Name;
         Error_Msg_SP -- CODEFIX
           ("(style) `EXIT &` required?e?");
      end if;
   end No_Exit_Name;

   ----------------------------
   -- Non_Lower_Case_Keyword --
   ----------------------------

   --  In check casing mode (-gnatyk), reserved keywords must be spelled
   --  in all lower case (excluding keywords range, access, delta and digits
   --  used as attribute designators).

   procedure Non_Lower_Case_Keyword is
   begin
      if Style_Check_Keyword_Casing then
         Error_Msg_SC -- CODEFIX
           ("(style) reserved words must be all lower case?k?");
      end if;
   end Non_Lower_Case_Keyword;

   -----------------------------
   -- Require_Following_Space --
   -----------------------------

   procedure Require_Following_Space is
   begin
      if Source (Scan_Ptr) > ' ' then
         Error_Space_Required (Scan_Ptr);
      end if;
   end Require_Following_Space;

   -----------------------------
   -- Require_Preceding_Space --
   -----------------------------

   procedure Require_Preceding_Space is
   begin
      if Token_Ptr > Source_First (Current_Source_File)
        and then Source (Token_Ptr - 1) > ' '
      then
         Error_Space_Required (Token_Ptr);
      end if;
   end Require_Preceding_Space;

end Styleg;
