------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             P R E P C O M P                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2003, 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,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Unchecked_Deallocation;

with Errout;   use Errout;
with Namet;    use Namet;
with Lib.Writ; use Lib.Writ;
with Opt;      use Opt;
with Osint;    use Osint;
with Prep;     use Prep;
with Scans;    use Scans;
with Scn;      use Scn;
with Sinput.L; use Sinput.L;
with Stringt;  use Stringt;
with Table;

package body Prepcomp is

   No_Preprocessing : Boolean := True;
   --  Set to True if there is at least one source that needs to be
   --  preprocessed.

   Source_Index_Of_Preproc_Data_File : Source_File_Index := No_Source_File;

   --  The following variable should be a constant, but this is not
   --  possible. Warnings are Off because it is never assigned a value.

   pragma Warnings (Off);
   No_Mapping : Prep.Symbol_Table.Instance;
   pragma Warnings (On);

   type String_Ptr is access String;
   type String_Array is array (Positive range <>) of String_Ptr;
   type String_Array_Ptr is access String_Array;

   procedure Free is
      new Ada.Unchecked_Deallocation (String_Array, String_Array_Ptr);

   Symbol_Definitions : String_Array_Ptr := new String_Array (1 .. 4);
   --  An extensible array to temporarily stores symbol definitions specified
   --  on the command line with -gnateD switches.

   Last_Definition : Natural := 0;
   --  Index of last symbol definition in array Symbol_Definitions

   type Preproc_Data is record
      Mapping      : Symbol_Table.Instance;
      File_Name    : Name_Id   := No_Name;
      Deffile      : String_Id := No_String;
      Undef_False  : Boolean   := False;
      Always_Blank : Boolean   := False;
      Comments     : Boolean   := False;
      List_Symbols : Boolean   := False;
      Processed    : Boolean   := False;
   end record;
   --  Structure to keep the preprocessing data for a file name or for the
   --  default (when Name_Id = No_Name).

   No_Preproc_Data : constant Preproc_Data :=
     (Mapping      => No_Mapping,
      File_Name    => No_Name,
      Deffile      => No_String,
      Undef_False  => False,
      Always_Blank => False,
      Comments     => False,
      List_Symbols => False,
      Processed    => False);

   Default_Data : Preproc_Data := No_Preproc_Data;
   --  The preprocessing data to be used when no specific preprocessing data
   --  is specified for a source.

   Default_Data_Defined : Boolean := False;
   --  True if source for which no specific preprocessing is specified need to
   --  be preprocess with the Default_Data.

   Current_Data : Preproc_Data := No_Preproc_Data;

   package Preproc_Data_Table is new Table.Table
     (Table_Component_Type => Preproc_Data,
      Table_Index_Type     => Int,
      Table_Low_Bound      => 1,
      Table_Initial        => 5,
      Table_Increment      => 5,
      Table_Name           => "Prepcomp.Preproc_Data_Table");
   --  Table to store the specific preprocessing data

   Command_Line_Symbols : Symbol_Table.Instance;
   --  A table to store symbol definitions specified on the command line with
   --  -gnateD switches.

   package Dependencies is new Table.Table
     (Table_Component_Type => Source_File_Index,
      Table_Index_Type     => Int,
      Table_Low_Bound      => 1,
      Table_Initial        => 5,
      Table_Increment      => 5,
      Table_Name           => "Prepcomp.Dependencies");
   --  Table to store the dependencies on preprocessing files

   procedure Add_Command_Line_Symbols;
   --  Add the command line symbol definitions, if any, to the
   --  Prep.Mapping table.

   procedure Skip_To_End_Of_Line;
   --  Ignore errors and scan up to the next end of line or the end of file

   ------------------------------
   -- Add_Command_Line_Symbols --
   ------------------------------

   procedure Add_Command_Line_Symbols is
      Symbol_Id : Prep.Symbol_Id;
   begin
      for J in 1 .. Symbol_Table.Last (Command_Line_Symbols) loop
         Symbol_Id := Prep.Index_Of (Command_Line_Symbols.Table (J).Symbol);

         if Symbol_Id = No_Symbol then
            Symbol_Table.Increment_Last (Prep.Mapping);
            Symbol_Id := Symbol_Table.Last (Prep.Mapping);
         end if;

         Prep.Mapping.Table (Symbol_Id) := Command_Line_Symbols.Table (J);
      end loop;
   end Add_Command_Line_Symbols;

   ----------------------
   -- Add_Dependencies --
   ----------------------

   procedure Add_Dependencies is
   begin
      for Index in 1 .. Dependencies.Last loop
         Add_Preprocessing_Dependency (Dependencies.Table (Index));
      end loop;
   end Add_Dependencies;

   ---------------------------
   -- Add_Symbol_Definition --
   ---------------------------

   procedure Add_Symbol_Definition (Def : String) is
   begin
      --  If Symbol_Definitions is not large enough, double it

      if Last_Definition = Symbol_Definitions'Last then
         declare
            New_Symbol_Definitions : constant String_Array_Ptr :=
              new String_Array (1 .. 2 * Last_Definition);

         begin
            New_Symbol_Definitions (Symbol_Definitions'Range) :=
              Symbol_Definitions.all;
            Free (Symbol_Definitions);
            Symbol_Definitions := New_Symbol_Definitions;
         end;
      end if;

      Last_Definition := Last_Definition + 1;
      Symbol_Definitions (Last_Definition) := new String'(Def);
   end Add_Symbol_Definition;

   -------------------
   -- Check_Symbols --
   -------------------

   procedure Check_Symbols is
   begin
      --  If there is at least one switch -gnateD specified

      if Symbol_Table.Last (Command_Line_Symbols) >= 1 then
         Current_Data := No_Preproc_Data;
         No_Preprocessing := False;
         Current_Data.Processed := True;

         --  Start with an empty, initialized mapping table; use Prep.Mapping,
         --  because Prep.Index_Of uses Prep.Mapping.

         Prep.Mapping := No_Mapping;
         Symbol_Table.Init (Prep.Mapping);

         --  Add the command line symbols

         Add_Command_Line_Symbols;

         --  Put the resulting Prep.Mapping in Current_Data, and immediately
         --  set Prep.Mapping to nil.

         Current_Data.Mapping := Prep.Mapping;
         Prep.Mapping := No_Mapping;

         --  Set the default data

         Default_Data := Current_Data;
         Default_Data_Defined := True;
      end if;
   end Check_Symbols;

   ------------------------------
   -- Parse_Preprocessing_Data --
   ------------------------------

   procedure Parse_Preprocessing_Data_File (N : File_Name_Type) is
      OK : Boolean := False;
      Dash_Location : Source_Ptr;
      Symbol_Data : Prep.Symbol_Data;
      Symbol_Id   : Prep.Symbol_Id;
      T : constant Nat := Total_Errors_Detected;

   begin
      --  Load the preprocessing data file

      Source_Index_Of_Preproc_Data_File := Load_Preprocessing_Data_File (N);

      --  Fail if preprocessing data file cannot be found

      if Source_Index_Of_Preproc_Data_File = No_Source_File then
         Get_Name_String (N);
         Fail ("preprocessing data file """,
               Name_Buffer (1 .. Name_Len),
               """ not found");
      end if;

      --  Initialize the sanner and set its behavior for a processing data file
      Scn.Scanner.Initialize_Scanner
        (No_Unit, Source_Index_Of_Preproc_Data_File);
      Scn.Scanner.Set_End_Of_Line_As_Token (True);
      Scn.Scanner.Reset_Special_Characters;

      For_Each_Line :
      loop
         <<Scan_Line>>
         Scan;

         exit For_Each_Line when Token = Tok_EOF;

         if Token = Tok_End_Of_Line then
            goto Scan_Line;
         end if;

         --  Line is not empty

         OK := False;
         No_Preprocessing := False;
         Current_Data := No_Preproc_Data;

         case Token is
            when Tok_Asterisk =>

               --  Default data

               if Default_Data_Defined then
                  Error_Msg
                    ("multiple default preprocessing data", Token_Ptr);

               else
                  OK := True;
                  Default_Data_Defined := True;
               end if;

            when Tok_String_Literal =>

               --  Specific data

               String_To_Name_Buffer (String_Literal_Id);
               Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
               Current_Data.File_Name := Name_Find;
               OK := True;

               for Index in 1 .. Preproc_Data_Table.Last loop
                  if Current_Data.File_Name =
                       Preproc_Data_Table.Table (Index).File_Name
                  then
                     Error_Msg_Name_1 := Current_Data.File_Name;
                     Error_Msg
                       ("multiple preprocessing data for{", Token_Ptr);
                     OK := False;
                     exit;
                  end if;
               end loop;

            when others =>
               Error_Msg ("`'*` or literal string expected", Token_Ptr);
         end case;

         --  If there is a problem, skip the line

         if not OK then
            Skip_To_End_Of_Line;
            goto Scan_Line;
         end if;

         --  Scan past the * or the literal string

         Scan;

         --  A literal string in second position is a definition file

         if Token = Tok_String_Literal then
            Current_Data.Deffile := String_Literal_Id;
            Current_Data.Processed := False;
            Scan;

         else
            --  If there is no definition file, set Processed to True now

            Current_Data.Processed := True;
         end if;

         --  Start with an empty, initialized mapping table; use Prep.Mapping,
         --  because Prep.Index_Of uses Prep.Mapping.

         Prep.Mapping := No_Mapping;
         Symbol_Table.Init (Prep.Mapping);

         --  Check the switches that may follow

         while Token /= Tok_End_Of_Line and then Token /= Tok_EOF loop

            if Token /= Tok_Minus then
               Error_Msg ("`'-` expected", Token_Ptr);
               Skip_To_End_Of_Line;
               goto Scan_Line;
            end if;

            --  Keep the location of the '-' for possible error reporting

            Dash_Location := Token_Ptr;

            --  Scan past the '-'

            Scan;
            OK := False;
            Change_Reserved_Keyword_To_Symbol;

            --  An identifier (or a reserved word converted to an
            --  identifier) is expected and there must be no blank space
            --  between the '-' and the identifier.

            if Token = Tok_Identifier
              and then Token_Ptr = Dash_Location + 1
            then
               Get_Name_String (Token_Name);

               --  Check the character in the source, because the case is
               --  significant.

               case Sinput.Source (Token_Ptr) is
                  when 'u' =>

                     --  Undefined symbol are False

                     if Name_Len = 1 then
                        Current_Data.Undef_False := True;
                        OK := True;
                     end if;

                  when 'b' =>

                     --  Blank lines

                     if Name_Len = 1 then
                        Current_Data.Always_Blank := True;
                        OK := True;
                     end if;

                  when 'c' =>

                     --  Comment removed lines

                     if Name_Len = 1 then
                        Current_Data.Comments := True;
                        OK := True;
                     end if;

                  when 's' =>

                     --  List symbols

                     if Name_Len = 1 then
                        Current_Data.List_Symbols := True;
                        OK := True;
                     end if;

                  when 'D' =>

                     --  Symbol definition

                     OK := Name_Len > 1;

                     if OK then

                        --  A symbol must be an Ada identifier; it cannot start
                        --  with an underline or a digit.

                        if Name_Buffer (2) = '_'
                          or Name_Buffer (2) in '0' .. '9'
                        then
                           Error_Msg ("symbol expected", Token_Ptr + 1);
                           Skip_To_End_Of_Line;
                           goto Scan_Line;
                        end if;

                        --  Get the name id of the symbol

                        Symbol_Data.On_The_Command_Line := True;
                        Name_Buffer (1 .. Name_Len - 1) :=
                          Name_Buffer (2 .. Name_Len);
                        Name_Len := Name_Len - 1;
                        Symbol_Data.Symbol := Name_Find;

                        if Name_Buffer (1 .. Name_Len) = "if"
                          or else Name_Buffer (1 .. Name_Len) = "else"
                          or else Name_Buffer (1 .. Name_Len) = "elsif"
                          or else Name_Buffer (1 .. Name_Len) = "end"
                          or else Name_Buffer (1 .. Name_Len) = "not"
                          or else Name_Buffer (1 .. Name_Len) = "and"
                          or else Name_Buffer (1 .. Name_Len) = "then"
                        then
                           Error_Msg ("symbol expected", Token_Ptr + 1);
                           Skip_To_End_Of_Line;
                           goto Scan_Line;
                        end if;

                        --  Get the name id of the original symbol, with
                        --  possibly capital letters.

                        Name_Len := Integer (Scan_Ptr - Token_Ptr - 1);

                        for J in 1 .. Name_Len loop
                           Name_Buffer (J) :=
                             Sinput.Source (Token_Ptr + Text_Ptr (J));
                        end loop;

                        Symbol_Data.Original := Name_Find;

                        --  Scan past D<symbol>

                        Scan;

                        if Token /= Tok_Equal then
                           Error_Msg ("`=` expected", Token_Ptr);
                           Skip_To_End_Of_Line;
                           goto Scan_Line;
                        end if;

                        --  Scan past '='

                        Scan;

                        --  Here any reserved word is OK

                        Change_Reserved_Keyword_To_Symbol
                          (All_Keywords => True);

                        --  Value can be an identifier (or a reserved word)
                        --  or a literal string.

                        case Token is
                           when Tok_String_Literal =>
                              Symbol_Data.Is_A_String := True;
                              Symbol_Data.Value := String_Literal_Id;

                           when Tok_Identifier =>
                              Symbol_Data.Is_A_String := False;
                              Start_String;

                              for J in Token_Ptr .. Scan_Ptr - 1 loop
                                 Store_String_Char (Sinput.Source (J));
                              end loop;

                              Symbol_Data.Value := End_String;

                           when others =>
                              Error_Msg
                                ("literal string or identifier expected",
                                 Token_Ptr);
                              Skip_To_End_Of_Line;
                              goto Scan_Line;
                        end case;

                        --  If symbol already exists, replace old definition
                        --  by new one.

                        Symbol_Id := Prep.Index_Of (Symbol_Data.Symbol);

                        --  Otherwise, add a new entry in the table.

                        if Symbol_Id = No_Symbol then
                           Symbol_Table.Increment_Last (Prep.Mapping);
                           Symbol_Id := Symbol_Table.Last (Mapping);
                        end if;

                        Prep.Mapping.Table (Symbol_Id) := Symbol_Data;
                     end if;

                  when others =>
                     null;
               end case;

               Scan;
            end if;

            if not OK then
               Error_Msg ("invalid switch", Dash_Location);
               Skip_To_End_Of_Line;
               goto Scan_Line;
            end if;
         end loop;

         --  Add the command line symbols, if any, possibly replacing symbols
         --  just defined.

         Add_Command_Line_Symbols;

         --  Put the resulting Prep.Mapping in Current_Data, and immediately
         --  set Prep.Mapping to nil.

         Current_Data.Mapping := Prep.Mapping;
         Prep.Mapping := No_Mapping;

         --  Record Current_Data

         if Current_Data.File_Name = No_Name then
            Default_Data := Current_Data;

         else
            Preproc_Data_Table.Increment_Last;
            Preproc_Data_Table.Table (Preproc_Data_Table.Last) := Current_Data;
         end if;

         Current_Data := No_Preproc_Data;
      end loop For_Each_Line;

      Scn.Scanner.Set_End_Of_Line_As_Token (False);

      --  Fail if there were errors in the preprocessing data file

      if Total_Errors_Detected > T then
         Errout.Finalize;
         Fail ("errors found in preprocessing data file """,
               Get_Name_String (N),
               """");
      end if;

      --  Record the dependency on the preprocessor data file

      Dependencies.Increment_Last;
      Dependencies.Table (Dependencies.Last) :=
        Source_Index_Of_Preproc_Data_File;
   end Parse_Preprocessing_Data_File;

   ---------------------------
   -- Prepare_To_Preprocess --
   ---------------------------

   procedure Prepare_To_Preprocess
     (Source               : File_Name_Type;
      Preprocessing_Needed : out Boolean)
   is
      Default : Boolean := False;
      Index   : Int := 0;

   begin
      --  By default, preprocessing is not needed

      Preprocessing_Needed := False;

      if No_Preprocessing then
         return;
      end if;

      --  First, look for preprocessing data specific to the current source

      for J in 1 .. Preproc_Data_Table.Last loop
         if Preproc_Data_Table.Table (J).File_Name = Source then
            Index := J;
            Current_Data := Preproc_Data_Table.Table (J);
            exit;
         end if;
      end loop;

      --  If no specific preprocessing data, then take the default

      if Index = 0 then
         if Default_Data_Defined then
            Current_Data := Default_Data;
            Default := True;

         else
            --  If no default, then nothing to do

            return;
         end if;
      end if;

      --  Set the preprocessing flags according to the preprocessing data

      if Current_Data.Comments and then not Current_Data.Always_Blank then
         Comment_Deleted_Lines := True;
         Blank_Deleted_Lines   := False;

      else
         Comment_Deleted_Lines := False;
         Blank_Deleted_Lines   := True;
      end if;

      Undefined_Symbols_Are_False := Current_Data.Undef_False;
      List_Preprocessing_Symbols  := Current_Data.List_Symbols;

      --  If not already done it, process the definition file

      if Current_Data.Processed then
         --  Set Prep.Mapping

         Prep.Mapping := Current_Data.Mapping;

      else
         --  First put the mapping in Prep.Mapping, because Prep.Parse_Def_File
         --  works on Prep.Mapping.

         Prep.Mapping := Current_Data.Mapping;

         String_To_Name_Buffer (Current_Data.Deffile);

         declare
            N : constant Name_Id := Name_Find;
            Deffile : constant Source_File_Index :=  Load_Definition_File (N);
            Add_Deffile : Boolean := True;
            T : constant Nat := Total_Errors_Detected;

         begin
            if Deffile = No_Source_File then
               Fail ("definition file """,
                     Get_Name_String (N),
                     """ cannot be found");
            end if;

            --  Initialize the preprocessor and set the characteristics of the
            --  scanner for a definition file.

            Prep.Initialize
              (Error_Msg         => Errout.Error_Msg'Access,
               Scan              => Scn.Scanner.Scan'Access,
               Set_Ignore_Errors => Errout.Set_Ignore_Errors'Access,
               Put_Char          => null,
               New_EOL           => null);

            Scn.Scanner.Set_End_Of_Line_As_Token (True);
            Scn.Scanner.Reset_Special_Characters;

            --  Initialize the scanner and process the definition file

            Scn.Scanner.Initialize_Scanner (No_Unit, Deffile);
            Prep.Parse_Def_File;

            --  Reset the behaviour of the scanner to the default

            Scn.Scanner.Set_End_Of_Line_As_Token (False);

            --  Fail if errors were found while processing the definition file

            if T /= Total_Errors_Detected then
               Errout.Finalize;
               Fail ("errors found in definition file """,
                     Get_Name_String (N),
                     """");
            end if;

            for Index in 1 .. Dependencies.Last loop
               if Dependencies.Table (Index) = Deffile then
                  Add_Deffile := False;
                  exit;
               end if;
            end loop;

            if Add_Deffile then
               Dependencies.Increment_Last;
               Dependencies.Table (Dependencies.Last) := Deffile;
            end if;
         end;

         --  Get back the mapping, indicate that the definition file is
         --  processed and store back the preprocessing data.

         Current_Data.Mapping := Prep.Mapping;
         Current_Data.Processed := True;

         if Default then
            Default_Data := Current_Data;

         else
            Preproc_Data_Table.Table (Index) := Current_Data;
         end if;
      end if;

      Preprocessing_Needed := True;
   end Prepare_To_Preprocess;

   ---------------------------------------------
   -- Process_Command_Line_Symbol_Definitions --
   ---------------------------------------------

   procedure Process_Command_Line_Symbol_Definitions is
      Symbol_Data : Prep.Symbol_Data;
      Found : Boolean := False;

   begin
      Symbol_Table.Init (Command_Line_Symbols);

      --  The command line definitions have been stored temporarily in
      --  array Symbol_Definitions.

      for Index in 1 .. Last_Definition loop
         --  Check each symbol definition, fail immediately if syntax is not
         --  correct.

         Check_Command_Line_Symbol_Definition
           (Definition => Symbol_Definitions (Index).all,
            Data => Symbol_Data);
         Found := False;

         --  If there is already a definition for this symbol, replace the old
         --  definition by this one.

         for J in 1 .. Symbol_Table.Last (Command_Line_Symbols) loop
            if Command_Line_Symbols.Table (J).Symbol = Symbol_Data.Symbol then
               Command_Line_Symbols.Table (J) := Symbol_Data;
               Found := True;
               exit;
            end if;
         end loop;

         --  Otherwise, create a new entry in the table

         if not Found then
            Symbol_Table.Increment_Last (Command_Line_Symbols);
            Command_Line_Symbols.Table
              (Symbol_Table.Last (Command_Line_Symbols)) := Symbol_Data;
         end if;
      end loop;
   end Process_Command_Line_Symbol_Definitions;

   -------------------------
   -- Skip_To_End_Of_Line --
   -------------------------

   procedure Skip_To_End_Of_Line is
   begin
      Set_Ignore_Errors (To => True);

      while Token /= Tok_End_Of_Line and then Token /= Tok_EOF loop
         Scan;
      end loop;

      Set_Ignore_Errors (To => False);
   end Skip_To_End_Of_Line;

end Prepcomp;
