------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             P R J . N M S C                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                            $Revision$
--                                                                          --
--          Copyright (C) 2000-2001 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. --
-- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Characters.Handling;    use Ada.Characters.Handling;
with Ada.Strings;                use Ada.Strings;
with Ada.Strings.Fixed;          use Ada.Strings.Fixed;
with Ada.Strings.Maps.Constants; use Ada.Strings.Maps.Constants;
with Errout;                     use Errout;
with GNAT.Case_Util;             use GNAT.Case_Util;
with GNAT.Directory_Operations;  use GNAT.Directory_Operations;
with GNAT.OS_Lib;                use GNAT.OS_Lib;
with MLib.Tgt;
with Namet;                      use Namet;
with Osint;                      use Osint;
with Output;                     use Output;
with Prj.Com;                    use Prj.Com;
with Prj.Util;                   use Prj.Util;
with Snames;                     use Snames;
with Stringt;                    use Stringt;
with Types;                      use Types;

package body Prj.Nmsc is

   Dir_Sep      : Character renames GNAT.OS_Lib.Directory_Separator;

   Error_Report : Put_Line_Access := null;

   procedure Check_Ada_Naming_Scheme (Naming : Naming_Data);
   --  Check that the package Naming is correct.

   procedure Check_Ada_Name
     (Name : Name_Id;
      Unit : out Name_Id);
   --  Check that a name is a valid Ada unit name.

   procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr);
   --  Output an error message. If Error_Report is null, simply call
   --  Errout.Error_Msg. Otherwise, disregard Flag_Location and use
   --  Error_Report.

   function Get_Name_String (S : String_Id) return String;
   --  Get the string from a String_Id

   procedure Get_Unit
     (File_Name    : Name_Id;
      Naming       : Naming_Data;
      Unit_Name    : out Name_Id;
      Unit_Kind    : out Spec_Or_Body;
      Needs_Pragma : out Boolean);
   --  Find out, from a file name, the unit name, the unit kind and if a
   --  specific SFN pragma is needed. If the file name corresponds to no
   --  unit, then Unit_Name will be No_Name.

   function Is_Illegal_Append (This : String) return Boolean;
   --  Returns True if the string This cannot be used as
   --  a Specification_Append, a Body_Append or a Separate_Append.

   procedure Record_Source
     (File_Name        : Name_Id;
      Path_Name        : Name_Id;
      Project          : Project_Id;
      Data             : in out Project_Data;
      Location         : Source_Ptr;
      Current_Source   : in out String_List_Id);
   --  Put a unit in the list of units of a project, if the file name
   --  corresponds to a valid unit name.

   procedure Show_Source_Dirs (Project : Project_Id);
   --  List all the source directories of a project.

   function Locate_Directory
     (Name   : Name_Id;
      Parent : Name_Id)
      return   Name_Id;
   --  Locate a directory.
   --  Returns No_Name if directory does not exist.

   function Path_Name_Of
     (File_Name : String_Id;
      Directory : Name_Id)
      return      String;
   --  Returns the path name of a (non project) file.
   --  Returns an empty string if file cannot be found.

   function Path_Name_Of
     (File_Name : String_Id;
      Directory : String_Id)
      return      String;
   --  Same as above except that Directory is a String_Id instead
   --  of a Name_Id.

   ---------------
   -- Ada_Check --
   ---------------

   procedure Ada_Check
     (Project      : Project_Id;
      Report_Error : Put_Line_Access)
   is
      Data         : Project_Data;
      Languages    : Variable_Value := Nil_Variable_Value;

      procedure Check_Unit_Names (List : Array_Element_Id);
      --  Check that a list of unit names contains only valid names.

      procedure Find_Sources;
      --  Find all the sources in all of the source directories
      --  of a project.

      procedure Get_Path_Name_And_Record_Source
        (File_Name        : String;
         Location         : Source_Ptr;
         Current_Source   : in out String_List_Id);
      --  Find the path name of a source in the source directories and
      --  record the source, if found.

      procedure Get_Sources_From_File
        (Path     : String;
         Location : Source_Ptr);
      --  Get the sources of a project from a text file

      ----------------------
      -- Check_Unit_Names --
      ----------------------

      procedure Check_Unit_Names (List : Array_Element_Id) is
         Current   : Array_Element_Id := List;
         Element   : Array_Element;
         Unit_Name : Name_Id;

      begin
         --  Loop through elements of the string list

         while Current /= No_Array_Element loop
            Element := Array_Elements.Table (Current);

            --  Check that it contains a valid unit name

            Check_Ada_Name (Element.Index, Unit_Name);

            if Unit_Name = No_Name then
               Error_Msg_Name_1 := Element.Index;
               Error_Msg
                 ("{ is not a valid unit name.",
                  Element.Value.Location);

            else
               if Current_Verbosity = High then
                  Write_Str ("   Body_Part (""");
                  Write_Str (Get_Name_String (Unit_Name));
                  Write_Line (""")");
               end if;

               Element.Index := Unit_Name;
               Array_Elements.Table (Current) := Element;
            end if;

            Current := Element.Next;
         end loop;
      end Check_Unit_Names;

      ------------------
      -- Find_Sources --
      ------------------

      procedure Find_Sources is
         Source_Dir     : String_List_Id := Data.Source_Dirs;
         Element        : String_Element;
         Dir            : Dir_Type;
         Current_Source : String_List_Id := Nil_String;

      begin
         if Current_Verbosity = High then
            Write_Line ("Looking for sources:");
         end if;

         --  For each subdirectory

         while Source_Dir /= Nil_String loop
            begin
               Element := String_Elements.Table (Source_Dir);
               if Element.Value /= No_String then
                  declare
                     Source_Directory : String
                       (1 .. Integer (String_Length (Element.Value)));
                  begin
                     String_To_Name_Buffer (Element.Value);
                     Source_Directory := Name_Buffer (1 .. Name_Len);
                     if Current_Verbosity = High then
                        Write_Str ("Source_Dir = ");
                        Write_Line (Source_Directory);
                     end if;

                     --  We look to every entry in the source directory

                     Open (Dir, Source_Directory);

                     loop
                        Read (Dir, Name_Buffer, Name_Len);

                        if Current_Verbosity = High then
                           Write_Str  ("   Checking ");
                           Write_Line (Name_Buffer (1 .. Name_Len));
                        end if;

                        exit when Name_Len = 0;

                        declare
                           Path_Access : constant GNAT.OS_Lib.String_Access :=
                                           Locate_Regular_File
                                             (Name_Buffer (1 .. Name_Len),
                                              Source_Directory);

                           File_Name : Name_Id;
                           Path_Name : Name_Id;

                        begin
                           --  If it is a regular file

                           if Path_Access /= null then
                              File_Name := Name_Find;
                              Name_Len := Path_Access'Length;
                              Name_Buffer (1 .. Name_Len) := Path_Access.all;
                              Path_Name := Name_Find;

                              --  We attempt to register it as a source.
                              --  However, there is no error if the file
                              --  does not contain a valid source.
                              --  But there is an error if we have a
                              --  duplicate unit name.

                              Record_Source
                                (File_Name        => File_Name,
                                 Path_Name        => Path_Name,
                                 Project          => Project,
                                 Data             => Data,
                                 Location         => No_Location,
                                 Current_Source   => Current_Source);

                           else
                              if Current_Verbosity = High then
                                 Write_Line
                                   ("      Not a regular file.");
                              end if;
                           end if;
                        end;
                     end loop;

                     Close (Dir);
                  end;
               end if;

            exception
               when Directory_Error =>
                  null;
            end;

            Source_Dir := Element.Next;
         end loop;

         if Current_Verbosity = High then
            Write_Line ("end Looking for sources.");
         end if;

         --  If we have looked for sources and found none, then
         --  it is an error. If a project is not supposed to contain
         --  any source, then we never call Find_Sources.

         if Current_Source = Nil_String then
            Error_Msg ("there are no sources in this project",
                       Data.Location);
         end if;
      end Find_Sources;

      -------------------------------------
      -- Get_Path_Name_And_Record_Source --
      -------------------------------------

      procedure Get_Path_Name_And_Record_Source
        (File_Name        : String;
         Location         : Source_Ptr;
         Current_Source   : in out String_List_Id)
      is
         Source_Dir : String_List_Id := Data.Source_Dirs;
         Element    : String_Element;
         Path_Name  : GNAT.OS_Lib.String_Access;
         Found      : Boolean := False;
         File       : Name_Id;

      begin
         if Current_Verbosity = High then
            Write_Str  ("   Checking """);
            Write_Str  (File_Name);
            Write_Line (""".");
         end if;

         --  We look in all source directories for this file name

         while Source_Dir /= Nil_String loop
            Element := String_Elements.Table (Source_Dir);

            if Current_Verbosity = High then
               Write_Str ("      """);
               Write_Str (Get_Name_String (Element.Value));
               Write_Str (""": ");
            end if;

            Path_Name :=
              Locate_Regular_File
              (File_Name,
               Get_Name_String (Element.Value));

            if Path_Name /= null then
               if Current_Verbosity = High then
                  Write_Line ("OK");
               end if;

               Name_Len := File_Name'Length;
               Name_Buffer (1 .. Name_Len) := File_Name;
               File := Name_Find;
               Name_Len := Path_Name'Length;
               Name_Buffer (1 .. Name_Len) := Path_Name.all;

               --  Register the source. Report an error if the file does not
               --  correspond to a source.

               Record_Source
                 (File_Name        => File,
                  Path_Name        => Name_Find,
                  Project          => Project,
                  Data             => Data,
                  Location         => Location,
                  Current_Source   => Current_Source);
               Found := True;
               exit;

            else
               if Current_Verbosity = High then
                  Write_Line ("No");
               end if;

               Source_Dir := Element.Next;
            end if;
         end loop;

      end Get_Path_Name_And_Record_Source;

      ---------------------------
      -- Get_Sources_From_File --
      ---------------------------

      procedure Get_Sources_From_File
        (Path     : String;
         Location : Source_Ptr)
      is
         File           : Prj.Util.Text_File;
         Line           : String (1 .. 250);
         Last           : Natural;
         Current_Source : String_List_Id := Nil_String;

         Nmb_Errors : constant Nat := Errors_Detected;

      begin
         if Current_Verbosity = High then
            Write_Str  ("Opening """);
            Write_Str  (Path);
            Write_Line (""".");
         end if;

         --  We open the file

         Prj.Util.Open (File, Path);

         if not Prj.Util.Is_Valid (File) then
            Error_Msg ("file does not exist", Location);
         else
            while not Prj.Util.End_Of_File (File) loop
               Prj.Util.Get_Line (File, Line, Last);

               --  If the line is not empty and does not start with "--",
               --  then it must contains a file name.

               if Last /= 0
                 and then (Last = 1 or else Line (1 .. 2) /= "--")
               then
                  Get_Path_Name_And_Record_Source
                    (File_Name => Line (1 .. Last),
                     Location => Location,
                     Current_Source => Current_Source);
                  exit when Nmb_Errors /= Errors_Detected;
               end if;
            end loop;

            Prj.Util.Close (File);

         end if;

         --  We should have found at least one source.
         --  If not, report an error.

         if Current_Source = Nil_String then
            Error_Msg ("this project has no source", Location);
         end if;
      end Get_Sources_From_File;

      --  Start of processing for Ada_Check

   begin
      Language_Independent_Check (Project, Report_Error);

      Error_Report := Report_Error;

      Data      := Projects.Table (Project);
      Languages := Prj.Util.Value_Of (Name_Languages, Data.Decl.Attributes);

      Data.Naming.Current_Language := Name_Ada;
      Data.Sources_Present         := Data.Source_Dirs /= Nil_String;

      if not Languages.Default then
         declare
            Current   : String_List_Id := Languages.Values;
            Element   : String_Element;
            Ada_Found : Boolean := False;

         begin
            Look_For_Ada : while Current /= Nil_String loop
               Element := String_Elements.Table (Current);
               String_To_Name_Buffer (Element.Value);
               To_Lower (Name_Buffer (1 .. Name_Len));

               if Name_Buffer (1 .. Name_Len) = "ada" then
                  Ada_Found := True;
                  exit Look_For_Ada;
               end if;

               Current := Element.Next;
            end loop Look_For_Ada;

            if not Ada_Found then

               --  Mark the project file as having no sources for Ada

               Data.Sources_Present := False;
            end if;
         end;
      end if;

      declare
         Naming_Id : constant Package_Id :=
                       Util.Value_Of (Name_Naming, Data.Decl.Packages);

         Naming : Package_Element;

      begin
         --  If there is a package Naming, we will put in Data.Naming
         --  what is in this package Naming.

         if Naming_Id /= No_Package then
            Naming := Packages.Table (Naming_Id);

            if Current_Verbosity = High then
               Write_Line ("Checking ""Naming"" for Ada.");
            end if;

            declare
               Bodies : constant Array_Element_Id :=
                                  Util.Value_Of
                                    (Name_Implementation, Naming.Decl.Arrays);

               Specifications : constant Array_Element_Id :=
                                  Util.Value_Of
                                    (Name_Specification, Naming.Decl.Arrays);

            begin
               if Bodies /= No_Array_Element then

                  --  We have elements in the array Body_Part

                  if Current_Verbosity = High then
                     Write_Line ("Found Bodies.");
                  end if;

                  Data.Naming.Bodies := Bodies;
                  Check_Unit_Names (Bodies);

               else
                  if Current_Verbosity = High then
                     Write_Line ("No Bodies.");
                  end if;
               end if;

               if Specifications /= No_Array_Element then

                  --  We have elements in the array Specification

                  if Current_Verbosity = High then
                     Write_Line ("Found Specifications.");
                  end if;

                  Data.Naming.Specifications := Specifications;
                  Check_Unit_Names (Specifications);

               else
                  if Current_Verbosity = High then
                     Write_Line ("No Specifications.");
                  end if;
               end if;
            end;

            --  We are now checking if variables Dot_Replacement, Casing,
            --  Specification_Append, Body_Append and/or Separate_Append
            --  exist.

            --  For each variable, if it does not exist, we do nothing,
            --  because we already have the default.

            --  Check Dot_Replacement

            declare
               Dot_Replacement : constant Variable_Value :=
                                   Util.Value_Of
                                     (Name_Dot_Replacement,
                                      Naming.Decl.Attributes);

            begin
               pragma Assert (Dot_Replacement.Kind = Single,
                              "Dot_Replacement is not a single string");

               if not Dot_Replacement.Default then

                  String_To_Name_Buffer (Dot_Replacement.Value);

                  if Name_Len = 0 then
                     Error_Msg ("Dot_Replacement cannot be empty",
                                Dot_Replacement.Location);

                  else
                     Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
                     Data.Naming.Dot_Replacement := Name_Find;
                     Data.Naming.Dot_Repl_Loc := Dot_Replacement.Location;
                  end if;

               end if;

            end;

            if Current_Verbosity = High then
               Write_Str  ("  Dot_Replacement = """);
               Write_Str  (Get_Name_String (Data.Naming.Dot_Replacement));
               Write_Char ('"');
               Write_Eol;
            end if;

            --  Check Casing

            declare
               Casing_String : constant Variable_Value :=
                 Util.Value_Of (Name_Casing, Naming.Decl.Attributes);

            begin
               pragma Assert (Casing_String.Kind = Single,
                              "Casing is not a single string");

               if not Casing_String.Default then
                  declare
                     Casing_Image : constant String :=
                                      Get_Name_String (Casing_String.Value);

                  begin
                     declare
                        Casing : constant Casing_Type :=
                          Value (Casing_Image);

                     begin
                        Data.Naming.Casing := Casing;
                     end;

                  exception
                     when Constraint_Error =>
                        if Casing_Image'Length = 0 then
                           Error_Msg ("Casing cannot be an empty string",
                                      Casing_String.Location);

                        else
                           Name_Len := Casing_Image'Length;
                           Name_Buffer (1 .. Name_Len) := Casing_Image;
                           Error_Msg_Name_1 := Name_Find;
                           Error_Msg
                             ("{ is not a correct Casing",
                              Casing_String.Location);
                        end if;
                  end;
               end if;
            end;

            if Current_Verbosity = High then
               Write_Str  ("  Casing = ");
               Write_Str  (Image (Data.Naming.Casing));
               Write_Char ('.');
               Write_Eol;
            end if;

            --  Check Specification_Suffix

            declare
               Ada_Spec_Suffix : constant Variable_Value :=
                 Prj.Util.Value_Of
                   (Index => Name_Ada,
                    In_Array => Data.Naming.Specification_Suffix);

            begin
               if Ada_Spec_Suffix.Kind = Single
                 and then String_Length (Ada_Spec_Suffix.Value) /= 0
               then
                  String_To_Name_Buffer (Ada_Spec_Suffix.Value);
                  Data.Naming.Current_Spec_Suffix := Name_Find;
                  Data.Naming.Spec_Suffix_Loc := Ada_Spec_Suffix.Location;

               else
                  Data.Naming.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
               end if;
            end;

            if Current_Verbosity = High then
               Write_Str  ("  Specification_Suffix = """);
               Write_Str  (Get_Name_String (Data.Naming.Current_Spec_Suffix));
               Write_Char ('"');
               Write_Eol;
            end if;

            --  Check Implementation_Suffix

            declare
               Ada_Impl_Suffix : constant Variable_Value :=
                 Prj.Util.Value_Of
                   (Index => Name_Ada,
                    In_Array => Data.Naming.Implementation_Suffix);

            begin
               if Ada_Impl_Suffix.Kind = Single
                 and then String_Length (Ada_Impl_Suffix.Value) /= 0
               then
                  String_To_Name_Buffer (Ada_Impl_Suffix.Value);
                  Data.Naming.Current_Impl_Suffix := Name_Find;
                  Data.Naming.Impl_Suffix_Loc := Ada_Impl_Suffix.Location;

               else
                  Data.Naming.Current_Impl_Suffix := Default_Ada_Impl_Suffix;
               end if;
            end;

            if Current_Verbosity = High then
               Write_Str  ("  Implementation_Suffix = """);
               Write_Str  (Get_Name_String (Data.Naming.Current_Impl_Suffix));
               Write_Char ('"');
               Write_Eol;
            end if;

            --  Check Separate_Suffix

            declare
               Ada_Sep_Suffix : constant Variable_Value :=
                 Prj.Util.Value_Of
                 (Variable_Name => Name_Separate_Suffix,
                  In_Variables  => Naming.Decl.Attributes);
            begin
               if Ada_Sep_Suffix.Default then
                  Data.Naming.Separate_Suffix :=
                    Data.Naming.Current_Impl_Suffix;

               else
                  String_To_Name_Buffer (Ada_Sep_Suffix.Value);

                  if Name_Len = 0 then
                     Error_Msg ("Separate_Suffix cannot be empty",
                                Ada_Sep_Suffix.Location);

                  else
                     Data.Naming.Separate_Suffix := Name_Find;
                     Data.Naming.Sep_Suffix_Loc  := Ada_Sep_Suffix.Location;
                  end if;

               end if;

            end;

            if Current_Verbosity = High then
               Write_Str  ("  Separate_Suffix = """);
               Write_Str  (Get_Name_String (Data.Naming.Separate_Suffix));
               Write_Char ('"');
               Write_Eol;
            end if;

            --  Check if Data.Naming is valid

            Check_Ada_Naming_Scheme (Data.Naming);

         else
            Data.Naming.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
            Data.Naming.Current_Impl_Suffix := Default_Ada_Impl_Suffix;
            Data.Naming.Separate_Suffix     := Default_Ada_Impl_Suffix;
         end if;
      end;

      --  If we have source directories, then find the sources

      if Data.Sources_Present then
         if Data.Source_Dirs = Nil_String then
            Data.Sources_Present := False;

         else
            declare
               Sources : constant Variable_Value :=
                 Util.Value_Of
                 (Name_Source_Files,
                  Data.Decl.Attributes);

               Source_List_File : constant Variable_Value :=
                 Util.Value_Of
                 (Name_Source_List_File,
                  Data.Decl.Attributes);

            begin
               pragma Assert
                 (Sources.Kind = List,
                    "Source_Files is not a list");
               pragma Assert
                 (Source_List_File.Kind = Single,
                    "Source_List_File is not a single string");

               if not Sources.Default then
                  if not Source_List_File.Default then
                     Error_Msg
                       ("?both variables source_files and " &
                        "source_list_file are present",
                        Source_List_File.Location);
                  end if;

                  --  Sources is a list of file names

                  declare
                     Current_Source : String_List_Id := Nil_String;
                     Current        : String_List_Id := Sources.Values;
                     Element        : String_Element;

                  begin
                     Data.Sources_Present := Current /= Nil_String;

                     while Current /= Nil_String loop
                        Element := String_Elements.Table (Current);
                        String_To_Name_Buffer (Element.Value);

                        declare
                           File_Name : constant String :=
                             Name_Buffer (1 .. Name_Len);

                        begin
                           Get_Path_Name_And_Record_Source
                             (File_Name        => File_Name,
                              Location         => Element.Location,
                              Current_Source   => Current_Source);
                           Current := Element.Next;
                        end;
                     end loop;
                  end;

                  --  No source_files specified.
                  --  We check Source_List_File has been specified.

               elsif not Source_List_File.Default then

                  --  Source_List_File is the name of the file
                  --  that contains the source file names

                  declare
                     Source_File_Path_Name : constant String :=
                       Path_Name_Of
                       (Source_List_File.Value,
                        Data.Directory);

                  begin
                     if Source_File_Path_Name'Length = 0 then
                        String_To_Name_Buffer (Source_List_File.Value);
                        Error_Msg_Name_1 := Name_Find;
                        Error_Msg
                          ("file with sources { does not exist",
                           Source_List_File.Location);

                     else
                        Get_Sources_From_File
                          (Source_File_Path_Name,
                           Source_List_File.Location);
                     end if;
                  end;

               else
                  --  Neither Source_Files nor Source_List_File has been
                  --  specified.
                  --  Find all the files that satisfy
                  --  the naming scheme in all the source directories.

                  Find_Sources;
               end if;
            end;
         end if;
      end if;

      Projects.Table (Project) := Data;
   end Ada_Check;

   --------------------
   -- Check_Ada_Name --
   --------------------

   procedure Check_Ada_Name
     (Name : Name_Id;
      Unit : out Name_Id)
   is
      The_Name        : String := Get_Name_String (Name);
      Need_Letter     : Boolean := True;
      Last_Underscore : Boolean := False;
      OK              : Boolean := The_Name'Length > 0;

   begin
      for Index in The_Name'Range loop
         if Need_Letter then

            --  We need a letter (at the beginning, and following a dot),
            --  but we don't have one.

            if Is_Letter (The_Name (Index)) then
               Need_Letter := False;

            else
               OK := False;

               if Current_Verbosity = High then
                  Write_Int  (Types.Int (Index));
                  Write_Str  (": '");
                  Write_Char (The_Name (Index));
                  Write_Line ("' is not a letter.");
               end if;

               exit;
            end if;

         elsif Last_Underscore
           and then (The_Name (Index) = '_' or else The_Name (Index) = '.')
         then
            --  Two underscores are illegal, and a dot cannot follow
            --  an underscore.

            OK := False;

            if Current_Verbosity = High then
               Write_Int  (Types.Int (Index));
               Write_Str  (": '");
               Write_Char (The_Name (Index));
               Write_Line ("' is illegal here.");
            end if;

            exit;

         elsif The_Name (Index) = '.' then

            --  We need a letter after a dot

            Need_Letter := True;

         elsif The_Name (Index) = '_' then
            Last_Underscore := True;

         else
            --  We need an letter or a digit

            Last_Underscore := False;

            if not Is_Alphanumeric (The_Name (Index)) then
               OK := False;

               if Current_Verbosity = High then
                  Write_Int  (Types.Int (Index));
                  Write_Str  (": '");
                  Write_Char (The_Name (Index));
                  Write_Line ("' is not alphanumeric.");
               end if;

               exit;
            end if;
         end if;
      end loop;

      --  Cannot end with an underscore or a dot

      OK := OK and then not Need_Letter and then not Last_Underscore;

      if OK then
         Unit := Name;
      else
         --  Signal a problem with No_Name

         Unit := No_Name;
      end if;
   end Check_Ada_Name;

   -----------------------------
   -- Check_Ada_Naming_Scheme --
   -----------------------------

   procedure Check_Ada_Naming_Scheme (Naming : Naming_Data) is
   begin
      --  Only check if we are not using the standard naming scheme

      if Naming /= Standard_Naming_Data then
         declare
            Dot_Replacement       : constant String :=
                                     Get_Name_String
                                       (Naming.Dot_Replacement);

            Specification_Suffix : constant String :=
                                     Get_Name_String
                                       (Naming.Current_Spec_Suffix);

            Implementation_Suffix : constant String :=
                                     Get_Name_String
                                       (Naming.Current_Impl_Suffix);

            Separate_Suffix       : constant String :=
                                     Get_Name_String
                                       (Naming.Separate_Suffix);

         begin
            --  Dot_Replacement cannot
            --   - be empty
            --   - start or end with an alphanumeric
            --   - be a single '_'
            --   - start with an '_' followed by an alphanumeric
            --   - contain a '.' except if it is "."

            if Dot_Replacement'Length = 0
              or else Is_Alphanumeric
                        (Dot_Replacement (Dot_Replacement'First))
              or else Is_Alphanumeric
                        (Dot_Replacement (Dot_Replacement'Last))
              or else (Dot_Replacement (Dot_Replacement'First) = '_'
                        and then
                        (Dot_Replacement'Length = 1
                          or else
                           Is_Alphanumeric
                             (Dot_Replacement (Dot_Replacement'First + 1))))
              or else (Dot_Replacement'Length > 1
                         and then
                           Index (Source => Dot_Replacement,
                                  Pattern => ".") /= 0)
            then
               Error_Msg
                 ('"' & Dot_Replacement &
                  """ is illegal for Dot_Replacement.",
                  Naming.Dot_Repl_Loc);
            end if;

            --  Suffixes cannot
            --   - be empty
            --   - start with an alphanumeric
            --   - start with an '_' followed by an alphanumeric

            if Is_Illegal_Append (Specification_Suffix) then
               Error_Msg_Name_1 := Naming.Current_Spec_Suffix;
               Error_Msg
                 ("{ is illegal for Specification_Suffix",
                  Naming.Spec_Suffix_Loc);
            end if;

            if Is_Illegal_Append (Implementation_Suffix) then
               Error_Msg_Name_1 := Naming.Current_Impl_Suffix;
               Error_Msg
                 ("% is illegal for Implementation_Suffix",
                  Naming.Impl_Suffix_Loc);
            end if;

            if Implementation_Suffix /= Separate_Suffix then
               if Is_Illegal_Append (Separate_Suffix) then
                  Error_Msg_Name_1 := Naming.Separate_Suffix;
                  Error_Msg
                    ("{ is illegal for Separate_Append",
                     Naming.Sep_Suffix_Loc);
               end if;
            end if;

            --  Specification_Suffix cannot have the same termination as
            --  Implementation_Suffix or Separate_Suffix

            if Specification_Suffix'Length <= Implementation_Suffix'Length
              and then
                Implementation_Suffix (Implementation_Suffix'Last -
                             Specification_Suffix'Length + 1 ..
                             Implementation_Suffix'Last) = Specification_Suffix
            then
               Error_Msg
                 ("Implementation_Suffix (""" &
                  Implementation_Suffix &
                  """) cannot end with" &
                  "Specification_Suffix  (""" &
                   Specification_Suffix & """).",
                  Naming.Impl_Suffix_Loc);
            end if;

            if Specification_Suffix'Length <= Separate_Suffix'Length
              and then
                Separate_Suffix
                  (Separate_Suffix'Last - Specification_Suffix'Length + 1
                    ..
                   Separate_Suffix'Last) = Specification_Suffix
            then
               Error_Msg
                 ("Separate_Suffix (""" &
                  Separate_Suffix &
                  """) cannot end with" &
                  " Specification_Suffix (""" &
                  Specification_Suffix & """).",
                  Naming.Sep_Suffix_Loc);
            end if;
         end;
      end if;

   end Check_Ada_Naming_Scheme;

   ---------------
   -- Error_Msg --
   ---------------

   procedure Error_Msg (Msg : String; Flag_Location : Source_Ptr) is

      Error_Buffer : String (1 .. 5_000);
      Error_Last   : Natural := 0;
      Msg_Name     : Natural := 0;
      First        : Positive := Msg'First;

      procedure Add (C : Character);
      --  Add a character to the buffer

      procedure Add (S : String);
      --  Add a string to the buffer

      procedure Add (Id : Name_Id);
      --  Add a name to the buffer

      ---------
      -- Add --
      ---------

      procedure Add (C : Character) is
      begin
         Error_Last := Error_Last + 1;
         Error_Buffer (Error_Last) := C;
      end Add;

      procedure Add (S : String) is
      begin
         Error_Buffer (Error_Last + 1 .. Error_Last + S'Length) := S;
         Error_Last := Error_Last + S'Length;
      end Add;

      procedure Add (Id : Name_Id) is
      begin
         Get_Name_String (Id);
         Add (Name_Buffer (1 .. Name_Len));
      end Add;

   --  Start of processing for Error_Msg

   begin
      if Error_Report = null then
         Errout.Error_Msg (Msg, Flag_Location);
         return;
      end if;

      if Msg (First) = '\' then

         --  Continuation character, ignore.

         First := First + 1;

      elsif Msg (First) = '?' then

         --  Warning character. It is always the first one,
         --  in this package.

         First := First + 1;
         Add ("Warning: ");
      end if;

      for Index in First .. Msg'Last loop
         if Msg (Index) = '{' or else Msg (Index) = '%' then

            --  Include a name between double quotes.

            Msg_Name := Msg_Name + 1;
            Add ('"');

            case Msg_Name is
               when 1 => Add (Error_Msg_Name_1);

               when 2 => Add (Error_Msg_Name_2);

               when 3 => Add (Error_Msg_Name_3);

               when others => null;
            end case;

            Add ('"');

         else
            Add (Msg (Index));
         end if;

      end loop;

      Error_Report (Error_Buffer (1 .. Error_Last));
   end Error_Msg;

   ---------------------
   -- Get_Name_String --
   ---------------------

   function Get_Name_String (S : String_Id) return String is
   begin
      if S = No_String then
         return "";
      else
         String_To_Name_Buffer (S);
         return Name_Buffer (1 .. Name_Len);
      end if;
   end Get_Name_String;

   --------------
   -- Get_Unit --
   --------------

   procedure Get_Unit
     (File_Name    : Name_Id;
      Naming       : Naming_Data;
      Unit_Name    : out Name_Id;
      Unit_Kind    : out Spec_Or_Body;
      Needs_Pragma : out Boolean)
   is
      Canonical_Case_Name : Name_Id;

   begin
      Needs_Pragma := False;
      Get_Name_String (File_Name);
      Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
      Canonical_Case_Name := Name_Find;

      if Naming.Bodies /= No_Array_Element then

         --  There are some specified file names for some bodies
         --  of this project. Find out if File_Name is one of these bodies.

         declare
            Current : Array_Element_Id := Naming.Bodies;
            Element : Array_Element;

         begin
            while Current /= No_Array_Element loop
               Element := Array_Elements.Table (Current);

               if Element.Index /= No_Name then
                  String_To_Name_Buffer (Element.Value.Value);
                  Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));

                  if Canonical_Case_Name = Name_Find then

                     --  File_Name corresponds to one body.
                     --  So, we know it is a body, and we know the unit name.

                     Unit_Kind := Body_Part;
                     Unit_Name := Element.Index;
                     Needs_Pragma := True;
                     return;
                  end if;
               end if;

               Current := Element.Next;
            end loop;
         end;
      end if;

      if Naming.Specifications /= No_Array_Element then

         --  There are some specified file names for some bodiesspecifications
         --  of this project. Find out if File_Name is one of these
         --  specifications.

         declare
            Current : Array_Element_Id := Naming.Specifications;
            Element : Array_Element;

         begin
            while Current /= No_Array_Element loop
               Element := Array_Elements.Table (Current);

               if Element.Index /= No_Name then
                  String_To_Name_Buffer (Element.Value.Value);
                  Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));

                  if Canonical_Case_Name = Name_Find then

                     --  File_Name corresponds to one specification.
                     --  So, we know it is a spec, and we know the unit name.

                     Unit_Kind := Specification;
                     Unit_Name := Element.Index;
                     Needs_Pragma := True;
                     return;
                  end if;

               end if;

               Current := Element.Next;
            end loop;
         end;
      end if;

      declare
         File  : String   := Get_Name_String (Canonical_Case_Name);
         First : Positive := File'First;
         Last  : Natural  := File'Last;

      begin
         --  Check if the end of the file name is Specification_Append

         Get_Name_String (Naming.Current_Spec_Suffix);

         if File'Length > Name_Len
           and then File (Last - Name_Len + 1 .. Last) =
                                                Name_Buffer (1 .. Name_Len)
         then
            --  We have a spec

            Unit_Kind := Specification;
            Last := Last - Name_Len;

            if Current_Verbosity = High then
               Write_Str  ("   Specification: ");
               Write_Line (File (First .. Last));
            end if;

         else
            Get_Name_String (Naming.Current_Impl_Suffix);

            --  Check if the end of the file name is Body_Append

            if File'Length > Name_Len
              and then File (Last - Name_Len + 1 .. Last) =
                                                Name_Buffer (1 .. Name_Len)
            then
               --  We have a body

               Unit_Kind := Body_Part;
               Last := Last - Name_Len;

               if Current_Verbosity = High then
                  Write_Str  ("   Body: ");
                  Write_Line (File (First .. Last));
               end if;

            elsif Naming.Separate_Suffix /= Naming.Current_Spec_Suffix then
               Get_Name_String (Naming.Separate_Suffix);

               --  Check if the end of the file name is Separate_Append

               if File'Length > Name_Len
                 and then File (Last - Name_Len + 1 .. Last) =
                                                Name_Buffer (1 .. Name_Len)
               then
                  --  We have a separate (a body)

                  Unit_Kind := Body_Part;
                  Last := Last - Name_Len;

                  if Current_Verbosity = High then
                     Write_Str  ("   Separate: ");
                     Write_Line (File (First .. Last));
                  end if;

               else
                  Last := 0;
               end if;

            else
               Last := 0;
            end if;
         end if;

         if Last = 0 then

            --  This is not a source file

            Unit_Name := No_Name;
            Unit_Kind := Specification;

            if Current_Verbosity = High then
               Write_Line ("   Not a valid file name.");
            end if;

            return;
         end if;

         Get_Name_String (Naming.Dot_Replacement);

         if Name_Buffer (1 .. Name_Len) /= "." then

            --  If Dot_Replacement is not a single dot,
            --  then there should not be any dot in the name.

            for Index in First .. Last loop
               if File (Index) = '.' then
                  if Current_Verbosity = High then
                     Write_Line
                       ("   Not a valid file name (some dot not replaced).");
                  end if;

                  Unit_Name := No_Name;
                  return;

               end if;
            end loop;

            --  Replace the substring Dot_Replacement with dots

            declare
               Index : Positive := First;

            begin
               while Index <= Last - Name_Len + 1 loop

                  if File (Index .. Index + Name_Len - 1) =
                    Name_Buffer (1 .. Name_Len)
                  then
                     File (Index) := '.';

                     if Name_Len > 1 and then Index < Last then
                        File (Index + 1 .. Last - Name_Len + 1) :=
                          File (Index + Name_Len .. Last);
                     end if;

                     Last := Last - Name_Len + 1;
                  end if;

                  Index := Index + 1;
               end loop;
            end;
         end if;

         --  Check if the casing is right

         declare
            Src : String := File (First .. Last);

         begin
            case Naming.Casing is
               when All_Lower_Case =>
                  Fixed.Translate
                    (Source  => Src,
                     Mapping => Lower_Case_Map);

               when All_Upper_Case =>
                  Fixed.Translate
                    (Source  => Src,
                     Mapping => Upper_Case_Map);

               when Mixed_Case | Unknown =>
                  null;
            end case;

            if Src /= File (First .. Last) then
               if Current_Verbosity = High then
                  Write_Line ("   Not a valid file name (casing).");
               end if;

               Unit_Name := No_Name;
               return;
            end if;

            --  We put the name in lower case

            Fixed.Translate
              (Source  => Src,
               Mapping => Lower_Case_Map);

            if Current_Verbosity = High then
               Write_Str  ("      ");
               Write_Line (Src);
            end if;

            Name_Len := Src'Length;
            Name_Buffer (1 .. Name_Len) := Src;

            --  Now, we check if this name is a valid unit name

            Check_Ada_Name (Name => Name_Find, Unit => Unit_Name);
         end;

      end;

   end Get_Unit;

   -----------------------
   -- Is_Illegal_Append --
   -----------------------

   function Is_Illegal_Append (This : String) return Boolean is
   begin
      return This'Length = 0
        or else Is_Alphanumeric (This (This'First))
        or else Index (This, ".") = 0
        or else (This'Length >= 2
                 and then This (This'First) = '_'
                 and then Is_Alphanumeric (This (This'First + 1)));
   end Is_Illegal_Append;

   --------------------------------
   -- Language_Independent_Check --
   --------------------------------

   procedure Language_Independent_Check
     (Project      : Project_Id;
      Report_Error : Put_Line_Access)
   is
      Last_Source_Dir   : String_List_Id  := Nil_String;
      Data              : Project_Data    := Projects.Table (Project);

      procedure Find_Source_Dirs (From : String_Id; Location : Source_Ptr);
      --  Find one or several source directories, and add them
      --  to the list of source directories of the project.

      ----------------------
      -- Find_Source_Dirs --
      ----------------------

      procedure Find_Source_Dirs (From : String_Id; Location : Source_Ptr) is

         Directory    : String (1 .. Integer (String_Length (From)));
         Directory_Id : Name_Id;
         Element      : String_Element;

         procedure Recursive_Find_Dirs (Path : String_Id);
         --  Find all the subdirectories (recursively) of Path
         --  and add them to the list of source directories
         --  of the project.

         -------------------------
         -- Recursive_Find_Dirs --
         -------------------------

         procedure Recursive_Find_Dirs (Path : String_Id) is
            Dir      : Dir_Type;
            Name     : String (1 .. 250);
            Last     : Natural;
            The_Path : String := Get_Name_String (Path) & Dir_Sep;

            The_Path_Last : Positive := The_Path'Last;

         begin
            if The_Path'Length > 1
              and then
                (The_Path (The_Path_Last - 1) = Dir_Sep
                   or else The_Path (The_Path_Last - 1) = '/')
            then
               The_Path_Last := The_Path_Last - 1;
            end if;

            if Current_Verbosity = High then
               Write_Str  ("   ");
               Write_Line (The_Path (The_Path'First .. The_Path_Last));
            end if;

            String_Elements.Increment_Last;
            Element :=
              (Value    => Path,
               Location => No_Location,
               Next     => Nil_String);

            --  Case of first source directory

            if Last_Source_Dir = Nil_String then
               Data.Source_Dirs := String_Elements.Last;

            --  Here we already have source directories.

            else
               --  Link the previous last to the new one

               String_Elements.Table (Last_Source_Dir).Next :=
                 String_Elements.Last;
            end if;

            --  And register this source directory as the new last

            Last_Source_Dir  := String_Elements.Last;
            String_Elements.Table (Last_Source_Dir) := Element;

            --  Now look for subdirectories

            Open (Dir, The_Path (The_Path'First .. The_Path_Last));

            loop
               Read (Dir, Name, Last);
               exit when Last = 0;

               if Current_Verbosity = High then
                  Write_Str  ("   Checking ");
                  Write_Line (Name (1 .. Last));
               end if;

               if Name (1 .. Last) /= "."
                 and then Name (1 .. Last) /= ".."
               then
                  --  Avoid . and ..

                  declare
                     Path_Name : constant String :=
                                   The_Path (The_Path'First .. The_Path_Last) &
                                   Name (1 .. Last);

                  begin
                     if Is_Directory (Path_Name) then

                        --  We have found a new subdirectory,
                        --  register it and find its own subdirectories.

                        Start_String;
                        Store_String_Chars (Path_Name);
                        Recursive_Find_Dirs (End_String);
                     end if;
                  end;
               end if;
            end loop;

            Close (Dir);

         exception
            when Directory_Error =>
               null;
         end Recursive_Find_Dirs;

         --  Start of processing for Find_Source_Dirs

      begin
         if Current_Verbosity = High then
            Write_Str ("Find_Source_Dirs (""");
         end if;

         String_To_Name_Buffer (From);
         Directory    := Name_Buffer (1 .. Name_Len);
         Directory_Id := Name_Find;

         if Current_Verbosity = High then
            Write_Str (Directory);
            Write_Line (""")");
         end if;

         --  First, check if we are looking for a directory tree,
         --  indicated by "/**" at the end.

         if Directory'Length >= 3
           and then Directory (Directory'Last - 1 .. Directory'Last) = "**"
           and then (Directory (Directory'Last - 2) = '/'
                       or else
                     Directory (Directory'Last - 2) = Dir_Sep)
         then
            Name_Len := Directory'Length - 3;

            if Name_Len = 0 then
               --  This is the case of "/**": all directories
               --  in the file system.

               Name_Len := 1;
               Name_Buffer (1) := Directory (Directory'First);

            else
               Name_Buffer (1 .. Name_Len) :=
                 Directory (Directory'First .. Directory'Last - 3);
            end if;

            if Current_Verbosity = High then
               Write_Str ("Looking for all subdirectories of """);
               Write_Str (Name_Buffer (1 .. Name_Len));
               Write_Line ("""");
            end if;

            declare
               Base_Dir : constant Name_Id := Name_Find;
               Root     : constant Name_Id :=
                            Locate_Directory (Base_Dir, Data.Directory);

            begin
               if Root = No_Name then
                  Error_Msg_Name_1 := Base_Dir;
                  if Location = No_Location then
                     Error_Msg ("{ is not a valid directory.", Data.Location);
                  else
                     Error_Msg ("{ is not a valid directory.", Location);
                  end if;

               else
                  --  We have an existing directory,
                  --  we register it and all of its subdirectories.

                  if Current_Verbosity = High then
                     Write_Line ("Looking for source directories:");
                  end if;

                  Start_String;
                  Store_String_Chars (Get_Name_String (Root));
                  Recursive_Find_Dirs (End_String);

                  if Current_Verbosity = High then
                     Write_Line ("End of looking for source directories.");
                  end if;
               end if;
            end;

         --  We have a single directory

         else
            declare
               Path_Name : constant Name_Id :=
                 Locate_Directory (Directory_Id, Data.Directory);

            begin
               if Path_Name = No_Name then
                  Error_Msg_Name_1 := Directory_Id;
                  if Location = No_Location then
                     Error_Msg ("{ is not a valid directory", Data.Location);
                  else
                     Error_Msg ("{ is not a valid directory", Location);
                  end if;
               else

                  --  As it is an existing directory, we add it to
                  --  the list of directories.

                  String_Elements.Increment_Last;
                  Start_String;
                  Store_String_Chars (Get_Name_String (Path_Name));
                  Element.Value := End_String;

                  if Last_Source_Dir = Nil_String then

                     --  This is the first source directory

                     Data.Source_Dirs := String_Elements.Last;

                  else
                     --  We already have source directories,
                     --  link the previous last to the new one.

                     String_Elements.Table (Last_Source_Dir).Next :=
                       String_Elements.Last;
                  end if;

                  --  And register this source directory as the new last

                  Last_Source_Dir := String_Elements.Last;
                  String_Elements.Table (Last_Source_Dir) := Element;
               end if;
            end;
         end if;
      end Find_Source_Dirs;

      --  Start of processing for Language_Independent_Check

   begin

      if Data.Language_Independent_Checked then
         return;
      end if;

      Data.Language_Independent_Checked := True;

      Error_Report := Report_Error;

      if Current_Verbosity = High then
         Write_Line ("Starting to look for directories");
      end if;

      --  Check the object directory

      declare
         Object_Dir : Variable_Value :=
                        Util.Value_Of (Name_Object_Dir, Data.Decl.Attributes);

      begin
         pragma Assert (Object_Dir.Kind = Single,
                        "Object_Dir is not a single string");

         --  We set the object directory to its default

         Data.Object_Directory := Data.Directory;

         if not String_Equal (Object_Dir.Value, Empty_String) then

            String_To_Name_Buffer (Object_Dir.Value);

            if Name_Len = 0 then
               Error_Msg ("Object_Dir cannot be empty",
                          Object_Dir.Location);

            else
               --  We check that the specified object directory
               --  does exist.

               Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));

               declare
                  Dir_Id : constant Name_Id := Name_Find;

               begin
                  Data.Object_Directory :=
                    Locate_Directory (Dir_Id, Data.Directory);

                  if Data.Object_Directory = No_Name then
                     Error_Msg_Name_1 := Dir_Id;
                     Error_Msg
                       ("the object directory { cannot be found",
                        Data.Location);
                  end if;
               end;
            end if;
         end if;
      end;

      if Current_Verbosity = High then
         if Data.Object_Directory = No_Name then
            Write_Line ("No object directory");
         else
            Write_Str ("Object directory: """);
            Write_Str (Get_Name_String (Data.Object_Directory));
            Write_Line ("""");
         end if;
      end if;

      --  Check the exec directory

      declare
         Exec_Dir : Variable_Value :=
                      Util.Value_Of (Name_Exec_Dir, Data.Decl.Attributes);

      begin
         pragma Assert (Exec_Dir.Kind = Single,
                        "Exec_Dir is not a single string");

         --  We set the object directory to its default

         Data.Exec_Directory := Data.Object_Directory;

         if not String_Equal (Exec_Dir.Value, Empty_String) then

            String_To_Name_Buffer (Exec_Dir.Value);

            if Name_Len = 0 then
               Error_Msg ("Exec_Dir cannot be empty",
                          Exec_Dir.Location);

            else
               --  We check that the specified object directory
               --  does exist.

               Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));

               declare
                  Dir_Id : constant Name_Id := Name_Find;

               begin
                  Data.Exec_Directory :=
                    Locate_Directory (Dir_Id, Data.Directory);

                  if Data.Exec_Directory = No_Name then
                     Error_Msg_Name_1 := Dir_Id;
                     Error_Msg
                       ("the exec directory { cannot be found",
                        Data.Location);
                  end if;
               end;
            end if;
         end if;
      end;

      if Current_Verbosity = High then
         if Data.Exec_Directory = No_Name then
            Write_Line ("No exec directory");
         else
            Write_Str ("Exec directory: """);
            Write_Str (Get_Name_String (Data.Exec_Directory));
            Write_Line ("""");
         end if;
      end if;

      --  Look for the source directories

      declare
         Source_Dirs : Variable_Value :=
           Util.Value_Of (Name_Source_Dirs, Data.Decl.Attributes);

      begin

         if Current_Verbosity = High then
            Write_Line ("Starting to look for source directories");
         end if;

         pragma Assert (Source_Dirs.Kind = List,
                          "Source_Dirs is not a list");

         if Source_Dirs.Default then

            --  No Source_Dirs specified: the single source directory
            --  is the one containing the project file

            String_Elements.Increment_Last;
            Data.Source_Dirs := String_Elements.Last;
            Start_String;
            Store_String_Chars (Get_Name_String (Data.Directory));
            String_Elements.Table (Data.Source_Dirs) :=
              (Value    => End_String,
               Location => No_Location,
               Next     => Nil_String);

            if Current_Verbosity = High then
               Write_Line ("(Undefined) Single object directory:");
               Write_Str ("    """);
               Write_Str (Get_Name_String (Data.Directory));
               Write_Line ("""");
            end if;

         elsif Source_Dirs.Values = Nil_String then

            --  If Source_Dirs is an empty string list, this means
            --  that this project contains no source.

            if Data.Object_Directory = Data.Directory then
               Data.Object_Directory := No_Name;
            end if;

            Data.Source_Dirs     := Nil_String;
            Data.Sources_Present := False;

         else
            declare
               Source_Dir : String_List_Id := Source_Dirs.Values;
               Element    : String_Element;

            begin
               --  We will find the source directories for each
               --  element of the list

               while Source_Dir /= Nil_String loop
                  Element := String_Elements.Table (Source_Dir);
                  Find_Source_Dirs (Element.Value, Element.Location);
                  Source_Dir := Element.Next;
               end loop;
            end;
         end if;

         if Current_Verbosity = High then
            Write_Line ("Puting source directories in canonical cases");
         end if;

         declare
            Current : String_List_Id := Data.Source_Dirs;
            Element : String_Element;

         begin
            while Current /= Nil_String loop
               Element := String_Elements.Table (Current);
               if Element.Value /= No_String then
                  String_To_Name_Buffer (Element.Value);
                  Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
                  Start_String;
                  Store_String_Chars (Name_Buffer (1 .. Name_Len));
                  Element.Value := End_String;
                  String_Elements.Table (Current) := Element;
               end if;

               Current := Element.Next;
            end loop;
         end;
      end;

      --  Library Dir, Name, Version and Kind

      declare
         Attributes : constant Prj.Variable_Id := Data.Decl.Attributes;

         Lib_Dir : Prj.Variable_Value :=
                     Prj.Util.Value_Of (Snames.Name_Library_Dir, Attributes);

         Lib_Name : Prj.Variable_Value :=
                      Prj.Util.Value_Of (Snames.Name_Library_Name, Attributes);

         Lib_Version : Prj.Variable_Value :=
                         Prj.Util.Value_Of
                           (Snames.Name_Library_Version, Attributes);

         The_Lib_Kind : Prj.Variable_Value :=
                          Prj.Util.Value_Of
                            (Snames.Name_Library_Kind, Attributes);

      begin
         pragma Assert (Lib_Dir.Kind = Single);

         if Lib_Dir.Value = Empty_String then

            if Current_Verbosity = High then
               Write_Line ("No library directory");
            end if;

         else
            --  Find path name, check that it is a directory

            Stringt.String_To_Name_Buffer (Lib_Dir.Value);

            declare
               Dir_Id : constant Name_Id := Name_Find;

            begin
               Data.Library_Dir :=
                 Locate_Directory (Dir_Id, Data.Directory);

               if Data.Library_Dir = No_Name then
                  Error_Msg ("not an existing directory",
                             Lib_Dir.Location);

               elsif Data.Library_Dir = Data.Object_Directory then
                  Error_Msg
                    ("library directory cannot be the same " &
                     "as object directory",
                     Lib_Dir.Location);
                  Data.Library_Dir := No_Name;

               else
                  if Current_Verbosity = High then
                     Write_Str ("Library directory =""");
                     Write_Str (Get_Name_String (Data.Library_Dir));
                     Write_Line ("""");
                  end if;
               end if;
            end;
         end if;

         pragma Assert (Lib_Name.Kind = Single);

         if Lib_Name.Value = Empty_String then
            if Current_Verbosity = High then
               Write_Line ("No library name");
            end if;

         else
            Stringt.String_To_Name_Buffer (Lib_Name.Value);

            if not Is_Letter (Name_Buffer (1)) then
               Error_Msg ("must start with a letter",
                          Lib_Name.Location);

            else
               Data.Library_Name := Name_Find;

               for Index in 2 .. Name_Len loop
                  if not Is_Alphanumeric (Name_Buffer (Index)) then
                     Data.Library_Name := No_Name;
                     Error_Msg ("only letters and digits are allowed",
                                Lib_Name.Location);
                     exit;
                  end if;
               end loop;

               if Data.Library_Name /= No_Name
                 and then Current_Verbosity = High then
                  Write_Str ("Library name = """);
                  Write_Str (Get_Name_String (Data.Library_Name));
                  Write_Line ("""");
               end if;
            end if;
         end if;

         Data.Library :=
           Data.Library_Dir /= No_Name
             and then
           Data.Library_Name /= No_Name;

         if Data.Library then

            if not MLib.Tgt.Libraries_Are_Supported then
               Error_Msg ("?libraries are not supported on this platform",
                          Lib_Name.Location);
               Data.Library := False;

            else
               if Current_Verbosity = High then
                  Write_Line ("This is a library project file");
               end if;

               pragma Assert (Lib_Version.Kind = Single);

               if Lib_Version.Value = Empty_String then
                  if Current_Verbosity = High then
                     Write_Line ("No library version specified");
                  end if;

               else
                  Stringt.String_To_Name_Buffer (Lib_Version.Value);
                  Data.Lib_Internal_Name := Name_Find;
               end if;

               pragma Assert (The_Lib_Kind.Kind = Single);

               if The_Lib_Kind.Value = Empty_String then
                  if Current_Verbosity = High then
                     Write_Line ("No library kind specified");
                  end if;

               else
                  Stringt.String_To_Name_Buffer (The_Lib_Kind.Value);

                  declare
                     Kind_Name : constant String :=
                                   To_Lower (Name_Buffer (1 .. Name_Len));

                     OK : Boolean := True;

                  begin
                     if Kind_Name = "static" then
                        Data.Library_Kind := Static;

                     elsif Kind_Name = "dynamic" then
                        Data.Library_Kind := Dynamic;

                     elsif Kind_Name = "relocatable" then
                        Data.Library_Kind := Relocatable;

                     else
                        Error_Msg
                          ("illegal value for Library_Kind",
                           The_Lib_Kind.Location);
                        OK := False;
                     end if;

                     if Current_Verbosity = High and then OK then
                        Write_Str ("Library kind = ");
                        Write_Line (Kind_Name);
                     end if;
                  end;
               end if;
            end if;
         end if;
      end;

      if Current_Verbosity = High then
         Show_Source_Dirs (Project);
      end if;

      declare
         Naming_Id : constant Package_Id :=
                       Util.Value_Of (Name_Naming, Data.Decl.Packages);

         Naming    : Package_Element;

      begin
         --  If there is a package Naming, we will put in Data.Naming
         --  what is in this package Naming.

         if Naming_Id /= No_Package then
            Naming := Packages.Table (Naming_Id);

            if Current_Verbosity = High then
               Write_Line ("Checking ""Naming"".");
            end if;

            --  Check Specification_Suffix

            Data.Naming.Specification_Suffix := Util.Value_Of
                                                 (Name_Specification_Suffix,
                                                  Naming.Decl.Arrays);

            declare
               Current : Array_Element_Id := Data.Naming.Specification_Suffix;
               Element : Array_Element;

            begin
               while Current /= No_Array_Element loop
                  Element := Array_Elements.Table (Current);
                  String_To_Name_Buffer (Element.Value.Value);

                  if Name_Len = 0 then
                     Error_Msg
                       ("Specification_Suffix cannot be empty",
                        Element.Value.Location);
                  end if;

                  Array_Elements.Table (Current) := Element;
                  Current := Element.Next;
               end loop;
            end;

            --  Check Implementation_Suffix

            Data.Naming.Implementation_Suffix := Util.Value_Of
                                          (Name_Implementation_Suffix,
                                           Naming.Decl.Arrays);

            declare
               Current : Array_Element_Id := Data.Naming.Implementation_Suffix;
               Element : Array_Element;

            begin
               while Current /= No_Array_Element loop
                  Element := Array_Elements.Table (Current);
                  String_To_Name_Buffer (Element.Value.Value);

                  if Name_Len = 0 then
                     Error_Msg
                       ("Implementation_Suffix cannot be empty",
                        Element.Value.Location);
                  end if;

                  Array_Elements.Table (Current) := Element;
                  Current := Element.Next;
               end loop;
            end;

         end if;
      end;

      Projects.Table (Project) := Data;
   end Language_Independent_Check;

   ----------------------
   -- Locate_Directory --
   ----------------------

   function Locate_Directory
     (Name   : Name_Id;
      Parent : Name_Id)
      return   Name_Id
   is
      The_Name   : constant String := Get_Name_String (Name);
      The_Parent : constant String :=
                     Get_Name_String (Parent) & Dir_Sep;

      The_Parent_Last : Positive := The_Parent'Last;

   begin
      if The_Parent'Length > 1
        and then (The_Parent (The_Parent_Last - 1) = Dir_Sep
                    or else The_Parent (The_Parent_Last - 1) = '/')
      then
         The_Parent_Last := The_Parent_Last - 1;
      end if;

      if Current_Verbosity = High then
         Write_Str ("Locate_Directory (""");
         Write_Str (The_Name);
         Write_Str (""", """);
         Write_Str (The_Parent);
         Write_Line (""")");
      end if;

      if Is_Absolute_Path (The_Name) then
         if Is_Directory (The_Name) then
            return Name;
         end if;

      else
         declare
            Full_Path : constant String :=
                          The_Parent (The_Parent'First .. The_Parent_Last) &
                                                                     The_Name;

         begin
            if Is_Directory (Full_Path) then
               Name_Len := Full_Path'Length;
               Name_Buffer (1 .. Name_Len) := Full_Path;
               return Name_Find;
            end if;
         end;

      end if;

      return No_Name;
   end Locate_Directory;

   ------------------
   -- Path_Name_Of --
   ------------------

   function Path_Name_Of
     (File_Name : String_Id;
      Directory : String_Id)
      return      String
   is
      Result : String_Access;

   begin
      String_To_Name_Buffer (File_Name);

      declare
         The_File_Name : constant String := Name_Buffer (1 .. Name_Len);

      begin
         String_To_Name_Buffer (Directory);
         Result := Locate_Regular_File
           (File_Name => The_File_Name,
            Path      => Name_Buffer (1 .. Name_Len));
      end;

      if Result = null then
         return "";
      else
         Canonical_Case_File_Name (Result.all);
         return Result.all;
      end if;
   end Path_Name_Of;

   function Path_Name_Of
     (File_Name : String_Id;
      Directory : Name_Id)
      return      String
   is
      Result : String_Access;
      The_Directory : constant String := Get_Name_String (Directory);

   begin
      String_To_Name_Buffer (File_Name);
      Result := Locate_Regular_File
        (File_Name => Name_Buffer (1 .. Name_Len),
         Path      => The_Directory);

      if Result = null then
         return "";
      else
         Canonical_Case_File_Name (Result.all);
         return Result.all;
      end if;
   end Path_Name_Of;

   -------------------
   -- Record_Source --
   -------------------

   procedure Record_Source
     (File_Name        : Name_Id;
      Path_Name        : Name_Id;
      Project          : Project_Id;
      Data             : in out Project_Data;
      Location         : Source_Ptr;
      Current_Source   : in out String_List_Id)
   is
      Unit_Name    : Name_Id;
      Unit_Kind    : Spec_Or_Body;
      Needs_Pragma : Boolean;
      The_Location : Source_Ptr := Location;

   begin
      --  Find out the unit name, the unit kind and if it needs
      --  a specific SFN pragma.

      Get_Unit
        (File_Name    => File_Name,
         Naming       => Data.Naming,
         Unit_Name    => Unit_Name,
         Unit_Kind    => Unit_Kind,
         Needs_Pragma => Needs_Pragma);

      if Unit_Name = No_Name then
         if Current_Verbosity = High then
            Write_Str  ("   """);
            Write_Str  (Get_Name_String (File_Name));
            Write_Line (""" is not a valid source file name (ignored).");
         end if;

      else
         --  Put the file name in the list of sources of the project

         String_Elements.Increment_Last;
         Get_Name_String (File_Name);
         Start_String;
         Store_String_Chars (Name_Buffer (1 .. Name_Len));
         String_Elements.Table (String_Elements.Last) :=
           (Value    => End_String,
            Location => No_Location,
            Next     => Nil_String);

         if Current_Source = Nil_String then
            Data.Sources := String_Elements.Last;

         else
            String_Elements.Table (Current_Source).Next :=
              String_Elements.Last;
         end if;

         Current_Source := String_Elements.Last;

         --  Put the unit in unit list

         declare
            The_Unit      : Unit_Id := Units_Htable.Get (Unit_Name);
            The_Unit_Data : Unit_Data;

         begin
            if Current_Verbosity = High then
               Write_Str  ("Putting ");
               Write_Str  (Get_Name_String (Unit_Name));
               Write_Line (" in the unit list.");
            end if;

            --  The unit is already in the list, but may be it is
            --  only the other unit kind (spec or body), or what is
            --  in the unit list is a unit of a project we are extending.

            if The_Unit /= Prj.Com.No_Unit then
               The_Unit_Data := Units.Table (The_Unit);

               if The_Unit_Data.File_Names (Unit_Kind).Name = No_Name
                 or else (Data.Modifies /= No_Project
                            and then
                          The_Unit_Data.File_Names (Unit_Kind).Project =
                                                            Data.Modifies)
               then
                  The_Unit_Data.File_Names (Unit_Kind) :=
                    (Name         => File_Name,
                     Path         => Path_Name,
                     Project      => Project,
                     Needs_Pragma => Needs_Pragma);
                  Units.Table (The_Unit) := The_Unit_Data;

               else
                  --  It is an error to have two units with the same name
                  --  and the same kind (spec or body).

                  if The_Location = No_Location then
                     The_Location := Projects.Table (Project).Location;
                  end if;

                  Error_Msg_Name_1 := Unit_Name;
                  Error_Msg ("duplicate source {", The_Location);

                  Error_Msg_Name_1 :=
                    Projects.Table
                      (The_Unit_Data.File_Names (Unit_Kind).Project).Name;
                  Error_Msg_Name_2 :=
                    The_Unit_Data.File_Names (Unit_Kind).Path;
                  Error_Msg ("\   project file {, {", The_Location);

                  Error_Msg_Name_1 := Projects.Table (Project).Name;
                  Error_Msg_Name_2 := Path_Name;
                  Error_Msg ("\   project file {, {", The_Location);

               end if;

            --  It is a new unit, create a new record

            else
               Units.Increment_Last;
               The_Unit := Units.Last;
               Units_Htable.Set (Unit_Name, The_Unit);
               The_Unit_Data.Name := Unit_Name;
               The_Unit_Data.File_Names (Unit_Kind) :=
                 (Name         => File_Name,
                  Path         => Path_Name,
                  Project      => Project,
                  Needs_Pragma => Needs_Pragma);
               Units.Table (The_Unit) := The_Unit_Data;
            end if;
         end;
      end if;
   end Record_Source;

   ----------------------
   -- Show_Source_Dirs --
   ----------------------

   procedure Show_Source_Dirs (Project : Project_Id) is
      Current : String_List_Id := Projects.Table (Project).Source_Dirs;
      Element : String_Element;

   begin
      Write_Line ("Source_Dirs:");

      while Current /= Nil_String loop
         Element := String_Elements.Table (Current);
         Write_Str  ("   ");
         Write_Line (Get_Name_String (Element.Value));
         Current := Element.Next;
      end loop;

      Write_Line ("end Source_Dirs.");
   end Show_Source_Dirs;

end Prj.Nmsc;
