------------------------------------------------------------------------------
--                                                                          --
--                            GNAT2XML COMPONENTS                           --
--                                                                          --
--                    G N A T 2 X M L . A D A _ T R E E S                   --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                  Copyright (C) 2012-2014, AdaCore, Inc.                  --
--                                                                          --
-- Gnat2xml is free software; you can redistribute it and/or modify it      --
-- under terms of the  GNU General Public License  as published by the Free --
-- Software Foundation;  either version 2,  or  (at your option)  any later --
-- version. Gnat2xml is distributed  in the hope  that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MER-      --
-- CHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General  --
-- Public License for more details. You should have received a copy of the  --
-- GNU General Public License distributed with GNAT; see file COPYING. If   --
-- not, write to the Free Software Foundation, 59 Temple Place Suite 330,   --
-- Boston, MA 02111-1307, USA.                                              --
-- The gnat2xml tool was derived from the Avatox sources.                   --
------------------------------------------------------------------------------

pragma Ada_2012;

--  This package provides a conversion routine for converting an Ada_Tree to
--  textual Ada code.

with System.WCh_Con;

pragma Warnings (Off); -- imported for children
with ASIS_UL.String_Utilities; use ASIS_UL.String_Utilities;
with ASIS_UL.Dbg_Out;
with Ada.Characters.Latin_1;   use Ada.Characters.Latin_1;
pragma Warnings (On);

with Ada_Trees.Buffers; use Ada_Trees.Buffers;

package Ada_Trees.Formatting is

   type PP_Casing is
   --  Defines the casing of identifiers and keywords generated by gnatpp
    (Lower_Case,
   --  All letters are lowercase
    Upper_Case,
   --  All letters are uppercase
    Mixed,
   --  For both defining and usage occurrences of identifiers The first letter
   --  and each letter which immediately follows the underscore are uppercase,
   --  and all the other letters are lowercase
    As_Declared);
   --  All the usage occurrences of identifiers have the same casing as
   --  defining occurrences, defining occurrences have the same casing as
   --  the corresponding defining occurrences in the argument source.

   Line_Len_Limit : constant Natural := 256;

   type Formatting_Options is record
      PP_Indentation : Positive range 1 .. 9 := 3;
      --  Indentation level

      PP_Cont_Line_Indentation : Positive range 1 .. 9 := 2;
      --  Indentation for continuation lines

      PP_Attribute_Casing : PP_Casing range Lower_Case .. Mixed := Mixed;

      PP_Keyword_Casing : PP_Casing range Lower_Case .. Upper_Case :=
        Lower_Case;

      PP_Pragma_Casing : PP_Casing range Lower_Case .. Mixed := Mixed;
      --  Specifies the casing of pragma names and identifiers specific to
      --  pragmas

      PP_Name_Casing : PP_Casing := As_Declared;
      --  Defines the casing for both defining and usage occurrences of the
      --  names

      PP_Enum_Literal_Casing : PP_Casing := As_Declared;
      --  Defines the casing for both defining and usage occurrences of the
      --  enumeration literals.

      PP_Type_Casing : PP_Casing := As_Declared;
      --  Defines the casing for both defining and usage occurrences of the
      --  type (and subtype???) names.

      PP_Nnumbers_Casing : PP_Casing := As_Declared;
      --  Defines the casing for both defining and usage occurrences of the
      --  named numbers names.

      Use_Predefined_Casing : Boolean := True;
      --  This flag specifies if for the predefined names should be used the
      --  same casing as given in RM95

      Use_Dictionary : Boolean := False;
      --  This flag specifies if the exception dictionary should be used for
      --  defining the name casing

      Format_Comments : Boolean := True;
      --  If this flag is set OFF, all the comments (comment lines and
      --  end-of-line comments) are moved into the result unchanged (no
      --  indentation or long line splitting is performed).

      GNAT_Comment_Inden : Boolean := True;
      --  Comment lines are indented in GNAT style. The difference with
      --  Standard_Comment_Indent is that comment lines preceding if and
      --  case statements alternatives and 'begin/ keywords are indented as
      --  the corresponding alternatives or keywords, but not as enclosing
      --  statements.

      Standard_Comment_Indent : Boolean := False;
      --  Comment lines are indented as the corresponding code lines.

      GNAT_Comment_Start : Boolean := False;
      --  The comment (if non-empty) should have at least two space characters
      --  after '--'

      Reformat_Comment_Block : Boolean := False;
      --  For sequences of comment lines (separated by space lines or empty
      --  comment lines (lines containing only two minuses) the attempt should
      --  be made to reformat the text of the comment in a word processor style
      --  - that is, to put as many words in the line as possible, using only
      --  one space as a separator.

      Preserve_Special_Comments : Boolean := False;
      --  Do not change the special comment lines. A comment line is considered
      --  as a special comments if it has a special character just after '--'.
      --  See ??? for the details of the definition of a special character

      No_Tab_In_Comments : Boolean := False;
      --  Remove HT and VT from the content of the comments. If this flag is
      --  set ON, all the VT characters are removed from the comment text and
      --  replaced with spaces to get to the nearest Tab stop (the Tab step is
      --  supposed to be equal to 8), and after that the comment line may be
      --  further reformatted to get the indentation and maximum line length
      --  rules. As for now, reformattable comment blocks can not contain HT
      --  characters, and VT are removed from reformattable blocks as a part
      --  of reformatting.

      Comments_Only : Boolean := False;

      End_Labels : Boolean := True;
      --  Do set end/exit labels even if missed in the argument source;

      Add_FF : Boolean := False;
      --  Add Form Feed after a pragma Page.

      Compact_Layout : Boolean := True;
      --  Use compact layout for records and named statements;

      Separate_Line_For_IS : Boolean := True;
      --  Use a separate sine for IS in subprogram body in case if we need more
      --  than one line for subprogram specification

      Separate_Line_For_THEN_and_LOOP : Boolean := False;
      --  Use a separate line for THEN in if statements and LOOP in FOR and
      --  WHILE loops.

      No_Separate_Line_For_THEN_and_LOOP : Boolean := False;
      --  Do not use a separate line for THEN in if statements and LOOP in FOR
      --  and WHILE loops.
      --
      --  If both Separate_Line_For_THEN_and_LOOP and
      --  No_Separate_Line_For_THEN_and_LOOP flags are off, the layout of
      --  THEN and LOOP keywords are defined by other formatting rules

      Separate_Line_For_Label : Boolean := False;
      --  Use a separate line for statement label(s).

      Separate_Line_For_USE : Boolean := False;
      --  Use a separate line for each USE clause that is a part of a context
      --  clause, applied to both type and package use clauses.

      Separate_Line_For_Stmt_Name : Boolean := False;
      --  Use a separate line for a loop or block name and do not use an extra
      --  indentation level for a statement itself. This overrides the layout
      --  of the named statements that is specified by -l(1|2|3) option.

      RM_Style_Spacing : Boolean := False;
      --  Follow Ada Reference Manual style when placing spaces before
      --  delimiters: - no space before '(' - no space between a statement
      --  name and colon. - what else?

      Add_Empty_Lines : Boolean := True;
      --  Add empty lines (if needed to separate compound statements, bodies
      --  and return statements)

      Insert_Blank_Lines : Boolean := False;
      --  Insert blank lines at certain places (between bodies, for example)

      Preserve_Blank_Lines : Boolean := False;
      --  Don't squeeze multiple blank lines down to one

      Max_Line_Length : Natural range 32 .. Line_Len_Limit := 79;

      Align_Colons_In_Decl : Boolean := True;
      Align_Asign_In_Decl  : Boolean := True;
      Align_Asign_In_Stmts : Boolean := True;
      Align_Arrows         : Boolean := True;
      Align_Ats            : Boolean := True;

      Case_Threshold : Natural := 10;
      --  Starting from this number an extra indentation level is not used for
      --  variants in record variant part and case statement alternatives in
      --  case statements, the value 0 means that the extra level is used for
      --  any number of variants and case alternatives

      Par_Specs_Threshold : Natural := Natural'Last;
      --  If the length of parameter specification list is greater than this
      --  number, each parameter specification is placed on a separate line
      --  (for functions the threshold is this value minus 1). The default is
      --  huge, which effectively disables this feature.

      Par_Associations_Threshold : Natural := Natural'Last;
      --  If the length of parameter association list is greater than this
      --  number, and the list contains at least one named association, then
      --  each parameter association is placed on a separate line.

      Decimal_Grouping : Natural := 0;
      --  Number of characters between underscores added to numeric literals
      --  with no base specified. E.g. "123_456". Zero means don't add
      --  underscores.
      Based_Grouping : Natural := 0;
      --  Same as Decimal_Grouping, but used when a base (including base 10)
      --  has been specified. E.g. "16#DEAD_BEEF#".

      Pp_Off_String, Pp_On_String : access String := null;
      --  Comment strings that cause pretty printing to be turned off and
      --  on. The initial lead "--" is not included, but initial leading
      --  blanks, if any are included.

      Output_Encoding : System.WCh_Con.WC_Encoding_Method :=
        System.WCh_Con.WCEM_Brackets;
      --  Encoding method for output of wide characters. Defaults to the input
      --  method.

      Is_PP : Boolean := False;
      --  True if this is gnatpp; False for xml2gnat. There are some formatting
      --  options that don't quite work in xml2gnat, which is why this is
      --  needed.
   end record; -- Formatting_Options

   procedure Tree_To_Ada
     (Root      : Ada_Tree;
      Src_Buf   : in out Buffer;
      Write_BOM : Boolean;
      Options   : Formatting_Options;
      Output_Name : String;
      Form_String : String;
      Do_Diff : Boolean;
      Output_Written : out Boolean);
   --  Convert Tree to Ada source text. Src_Buf is the contents of the original
   --  Ada source file. It needs to be 'in out' because we call things like
   --  Move_Forward and Mark, but we don't modify the actual text.  Write_BOM
   --  indicates that a BOM should be written to the output.  Output goes to
   --  the file named Output_Name; "" means current output. Form_String is the
   --  Form string to pass to Create. If Do_Diff is True, and the output is
   --  identical to the input, nothing is written.  Output_Written indicates
   --  whether the output was written.

   procedure Tree_To_Ada
     (Root        : Ada_Tree;
      Source_Name : String;
      Options     : Formatting_Options;
      Output_Name : String);
   --  Same as above, but reads the source from the named file. This one is
   --  called from code generated by Ada_Trees.Self_Rep.

   Token_Mismatch : exception;
   --  Raised by Tree_To_Ada if it detects a bug in itself that causes the
   --  output tokens to not match the input properly.

   --  For debugging:

   procedure Put_Ada_Templates;
   procedure Format_Debug_Output (Message : String);

end Ada_Trees.Formatting;
