------------------------------------------------------------------------------
--                                                                          --
--                            GNATPP COMPONENTS                             --
--                                                                          --
--                     G N A T P P . P P _ O U T P U T                      --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                     Copyright (C) 2001-2009, AdaCore                     --
--                                                                          --
-- GNATPP 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.  GNATPP is  distributed in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABI- --
-- LITY 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,                                                                  --
--                                                                          --
-- GNATPP is maintained by AdaCore (http://www.adacore.com)                 --
--                                                                          --
------------------------------------------------------------------------------

--  This package defines the routines which send pieces of the pretty-printed
--  source into the out stream.

with Asis;                       use Asis;
with Asis.Extensions.Flat_Kinds; use Asis.Extensions.Flat_Kinds;

with GNATPP.Options;             use GNATPP.Options;
with GNATPP.Common;              use GNATPP.Common;

package GNATPP.PP_Output is

   --  ??? May be some of the status variables defined in this package should
   --  ??? go into Status package.

   Output_Pos : Integer range 1 .. Line_Len_Limit + 1 := 1;
   --  The position in the output string to place the next character into
   --  Note: we will never put anything into the max output position!

   Postponed_Space : Boolean := False;
   --  Flag indicating if a space should be sent into the output line
   --  if some other (non-comment) token is supposed to be placed here

   Output_Line : Natural := 0;
   --  The number of the output line.

   Is_New_Output_Line : Boolean := True;
   --  The flag indicating if the previous line is just closed and no
   --  character except white spaces has been outputted into the current line
   --  yet

   function Get_Output_Pos return Integer;
   --  Returns the position in the output line taking into account the setting
   --  of Postponed_Space flag.

   procedure PP_Close_Line;
   --  Closes the current output line by sending New_Line into the output
   --  stream. Sets Is_New_Output_Line ON.

   procedure PP_New_Line
     (Adjust_Depth : Integer := 0;
      Backspace    : Natural := 0);
   --  First, checks Is_New_Output_Line and if it is OFF, closes the current
   --  line. Then sends the proper number of spaces into the new line to get
   --  the required indentation. This number is computed as
   --       (Logical_Depth + Adjust_Depth) * PP_Indentation - Backspace
   --  (at the moment we do not check that this value is not negative but
   --  probably we have to.

   procedure PP_New_Continuation_Line (Adjust_New_Line_Depth : Integer := 0);
   --  Similar to PP_New_Line, but should be used for continuation lines.
   --  It uses PP_Cont_Line_Indentation to compute the indentation.
   --   Adjust_New_Line_Depth may be used to correct indentation level in the
   --  new line.

   procedure PP_New_Line_And_Pad (Up_To : Natural := 0);
   --  The same as previous, but the number of spaces to be sent to the new
   --  line is defined by Up_To parameter (Up_To - 1 space is sent)

   procedure PP_New_Line_For_Index_Def;
   --  A sepcial version of new line procedure for componens of the array
   --  definition (index definitions and component definition).

   procedure PP_Space;
   --  Send one space character into output stream. This procedure does not
   --  check if there is the room for this character in the output line

   procedure PP_Space_If_Needed;
   --  The same  as previous, but it orints out the space only if the
   --  preceding output character was not a space character

   procedure PP_Postponed_Space;
   --  If Postponed_Space is set on, calls PP_Space and sets Postponed_Space
   --  OFF

   procedure PP_Word_No_Move (S : Program_Text);
   --  Send S into output stream. If there is no enough room for S in the
   --  output string, generates the corresponding diagnostic message and
   --  closes the current output line and outputs S in the next line starting
   --  from the first character.
   --  This procedure sets Is_New_Output_Line OFF, and it has not been called
   --  with the argument string containing white spaces only.

   procedure PP_Word (S : Program_Text);
   --  Does the same as PP_Word_No_Move and then moves Line_Pos in the input
   --  string buffer S'Length characters ahead.

   procedure PP_Pad (N : Natural);
   --  Is supposed to be called for a new string. Pads the string up to N
   --  position by sending N-1 spaces into it (does nothing if N=0). This
   --  procedure does not check that there is enough room for these spaces.

   procedure PP_Pad_Up_To (N : Natural);
   --  If N is greater then Output_Pos, pads the positions up to N by space
   --  characters. Otherwise does nothing. This procedure is supposed to be
   --  called for the new string. It does not check that there is enough room
   --  for these spaces

   procedure PP_Keyword (KW : Keyword_Kinds);
   --  Sends the argument keyword in proper case into the output stream.
   --  Changes Line_Pos accordingly

   procedure PP_Delimiter (DL : Delimiter_Kinds);
   --  Sends the argument delimiter into the output stream. Changes Line_Pos
   --  accordingly

   procedure PP_Operator (Op : Flat_Element_Kinds);
   --  Does teh same as two previous functions, but takes the elemend kind
   --  as an operand. Is supposed to be aplied to operators

   procedure PP_Continue_Line
     (Adjust_New_Line_Depth : Integer := 0;
      No_Space              : Boolean := False);
   --  Encapsulates the sequence of actions oftenly needed when continuing the
   --  output of a construct - if the output line is a new line - to add
   --  a proper indentation (for a continuation) or to output a space as a
   --  separator (if No_Space is ON, no space is sent to output line, this
   --  is needed for GNATPP.Options.RM_Style_Spacing mode).
   --  Adjust_New_Line_Depth may be used to correct indentation level in the
   --  new line.

   procedure PP_Continue_Line_Postponed (Adjust_New_Line_Depth : Integer := 0);
   --  Similar to PP_Continue_Line, but instead of sending a space character
   --  into the output is sets the Postponed_Space flag ON. The space
   --  will be output later only if some other token will be sent to the
   --  same output line

   function Available_In_Output return Integer;
   --  Returns the number of positions available in the output line.
   --  The negative result means that the maximal line length is exceeded (this
   --  can happen when printing out a VERY long identifier)

   function Space_Just_Printed return Boolean;
   --  Checks if the latest character sent into the pretty-printed source was
   --   a space character

end GNATPP.PP_Output;
