1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
11 -- Copyright (C) 2001 Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
27 ------------------------------------------------------------------------------
29 with Errout; use Errout;
30 with Namet; use Namet;
32 with Output; use Output;
33 with Prj.Attr; use Prj.Attr;
34 with Prj.Com; use Prj.Com;
35 with Prj.Ext; use Prj.Ext;
36 with Prj.Nmsc; use Prj.Nmsc;
37 with Stringt; use Stringt;
42 package body Prj.Proc is
44 Error_Report : Put_Line_Access := null;
46 package Processed_Projects is new GNAT.HTable.Simple_HTable
47 (Header_Num => Header_Num,
48 Element => Project_Id,
49 No_Element => No_Project,
53 -- This hash table contains all processed projects
55 procedure Add (To_Exp : in out String_Id; Str : String_Id);
56 -- Concatenate two strings and returns another string if both
57 -- arguments are not null string.
59 procedure Add_Attributes
60 (Decl : in out Declarations;
61 First : Attribute_Node_Id);
62 -- Add all attributes, starting with First, with their default
63 -- values to the package or project with declarations Decl.
66 (Project : Project_Id;
67 From_Project_Node : Project_Node_Id;
69 First_Term : Project_Node_Id;
71 return Variable_Value;
72 -- From N_Expression project node From_Project_Node, compute the value
73 -- of an expression and return it as a Variable_Value.
75 function Imported_Or_Modified_Project_From
76 (Project : Project_Id;
79 -- Find an imported or modified project of Project whose name is With_Name.
82 (Project : Project_Id;
85 -- Find the package of Project whose name is With_Name.
87 procedure Process_Declarative_Items
88 (Project : Project_Id;
89 From_Project_Node : Project_Node_Id;
91 Item : Project_Node_Id);
92 -- Process declarative items starting with From_Project_Node, and put them
93 -- in declarations Decl. This is a recursive procedure; it calls itself for
94 -- a package declaration or a case construction.
96 procedure Recursive_Process
97 (Project : out Project_Id;
98 From_Project_Node : Project_Node_Id;
99 Modified_By : Project_Id);
100 -- Process project with node From_Project_Node in the tree.
101 -- Do nothing if From_Project_Node is Empty_Node.
102 -- If project has already been processed, simply return its project id.
103 -- Otherwise create a new project id, mark it as processed, call itself
104 -- recursively for all imported projects and a modified project, if any.
105 -- Then process the declarative items of the project.
107 procedure Check (Project : in out Project_Id);
108 -- Set all projects to not checked, then call Recursive_Check for
109 -- the main project Project.
110 -- Project is set to No_Project if errors occurred.
112 procedure Recursive_Check (Project : Project_Id);
113 -- If Project is marked as not checked, mark it as checked,
114 -- call Check_Naming_Scheme for the project, then call itself
115 -- for a possible modified project and all the imported projects
122 procedure Add (To_Exp : in out String_Id; Str : String_Id) is
124 if To_Exp = Types.No_String or else String_Length (To_Exp) = 0 then
126 -- To_Exp is nil or empty. The result is Str.
130 -- If Str is nil, then do not change To_Ext
132 elsif Str /= No_String then
133 Start_String (To_Exp);
134 Store_String_Chars (Str);
135 To_Exp := End_String;
143 procedure Add_Attributes
144 (Decl : in out Declarations;
145 First : Attribute_Node_Id) is
146 The_Attribute : Attribute_Node_Id := First;
147 Attribute_Data : Attribute_Record;
150 while The_Attribute /= Empty_Attribute loop
151 Attribute_Data := Attributes.Table (The_Attribute);
153 if Attribute_Data.Kind_2 /= Associative_Array then
155 New_Attribute : Variable_Value;
158 case Attribute_Data.Kind_1 is
160 -- Undefined should not happen
164 (False, "attribute with an undefined kind");
167 -- Single attributes have a default value of empty string
172 Location => No_Location,
174 Value => Empty_String);
176 -- List attributes have a default value of nil list
181 Location => No_Location,
183 Values => Nil_String);
187 Variable_Elements.Increment_Last;
188 Variable_Elements.Table (Variable_Elements.Last) :=
189 (Next => Decl.Attributes,
190 Name => Attribute_Data.Name,
191 Value => New_Attribute);
192 Decl.Attributes := Variable_Elements.Last;
196 The_Attribute := Attributes.Table (The_Attribute).Next;
205 procedure Check (Project : in out Project_Id) is
207 -- Make sure that all projects are marked as not checked.
209 for Index in 1 .. Projects.Last loop
210 Projects.Table (Index).Checked := False;
213 Recursive_Check (Project);
215 if Errout.Errors_Detected > 0 then
216 Project := No_Project;
226 (Project : Project_Id;
227 From_Project_Node : Project_Node_Id;
229 First_Term : Project_Node_Id;
230 Kind : Variable_Kind)
231 return Variable_Value
233 The_Term : Project_Node_Id := First_Term;
234 -- The term in the expression list
236 The_Current_Term : Project_Node_Id := Empty_Node;
237 -- The current term node id
239 Term_Kind : Variable_Kind;
240 -- The kind of the current term
242 Result : Variable_Value (Kind => Kind);
243 -- The returned result
245 Last : String_List_Id := Nil_String;
246 -- Reference to the last string elements in Result, when Kind is List.
249 Result.Location := Location_Of (From_Project_Node);
251 -- Process each term of the expression, starting with First_Term
253 while The_Term /= Empty_Node loop
255 -- We get the term data and kind ...
257 Term_Kind := Expression_Kind_Of (The_Term);
259 The_Current_Term := Current_Term (The_Term);
261 case Kind_Of (The_Current_Term) is
263 when N_Literal_String =>
269 -- Should never happen
271 pragma Assert (False, "Undefined expression kind");
275 Add (Result.Value, String_Value_Of (The_Current_Term));
279 String_Elements.Increment_Last;
281 if Last = Nil_String then
283 -- This can happen in an expression such as
286 Result.Values := String_Elements.Last;
289 String_Elements.Table (Last).Next :=
290 String_Elements.Last;
293 Last := String_Elements.Last;
294 String_Elements.Table (Last) :=
295 (Value => String_Value_Of (The_Current_Term),
296 Location => Location_Of (The_Current_Term),
301 when N_Literal_String_List =>
304 String_Node : Project_Node_Id :=
305 First_Expression_In_List (The_Current_Term);
307 Value : Variable_Value;
310 if String_Node /= Empty_Node then
312 -- If String_Node is nil, it is an empty list,
313 -- there is nothing to do
317 From_Project_Node => From_Project_Node,
319 First_Term => Tree.First_Term (String_Node),
321 String_Elements.Increment_Last;
323 if Result.Values = Nil_String then
325 -- This literal string list is the first term
326 -- in a string list expression
328 Result.Values := String_Elements.Last;
331 String_Elements.Table (Last).Next :=
332 String_Elements.Last;
335 Last := String_Elements.Last;
336 String_Elements.Table (Last) :=
337 (Value => Value.Value,
338 Location => Value.Location,
342 -- Add the other element of the literal string list
343 -- one after the other
346 Next_Expression_In_List (String_Node);
348 exit when String_Node = Empty_Node;
353 From_Project_Node => From_Project_Node,
355 First_Term => Tree.First_Term (String_Node),
358 String_Elements.Increment_Last;
359 String_Elements.Table (Last).Next :=
360 String_Elements.Last;
361 Last := String_Elements.Last;
362 String_Elements.Table (Last) :=
363 (Value => Value.Value,
364 Location => Value.Location,
372 when N_Variable_Reference | N_Attribute_Reference =>
375 The_Project : Project_Id := Project;
376 The_Package : Package_Id := Pkg;
377 The_Name : Name_Id := No_Name;
378 The_Variable_Id : Variable_Id := No_Variable;
379 The_Variable : Variable;
380 Term_Project : constant Project_Node_Id :=
381 Project_Node_Of (The_Current_Term);
382 Term_Package : constant Project_Node_Id :=
383 Package_Node_Of (The_Current_Term);
386 if Term_Project /= Empty_Node and then
387 Term_Project /= From_Project_Node
389 -- This variable or attribute comes from another project
391 The_Name := Name_Of (Term_Project);
392 The_Project := Imported_Or_Modified_Project_From
393 (Project => Project, With_Name => The_Name);
396 if Term_Package /= Empty_Node then
398 -- This is an attribute of a package
400 The_Name := Name_Of (Term_Package);
401 The_Package := Projects.Table (The_Project).Decl.Packages;
403 while The_Package /= No_Package
404 and then Packages.Table (The_Package).Name /= The_Name
406 The_Package := Packages.Table (The_Package).Next;
410 (The_Package /= No_Package,
411 "package not found.");
413 elsif Kind_Of (The_Current_Term) = N_Attribute_Reference then
414 The_Package := No_Package;
417 The_Name := Name_Of (The_Current_Term);
419 if The_Package /= No_Package then
421 -- First, if there is a package, look into the package
423 if Kind_Of (The_Current_Term) = N_Variable_Reference then
425 Packages.Table (The_Package).Decl.Variables;
429 Packages.Table (The_Package).Decl.Attributes;
432 while The_Variable_Id /= No_Variable
434 Variable_Elements.Table (The_Variable_Id).Name /=
438 Variable_Elements.Table (The_Variable_Id).Next;
443 if The_Variable_Id = No_Variable then
445 -- If we have not found it, look into the project
447 if Kind_Of (The_Current_Term) = N_Variable_Reference then
449 Projects.Table (The_Project).Decl.Variables;
453 Projects.Table (The_Project).Decl.Attributes;
456 while The_Variable_Id /= No_Variable
458 Variable_Elements.Table (The_Variable_Id).Name /=
462 Variable_Elements.Table (The_Variable_Id).Next;
467 pragma Assert (The_Variable_Id /= No_Variable,
468 "variable or attribute not found");
470 The_Variable := Variable_Elements.Table (The_Variable_Id);
476 -- Should never happen
478 pragma Assert (False, "undefined expression kind");
483 case The_Variable.Value.Kind is
489 Add (Result.Value, The_Variable.Value.Value);
493 -- Should never happen
497 "list cannot appear in single " &
498 "string expression");
504 case The_Variable.Value.Kind is
510 String_Elements.Increment_Last;
512 if Last = Nil_String then
514 -- This can happen in an expression such as
517 Result.Values := String_Elements.Last;
520 String_Elements.Table (Last).Next :=
521 String_Elements.Last;
524 Last := String_Elements.Last;
525 String_Elements.Table (Last) :=
526 (Value => The_Variable.Value.Value,
527 Location => Location_Of (The_Current_Term),
533 The_List : String_List_Id :=
534 The_Variable.Value.Values;
537 while The_List /= Nil_String loop
538 String_Elements.Increment_Last;
540 if Last = Nil_String then
541 Result.Values := String_Elements.Last;
544 String_Elements.Table (Last).Next :=
545 String_Elements.Last;
549 Last := String_Elements.Last;
550 String_Elements.Table (Last) :=
552 String_Elements.Table
554 Location => Location_Of
558 String_Elements.Table (The_List).Next;
566 when N_External_Value =>
567 String_To_Name_Buffer
568 (String_Value_Of (External_Reference_Of (The_Current_Term)));
571 Name : constant Name_Id := Name_Find;
572 Default : String_Id := No_String;
573 Value : String_Id := No_String;
575 Default_Node : constant Project_Node_Id :=
576 External_Default_Of (The_Current_Term);
579 if Default_Node /= Empty_Node then
580 Default := String_Value_Of (Default_Node);
583 Value := Prj.Ext.Value_Of (Name, Default);
585 if Value = No_String then
586 if Error_Report = null then
588 ("undefined external reference",
589 Location_Of (The_Current_Term));
593 ("""" & Get_Name_String (Name) &
594 """ is an undefined external reference");
597 Value := Empty_String;
607 Add (Result.Value, Value);
610 String_Elements.Increment_Last;
612 if Last = Nil_String then
613 Result.Values := String_Elements.Last;
616 String_Elements.Table (Last).Next :=
617 String_Elements.Last;
620 Last := String_Elements.Last;
621 String_Elements.Table (Last) :=
623 Location => Location_Of (The_Current_Term),
632 -- Should never happen
636 "illegal node kind in an expression");
641 The_Term := Next_Term (The_Term);
648 ---------------------------------------
649 -- Imported_Or_Modified_Project_From --
650 ---------------------------------------
652 function Imported_Or_Modified_Project_From
653 (Project : Project_Id;
657 Data : constant Project_Data := Projects.Table (Project);
658 List : Project_List := Data.Imported_Projects;
661 -- First check if it is the name of a modified project
663 if Data.Modifies /= No_Project
664 and then Projects.Table (Data.Modifies).Name = With_Name
666 return Data.Modifies;
669 -- Then check the name of each imported project
671 while List /= Empty_Project_List
674 (Project_Lists.Table (List).Project).Name /= With_Name
677 List := Project_Lists.Table (List).Next;
681 (List /= Empty_Project_List,
682 "project not found");
684 return Project_Lists.Table (List).Project;
686 end Imported_Or_Modified_Project_From;
692 function Package_From
693 (Project : Project_Id;
697 Data : constant Project_Data := Projects.Table (Project);
698 Result : Package_Id := Data.Decl.Packages;
701 -- Check the name of each existing package of Project
703 while Result /= No_Package
705 Packages.Table (Result).Name /= With_Name
707 Result := Packages.Table (Result).Next;
710 if Result = No_Package then
711 -- Should never happen
712 Write_Line ("package """ & Get_Name_String (With_Name) &
726 (Project : out Project_Id;
727 From_Project_Node : Project_Node_Id;
728 Report_Error : Put_Line_Access)
731 Error_Report := Report_Error;
733 -- Make sure there is no projects in the data structure
735 Projects.Set_Last (No_Project);
736 Processed_Projects.Reset;
738 -- And process the main project and all of the projects it depends on,
743 From_Project_Node => From_Project_Node,
744 Modified_By => No_Project);
746 if Errout.Errors_Detected > 0 then
747 Project := No_Project;
750 if Project /= No_Project then
756 -------------------------------
757 -- Process_Declarative_Items --
758 -------------------------------
760 procedure Process_Declarative_Items
761 (Project : Project_Id;
762 From_Project_Node : Project_Node_Id;
764 Item : Project_Node_Id) is
766 Current_Declarative_Item : Project_Node_Id := Item;
768 Current_Item : Project_Node_Id := Empty_Node;
771 -- For each declarative item
773 while Current_Declarative_Item /= Empty_Node loop
777 Current_Item := Current_Item_Node (Current_Declarative_Item);
779 -- And set Current_Declarative_Item to the next declarative item
780 -- ready for the next iteration
782 Current_Declarative_Item := Next_Declarative_Item
783 (Current_Declarative_Item);
785 case Kind_Of (Current_Item) is
787 when N_Package_Declaration =>
788 Packages.Increment_Last;
791 New_Pkg : constant Package_Id := Packages.Last;
792 The_New_Package : Package_Element;
794 Project_Of_Renamed_Package : constant Project_Node_Id :=
795 Project_Of_Renamed_Package_Of
799 The_New_Package.Name := Name_Of (Current_Item);
801 if Pkg /= No_Package then
802 The_New_Package.Next :=
803 Packages.Table (Pkg).Decl.Packages;
804 Packages.Table (Pkg).Decl.Packages := New_Pkg;
806 The_New_Package.Next :=
807 Projects.Table (Project).Decl.Packages;
808 Projects.Table (Project).Decl.Packages := New_Pkg;
811 Packages.Table (New_Pkg) := The_New_Package;
813 if Project_Of_Renamed_Package /= Empty_Node then
818 Project_Name : constant Name_Id :=
820 (Project_Of_Renamed_Package);
822 Renamed_Project : constant Project_Id :=
823 Imported_Or_Modified_Project_From
824 (Project, Project_Name);
826 Renamed_Package : constant Package_Id :=
829 Name_Of (Current_Item));
832 Packages.Table (New_Pkg).Decl :=
833 Packages.Table (Renamed_Package).Decl;
837 -- Set the default values of the attributes
840 (Packages.Table (New_Pkg).Decl,
841 Package_Attributes.Table
842 (Package_Id_Of (Current_Item)).First_Attribute);
844 Process_Declarative_Items
846 From_Project_Node => From_Project_Node,
848 Item => First_Declarative_Item_Of
854 when N_String_Type_Declaration =>
856 -- There is nothing to process
860 when N_Attribute_Declaration |
861 N_Typed_Variable_Declaration |
862 N_Variable_Declaration =>
864 pragma Assert (Expression_Of (Current_Item) /= Empty_Node,
865 "no expression for an object declaration");
868 New_Value : constant Variable_Value :=
871 From_Project_Node => From_Project_Node,
874 Tree.First_Term (Expression_Of
877 Expression_Kind_Of (Current_Item));
879 The_Variable : Variable_Id := No_Variable;
881 Current_Item_Name : constant Name_Id :=
882 Name_Of (Current_Item);
885 if Kind_Of (Current_Item) = N_Typed_Variable_Declaration then
887 if String_Equal (New_Value.Value, Empty_String) then
888 Error_Msg_Name_1 := Name_Of (Current_Item);
890 if Error_Report = null then
892 ("no value defined for %",
893 Location_Of (Current_Item));
897 ("no value defined for " &
898 Get_Name_String (Error_Msg_Name_1));
903 Current_String : Project_Node_Id :=
909 while Current_String /= Empty_Node
910 and then not String_Equal
911 (String_Value_Of (Current_String),
915 Next_Literal_String (Current_String);
918 if Current_String = Empty_Node then
919 String_To_Name_Buffer (New_Value.Value);
920 Error_Msg_Name_1 := Name_Find;
921 Error_Msg_Name_2 := Name_Of (Current_Item);
923 if Error_Report = null then
925 ("value { is illegal for typed string %",
926 Location_Of (Current_Item));
931 Get_Name_String (Error_Msg_Name_1) &
932 """ is illegal for typed string """ &
933 Get_Name_String (Error_Msg_Name_2) &
941 if Kind_Of (Current_Item) /= N_Attribute_Declaration
943 Associative_Array_Index_Of (Current_Item) = No_String
947 -- Code below really needs more comments ???
949 if Kind_Of (Current_Item) = N_Attribute_Declaration then
950 if Pkg /= No_Package then
952 Packages.Table (Pkg).Decl.Attributes;
956 Projects.Table (Project).Decl.Attributes;
960 if Pkg /= No_Package then
962 Packages.Table (Pkg).Decl.Variables;
966 Projects.Table (Project).Decl.Variables;
972 The_Variable /= No_Variable
974 Variable_Elements.Table (The_Variable).Name /=
978 Variable_Elements.Table (The_Variable).Next;
981 if The_Variable = No_Variable then
983 (Kind_Of (Current_Item) /= N_Attribute_Declaration,
984 "illegal attribute declaration");
986 Variable_Elements.Increment_Last;
987 The_Variable := Variable_Elements.Last;
989 if Pkg /= No_Package then
990 Variable_Elements.Table (The_Variable) :=
992 Packages.Table (Pkg).Decl.Variables,
993 Name => Current_Item_Name,
995 Packages.Table (Pkg).Decl.Variables := The_Variable;
998 Variable_Elements.Table (The_Variable) :=
1000 Projects.Table (Project).Decl.Variables,
1001 Name => Current_Item_Name,
1002 Value => New_Value);
1003 Projects.Table (Project).Decl.Variables :=
1008 Variable_Elements.Table (The_Variable).Value :=
1014 -- Associative array attribute
1016 String_To_Name_Buffer
1017 (Associative_Array_Index_Of (Current_Item));
1019 if Case_Insensitive (Current_Item) then
1020 GNAT.Case_Util.To_Lower (Name_Buffer (1 .. Name_Len));
1024 The_Array : Array_Id;
1026 The_Array_Element : Array_Element_Id :=
1029 Index_Name : constant Name_Id := Name_Find;
1033 if Pkg /= No_Package then
1034 The_Array := Packages.Table (Pkg).Decl.Arrays;
1037 The_Array := Projects.Table (Project).Decl.Arrays;
1041 The_Array /= No_Array
1042 and then Arrays.Table (The_Array).Name /=
1045 The_Array := Arrays.Table (The_Array).Next;
1048 if The_Array = No_Array then
1049 Arrays.Increment_Last;
1050 The_Array := Arrays.Last;
1052 if Pkg /= No_Package then
1053 Arrays.Table (The_Array) :=
1054 (Name => Current_Item_Name,
1055 Value => No_Array_Element,
1056 Next => Packages.Table (Pkg).Decl.Arrays);
1057 Packages.Table (Pkg).Decl.Arrays := The_Array;
1060 Arrays.Table (The_Array) :=
1061 (Name => Current_Item_Name,
1062 Value => No_Array_Element,
1064 Projects.Table (Project).Decl.Arrays);
1065 Projects.Table (Project).Decl.Arrays :=
1070 The_Array_Element := Arrays.Table (The_Array).Value;
1073 while The_Array_Element /= No_Array_Element
1075 Array_Elements.Table (The_Array_Element).Index /=
1078 The_Array_Element :=
1079 Array_Elements.Table (The_Array_Element).Next;
1082 if The_Array_Element = No_Array_Element then
1083 Array_Elements.Increment_Last;
1084 The_Array_Element := Array_Elements.Last;
1085 Array_Elements.Table (The_Array_Element) :=
1086 (Index => Index_Name,
1088 Next => Arrays.Table (The_Array).Value);
1089 Arrays.Table (The_Array).Value := The_Array_Element;
1092 Array_Elements.Table (The_Array_Element).Value :=
1099 when N_Case_Construction =>
1101 The_Project : Project_Id := Project;
1102 The_Package : Package_Id := Pkg;
1103 The_Variable : Variable_Value := Nil_Variable_Value;
1104 Case_Value : String_Id := No_String;
1105 Case_Item : Project_Node_Id := Empty_Node;
1106 Choice_String : Project_Node_Id := Empty_Node;
1107 Decl_Item : Project_Node_Id := Empty_Node;
1111 Variable_Node : constant Project_Node_Id :=
1112 Case_Variable_Reference_Of
1115 Var_Id : Variable_Id := No_Variable;
1116 Name : Name_Id := No_Name;
1119 if Project_Node_Of (Variable_Node) /= Empty_Node then
1120 Name := Name_Of (Project_Node_Of (Variable_Node));
1122 Imported_Or_Modified_Project_From (Project, Name);
1125 if Package_Node_Of (Variable_Node) /= Empty_Node then
1126 Name := Name_Of (Package_Node_Of (Variable_Node));
1127 The_Package := Package_From (The_Project, Name);
1130 Name := Name_Of (Variable_Node);
1132 if The_Package /= No_Package then
1133 Var_Id := Packages.Table (The_Package).Decl.Variables;
1134 Name := Name_Of (Variable_Node);
1135 while Var_Id /= No_Variable
1137 Variable_Elements.Table (Var_Id).Name /= Name
1139 Var_Id := Variable_Elements.Table (Var_Id).Next;
1143 if Var_Id = No_Variable
1144 and then Package_Node_Of (Variable_Node) = Empty_Node
1146 Var_Id := Projects.Table (The_Project).Decl.Variables;
1147 while Var_Id /= No_Variable
1149 Variable_Elements.Table (Var_Id).Name /= Name
1151 Var_Id := Variable_Elements.Table (Var_Id).Next;
1155 if Var_Id = No_Variable then
1157 -- Should never happen
1159 Write_Line ("variable """ &
1160 Get_Name_String (Name) &
1162 raise Program_Error;
1165 The_Variable := Variable_Elements.Table (Var_Id).Value;
1167 if The_Variable.Kind /= Single then
1169 -- Should never happen
1171 Write_Line ("variable""" &
1172 Get_Name_String (Name) &
1173 """ is not a single string variable");
1174 raise Program_Error;
1177 Case_Value := The_Variable.Value;
1180 Case_Item := First_Case_Item_Of (Current_Item);
1182 while Case_Item /= Empty_Node loop
1183 Choice_String := First_Choice_Of (Case_Item);
1185 if Choice_String = Empty_Node then
1186 Decl_Item := First_Declarative_Item_Of (Case_Item);
1187 exit Case_Item_Loop;
1191 while Choice_String /= Empty_Node loop
1192 if String_Equal (Case_Value,
1193 String_Value_Of (Choice_String))
1196 First_Declarative_Item_Of (Case_Item);
1197 exit Case_Item_Loop;
1201 Next_Literal_String (Choice_String);
1202 end loop Choice_Loop;
1203 Case_Item := Next_Case_Item (Case_Item);
1204 end loop Case_Item_Loop;
1206 if Decl_Item /= Empty_Node then
1207 Process_Declarative_Items
1208 (Project => Project,
1209 From_Project_Node => From_Project_Node,
1217 -- Should never happen
1219 Write_Line ("Illegal declarative item: " &
1220 Project_Node_Kind'Image (Kind_Of (Current_Item)));
1221 raise Program_Error;
1224 end Process_Declarative_Items;
1226 ---------------------
1227 -- Recursive_Check --
1228 ---------------------
1230 procedure Recursive_Check (Project : Project_Id) is
1231 Data : Project_Data;
1232 Imported_Project_List : Project_List := Empty_Project_List;
1235 -- Do nothing if Project is No_Project, or Project has already
1236 -- been marked as checked.
1238 if Project /= No_Project
1239 and then not Projects.Table (Project).Checked
1241 Data := Projects.Table (Project);
1243 -- Call itself for a possible modified project.
1244 -- (if there is no modified project, then nothing happens).
1246 Recursive_Check (Data.Modifies);
1248 -- Call itself for all imported projects
1250 Imported_Project_List := Data.Imported_Projects;
1251 while Imported_Project_List /= Empty_Project_List loop
1253 (Project_Lists.Table (Imported_Project_List).Project);
1254 Imported_Project_List :=
1255 Project_Lists.Table (Imported_Project_List).Next;
1258 -- Mark project as checked
1260 Projects.Table (Project).Checked := True;
1262 if Opt.Verbose_Mode then
1263 Write_Str ("Checking project file """);
1264 Write_Str (Get_Name_String (Data.Name));
1268 Prj.Nmsc.Ada_Check (Project, Error_Report);
1270 end Recursive_Check;
1272 -----------------------
1273 -- Recursive_Process --
1274 -----------------------
1276 procedure Recursive_Process
1277 (Project : out Project_Id;
1278 From_Project_Node : Project_Node_Id;
1279 Modified_By : Project_Id)
1281 With_Clause : Project_Node_Id;
1284 if From_Project_Node = Empty_Node then
1285 Project := No_Project;
1289 Processed_Data : Project_Data := Empty_Project;
1290 Imported : Project_List := Empty_Project_List;
1291 Declaration_Node : Project_Node_Id := Empty_Node;
1292 Name : constant Name_Id :=
1293 Name_Of (From_Project_Node);
1296 Project := Processed_Projects.Get (Name);
1298 if Project /= No_Project then
1302 Projects.Increment_Last;
1303 Project := Projects.Last;
1304 Processed_Projects.Set (Name, Project);
1305 Processed_Data.Name := Name;
1306 Processed_Data.Path_Name := Path_Name_Of (From_Project_Node);
1307 Processed_Data.Location := Location_Of (From_Project_Node);
1308 Processed_Data.Directory := Directory_Of (From_Project_Node);
1309 Processed_Data.Modified_By := Modified_By;
1310 Add_Attributes (Processed_Data.Decl, Attribute_First);
1311 With_Clause := First_With_Clause_Of (From_Project_Node);
1313 while With_Clause /= Empty_Node loop
1315 New_Project : Project_Id;
1316 New_Data : Project_Data;
1320 (Project => New_Project,
1321 From_Project_Node => Project_Node_Of (With_Clause),
1322 Modified_By => No_Project);
1323 New_Data := Projects.Table (New_Project);
1325 -- If we were the first project to import it,
1326 -- set First_Referred_By to us.
1328 if New_Data.First_Referred_By = No_Project then
1329 New_Data.First_Referred_By := Project;
1330 Projects.Table (New_Project) := New_Data;
1333 -- Add this project to our list of imported projects
1335 Project_Lists.Increment_Last;
1336 Project_Lists.Table (Project_Lists.Last) :=
1337 (Project => New_Project, Next => Empty_Project_List);
1339 -- Imported is the id of the last imported project.
1340 -- If it is nil, then this imported project is our first.
1342 if Imported = Empty_Project_List then
1343 Processed_Data.Imported_Projects := Project_Lists.Last;
1346 Project_Lists.Table (Imported).Next := Project_Lists.Last;
1349 Imported := Project_Lists.Last;
1351 With_Clause := Next_With_Clause_Of (With_Clause);
1355 Declaration_Node := Project_Declaration_Of (From_Project_Node);
1358 (Project => Processed_Data.Modifies,
1359 From_Project_Node => Modified_Project_Of (Declaration_Node),
1360 Modified_By => Project);
1362 Projects.Table (Project) := Processed_Data;
1364 Process_Declarative_Items
1365 (Project => Project,
1366 From_Project_Node => From_Project_Node,
1368 Item => First_Declarative_Item_Of
1369 (Declaration_Node));
1373 end Recursive_Process;