OSDN Git Service

2010-10-05 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / gprep.adb
index fdd1f8b..88710d6 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2002-2004, Free Software Foundation, Inc.         --
+--          Copyright (C) 2002-2010, 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- --
+-- 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 COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- 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.      --
@@ -27,7 +26,6 @@
 with Csets;
 with Err_Vars; use Err_Vars;
 with Errutil;
-with Gnatvsn;
 with Namet;    use Namet;
 with Opt;
 with Osint;    use Osint;
@@ -37,14 +35,16 @@ with Scng;
 with Sinput.C;
 with Snames;
 with Stringt;  use Stringt;
+with Switch;   use Switch;
 with Types;    use Types;
 
-with Ada.Text_IO;               use Ada.Text_IO;
+with Ada.Text_IO;     use Ada.Text_IO;
+
 with GNAT.Case_Util;            use GNAT.Case_Util;
 with GNAT.Command_Line;
 with GNAT.Directory_Operations; use GNAT.Directory_Operations;
-with GNAT.OS_Lib;               use GNAT.OS_Lib;
 
+with System.OS_Lib; use System.OS_Lib;
 
 package body GPrep is
 
@@ -55,6 +55,14 @@ package body GPrep is
    -- Argument Line Data --
    ------------------------
 
+   Unix_Line_Terminators : Boolean := False;
+   --  Set to True with option -T
+
+   type String_Array is array (Boolean) of String_Access;
+   Yes_No : constant String_Array :=
+     (False => new String'("YES"),
+      True  => new String'("NO"));
+
    Infile_Name  : Name_Id := No_Name;
    Outfile_Name : Name_Id := No_Name;
    Deffile_Name : Name_Id := No_Name;
@@ -74,7 +82,7 @@ package body GPrep is
    File_Name_Buffer_Initial_Size : constant := 50;
    File_Name_Buffer : String_Access :=
                         new String (1 .. File_Name_Buffer_Initial_Size);
-   --  A buffer to build output file names from input file names.
+   --  A buffer to build output file names from input file names
 
    -----------------
    -- Subprograms --
@@ -99,7 +107,7 @@ package body GPrep is
    --  True if C is in 'a' .. 'z' or in 'A' .. 'Z'
 
    procedure Double_File_Name_Buffer;
-   --  Double the size of the file name buffer.
+   --  Double the size of the file name buffer
 
    procedure Preprocess_Infile_Name;
    --  When the specified output is a directory, preprocess the infile name
@@ -113,12 +121,12 @@ package body GPrep is
    --  Process a -D switch on the command line
 
    procedure Put_Char_To_Outfile (C : Character);
-   --  Output one character to the output file.
-   --  Used to initialize the preprocessor.
+   --  Output one character to the output file. Used to initialize the
+   --  preprocessor.
 
    procedure New_EOL_To_Outfile;
-   --  Output a new line to the output file.
-   --  Used to initialize the preprocessor.
+   --  Output a new line to the output file. Used to initialize the
+   --  preprocessor.
 
    procedure Scan_Command_Line;
    --  Scan the switches and the file names
@@ -133,9 +141,7 @@ package body GPrep is
    procedure Display_Copyright is
    begin
       if not Copyright_Displayed then
-         Write_Line ("GNAT Preprocessor " &
-                     Gnatvsn.Gnat_Version_String &
-                     " Copyright 1996-2004 Free Software Foundation, Inc.");
+         Display_Version ("GNAT Preprocessor", "1996");
          Copyright_Displayed := True;
       end if;
    end Display_Copyright;
@@ -162,13 +168,13 @@ package body GPrep is
       --  Do some initializations (order is important here!)
 
       Csets.Initialize;
-      Namet.Initialize;
       Snames.Initialize;
       Stringt.Initialize;
+      Prep.Initialize;
 
       --  Initialize the preprocessor
 
-      Prep.Initialize
+      Prep.Setup_Hooks
         (Error_Msg         => Errutil.Error_Msg'Access,
          Scan              => Scanner.Scan'Access,
          Set_Ignore_Errors => Errutil.Set_Ignore_Errors'Access,
@@ -196,21 +202,23 @@ package body GPrep is
       --  Test we had all the arguments needed
 
       if Infile_Name = No_Name then
+
          --  No input file specified, just output the usage and exit
 
          Usage;
          return;
 
       elsif Outfile_Name = No_Name then
+
          --  No output file specified, just output the usage and exit
 
          Usage;
          return;
       end if;
 
-      --  If a pragma Source_File_Name, we need to keep line numbers.
-      --  So, if the deleted lines are not put as comment, we must output them
-      --  as blank lines.
+      --  If a pragma Source_File_Name, we need to keep line numbers. So, if
+      --  the deleted lines are not put as comment, we must output them as
+      --  blank lines.
 
       if Source_Ref_Pragma and (not Opt.Comment_Deleted_Lines) then
          Opt.Blank_Deleted_Lines := True;
@@ -232,24 +240,24 @@ package body GPrep is
             Sinput.Main_Source_File := Deffile;
 
             if Deffile = No_Source_File then
-               Fail ("unable to find definition file """,
-                     Get_Name_String (Deffile_Name),
-                     """");
+               Fail ("unable to find definition file """
+                     & Get_Name_String (Deffile_Name)
+                     """");
             end if;
 
-            Scanner.Initialize_Scanner (No_Unit, Deffile);
+            Scanner.Initialize_Scanner (Deffile);
 
             Prep.Parse_Def_File;
          end;
       end if;
 
-      --  If there are errors in the definition file, output these errors
-      --  and exit.
+      --  If there are errors in the definition file, output them and exit
 
       if Total_Errors_Detected > 0 then
          Errutil.Finalize (Source_Type => "definition");
-         Fail ("errors in definition file """,
-               Get_Name_String (Deffile_Name), """");
+         Fail ("errors in definition file """
+               & Get_Name_String (Deffile_Name)
+               & """");
       end if;
 
       --  If -s switch was specified, print a sorted list of symbol names and
@@ -279,7 +287,6 @@ package body GPrep is
       --  rooted at the input directory.
 
       Process_Files;
-
    end Gnatprep;
 
    ---------------------
@@ -315,7 +322,7 @@ package body GPrep is
 
    procedure Preprocess_Infile_Name is
       Len    : Natural;
-      First  : Positive := 1;
+      First  : Positive;
       Last   : Natural;
       Symbol : Name_Id;
       Data   : Symbol_Data;
@@ -334,6 +341,7 @@ package body GPrep is
 
       --  Look for possible symbols in the file name
 
+      First := 1;
       while First < Len loop
 
          --  A symbol starts with a dollar sign followed by a letter
@@ -375,7 +383,7 @@ package body GPrep is
 
                      declare
                         Sym_Len : constant Positive := Last - First + 1;
-                        Offset : constant Integer := Name_Len - Sym_Len;
+                        Offset  : constant Integer := Name_Len - Sym_Len;
                         New_Len : constant Natural := Len + Offset;
 
                      begin
@@ -431,7 +439,7 @@ package body GPrep is
 
       Symbol := Index_Of (Data.Symbol);
 
-      --  If symbol does not alrady exist, create a new entry in the mapping
+      --  If symbol does not already exist, create a new entry in the mapping
       --  table.
 
       if Symbol = No_Symbol then
@@ -453,7 +461,7 @@ package body GPrep is
       --  Outfile_Name.
 
       procedure Recursive_Process (In_Dir : String; Out_Dir : String);
-      --  Process recursively files in In_Dir. Results go to Out_Dir.
+      --  Process recursively files in In_Dir. Results go to Out_Dir
 
       ----------------------
       -- Process_One_File --
@@ -462,17 +470,26 @@ package body GPrep is
       procedure Process_One_File is
          Infile : Source_File_Index;
 
+         Modified : Boolean;
+         pragma Warnings (Off, Modified);
+
       begin
-         --  Create the output file; fails if this does not work.
+         --  Create the output file (fails if this does not work)
 
          begin
-            Create (Text_Outfile, Out_File, Get_Name_String (Outfile_Name));
+            Create
+              (File => Text_Outfile,
+               Mode => Out_File,
+               Name => Get_Name_String (Outfile_Name),
+               Form => "Text_Translation=" &
+                       Yes_No (Unix_Line_Terminators).all);
 
          exception
             when others =>
                Fail
-                 ("unable to create output file """,
-                  Get_Name_String (Outfile_Name), """");
+                 ("unable to create output file """
+                  & Get_Name_String (Outfile_Name)
+                  & """");
          end;
 
          --  Load the input file
@@ -480,8 +497,9 @@ package body GPrep is
          Infile := Sinput.C.Load_File (Get_Name_String (Infile_Name));
 
          if Infile = No_Source_File then
-            Fail ("unable to find input file """,
-                  Get_Name_String (Infile_Name), """");
+            Fail ("unable to find input file """
+                  & Get_Name_String (Infile_Name)
+                  & """");
          end if;
 
          --  Set Main_Source_File to the input file for the benefit of
@@ -489,19 +507,20 @@ package body GPrep is
 
          Sinput.Main_Source_File := Infile;
 
-         Scanner.Initialize_Scanner (No_Unit, Infile);
+         Scanner.Initialize_Scanner (Infile);
 
-         --  Output the SFN pragma if asked to
+         --  Output the pragma Source_Reference if asked to
 
          if Source_Ref_Pragma then
-            Put_Line (Outfile.all, "pragma Source_Reference (1, """ &
-                      Get_Name_String (Sinput.File_Name (Infile)) &
-                      """);");
+            Put_Line
+              (Outfile.all,
+               "pragma Source_Reference (1, """ &
+                 Get_Name_String (Sinput.Full_File_Name (Infile)) & """);");
          end if;
 
          --  Preprocess the input file
 
-         Prep.Preprocess;
+         Prep.Preprocess (Modified);
 
          --  In verbose mode, if there is no error, report it
 
@@ -509,8 +528,7 @@ package body GPrep is
             Errutil.Finalize (Source_Type => "input");
          end if;
 
-         --  If we had some errors, delete the output file, and report
-         --  the errors.
+         --  If we had some errors, delete the output file, and report them
 
          if Err_Vars.Total_Errors_Detected > 0 then
             if Outfile /= Standard_Output then
@@ -521,7 +539,7 @@ package body GPrep is
 
             OS_Exit (0);
 
-         --  otherwise, close the output file, and we are done.
+         --  Otherwise, close the output file, and we are done
 
          elsif Outfile /= Standard_Output then
             Close (Text_Outfile);
@@ -552,6 +570,8 @@ package body GPrep is
             Output_Directory := Out_Dir_Name;
          end Set_Directory_Names;
 
+      --  Start of processing for Recursive_Process
+
       begin
          --  Open the current input directory
 
@@ -614,8 +634,9 @@ package body GPrep is
 
                         exception
                            when Directory_Error =>
-                              Fail ("could not create directory """,
-                                    Output, """");
+                              Fail ("could not create directory """
+                                    & Output
+                                    & """");
                         end;
                      end if;
 
@@ -633,8 +654,11 @@ package body GPrep is
          end loop;
       end Recursive_Process;
 
+   --  Start of processing for Process_Files
+
    begin
       if Output_Directory = No_Name then
+
          --  If the output is not a directory, fail if the input is
          --  an existing directory, to avoid possible problems.
 
@@ -648,6 +672,7 @@ package body GPrep is
          Process_One_File;
 
       elsif Input_Directory = No_Name then
+
          --  Get the output file name from the input file name, and process
          --  the single input file.
 
@@ -680,12 +705,23 @@ package body GPrep is
    procedure Scan_Command_Line is
       Switch : Character;
 
+      procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage);
+
+      --  Start of processing for Scan_Command_Line
+
    begin
-      --  Parse the switches
+      --  First check for --version or --help
+
+      Check_Version_And_Help ("GNATPREP", "1996");
+
+      --  Now scan the other switches
+
+      GNAT.Command_Line.Initialize_Option_Scan;
 
       loop
          begin
-            Switch := GNAT.Command_Line.Getopt ("D: b c r s u v");
+            Switch := GNAT.Command_Line.Getopt ("D: b c C r s T u v");
+
             case Switch is
 
                when ASCII.NUL =>
@@ -701,12 +737,18 @@ package body GPrep is
                when 'c' =>
                   Opt.Comment_Deleted_Lines := True;
 
+               when 'C' =>
+                  Opt.Replace_In_Comments := True;
+
                when 'r' =>
                   Source_Ref_Pragma := True;
 
                when 's' =>
                   Opt.List_Preprocessing_Symbols := True;
 
+               when 'T' =>
+                  Unix_Line_Terminators := True;
+
                when 'u' =>
                   Opt.Undefined_Symbols_Are_False := True;
 
@@ -745,7 +787,7 @@ package body GPrep is
             elsif Deffile_Name = No_Name then
                Deffile_Name := Name_Find;
             else
-               Fail ("too many arguments specifed");
+               Fail ("too many arguments specified");
             end if;
          end;
       end loop;
@@ -768,9 +810,11 @@ package body GPrep is
       Write_Line ("gnatprep switches:");
       Write_Line ("   -b  Replace preprocessor lines by blank lines");
       Write_Line ("   -c  Keep preprocessor lines as comments");
+      Write_Line ("   -C  Do symbol replacements within comments");
       Write_Line ("   -D  Associate symbol with value");
       Write_Line ("   -r  Generate Source_Reference pragma");
       Write_Line ("   -s  Print a sorted list of symbol names and values");
+      Write_Line ("   -T  Use LF as line terminators");
       Write_Line ("   -u  Treat undefined symbols as FALSE");
       Write_Line ("   -v  Verbose mode");
       Write_Eol;