diff options
Diffstat (limited to 'gcc/ada/gprep.adb')
-rw-r--r-- | gcc/ada/gprep.adb | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/gcc/ada/gprep.adb b/gcc/ada/gprep.adb new file mode 100644 index 00000000000..635d0df8b2b --- /dev/null +++ b/gcc/ada/gprep.adb @@ -0,0 +1,439 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- G P R E P -- +-- -- +-- B o d y -- +-- -- +-- Copyright (C) 2002-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.Text_IO; use Ada.Text_IO; + +with Csets; +with Err_Vars; use Err_Vars; +with Errutil; +with Gnatvsn; +with Namet; use Namet; +with Opt; +with Osint; use Osint; +with Output; use Output; +with Prep; use Prep; +with Scng; +with Sinput.C; +with Snames; +with Stringt; use Stringt; +with Types; use Types; + +with GNAT.Command_Line; +with GNAT.OS_Lib; use GNAT.OS_Lib; + +package body GPrep is + + Copyright_Displayed : Boolean := False; + -- Used to prevent multiple displays of the copyright notice + + ------------------------ + -- Argument Line Data -- + ------------------------ + + Infile_Name : String_Access; + Outfile_Name : String_Access; + Deffile_Name : String_Access; + + Source_Ref_Pragma : Boolean := False; -- Set if -r switch set + -- Record command line options + + Text_Outfile : aliased Ada.Text_IO.File_Type; + Outfile : File_Access := Text_Outfile'Access; + + ----------------- + -- Subprograms -- + ----------------- + + procedure Display_Copyright; + -- Display the copyright notice + + procedure Post_Scan; + -- Null procedure, needed by instantiation of Scng below + + package Scanner is new Scng + (Post_Scan, + Errutil.Error_Msg, + Errutil.Error_Msg_S, + Errutil.Error_Msg_SC, + Errutil.Error_Msg_SP, + Errutil.Style); + -- The scanner for the preprocessor + + procedure Process_Command_Line_Symbol_Definition (S : String); + -- Process a -D switch on ther command line + + procedure Put_Char_To_Outfile (C : Character); + -- 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. + + procedure Scan_Command_Line; + -- Scan the switches and the file names + + procedure Usage; + -- Display the usage + + ----------------------- + -- Display_Copyright -- + ----------------------- + + procedure Display_Copyright is + begin + if not Copyright_Displayed then + Write_Line ("GNAT Preprocessor " & + Gnatvsn.Gnat_Version_String & + " Copyright 1996-2003 Free Software Foundation, Inc."); + Copyright_Displayed := True; + end if; + end Display_Copyright; + + -------------- + -- Gnatprep -- + -------------- + + procedure Gnatprep is + Infile : Source_File_Index; + + begin + -- Do some initializations (order is important here!) + + Csets.Initialize; + Namet.Initialize; + Snames.Initialize; + Stringt.Initialize; + + -- Initialize the preprocessor + + Prep.Initialize + (Error_Msg => Errutil.Error_Msg'Access, + Scan => Scanner.Scan'Access, + Set_Ignore_Errors => Errutil.Set_Ignore_Errors'Access, + Put_Char => Put_Char_To_Outfile'Access, + New_EOL => New_EOL_To_Outfile'Access); + + -- Set the scanner characteristics for the preprocessor + + Scanner.Set_Special_Character ('#'); + Scanner.Set_Special_Character ('$'); + Scanner.Set_End_Of_Line_As_Token (True); + + -- Initialize the mapping table of symbols to values + + Prep.Symbol_Table.Init (Prep.Mapping); + + -- Parse the switches and arguments + + Scan_Command_Line; + + if Opt.Verbose_Mode then + Display_Copyright; + end if; + + -- Test we had all the arguments needed + + if Infile_Name = null then + -- No input file specified, just output the usage and exit + + Usage; + return; + elsif Outfile_Name = null 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 Source_Ref_Pragma and (not Opt.Comment_Deleted_Lines) then + Opt.Blank_Deleted_Lines := True; + end if; + + -- If we have a definition file, parse it + + if Deffile_Name /= null then + declare + Deffile : Source_File_Index; + + begin + Errutil.Initialize; + Deffile := Sinput.C.Load_File (Deffile_Name.all); + + -- Set Main_Source_File to the definition file for the benefit of + -- Errutil.Finalize. + + Sinput.Main_Source_File := Deffile; + + if Deffile = No_Source_File then + Fail ("unable to find definition file """, + Deffile_Name.all, + """"); + end if; + + Scanner.Initialize_Scanner (No_Unit, Deffile); + + Prep.Parse_Def_File; + end; + end if; + + -- If there are errors in the definition file, output these errors + -- and exit. + + if Total_Errors_Detected > 0 then + Errutil.Finalize (Source_Type => "definition"); + Fail ("errors in definition file """, Deffile_Name.all, """"); + end if; + + -- If -s switch was specified, print a sorted list of symbol names and + -- values, if any. + + if Opt.List_Preprocessing_Symbols then + Prep.List_Symbols (Foreword => ""); + end if; + + -- Load the input file + + Infile := Sinput.C.Load_File (Infile_Name.all); + + if Infile = No_Source_File then + Fail ("unable to find input file """, Infile_Name.all, """"); + end if; + + -- Set Main_Source_File to the input file for the benefit of + -- Errutil.Finalize. + + Sinput.Main_Source_File := Infile; + + Scanner.Initialize_Scanner (No_Unit, Infile); + + -- If an output file were specified, create it; fails if this did not + -- work. + + if Outfile_Name /= null then + begin + Create (Text_Outfile, Out_File, Outfile_Name.all); + + exception + when others => + Fail + ("unable to create output file """, Outfile_Name.all, """"); + end; + end if; + + -- Output the SFN pragma if asked to + + if Source_Ref_Pragma then + Put_Line (Outfile.all, "pragma Source_Reference (1, """ & + Get_Name_String (Sinput.File_Name (Infile)) & + """);"); + end if; + + -- Preprocess the input file + + Prep.Preprocess; + + -- In verbose mode, if there is no error, report it + + if Opt.Verbose_Mode and then Err_Vars.Total_Errors_Detected = 0 then + Errutil.Finalize (Source_Type => "input"); + end if; + + -- If we had some errors, delete the output file, and report the errors, + + if Err_Vars.Total_Errors_Detected > 0 then + if Outfile /= Standard_Output then + Delete (Text_Outfile); + end if; + + Errutil.Finalize (Source_Type => "input"); + + -- otherwise, close the output file, and we are done. + + elsif Outfile /= Standard_Output then + Close (Text_Outfile); + end if; + end Gnatprep; + + ------------------------ + -- New_EOL_To_Outfile -- + ------------------------ + + procedure New_EOL_To_Outfile is + begin + New_Line (Outfile.all); + end New_EOL_To_Outfile; + + --------------- + -- Post_Scan -- + --------------- + + procedure Post_Scan is + begin + null; + end Post_Scan; + + -------------------------------------------- + -- Process_Command_Line_Symbol_Definition -- + -------------------------------------------- + + procedure Process_Command_Line_Symbol_Definition (S : String) is + Data : Symbol_Data; + Symbol : Symbol_Id; + + begin + -- Check the symbol definition and get the symbol and its value. + -- Fail if symbol definition is illegal. + + Check_Command_Line_Symbol_Definition (S, Data); + + Symbol := Index_Of (Data.Symbol); + + -- If symbol does not alrady exist, create a new entry in the mapping + -- table. + + if Symbol = No_Symbol then + Symbol_Table.Increment_Last (Mapping); + Symbol := Symbol_Table.Last (Mapping); + end if; + + Mapping.Table (Symbol) := Data; + end Process_Command_Line_Symbol_Definition; + + ------------------------- + -- Put_Char_To_Outfile -- + ------------------------- + + procedure Put_Char_To_Outfile (C : Character) is + begin + Put (Outfile.all, C); + end Put_Char_To_Outfile; + + ----------------------- + -- Scan_Command_Line -- + ----------------------- + + procedure Scan_Command_Line is + Switch : Character; + + begin + -- Parse the switches + + loop + begin + Switch := GNAT.Command_Line.Getopt ("D: b c r s u v"); + case Switch is + + when ASCII.NUL => + exit; + + when 'D' => + Process_Command_Line_Symbol_Definition + (S => GNAT.Command_Line.Parameter); + + when 'b' => + Opt.Blank_Deleted_Lines := True; + + when 'c' => + Opt.Comment_Deleted_Lines := True; + + when 'r' => + Source_Ref_Pragma := True; + + when 's' => + Opt.List_Preprocessing_Symbols := True; + + when 'u' => + Opt.Undefined_Symbols_Are_False := True; + + when 'v' => + Opt.Verbose_Mode := True; + + when others => + Fail ("Invalid Switch: -" & Switch); + end case; + + exception + when GNAT.Command_Line.Invalid_Switch => + Write_Str ("Invalid Switch: -"); + Write_Line (GNAT.Command_Line.Full_Switch); + Usage; + OS_Exit (1); + end; + end loop; + + -- Get the file names + + loop + declare + S : constant String := GNAT.Command_Line.Get_Argument; + + begin + exit when S'Length = 0; + + if Infile_Name = null then + Infile_Name := new String'(S); + elsif Outfile_Name = null then + Outfile_Name := new String'(S); + elsif Deffile_Name = null then + Deffile_Name := new String'(S); + else + Fail ("too many arguments specifed"); + end if; + end; + end loop; + end Scan_Command_Line; + + ----------- + -- Usage -- + ----------- + + procedure Usage is + begin + Display_Copyright; + Write_Line ("Usage: gnatprep [-bcrsuv] [-Dsymbol=value] " & + "infile outfile [deffile]"); + Write_Eol; + Write_Line (" infile Name of the input file"); + Write_Line (" outfile Name of the output file"); + Write_Line (" deffile Name of the definition file"); + Write_Eol; + Write_Line ("gnatprep switches:"); + Write_Line (" -b Replace preprocessor lines by blank lines"); + Write_Line (" -c Keep preprocessor lines as 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 (" -u Treat undefined symbols as FALSE"); + Write_Line (" -v Verbose mode"); + Write_Eol; + end Usage; + +end GPrep; |