------------------------------------------------------------------------------ -- -- -- GPR TECHNOLOGY -- -- -- -- Copyright (C) 2015-2016, AdaCore -- -- -- -- This 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 3, or (at your option) any later ver- -- -- sion. This software is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- -- TABILITY 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, -- -- see . -- -- -- ------------------------------------------------------------------------------ with Ada.Text_IO; use Ada.Text_IO; with GPR.Err; with GPR.Names; use GPR.Names; with GPR.Opt; use GPR.Opt; with GPR.Scans; with GPR.Sinput; package body Gprls is No_Obj : aliased String := ""; use GPR.Stamps; procedure Find_Status (Source : GPR.Source_Id; Stamp : Time_Stamp_Type; Checksum : Word; Status : out File_Status); -- Determine the file status (Status) of the file represented by FS with -- the expected Stamp and checksum given as argument. FS will be updated -- to the full file name if available. use Rident; ------------- -- Add_ALI -- ------------- procedure Add_ALI (ALI_Name : File_Name_Type; Spec : Boolean; Source : GPR.Source_Id) is A : constant ALI_Kind := (File => ALI_Name, Spec => Spec); begin ALI_Names.Set (A, Source); end Add_ALI; -------------- -- Add_File -- -------------- procedure Add_File (File_Name : String; Source : GPR.Source_Id := No_Source) is begin if Current_Verbosity = High then Put_Line ("adding file """ & File_Name & '"'); end if; Number_File_Names := Number_File_Names + 1; -- As Add_File may be called for mains specified inside a project file, -- File_Names may be too short and needs to be extended. if Number_File_Names > File_Names'Last then File_Names := new File_Name_Array'(File_Names.all & File_Names.all); end if; File_Names (Number_File_Names) := (new String'(File_Name), Source, No_ALI_Id); end Add_File; ------------------------------ -- Corresponding_Sdep_Entry -- ------------------------------ function Corresponding_Sdep_Entry (A : ALI_Id; U : Unit_Id) return Sdep_Id is begin for D in ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep loop if Sdep.Table (D).Sfile = Units.Table (U).Sfile then return D; end if; end loop; return No_Sdep_Id; end Corresponding_Sdep_Entry; -------------- -- Find_ALI -- -------------- function Find_ALI (Source : GPR.Source_Id) return ALI_Id is Text : Text_Buffer_Ptr; Result : ALI_Id; begin Text := Osint.Read_Library_Info (File_Name_Type (Source.Dep_Path)); if Text /= null then Result := Scan_ALI (F => File_Name_Type (Source.Dep_Path), T => Text, Ignore_ED => False, Err => True, Read_Lines => "WD"); Free (Text); return Result; else return No_ALI_Id; end if; end Find_ALI; ----------------- -- Find_Source -- ----------------- function Find_Source (ALI_Name : File_Name_Type; Spec : Boolean) return GPR.Source_Id is A : constant ALI_Kind := (File => ALI_Name, Spec => Spec); begin return ALI_Names.Get (A); end Find_Source; ----------------- -- Find_Status -- ----------------- procedure Find_Status (Source : GPR.Source_Id; ALI : ALI_Id; Status : out File_Status) is U : Unit_Id; begin if ALI = No_ALI_Id then Status := Not_Found; else if Source.Kind = Spec then U := ALIs.Table (ALI).Last_Unit; else U := ALIs.Table (ALI).First_Unit; end if; Find_Status (Source, ALI, U, Status); end if; end Find_Status; procedure Find_Status (Source : GPR.Source_Id; ALI : ALI_Id; U : Unit_Id; Status : out File_Status) is use GPR.Scans; Stamp : constant Time_Stamp_Type := File_Stamp (Source.Path.Name); SD : constant Sdep_Id := Corresponding_Sdep_Entry (ALI, U); Source_Index : Source_File_Index; Checksums_Match : Boolean; begin if Stamp = Sdep.Table (SD).Stamp then Status := OK; else Checksums_Match := False; Source_Index := Sinput.Load_File (Get_Name_String (Source.Path.Name)); if Source_Index /= No_Source_File then Err.Scanner.Initialize_Scanner (Source_Index, Err.Scanner.Ada); -- Scan the complete file to compute its -- checksum. loop Err.Scanner.Scan; exit when Token = Tok_EOF; end loop; if Scans.Checksum = Sdep.Table (SD).Checksum then Checksums_Match := True; end if; end if; if Checksums_Match then Status := Checksum_OK; else Status := Not_Same; end if; end if; end Find_Status; procedure Find_Status (Source : GPR.Source_Id; Stamp : Time_Stamp_Type; Checksum : Word; Status : out File_Status) is Source_Index : Source_File_Index; Checksums_Match : Boolean; use GPR.Scans; begin if Source = No_Source then Status := Not_Found; elsif File_Stamp (Source.Path.Name) = Stamp then Status := OK; else Checksums_Match := False; Source_Index := Sinput.Load_File (Get_Name_String (Source.Path.Name)); if Source_Index /= No_Source_File then Err.Scanner.Initialize_Scanner (Source_Index, Err.Scanner.Ada); -- Scan the complete file to compute its -- checksum. loop Err.Scanner.Scan; exit when Token = Tok_EOF; end loop; if Scans.Checksum = Checksum then Checksums_Match := True; end if; end if; if Checksums_Match then Status := Checksum_OK; else Status := Not_Same; end if; end if; end Find_Status; ---------- -- Hash -- ---------- function Hash (A : ALI_Kind) return GPR.Header_Num is begin return GPR.Hash (A.File); end Hash; ------------------- -- Output_Object -- ------------------- procedure Output_Object (O : File_Name_Type) is Object_Name : String_Access; begin if Print_Object then if O /= No_File then Get_Name_String (O); Object_Name := new String'(Name_Buffer (1 .. Name_Len)); else Object_Name := No_Obj'Unchecked_Access; end if; Put_Line (Object_Name.all); end if; end Output_Object; ------------------- -- Output_Source -- ------------------- procedure Output_Source (Source : GPR.Source_Id; Sdep_I : Sdep_Id) is Stamp : GPR.Stamps.Time_Stamp_Type; Checksum : Word; Status : File_Status; begin if Sdep_I = No_Sdep_Id then return; end if; Stamp := Sdep.Table (Sdep_I).Stamp; Checksum := Sdep.Table (Sdep_I).Checksum; if Print_Source then Find_Status (Source, Stamp, Checksum, Status); if Verbose_Mode then Put (" Source => "); Put (Get_Name_String (Source.Path.Display_Name)); Output_Status (Status, True); New_Line; else if not Selective_Output then Put (" "); Output_Status (Status, Verbose => False); end if; Put_Line (Get_Name_String (Source.Path.Display_Name)); end if; end if; end Output_Source; procedure Output_Source (Sdep_I : Sdep_Id) is Stamp : GPR.Stamps.Time_Stamp_Type; Checksum : Word; Source : GPR.Source_Id; FS : File_Name_Type; Status : File_Status; Source_Name : String_Access; begin if Sdep_I = No_Sdep_Id then return; end if; Stamp := Sdep.Table (Sdep_I).Stamp; Checksum := Sdep.Table (Sdep_I).Checksum; FS := Sdep.Table (Sdep_I).Sfile; Source := Source_Files_Htable.Get (Project_Tree.Source_Files_HT, FS); if Print_Source then Find_Status (Source, Stamp, Checksum, Status); Get_Name_String (FS); Source_Name := new String'(Name_Buffer (1 .. Name_Len)); if Verbose_Mode then Put (" Source => "); Put (Source_Name.all); Output_Status (Status, Verbose => True); New_Line; else if not Selective_Output then Put (" "); Output_Status (Status, Verbose => False); end if; Put_Line (Source_Name.all); end if; end if; end Output_Source; ------------------- -- Output_Status -- ------------------- procedure Output_Status (FS : File_Status; Verbose : Boolean) is begin if Verbose then case FS is when OK => Put (" unchanged"); when Checksum_OK => Put (" slightly modified"); when Not_Found => Put (" dependency file not found"); when Not_Same => Put (" modified"); end case; else case FS is when OK => Put (" OK "); when Checksum_OK => Put (" MOK "); when Not_Found => Put (" ??? "); when Not_Same => Put (" DIF "); end case; end if; end Output_Status; ----------------- -- Output_Unit -- ----------------- procedure Output_Unit (U_Id : Unit_Id) is Kind : Character; U : Unit_Record renames Units.Table (U_Id); begin Get_Name_String (U.Uname); Kind := Name_Buffer (Name_Len); Name_Len := Name_Len - 2; if not Verbose_Mode then Put_Line (" " & Name_Buffer (1 .. Name_Len)); else Put (" Unit => "); New_Line; Put (" Name => "); Put (Name_Buffer (1 .. Name_Len)); New_Line; Put (" Kind => "); if Units.Table (U_Id).Unit_Kind = 'p' then Put ("package "); else Put ("subprogram "); end if; if Kind = 's' then Put ("spec"); else Put ("body"); end if; end if; if Verbose_Mode then if U.Preelab or else U.No_Elab or else U.Pure or else U.Dynamic_Elab or else U.Has_RACW or else U.Remote_Types or else U.Shared_Passive or else U.RCI or else U.Predefined or else U.Internal or else U.Is_Generic or else U.Init_Scalars or else U.SAL_Interface or else U.Body_Needed_For_SAL or else U.Elaborate_Body then New_Line; Put (" Flags =>"); if U.Preelab then Put (" Preelaborable"); end if; if U.No_Elab then Put (" No_Elab_Code"); end if; if U.Pure then Put (" Pure"); end if; if U.Dynamic_Elab then Put (" Dynamic_Elab"); end if; if U.Has_RACW then Put (" Has_RACW"); end if; if U.Remote_Types then Put (" Remote_Types"); end if; if U.Shared_Passive then Put (" Shared_Passive"); end if; if U.RCI then Put (" RCI"); end if; if U.Predefined then Put (" Predefined"); end if; if U.Internal then Put (" Internal"); end if; if U.Is_Generic then Put (" Is_Generic"); end if; if U.Init_Scalars then Put (" Init_Scalars"); end if; if U.SAL_Interface then Put (" SAL_Interface"); end if; if U.Body_Needed_For_SAL then Put (" Body_Needed_For_SAL"); end if; if U.Elaborate_Body then Put (" Elaborate Body"); end if; if U.Remote_Types then Put (" Remote_Types"); end if; if U.Shared_Passive then Put (" Shared_Passive"); end if; if U.Predefined then Put (" Predefined"); end if; New_Line; end if; end if; end Output_Unit; ----------------- -- Reset_Print -- ----------------- procedure Reset_Print is begin if not Selective_Output then Selective_Output := True; Print_Source := False; Print_Object := False; Print_Unit := False; end if; end Reset_Print; end Gprls;