-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2005, Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2009, 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, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, 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. --
with Csets;
with Err_Vars; use Err_Vars;
with Errutil;
-with Gnatvsn;
with Namet; use Namet;
with Opt;
with Osint; use Osint;
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
-- 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;
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 --
-- 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
-- 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
procedure Display_Copyright is
begin
if not Copyright_Displayed then
- Write_Line ("GNAT Preprocessor " & Gnatvsn.Gnat_Version_String);
- Write_Line ("Copyright 1996-2004 Free Software Foundation, Inc.");
+ Display_Version ("GNAT Preprocessor", "1996");
Copyright_Displayed := True;
end if;
end Display_Copyright;
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,
-- 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;
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
-- rooted at the input directory.
Process_Files;
-
end Gnatprep;
---------------------
procedure Preprocess_Infile_Name is
Len : Natural;
- First : Positive := 1;
+ First : Positive;
Last : Natural;
Symbol : Name_Id;
Data : Symbol_Data;
-- 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
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
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
-- 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 --
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
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
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
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
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);
Output_Directory := Out_Dir_Name;
end Set_Directory_Names;
+ -- Start of processing for Recursive_Process
+
begin
-- Open the current input directory
exception
when Directory_Error =>
- Fail ("could not create directory """,
- Output, """");
+ Fail ("could not create directory """
+ & Output
+ & """");
end;
end if;
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.
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.
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 =>
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;
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;
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;