------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- O S I N T - C -- -- -- -- B o d y -- -- -- -- Copyright (C) 2001-2004 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 Hostparm; with Namet; use Namet; with Opt; use Opt; with Tree_IO; use Tree_IO; package body Osint.C is Output_Object_File_Name : String_Ptr; -- Argument of -o compiler option, if given. This is needed to -- verify consistency with the ALI file name. procedure Adjust_OS_Resource_Limits; pragma Import (C, Adjust_OS_Resource_Limits, "__gnat_adjust_os_resource_limits"); -- Procedure to make system specific adjustments to make GNAT -- run better. function Create_Auxiliary_File (Src : File_Name_Type; Suffix : String) return File_Name_Type; -- Common processing for Creat_Repinfo_File and Create_Debug_File. -- Src is the file name used to create the required output file and -- Suffix is the desired suffic (dg/rep for debug/repinfo file). procedure Set_Library_Info_Name; -- Sets a default ali file name from the main compiler source name. -- This is used by Create_Output_Library_Info, and by the version of -- Read_Library_Info that takes a default file name. The name is in -- Name_Buffer (with length in Name_Len) on return from the call ---------------------- -- Close_Debug_File -- ---------------------- procedure Close_Debug_File is Status : Boolean; begin Close (Output_FD, Status); if not Status then Fail ("error while closing expanded source file ", Get_Name_String (Output_File_Name)); end if; end Close_Debug_File; ------------------------------- -- Close_Output_Library_Info -- ------------------------------- procedure Close_Output_Library_Info is Status : Boolean; begin Close (Output_FD, Status); if not Status then Fail ("error while closing ALI file ", Get_Name_String (Output_File_Name)); end if; end Close_Output_Library_Info; ------------------------ -- Close_Repinfo_File -- ------------------------ procedure Close_Repinfo_File is Status : Boolean; begin Close (Output_FD, Status); if not Status then Fail ("error while closing representation info file ", Get_Name_String (Output_File_Name)); end if; end Close_Repinfo_File; --------------------------- -- Create_Auxiliary_File -- --------------------------- function Create_Auxiliary_File (Src : File_Name_Type; Suffix : String) return File_Name_Type is Result : File_Name_Type; begin Get_Name_String (Src); if Hostparm.OpenVMS then Name_Buffer (Name_Len + 1) := '_'; else Name_Buffer (Name_Len + 1) := '.'; end if; Name_Len := Name_Len + 1; Name_Buffer (Name_Len + 1 .. Name_Len + Suffix'Length) := Suffix; Name_Len := Name_Len + Suffix'Length; if Output_Object_File_Name /= null then for Index in reverse Output_Object_File_Name'Range loop if Output_Object_File_Name (Index) = Directory_Separator then declare File_Name : constant String := Name_Buffer (1 .. Name_Len); begin Name_Len := Index - Output_Object_File_Name'First + 1; Name_Buffer (1 .. Name_Len) := Output_Object_File_Name (Output_Object_File_Name'First .. Index); Name_Buffer (Name_Len + 1 .. Name_Len + File_Name'Length) := File_Name; Name_Len := Name_Len + File_Name'Length; end; exit; end if; end loop; end if; Result := Name_Find; Name_Buffer (Name_Len + 1) := ASCII.NUL; Create_File_And_Check (Output_FD, Text); return Result; end Create_Auxiliary_File; ----------------------- -- Create_Debug_File -- ----------------------- function Create_Debug_File (Src : File_Name_Type) return File_Name_Type is begin return Create_Auxiliary_File (Src, "dg"); end Create_Debug_File; -------------------------------- -- Create_Output_Library_Info -- -------------------------------- procedure Create_Output_Library_Info is begin Set_Library_Info_Name; Create_File_And_Check (Output_FD, Text); end Create_Output_Library_Info; -------------------------- -- Creat_Repinfo_File -- -------------------------- procedure Creat_Repinfo_File (Src : File_Name_Type) is S : constant File_Name_Type := Create_Auxiliary_File (Src, "rep"); pragma Warnings (Off, S); begin return; end Creat_Repinfo_File; --------------------------- -- Debug_File_Eol_Length -- --------------------------- function Debug_File_Eol_Length return Nat is begin -- There has to be a cleaner way to do this! ??? if Directory_Separator = '/' then return 1; else return 2; end if; end Debug_File_Eol_Length; ----------------------- -- More_Source_Files -- ----------------------- function More_Source_Files return Boolean renames More_Files; ---------------------- -- Next_Main_Source -- ---------------------- function Next_Main_Source return File_Name_Type renames Next_Main_File; ----------------------- -- Read_Library_Info -- ----------------------- -- Version with default file name procedure Read_Library_Info (Name : out File_Name_Type; Text : out Text_Buffer_Ptr) is begin Set_Library_Info_Name; Name := Name_Find; Text := Read_Library_Info (Name, Fatal_Err => False); end Read_Library_Info; --------------------------- -- Set_Library_Info_Name -- --------------------------- procedure Set_Library_Info_Name is Dot_Index : Natural; begin Get_Name_String (Current_Main); -- Find last dot since we replace the existing extension by .ali. The -- initialization to Name_Len + 1 provides for simply adding the .ali -- extension if the source file name has no extension. Dot_Index := Name_Len + 1; for J in reverse 1 .. Name_Len loop if Name_Buffer (J) = '.' then Dot_Index := J; exit; end if; end loop; -- Make sure that the output file name matches the source file name. -- To compare them, remove file name directories and extensions. if Output_Object_File_Name /= null then -- Make sure there is a dot at Dot_Index. This may not be the case -- if the source file name has no extension. Name_Buffer (Dot_Index) := '.'; -- If we are in multiple unit per file mode, then add ~nnn -- extension to the name before doing the comparison. if Multiple_Unit_Index /= 0 then declare Exten : constant String := Name_Buffer (Dot_Index .. Name_Len); begin Name_Len := Dot_Index - 1; Add_Char_To_Name_Buffer (Multi_Unit_Index_Character); Add_Nat_To_Name_Buffer (Multiple_Unit_Index); Dot_Index := Name_Len + 1; Add_Str_To_Name_Buffer (Exten); end; end if; -- Remove extension preparing to replace it declare Name : constant String := Name_Buffer (1 .. Dot_Index); Len : constant Natural := Dot_Index; begin Name_Buffer (1 .. Output_Object_File_Name'Length) := Output_Object_File_Name.all; Dot_Index := 0; for J in reverse Output_Object_File_Name'Range loop if Name_Buffer (J) = '.' then Dot_Index := J; exit; end if; end loop; -- Dot_Index should be zero now (we check for extension elsewhere) pragma Assert (Dot_Index /= 0); -- Check name of object file is what we expect if Name /= Name_Buffer (Dot_Index - Len + 1 .. Dot_Index) then Fail ("incorrect object file name"); end if; end; end if; Name_Buffer (Dot_Index) := '.'; Name_Buffer (Dot_Index + 1 .. Dot_Index + 3) := ALI_Suffix.all; Name_Buffer (Dot_Index + 4) := ASCII.NUL; Name_Len := Dot_Index + 3; end Set_Library_Info_Name; --------------------------------- -- Set_Output_Object_File_Name -- --------------------------------- procedure Set_Output_Object_File_Name (Name : String) is Ext : constant String := Object_Suffix; NL : constant Natural := Name'Length; EL : constant Natural := Ext'Length; begin -- Make sure that the object file has the expected extension. if NL <= EL or else (Name (NL - EL + Name'First .. Name'Last) /= Ext and then Name (NL - 2 + Name'First .. Name'Last) /= ".o") then Fail ("incorrect object file extension"); end if; Output_Object_File_Name := new String'(Name); end Set_Output_Object_File_Name; ---------------- -- Tree_Close -- ---------------- procedure Tree_Close is Status : Boolean; begin Tree_Write_Terminate; Close (Output_FD, Status); if not Status then Fail ("error while closing tree file ", Get_Name_String (Output_File_Name)); end if; end Tree_Close; ----------------- -- Tree_Create -- ----------------- procedure Tree_Create is Dot_Index : Natural; begin Get_Name_String (Current_Main); -- If an object file has been specified, then the ALI file -- will be in the same directory as the object file; -- so, we put the tree file in this same directory, -- even though no object file needs to be generated. if Output_Object_File_Name /= null then Name_Len := Output_Object_File_Name'Length; Name_Buffer (1 .. Name_Len) := Output_Object_File_Name.all; end if; Dot_Index := Name_Len + 1; for J in reverse 1 .. Name_Len loop if Name_Buffer (J) = '.' then Dot_Index := J; exit; end if; end loop; -- Should be impossible to not have an extension pragma Assert (Dot_Index /= 0); -- Change exctension to adt Name_Buffer (Dot_Index) := '.'; Name_Buffer (Dot_Index + 1) := 'a'; Name_Buffer (Dot_Index + 2) := 'd'; Name_Buffer (Dot_Index + 3) := 't'; Name_Buffer (Dot_Index + 4) := ASCII.NUL; Name_Len := Dot_Index + 3; Create_File_And_Check (Output_FD, Binary); Tree_Write_Initialize (Output_FD); end Tree_Create; ----------------------- -- Write_Debug_Info -- ----------------------- procedure Write_Debug_Info (Info : String) renames Write_Info; ------------------------ -- Write_Library_Info -- ------------------------ procedure Write_Library_Info (Info : String) renames Write_Info; ------------------------ -- Write_Repinfo_Line -- ------------------------ procedure Write_Repinfo_Line (Info : String) renames Write_Info; begin Adjust_OS_Resource_Limits; Opt.Creat_Repinfo_File_Access := Creat_Repinfo_File'Access; Opt.Write_Repinfo_Line_Access := Write_Repinfo_Line'Access; Opt.Close_Repinfo_File_Access := Close_Repinfo_File'Access; Set_Program (Compiler); end Osint.C;