diff options
author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-10-02 14:23:52 +0000 |
---|---|---|
committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-10-02 14:23:52 +0000 |
commit | 49d882a7d8c985758c04737e801f6028d5b7240f (patch) | |
tree | 0509e847916fc00cfe5c311617e039600afa9622 /gcc/ada/prj-proc.adb | |
parent | 83cce46b47d48de4c71b02a20f5bf36296a48568 (diff) | |
download | gcc-49d882a7d8c985758c04737e801f6028d5b7240f.tar.gz |
New Language: Ada
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45956 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/prj-proc.adb')
-rw-r--r-- | gcc/ada/prj-proc.adb | 1371 |
1 files changed, 1371 insertions, 0 deletions
diff --git a/gcc/ada/prj-proc.adb b/gcc/ada/prj-proc.adb new file mode 100644 index 00000000000..4822596f964 --- /dev/null +++ b/gcc/ada/prj-proc.adb @@ -0,0 +1,1371 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- P R J . P R O C -- +-- -- +-- B o d y -- +-- -- +-- $Revision: 1.16 $ +-- -- +-- Copyright (C) 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 Errout; use Errout; +with Namet; use Namet; +with Opt; +with Output; use Output; +with Prj.Attr; use Prj.Attr; +with Prj.Com; use Prj.Com; +with Prj.Ext; use Prj.Ext; +with Prj.Nmsc; use Prj.Nmsc; +with Stringt; use Stringt; + +with GNAT.HTable; + +package body Prj.Proc is + + Error_Report : Put_Line_Access := null; + + package Processed_Projects is new GNAT.HTable.Simple_HTable + (Header_Num => Header_Num, + Element => Project_Id, + No_Element => No_Project, + Key => Name_Id, + Hash => Hash, + Equal => "="); + -- This hash table contains all processed projects + + procedure Add (To_Exp : in out String_Id; Str : String_Id); + -- Concatenate two strings and returns another string if both + -- arguments are not null string. + + procedure Add_Attributes + (Decl : in out Declarations; + First : Attribute_Node_Id); + -- Add all attributes, starting with First, with their default + -- values to the package or project with declarations Decl. + + function Expression + (Project : Project_Id; + From_Project_Node : Project_Node_Id; + Pkg : Package_Id; + First_Term : Project_Node_Id; + Kind : Variable_Kind) + return Variable_Value; + -- From N_Expression project node From_Project_Node, compute the value + -- of an expression and return it as a Variable_Value. + + function Imported_Or_Modified_Project_From + (Project : Project_Id; + With_Name : Name_Id) + return Project_Id; + -- Find an imported or modified project of Project whose name is With_Name. + + function Package_From + (Project : Project_Id; + With_Name : Name_Id) + return Package_Id; + -- Find the package of Project whose name is With_Name. + + procedure Process_Declarative_Items + (Project : Project_Id; + From_Project_Node : Project_Node_Id; + Pkg : Package_Id; + Item : Project_Node_Id); + -- Process declarative items starting with From_Project_Node, and put them + -- in declarations Decl. This is a recursive procedure; it calls itself for + -- a package declaration or a case construction. + + procedure Recursive_Process + (Project : out Project_Id; + From_Project_Node : Project_Node_Id; + Modified_By : Project_Id); + -- Process project with node From_Project_Node in the tree. + -- Do nothing if From_Project_Node is Empty_Node. + -- If project has already been processed, simply return its project id. + -- Otherwise create a new project id, mark it as processed, call itself + -- recursively for all imported projects and a modified project, if any. + -- Then process the declarative items of the project. + + procedure Check (Project : in out Project_Id); + -- Set all projects to not checked, then call Recursive_Check for + -- the main project Project. + -- Project is set to No_Project if errors occurred. + + procedure Recursive_Check (Project : Project_Id); + -- If Project is marked as not checked, mark it as checked, + -- call Check_Naming_Scheme for the project, then call itself + -- for a possible modified project and all the imported projects + -- of Project. + + --------- + -- Add -- + --------- + + procedure Add (To_Exp : in out String_Id; Str : String_Id) is + begin + if To_Exp = Types.No_String or else String_Length (To_Exp) = 0 then + + -- To_Exp is nil or empty. The result is Str. + + To_Exp := Str; + + -- If Str is nil, then do not change To_Ext + + elsif Str /= No_String then + Start_String (To_Exp); + Store_String_Chars (Str); + To_Exp := End_String; + end if; + end Add; + + -------------------- + -- Add_Attributes -- + -------------------- + + procedure Add_Attributes + (Decl : in out Declarations; + First : Attribute_Node_Id) is + The_Attribute : Attribute_Node_Id := First; + Attribute_Data : Attribute_Record; + + begin + while The_Attribute /= Empty_Attribute loop + Attribute_Data := Attributes.Table (The_Attribute); + + if Attribute_Data.Kind_2 /= Associative_Array then + declare + New_Attribute : Variable_Value; + + begin + case Attribute_Data.Kind_1 is + + -- Undefined should not happen + + when Undefined => + pragma Assert + (False, "attribute with an undefined kind"); + raise Program_Error; + + -- Single attributes have a default value of empty string + + when Single => + New_Attribute := + (Kind => Single, + Location => No_Location, + Default => True, + Value => Empty_String); + + -- List attributes have a default value of nil list + + when List => + New_Attribute := + (Kind => List, + Location => No_Location, + Default => True, + Values => Nil_String); + + end case; + + Variable_Elements.Increment_Last; + Variable_Elements.Table (Variable_Elements.Last) := + (Next => Decl.Attributes, + Name => Attribute_Data.Name, + Value => New_Attribute); + Decl.Attributes := Variable_Elements.Last; + end; + end if; + + The_Attribute := Attributes.Table (The_Attribute).Next; + end loop; + + end Add_Attributes; + + ----------- + -- Check -- + ----------- + + procedure Check (Project : in out Project_Id) is + begin + -- Make sure that all projects are marked as not checked. + + for Index in 1 .. Projects.Last loop + Projects.Table (Index).Checked := False; + end loop; + + Recursive_Check (Project); + + if Errout.Errors_Detected > 0 then + Project := No_Project; + end if; + + end Check; + + ---------------- + -- Expression -- + ---------------- + + function Expression + (Project : Project_Id; + From_Project_Node : Project_Node_Id; + Pkg : Package_Id; + First_Term : Project_Node_Id; + Kind : Variable_Kind) + return Variable_Value + is + The_Term : Project_Node_Id := First_Term; + -- The term in the expression list + + The_Current_Term : Project_Node_Id := Empty_Node; + -- The current term node id + + Term_Kind : Variable_Kind; + -- The kind of the current term + + Result : Variable_Value (Kind => Kind); + -- The returned result + + Last : String_List_Id := Nil_String; + -- Reference to the last string elements in Result, when Kind is List. + + begin + Result.Location := Location_Of (From_Project_Node); + + -- Process each term of the expression, starting with First_Term + + while The_Term /= Empty_Node loop + + -- We get the term data and kind ... + + Term_Kind := Expression_Kind_Of (The_Term); + + The_Current_Term := Current_Term (The_Term); + + case Kind_Of (The_Current_Term) is + + when N_Literal_String => + + case Kind is + + when Undefined => + + -- Should never happen + + pragma Assert (False, "Undefined expression kind"); + raise Program_Error; + + when Single => + Add (Result.Value, String_Value_Of (The_Current_Term)); + + when List => + + String_Elements.Increment_Last; + + if Last = Nil_String then + + -- This can happen in an expression such as + -- () & "toto" + + Result.Values := String_Elements.Last; + + else + String_Elements.Table (Last).Next := + String_Elements.Last; + end if; + + Last := String_Elements.Last; + String_Elements.Table (Last) := + (Value => String_Value_Of (The_Current_Term), + Location => Location_Of (The_Current_Term), + Next => Nil_String); + + end case; + + when N_Literal_String_List => + + declare + String_Node : Project_Node_Id := + First_Expression_In_List (The_Current_Term); + + Value : Variable_Value; + + begin + if String_Node /= Empty_Node then + + -- If String_Node is nil, it is an empty list, + -- there is nothing to do + + Value := Expression + (Project => Project, + From_Project_Node => From_Project_Node, + Pkg => Pkg, + First_Term => Tree.First_Term (String_Node), + Kind => Single); + String_Elements.Increment_Last; + + if Result.Values = Nil_String then + + -- This literal string list is the first term + -- in a string list expression + + Result.Values := String_Elements.Last; + + else + String_Elements.Table (Last).Next := + String_Elements.Last; + end if; + + Last := String_Elements.Last; + String_Elements.Table (Last) := + (Value => Value.Value, + Location => Value.Location, + Next => Nil_String); + + loop + -- Add the other element of the literal string list + -- one after the other + + String_Node := + Next_Expression_In_List (String_Node); + + exit when String_Node = Empty_Node; + + Value := + Expression + (Project => Project, + From_Project_Node => From_Project_Node, + Pkg => Pkg, + First_Term => Tree.First_Term (String_Node), + Kind => Single); + + String_Elements.Increment_Last; + String_Elements.Table (Last).Next := + String_Elements.Last; + Last := String_Elements.Last; + String_Elements.Table (Last) := + (Value => Value.Value, + Location => Value.Location, + Next => Nil_String); + end loop; + + end if; + + end; + + when N_Variable_Reference | N_Attribute_Reference => + + declare + The_Project : Project_Id := Project; + The_Package : Package_Id := Pkg; + The_Name : Name_Id := No_Name; + The_Variable_Id : Variable_Id := No_Variable; + The_Variable : Variable; + Term_Project : constant Project_Node_Id := + Project_Node_Of (The_Current_Term); + Term_Package : constant Project_Node_Id := + Package_Node_Of (The_Current_Term); + + begin + if Term_Project /= Empty_Node and then + Term_Project /= From_Project_Node + then + -- This variable or attribute comes from another project + + The_Name := Name_Of (Term_Project); + The_Project := Imported_Or_Modified_Project_From + (Project => Project, With_Name => The_Name); + end if; + + if Term_Package /= Empty_Node then + + -- This is an attribute of a package + + The_Name := Name_Of (Term_Package); + The_Package := Projects.Table (The_Project).Decl.Packages; + + while The_Package /= No_Package + and then Packages.Table (The_Package).Name /= The_Name + loop + The_Package := Packages.Table (The_Package).Next; + end loop; + + pragma Assert + (The_Package /= No_Package, + "package not found."); + + elsif Kind_Of (The_Current_Term) = N_Attribute_Reference then + The_Package := No_Package; + end if; + + The_Name := Name_Of (The_Current_Term); + + if The_Package /= No_Package then + + -- First, if there is a package, look into the package + + if Kind_Of (The_Current_Term) = N_Variable_Reference then + The_Variable_Id := + Packages.Table (The_Package).Decl.Variables; + + else + The_Variable_Id := + Packages.Table (The_Package).Decl.Attributes; + end if; + + while The_Variable_Id /= No_Variable + and then + Variable_Elements.Table (The_Variable_Id).Name /= + The_Name + loop + The_Variable_Id := + Variable_Elements.Table (The_Variable_Id).Next; + end loop; + + end if; + + if The_Variable_Id = No_Variable then + + -- If we have not found it, look into the project + + if Kind_Of (The_Current_Term) = N_Variable_Reference then + The_Variable_Id := + Projects.Table (The_Project).Decl.Variables; + + else + The_Variable_Id := + Projects.Table (The_Project).Decl.Attributes; + end if; + + while The_Variable_Id /= No_Variable + and then + Variable_Elements.Table (The_Variable_Id).Name /= + The_Name + loop + The_Variable_Id := + Variable_Elements.Table (The_Variable_Id).Next; + end loop; + + end if; + + pragma Assert (The_Variable_Id /= No_Variable, + "variable or attribute not found"); + + The_Variable := Variable_Elements.Table (The_Variable_Id); + + case Kind is + + when Undefined => + + -- Should never happen + + pragma Assert (False, "undefined expression kind"); + null; + + when Single => + + case The_Variable.Value.Kind is + + when Undefined => + null; + + when Single => + Add (Result.Value, The_Variable.Value.Value); + + when List => + + -- Should never happen + + pragma Assert + (False, + "list cannot appear in single " & + "string expression"); + null; + + end case; + + when List => + case The_Variable.Value.Kind is + + when Undefined => + null; + + when Single => + String_Elements.Increment_Last; + + if Last = Nil_String then + + -- This can happen in an expression such as + -- () & Var + + Result.Values := String_Elements.Last; + + else + String_Elements.Table (Last).Next := + String_Elements.Last; + end if; + + Last := String_Elements.Last; + String_Elements.Table (Last) := + (Value => The_Variable.Value.Value, + Location => Location_Of (The_Current_Term), + Next => Nil_String); + + when List => + + declare + The_List : String_List_Id := + The_Variable.Value.Values; + + begin + while The_List /= Nil_String loop + String_Elements.Increment_Last; + + if Last = Nil_String then + Result.Values := String_Elements.Last; + + else + String_Elements.Table (Last).Next := + String_Elements.Last; + + end if; + + Last := String_Elements.Last; + String_Elements.Table (Last) := + (Value => + String_Elements.Table + (The_List).Value, + Location => Location_Of + (The_Current_Term), + Next => Nil_String); + The_List := + String_Elements.Table (The_List).Next; + + end loop; + end; + end case; + end case; + end; + + when N_External_Value => + String_To_Name_Buffer + (String_Value_Of (External_Reference_Of (The_Current_Term))); + + declare + Name : constant Name_Id := Name_Find; + Default : String_Id := No_String; + Value : String_Id := No_String; + + Default_Node : constant Project_Node_Id := + External_Default_Of (The_Current_Term); + + begin + if Default_Node /= Empty_Node then + Default := String_Value_Of (Default_Node); + end if; + + Value := Prj.Ext.Value_Of (Name, Default); + + if Value = No_String then + if Error_Report = null then + Error_Msg + ("undefined external reference", + Location_Of (The_Current_Term)); + + else + Error_Report + ("""" & Get_Name_String (Name) & + """ is an undefined external reference"); + end if; + + Value := Empty_String; + + end if; + + case Kind is + + when Undefined => + null; + + when Single => + Add (Result.Value, Value); + + when List => + String_Elements.Increment_Last; + + if Last = Nil_String then + Result.Values := String_Elements.Last; + + else + String_Elements.Table (Last).Next := + String_Elements.Last; + end if; + + Last := String_Elements.Last; + String_Elements.Table (Last) := + (Value => Value, + Location => Location_Of (The_Current_Term), + Next => Nil_String); + + end case; + + end; + + when others => + + -- Should never happen + + pragma Assert + (False, + "illegal node kind in an expression"); + raise Program_Error; + + end case; + + The_Term := Next_Term (The_Term); + + end loop; + return Result; + end Expression; + + --------------------------------------- + -- Imported_Or_Modified_Project_From -- + --------------------------------------- + + function Imported_Or_Modified_Project_From + (Project : Project_Id; + With_Name : Name_Id) + return Project_Id + is + Data : constant Project_Data := Projects.Table (Project); + List : Project_List := Data.Imported_Projects; + + begin + -- First check if it is the name of a modified project + + if Data.Modifies /= No_Project + and then Projects.Table (Data.Modifies).Name = With_Name + then + return Data.Modifies; + + else + -- Then check the name of each imported project + + while List /= Empty_Project_List + and then + Projects.Table + (Project_Lists.Table (List).Project).Name /= With_Name + + loop + List := Project_Lists.Table (List).Next; + end loop; + + pragma Assert + (List /= Empty_Project_List, + "project not found"); + + return Project_Lists.Table (List).Project; + end if; + + end Imported_Or_Modified_Project_From; + + ------------------ + -- Package_From -- + ------------------ + + function Package_From + (Project : Project_Id; + With_Name : Name_Id) + return Package_Id + is + Data : constant Project_Data := Projects.Table (Project); + Result : Package_Id := Data.Decl.Packages; + + begin + -- Check the name of each existing package of Project + + while Result /= No_Package + and then + Packages.Table (Result).Name /= With_Name + loop + Result := Packages.Table (Result).Next; + end loop; + + if Result = No_Package then + -- Should never happen + Write_Line ("package """ & Get_Name_String (With_Name) & + """ not found"); + raise Program_Error; + + else + return Result; + end if; + end Package_From; + + ------------- + -- Process -- + ------------- + + procedure Process + (Project : out Project_Id; + From_Project_Node : Project_Node_Id; + Report_Error : Put_Line_Access) + is + begin + Error_Report := Report_Error; + + -- Make sure there is no projects in the data structure + + Projects.Set_Last (No_Project); + Processed_Projects.Reset; + + -- And process the main project and all of the projects it depends on, + -- recursively + + Recursive_Process + (Project => Project, + From_Project_Node => From_Project_Node, + Modified_By => No_Project); + + if Errout.Errors_Detected > 0 then + Project := No_Project; + end if; + + if Project /= No_Project then + Check (Project); + end if; + + end Process; + + ------------------------------- + -- Process_Declarative_Items -- + ------------------------------- + + procedure Process_Declarative_Items + (Project : Project_Id; + From_Project_Node : Project_Node_Id; + Pkg : Package_Id; + Item : Project_Node_Id) is + + Current_Declarative_Item : Project_Node_Id := Item; + + Current_Item : Project_Node_Id := Empty_Node; + + begin + -- For each declarative item + + while Current_Declarative_Item /= Empty_Node loop + + -- Get its data + + Current_Item := Current_Item_Node (Current_Declarative_Item); + + -- And set Current_Declarative_Item to the next declarative item + -- ready for the next iteration + + Current_Declarative_Item := Next_Declarative_Item + (Current_Declarative_Item); + + case Kind_Of (Current_Item) is + + when N_Package_Declaration => + Packages.Increment_Last; + + declare + New_Pkg : constant Package_Id := Packages.Last; + The_New_Package : Package_Element; + + Project_Of_Renamed_Package : constant Project_Node_Id := + Project_Of_Renamed_Package_Of + (Current_Item); + + begin + The_New_Package.Name := Name_Of (Current_Item); + + if Pkg /= No_Package then + The_New_Package.Next := + Packages.Table (Pkg).Decl.Packages; + Packages.Table (Pkg).Decl.Packages := New_Pkg; + else + The_New_Package.Next := + Projects.Table (Project).Decl.Packages; + Projects.Table (Project).Decl.Packages := New_Pkg; + end if; + + Packages.Table (New_Pkg) := The_New_Package; + + if Project_Of_Renamed_Package /= Empty_Node then + + -- Renamed package + + declare + Project_Name : constant Name_Id := + Name_Of + (Project_Of_Renamed_Package); + + Renamed_Project : constant Project_Id := + Imported_Or_Modified_Project_From + (Project, Project_Name); + + Renamed_Package : constant Package_Id := + Package_From + (Renamed_Project, + Name_Of (Current_Item)); + + begin + Packages.Table (New_Pkg).Decl := + Packages.Table (Renamed_Package).Decl; + end; + + else + -- Set the default values of the attributes + + Add_Attributes + (Packages.Table (New_Pkg).Decl, + Package_Attributes.Table + (Package_Id_Of (Current_Item)).First_Attribute); + + Process_Declarative_Items + (Project => Project, + From_Project_Node => From_Project_Node, + Pkg => New_Pkg, + Item => First_Declarative_Item_Of + (Current_Item)); + end if; + + end; + + when N_String_Type_Declaration => + + -- There is nothing to process + + null; + + when N_Attribute_Declaration | + N_Typed_Variable_Declaration | + N_Variable_Declaration => + + pragma Assert (Expression_Of (Current_Item) /= Empty_Node, + "no expression for an object declaration"); + + declare + New_Value : constant Variable_Value := + Expression + (Project => Project, + From_Project_Node => From_Project_Node, + Pkg => Pkg, + First_Term => + Tree.First_Term (Expression_Of + (Current_Item)), + Kind => + Expression_Kind_Of (Current_Item)); + + The_Variable : Variable_Id := No_Variable; + + Current_Item_Name : constant Name_Id := + Name_Of (Current_Item); + + begin + if Kind_Of (Current_Item) = N_Typed_Variable_Declaration then + + if String_Equal (New_Value.Value, Empty_String) then + Error_Msg_Name_1 := Name_Of (Current_Item); + + if Error_Report = null then + Error_Msg + ("no value defined for %", + Location_Of (Current_Item)); + + else + Error_Report + ("no value defined for " & + Get_Name_String (Error_Msg_Name_1)); + end if; + + else + declare + Current_String : Project_Node_Id := + First_Literal_String + (String_Type_Of + (Current_Item)); + + begin + while Current_String /= Empty_Node + and then not String_Equal + (String_Value_Of (Current_String), + New_Value.Value) + loop + Current_String := + Next_Literal_String (Current_String); + end loop; + + if Current_String = Empty_Node then + String_To_Name_Buffer (New_Value.Value); + Error_Msg_Name_1 := Name_Find; + Error_Msg_Name_2 := Name_Of (Current_Item); + + if Error_Report = null then + Error_Msg + ("value { is illegal for typed string %", + Location_Of (Current_Item)); + + else + Error_Report + ("value """ & + Get_Name_String (Error_Msg_Name_1) & + """ is illegal for typed string """ & + Get_Name_String (Error_Msg_Name_2) & + """"); + end if; + end if; + end; + end if; + end if; + + if Kind_Of (Current_Item) /= N_Attribute_Declaration + or else + Associative_Array_Index_Of (Current_Item) = No_String + then + -- Usual case + + -- Code below really needs more comments ??? + + if Kind_Of (Current_Item) = N_Attribute_Declaration then + if Pkg /= No_Package then + The_Variable := + Packages.Table (Pkg).Decl.Attributes; + + else + The_Variable := + Projects.Table (Project).Decl.Attributes; + end if; + + else + if Pkg /= No_Package then + The_Variable := + Packages.Table (Pkg).Decl.Variables; + + else + The_Variable := + Projects.Table (Project).Decl.Variables; + end if; + + end if; + + while + The_Variable /= No_Variable + and then + Variable_Elements.Table (The_Variable).Name /= + Current_Item_Name + loop + The_Variable := + Variable_Elements.Table (The_Variable).Next; + end loop; + + if The_Variable = No_Variable then + pragma Assert + (Kind_Of (Current_Item) /= N_Attribute_Declaration, + "illegal attribute declaration"); + + Variable_Elements.Increment_Last; + The_Variable := Variable_Elements.Last; + + if Pkg /= No_Package then + Variable_Elements.Table (The_Variable) := + (Next => + Packages.Table (Pkg).Decl.Variables, + Name => Current_Item_Name, + Value => New_Value); + Packages.Table (Pkg).Decl.Variables := The_Variable; + + else + Variable_Elements.Table (The_Variable) := + (Next => + Projects.Table (Project).Decl.Variables, + Name => Current_Item_Name, + Value => New_Value); + Projects.Table (Project).Decl.Variables := + The_Variable; + end if; + + else + Variable_Elements.Table (The_Variable).Value := + New_Value; + + end if; + + else + -- Associative array attribute + + String_To_Name_Buffer + (Associative_Array_Index_Of (Current_Item)); + + declare + The_Array : Array_Id; + + The_Array_Element : Array_Element_Id := + No_Array_Element; + + Index_Name : constant Name_Id := Name_Find; + + begin + + if Pkg /= No_Package then + The_Array := Packages.Table (Pkg).Decl.Arrays; + + else + The_Array := Projects.Table (Project).Decl.Arrays; + end if; + + while + The_Array /= No_Array + and then Arrays.Table (The_Array).Name /= + Current_Item_Name + loop + The_Array := Arrays.Table (The_Array).Next; + end loop; + + if The_Array = No_Array then + Arrays.Increment_Last; + The_Array := Arrays.Last; + + if Pkg /= No_Package then + Arrays.Table (The_Array) := + (Name => Current_Item_Name, + Value => No_Array_Element, + Next => Packages.Table (Pkg).Decl.Arrays); + Packages.Table (Pkg).Decl.Arrays := The_Array; + + else + Arrays.Table (The_Array) := + (Name => Current_Item_Name, + Value => No_Array_Element, + Next => + Projects.Table (Project).Decl.Arrays); + Projects.Table (Project).Decl.Arrays := + The_Array; + end if; + + else + The_Array_Element := Arrays.Table (The_Array).Value; + end if; + + while The_Array_Element /= No_Array_Element + and then + Array_Elements.Table (The_Array_Element).Index /= + Index_Name + loop + The_Array_Element := + Array_Elements.Table (The_Array_Element).Next; + end loop; + + if The_Array_Element = No_Array_Element then + Array_Elements.Increment_Last; + The_Array_Element := Array_Elements.Last; + Array_Elements.Table (The_Array_Element) := + (Index => Index_Name, + Value => New_Value, + Next => Arrays.Table (The_Array).Value); + Arrays.Table (The_Array).Value := The_Array_Element; + + else + Array_Elements.Table (The_Array_Element).Value := + New_Value; + end if; + end; + end if; + end; + + when N_Case_Construction => + declare + The_Project : Project_Id := Project; + The_Package : Package_Id := Pkg; + The_Variable : Variable_Value := Nil_Variable_Value; + Case_Value : String_Id := No_String; + Case_Item : Project_Node_Id := Empty_Node; + Choice_String : Project_Node_Id := Empty_Node; + Decl_Item : Project_Node_Id := Empty_Node; + + begin + declare + Variable_Node : constant Project_Node_Id := + Case_Variable_Reference_Of + (Current_Item); + + Var_Id : Variable_Id := No_Variable; + Name : Name_Id := No_Name; + + begin + if Project_Node_Of (Variable_Node) /= Empty_Node then + Name := Name_Of (Project_Node_Of (Variable_Node)); + The_Project := + Imported_Or_Modified_Project_From (Project, Name); + end if; + + if Package_Node_Of (Variable_Node) /= Empty_Node then + Name := Name_Of (Package_Node_Of (Variable_Node)); + The_Package := Package_From (The_Project, Name); + end if; + + Name := Name_Of (Variable_Node); + + if The_Package /= No_Package then + Var_Id := Packages.Table (The_Package).Decl.Variables; + Name := Name_Of (Variable_Node); + while Var_Id /= No_Variable + and then + Variable_Elements.Table (Var_Id).Name /= Name + loop + Var_Id := Variable_Elements.Table (Var_Id).Next; + end loop; + end if; + + if Var_Id = No_Variable + and then Package_Node_Of (Variable_Node) = Empty_Node + then + Var_Id := Projects.Table (The_Project).Decl.Variables; + while Var_Id /= No_Variable + and then + Variable_Elements.Table (Var_Id).Name /= Name + loop + Var_Id := Variable_Elements.Table (Var_Id).Next; + end loop; + end if; + + if Var_Id = No_Variable then + + -- Should never happen + + Write_Line ("variable """ & + Get_Name_String (Name) & + """ not found"); + raise Program_Error; + end if; + + The_Variable := Variable_Elements.Table (Var_Id).Value; + + if The_Variable.Kind /= Single then + + -- Should never happen + + Write_Line ("variable""" & + Get_Name_String (Name) & + """ is not a single string variable"); + raise Program_Error; + end if; + + Case_Value := The_Variable.Value; + end; + + Case_Item := First_Case_Item_Of (Current_Item); + Case_Item_Loop : + while Case_Item /= Empty_Node loop + Choice_String := First_Choice_Of (Case_Item); + + if Choice_String = Empty_Node then + Decl_Item := First_Declarative_Item_Of (Case_Item); + exit Case_Item_Loop; + end if; + + Choice_Loop : + while Choice_String /= Empty_Node loop + if String_Equal (Case_Value, + String_Value_Of (Choice_String)) + then + Decl_Item := + First_Declarative_Item_Of (Case_Item); + exit Case_Item_Loop; + end if; + + Choice_String := + Next_Literal_String (Choice_String); + end loop Choice_Loop; + Case_Item := Next_Case_Item (Case_Item); + end loop Case_Item_Loop; + + if Decl_Item /= Empty_Node then + Process_Declarative_Items + (Project => Project, + From_Project_Node => From_Project_Node, + Pkg => Pkg, + Item => Decl_Item); + end if; + end; + + when others => + + -- Should never happen + + Write_Line ("Illegal declarative item: " & + Project_Node_Kind'Image (Kind_Of (Current_Item))); + raise Program_Error; + end case; + end loop; + end Process_Declarative_Items; + + --------------------- + -- Recursive_Check -- + --------------------- + + procedure Recursive_Check (Project : Project_Id) is + Data : Project_Data; + Imported_Project_List : Project_List := Empty_Project_List; + + begin + -- Do nothing if Project is No_Project, or Project has already + -- been marked as checked. + + if Project /= No_Project + and then not Projects.Table (Project).Checked + then + Data := Projects.Table (Project); + + -- Call itself for a possible modified project. + -- (if there is no modified project, then nothing happens). + + Recursive_Check (Data.Modifies); + + -- Call itself for all imported projects + + Imported_Project_List := Data.Imported_Projects; + while Imported_Project_List /= Empty_Project_List loop + Recursive_Check + (Project_Lists.Table (Imported_Project_List).Project); + Imported_Project_List := + Project_Lists.Table (Imported_Project_List).Next; + end loop; + + -- Mark project as checked + + Projects.Table (Project).Checked := True; + + if Opt.Verbose_Mode then + Write_Str ("Checking project file """); + Write_Str (Get_Name_String (Data.Name)); + Write_Line (""""); + end if; + + Prj.Nmsc.Check_Naming_Scheme (Project, Error_Report); + end if; + + end Recursive_Check; + + ----------------------- + -- Recursive_Process -- + ----------------------- + + procedure Recursive_Process + (Project : out Project_Id; + From_Project_Node : Project_Node_Id; + Modified_By : Project_Id) + is + With_Clause : Project_Node_Id; + + begin + if From_Project_Node = Empty_Node then + Project := No_Project; + + else + declare + Processed_Data : Project_Data := Empty_Project; + Imported : Project_List := Empty_Project_List; + Declaration_Node : Project_Node_Id := Empty_Node; + Name : constant Name_Id := + Name_Of (From_Project_Node); + + begin + Project := Processed_Projects.Get (Name); + + if Project /= No_Project then + return; + end if; + + Projects.Increment_Last; + Project := Projects.Last; + Processed_Projects.Set (Name, Project); + Processed_Data.Name := Name; + Processed_Data.Path_Name := Path_Name_Of (From_Project_Node); + Processed_Data.Location := Location_Of (From_Project_Node); + Processed_Data.Directory := Directory_Of (From_Project_Node); + Processed_Data.Modified_By := Modified_By; + Add_Attributes (Processed_Data.Decl, Attribute_First); + With_Clause := First_With_Clause_Of (From_Project_Node); + + while With_Clause /= Empty_Node loop + declare + New_Project : Project_Id; + New_Data : Project_Data; + + begin + Recursive_Process + (Project => New_Project, + From_Project_Node => Project_Node_Of (With_Clause), + Modified_By => No_Project); + New_Data := Projects.Table (New_Project); + + -- If we were the first project to import it, + -- set First_Referred_By to us. + + if New_Data.First_Referred_By = No_Project then + New_Data.First_Referred_By := Project; + Projects.Table (New_Project) := New_Data; + end if; + + -- Add this project to our list of imported projects + + Project_Lists.Increment_Last; + Project_Lists.Table (Project_Lists.Last) := + (Project => New_Project, Next => Empty_Project_List); + + -- Imported is the id of the last imported project. + -- If it is nil, then this imported project is our first. + + if Imported = Empty_Project_List then + Processed_Data.Imported_Projects := Project_Lists.Last; + + else + Project_Lists.Table (Imported).Next := Project_Lists.Last; + end if; + + Imported := Project_Lists.Last; + + With_Clause := Next_With_Clause_Of (With_Clause); + end; + end loop; + + Declaration_Node := Project_Declaration_Of (From_Project_Node); + + Recursive_Process + (Project => Processed_Data.Modifies, + From_Project_Node => Modified_Project_Of (Declaration_Node), + Modified_By => Project); + + Projects.Table (Project) := Processed_Data; + + Process_Declarative_Items + (Project => Project, + From_Project_Node => From_Project_Node, + Pkg => No_Package, + Item => First_Declarative_Item_Of + (Declaration_Node)); + + end; + end if; + end Recursive_Process; + +end Prj.Proc; |