1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2005 Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 with Err_Vars
; use Err_Vars
;
28 with Namet
; use Namet
;
30 with Osint
; use Osint
;
31 with Output
; use Output
;
32 with Prj
.Attr
; use Prj
.Attr
;
33 with Prj
.Err
; use Prj
.Err
;
34 with Prj
.Ext
; use Prj
.Ext
;
35 with Prj
.Nmsc
; use Prj
.Nmsc
;
36 with Sinput
; use Sinput
;
39 with GNAT
.Case_Util
; use GNAT
.Case_Util
;
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 Name_Id
; Str
: Name_Id
);
56 -- Concatenate two strings and returns another string if both
57 -- arguments are not null string.
59 procedure Add_Attributes
60 (Project
: Project_Id
;
61 In_Tree
: Project_Tree_Ref
;
62 Decl
: in out Declarations
;
63 First
: Attribute_Node_Id
);
64 -- Add all attributes, starting with First, with their default
65 -- values to the package or project with declarations Decl.
68 (In_Tree
: Project_Tree_Ref
;
69 Project
: in out Project_Id
;
70 Follow_Links
: Boolean);
71 -- Set all projects to not checked, then call Recursive_Check for the
72 -- main project Project. Project is set to No_Project if errors occurred.
75 (Project
: Project_Id
;
76 In_Tree
: Project_Tree_Ref
;
77 From_Project_Node
: Project_Node_Id
;
78 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
80 First_Term
: Project_Node_Id
;
81 Kind
: Variable_Kind
) return Variable_Value
;
82 -- From N_Expression project node From_Project_Node, compute the value
83 -- of an expression and return it as a Variable_Value.
85 function Imported_Or_Extended_Project_From
86 (Project
: Project_Id
;
87 In_Tree
: Project_Tree_Ref
;
88 With_Name
: Name_Id
) return Project_Id
;
89 -- Find an imported or extended project of Project whose name is With_Name
92 (Project
: Project_Id
;
93 In_Tree
: Project_Tree_Ref
;
94 With_Name
: Name_Id
) return Package_Id
;
95 -- Find the package of Project whose name is With_Name
97 procedure Process_Declarative_Items
98 (Project
: Project_Id
;
99 In_Tree
: Project_Tree_Ref
;
100 From_Project_Node
: Project_Node_Id
;
101 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
103 Item
: Project_Node_Id
);
104 -- Process declarative items starting with From_Project_Node, and put them
105 -- in declarations Decl. This is a recursive procedure; it calls itself for
106 -- a package declaration or a case construction.
108 procedure Recursive_Process
109 (In_Tree
: Project_Tree_Ref
;
110 Project
: out Project_Id
;
111 From_Project_Node
: Project_Node_Id
;
112 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
113 Extended_By
: Project_Id
);
114 -- Process project with node From_Project_Node in the tree.
115 -- Do nothing if From_Project_Node is Empty_Node.
116 -- If project has already been processed, simply return its project id.
117 -- Otherwise create a new project id, mark it as processed, call itself
118 -- recursively for all imported projects and a extended project, if any.
119 -- Then process the declarative items of the project.
121 procedure Recursive_Check
122 (Project
: Project_Id
;
123 In_Tree
: Project_Tree_Ref
;
124 Follow_Links
: Boolean);
125 -- If Project is not marked as checked, mark it as checked, call
126 -- Check_Naming_Scheme for the project, then call itself for a
127 -- possible extended project and all the imported projects of Project.
133 procedure Add
(To_Exp
: in out Name_Id
; Str
: Name_Id
) is
135 if To_Exp
= Types
.No_Name
or else To_Exp
= Empty_String
then
137 -- To_Exp is nil or empty. The result is Str
141 -- If Str is nil, then do not change To_Ext
143 elsif Str
/= No_Name
and then Str
/= Empty_String
then
145 S
: constant String := Get_Name_String
(Str
);
148 Get_Name_String
(To_Exp
);
149 Add_Str_To_Name_Buffer
(S
);
159 procedure Add_Attributes
160 (Project
: Project_Id
;
161 In_Tree
: Project_Tree_Ref
;
162 Decl
: in out Declarations
;
163 First
: Attribute_Node_Id
)
165 The_Attribute
: Attribute_Node_Id
:= First
;
168 while The_Attribute
/= Empty_Attribute
loop
169 if Attribute_Kind_Of
(The_Attribute
) = Single
then
171 New_Attribute
: Variable_Value
;
174 case Variable_Kind_Of
(The_Attribute
) is
176 -- Undefined should not happen
180 (False, "attribute with an undefined kind");
183 -- Single attributes have a default value of empty string
189 Location
=> No_Location
,
191 Value
=> Empty_String
,
194 -- List attributes have a default value of nil list
200 Location
=> No_Location
,
202 Values
=> Nil_String
);
206 Variable_Element_Table
.Increment_Last
207 (In_Tree
.Variable_Elements
);
208 In_Tree
.Variable_Elements
.Table
209 (Variable_Element_Table
.Last
210 (In_Tree
.Variable_Elements
)) :=
211 (Next
=> Decl
.Attributes
,
212 Name
=> Attribute_Name_Of
(The_Attribute
),
213 Value
=> New_Attribute
);
214 Decl
.Attributes
:= Variable_Element_Table
.Last
215 (In_Tree
.Variable_Elements
);
219 The_Attribute
:= Next_Attribute
(After
=> The_Attribute
);
228 (In_Tree
: Project_Tree_Ref
;
229 Project
: in out Project_Id
;
230 Follow_Links
: Boolean)
233 -- Make sure that all projects are marked as not checked
235 for Index
in Project_Table
.First
..
236 Project_Table
.Last
(In_Tree
.Projects
)
238 In_Tree
.Projects
.Table
(Index
).Checked
:= False;
241 Recursive_Check
(Project
, In_Tree
, Follow_Links
);
249 (Project
: Project_Id
;
250 In_Tree
: Project_Tree_Ref
;
251 From_Project_Node
: Project_Node_Id
;
252 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
254 First_Term
: Project_Node_Id
;
255 Kind
: Variable_Kind
) return Variable_Value
257 The_Term
: Project_Node_Id
:= First_Term
;
258 -- The term in the expression list
260 The_Current_Term
: Project_Node_Id
:= Empty_Node
;
261 -- The current term node id
263 Result
: Variable_Value
(Kind
=> Kind
);
264 -- The returned result
266 Last
: String_List_Id
:= Nil_String
;
267 -- Reference to the last string elements in Result, when Kind is List
270 Result
.Project
:= Project
;
271 Result
.Location
:= Location_Of
(First_Term
, From_Project_Node_Tree
);
273 -- Process each term of the expression, starting with First_Term
275 while The_Term
/= Empty_Node
loop
276 The_Current_Term
:= Current_Term
(The_Term
, From_Project_Node_Tree
);
278 case Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) is
280 when N_Literal_String
=>
286 -- Should never happen
288 pragma Assert
(False, "Undefined expression kind");
294 (The_Current_Term
, From_Project_Node_Tree
));
297 (The_Current_Term
, From_Project_Node_Tree
);
301 String_Element_Table
.Increment_Last
302 (In_Tree
.String_Elements
);
304 if Last
= Nil_String
then
306 -- This can happen in an expression like () & "toto"
308 Result
.Values
:= String_Element_Table
.Last
309 (In_Tree
.String_Elements
);
312 In_Tree
.String_Elements
.Table
313 (Last
).Next
:= String_Element_Table
.Last
314 (In_Tree
.String_Elements
);
317 Last
:= String_Element_Table
.Last
318 (In_Tree
.String_Elements
);
319 In_Tree
.String_Elements
.Table
(Last
) :=
323 From_Project_Node_Tree
),
326 (The_Current_Term
, From_Project_Node_Tree
),
327 Display_Value
=> No_Name
,
331 From_Project_Node_Tree
),
336 when N_Literal_String_List
=>
339 String_Node
: Project_Node_Id
:=
340 First_Expression_In_List
342 From_Project_Node_Tree
);
344 Value
: Variable_Value
;
347 if String_Node
/= Empty_Node
then
349 -- If String_Node is nil, it is an empty list,
350 -- there is nothing to do
355 From_Project_Node
=> From_Project_Node
,
356 From_Project_Node_Tree
=> From_Project_Node_Tree
,
360 (String_Node
, From_Project_Node_Tree
),
362 String_Element_Table
.Increment_Last
363 (In_Tree
.String_Elements
);
365 if Result
.Values
= Nil_String
then
367 -- This literal string list is the first term
368 -- in a string list expression
371 String_Element_Table
.Last
(In_Tree
.String_Elements
);
374 In_Tree
.String_Elements
.Table
376 String_Element_Table
.Last
(In_Tree
.String_Elements
);
380 String_Element_Table
.Last
(In_Tree
.String_Elements
);
382 In_Tree
.String_Elements
.Table
(Last
) :=
383 (Value
=> Value
.Value
,
384 Display_Value
=> No_Name
,
385 Location
=> Value
.Location
,
388 Index
=> Value
.Index
);
391 -- Add the other element of the literal string list
392 -- one after the other
395 Next_Expression_In_List
396 (String_Node
, From_Project_Node_Tree
);
398 exit when String_Node
= Empty_Node
;
404 From_Project_Node
=> From_Project_Node
,
405 From_Project_Node_Tree
=> From_Project_Node_Tree
,
409 (String_Node
, From_Project_Node_Tree
),
412 String_Element_Table
.Increment_Last
413 (In_Tree
.String_Elements
);
414 In_Tree
.String_Elements
.Table
415 (Last
).Next
:= String_Element_Table
.Last
416 (In_Tree
.String_Elements
);
417 Last
:= String_Element_Table
.Last
418 (In_Tree
.String_Elements
);
419 In_Tree
.String_Elements
.Table
(Last
) :=
420 (Value
=> Value
.Value
,
421 Display_Value
=> No_Name
,
422 Location
=> Value
.Location
,
425 Index
=> Value
.Index
);
430 when N_Variable_Reference | N_Attribute_Reference
=>
433 The_Project
: Project_Id
:= Project
;
434 The_Package
: Package_Id
:= Pkg
;
435 The_Name
: Name_Id
:= No_Name
;
436 The_Variable_Id
: Variable_Id
:= No_Variable
;
437 The_Variable
: Variable_Value
;
438 Term_Project
: constant Project_Node_Id
:=
440 (The_Current_Term
, From_Project_Node_Tree
);
441 Term_Package
: constant Project_Node_Id
:=
443 (The_Current_Term
, From_Project_Node_Tree
);
444 Index
: Name_Id
:= No_Name
;
447 if Term_Project
/= Empty_Node
and then
448 Term_Project
/= From_Project_Node
450 -- This variable or attribute comes from another project
453 Name_Of
(Term_Project
, From_Project_Node_Tree
);
454 The_Project
:= Imported_Or_Extended_Project_From
457 With_Name
=> The_Name
);
460 if Term_Package
/= Empty_Node
then
462 -- This is an attribute of a package
465 Name_Of
(Term_Package
, From_Project_Node_Tree
);
466 The_Package
:= In_Tree
.Projects
.Table
467 (The_Project
).Decl
.Packages
;
469 while The_Package
/= No_Package
470 and then In_Tree
.Packages
.Table
471 (The_Package
).Name
/= The_Name
474 In_Tree
.Packages
.Table
479 (The_Package
/= No_Package
,
480 "package not found.");
482 elsif Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
483 N_Attribute_Reference
485 The_Package
:= No_Package
;
489 Name_Of
(The_Current_Term
, From_Project_Node_Tree
);
491 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
492 N_Attribute_Reference
495 Associative_Array_Index_Of
496 (The_Current_Term
, From_Project_Node_Tree
);
499 -- If it is not an associative array attribute
501 if Index
= No_Name
then
503 -- It is not an associative array attribute
505 if The_Package
/= No_Package
then
507 -- First, if there is a package, look into the package
509 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
513 In_Tree
.Packages
.Table
514 (The_Package
).Decl
.Variables
;
517 In_Tree
.Packages
.Table
518 (The_Package
).Decl
.Attributes
;
521 while The_Variable_Id
/= No_Variable
523 In_Tree
.Variable_Elements
.Table
524 (The_Variable_Id
).Name
/= The_Name
527 In_Tree
.Variable_Elements
.Table
528 (The_Variable_Id
).Next
;
533 if The_Variable_Id
= No_Variable
then
535 -- If we have not found it, look into the project
537 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
541 In_Tree
.Projects
.Table
542 (The_Project
).Decl
.Variables
;
545 In_Tree
.Projects
.Table
546 (The_Project
).Decl
.Attributes
;
549 while The_Variable_Id
/= No_Variable
551 In_Tree
.Variable_Elements
.Table
552 (The_Variable_Id
).Name
/= The_Name
555 In_Tree
.Variable_Elements
.Table
556 (The_Variable_Id
).Next
;
561 pragma Assert
(The_Variable_Id
/= No_Variable
,
562 "variable or attribute not found");
565 In_Tree
.Variable_Elements
.Table
566 (The_Variable_Id
).Value
;
570 -- It is an associative array attribute
573 The_Array
: Array_Id
:= No_Array
;
574 The_Element
: Array_Element_Id
:= No_Array_Element
;
575 Array_Index
: Name_Id
:= No_Name
;
578 if The_Package
/= No_Package
then
580 In_Tree
.Packages
.Table
581 (The_Package
).Decl
.Arrays
;
584 In_Tree
.Projects
.Table
585 (The_Project
).Decl
.Arrays
;
588 while The_Array
/= No_Array
589 and then In_Tree
.Arrays
.Table
590 (The_Array
).Name
/= The_Name
592 The_Array
:= In_Tree
.Arrays
.Table
596 if The_Array
/= No_Array
then
597 The_Element
:= In_Tree
.Arrays
.Table
600 Get_Name_String
(Index
);
603 (The_Current_Term
, From_Project_Node_Tree
)
605 To_Lower
(Name_Buffer
(1 .. Name_Len
));
608 Array_Index
:= Name_Find
;
610 while The_Element
/= No_Array_Element
612 In_Tree
.Array_Elements
.Table
613 (The_Element
).Index
/= Array_Index
616 In_Tree
.Array_Elements
.Table
622 if The_Element
/= No_Array_Element
then
624 In_Tree
.Array_Elements
.Table
628 if Expression_Kind_Of
629 (The_Current_Term
, From_Project_Node_Tree
) =
635 Location
=> No_Location
,
637 Values
=> Nil_String
);
642 Location
=> No_Location
,
644 Value
=> Empty_String
,
655 -- Should never happen
657 pragma Assert
(False, "undefined expression kind");
662 case The_Variable
.Kind
is
668 Add
(Result
.Value
, The_Variable
.Value
);
672 -- Should never happen
676 "list cannot appear in single " &
677 "string expression");
682 case The_Variable
.Kind
is
688 String_Element_Table
.Increment_Last
689 (In_Tree
.String_Elements
);
691 if Last
= Nil_String
then
693 -- This can happen in an expression such as
697 String_Element_Table
.Last
698 (In_Tree
.String_Elements
);
701 In_Tree
.String_Elements
.Table
703 String_Element_Table
.Last
704 (In_Tree
.String_Elements
);
708 String_Element_Table
.Last
709 (In_Tree
.String_Elements
);
711 In_Tree
.String_Elements
.Table
(Last
) :=
712 (Value
=> The_Variable
.Value
,
713 Display_Value
=> No_Name
,
714 Location
=> Location_Of
716 From_Project_Node_Tree
),
724 The_List
: String_List_Id
:=
728 while The_List
/= Nil_String
loop
729 String_Element_Table
.Increment_Last
730 (In_Tree
.String_Elements
);
732 if Last
= Nil_String
then
734 String_Element_Table
.Last
740 String_Elements
.Table
(Last
).Next
:=
741 String_Element_Table
.Last
748 String_Element_Table
.Last
749 (In_Tree
.String_Elements
);
751 In_Tree
.String_Elements
.Table
(Last
) :=
753 In_Tree
.String_Elements
.Table
755 Display_Value
=> No_Name
,
759 From_Project_Node_Tree
),
765 In_Tree
. String_Elements
.Table
773 when N_External_Value
=>
776 (External_Reference_Of
777 (The_Current_Term
, From_Project_Node_Tree
),
778 From_Project_Node_Tree
));
781 Name
: constant Name_Id
:= Name_Find
;
782 Default
: Name_Id
:= No_Name
;
783 Value
: Name_Id
:= No_Name
;
785 Def_Var
: Variable_Value
;
787 Default_Node
: constant Project_Node_Id
:=
789 (The_Current_Term
, From_Project_Node_Tree
);
792 -- If there is a default value for the external reference,
795 if Default_Node
/= Empty_Node
then
796 Def_Var
:= Expression
799 From_Project_Node
=> Default_Node
,
800 From_Project_Node_Tree
=> From_Project_Node_Tree
,
804 (Default_Node
, From_Project_Node_Tree
),
807 if Def_Var
/= Nil_Variable_Value
then
808 Default
:= Def_Var
.Value
;
812 Value
:= Prj
.Ext
.Value_Of
(Name
, Default
);
814 if Value
= No_Name
then
815 if not Opt
.Quiet_Output
then
816 if Error_Report
= null then
818 ("?undefined external reference",
820 (The_Current_Term
, From_Project_Node_Tree
));
823 ("warning: """ & Get_Name_String
(Name
) &
824 """ is an undefined external reference",
829 Value
:= Empty_String
;
838 Add
(Result
.Value
, Value
);
841 String_Element_Table
.Increment_Last
842 (In_Tree
.String_Elements
);
844 if Last
= Nil_String
then
845 Result
.Values
:= String_Element_Table
.Last
846 (In_Tree
.String_Elements
);
849 In_Tree
.String_Elements
.Table
850 (Last
).Next
:= String_Element_Table
.Last
851 (In_Tree
.String_Elements
);
854 Last
:= String_Element_Table
.Last
855 (In_Tree
.String_Elements
);
856 In_Tree
.String_Elements
.Table
(Last
) :=
858 Display_Value
=> No_Name
,
861 (The_Current_Term
, From_Project_Node_Tree
),
871 -- Should never happen
875 "illegal node kind in an expression");
880 The_Term
:= Next_Term
(The_Term
, From_Project_Node_Tree
);
886 ---------------------------------------
887 -- Imported_Or_Extended_Project_From --
888 ---------------------------------------
890 function Imported_Or_Extended_Project_From
891 (Project
: Project_Id
;
892 In_Tree
: Project_Tree_Ref
;
893 With_Name
: Name_Id
) return Project_Id
895 Data
: constant Project_Data
:=
896 In_Tree
.Projects
.Table
(Project
);
897 List
: Project_List
:= Data
.Imported_Projects
;
898 Result
: Project_Id
:= No_Project
;
899 Temp_Result
: Project_Id
:= No_Project
;
902 -- First check if it is the name of an extended project
904 if Data
.Extends
/= No_Project
905 and then In_Tree
.Projects
.Table
(Data
.Extends
).Name
=
911 -- Then check the name of each imported project
913 while List
/= Empty_Project_List
loop
914 Result
:= In_Tree
.Project_Lists
.Table
(List
).Project
;
916 -- If the project is directly imported, then returns its ID
919 In_Tree
.Projects
.Table
(Result
).Name
= With_Name
924 -- If a project extending the project is imported, then keep
925 -- this extending project as a possibility. It will be the
926 -- returned ID if the project is not imported directly.
930 In_Tree
.Projects
.Table
(Result
).Extends
;
932 while Proj
/= No_Project
loop
933 if In_Tree
.Projects
.Table
(Proj
).Name
=
936 Temp_Result
:= Result
;
940 Proj
:= In_Tree
.Projects
.Table
(Proj
).Extends
;
944 List
:= In_Tree
.Project_Lists
.Table
(List
).Next
;
948 (Temp_Result
/= No_Project
,
949 "project not found");
953 end Imported_Or_Extended_Project_From
;
959 function Package_From
960 (Project
: Project_Id
;
961 In_Tree
: Project_Tree_Ref
;
962 With_Name
: Name_Id
) return Package_Id
964 Data
: constant Project_Data
:=
965 In_Tree
.Projects
.Table
(Project
);
966 Result
: Package_Id
:= Data
.Decl
.Packages
;
969 -- Check the name of each existing package of Project
971 while Result
/= No_Package
972 and then In_Tree
.Packages
.Table
(Result
).Name
/= With_Name
974 Result
:= In_Tree
.Packages
.Table
(Result
).Next
;
977 if Result
= No_Package
then
979 -- Should never happen
981 Write_Line
("package """ & Get_Name_String
(With_Name
) &
995 (In_Tree
: Project_Tree_Ref
;
996 Project
: out Project_Id
;
997 Success
: out Boolean;
998 From_Project_Node
: Project_Node_Id
;
999 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
1000 Report_Error
: Put_Line_Access
;
1001 Follow_Links
: Boolean := True)
1004 Extending
: Project_Id
;
1005 Extending2
: Project_Id
;
1008 Error_Report
:= Report_Error
;
1011 -- Make sure there is no projects in the data structure
1013 Project_Table
.Set_Last
(In_Tree
.Projects
, No_Project
);
1014 Processed_Projects
.Reset
;
1016 -- And process the main project and all of the projects it depends on,
1020 (Project
=> Project
,
1022 From_Project_Node
=> From_Project_Node
,
1023 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1024 Extended_By
=> No_Project
);
1026 if Project
/= No_Project
then
1027 Check
(In_Tree
, Project
, Follow_Links
);
1030 -- If main project is an extending all project, set the object
1031 -- directory of all virtual extending projects to the object directory
1032 -- of the main project.
1034 if Project
/= No_Project
1035 and then Is_Extending_All
(From_Project_Node
, From_Project_Node_Tree
)
1038 Object_Dir
: constant Name_Id
:=
1039 In_Tree
.Projects
.Table
(Project
).Object_Directory
;
1042 Project_Table
.First
.. Project_Table
.Last
(In_Tree
.Projects
)
1044 if In_Tree
.Projects
.Table
(Index
).Virtual
then
1045 In_Tree
.Projects
.Table
(Index
).Object_Directory
:=
1052 -- Check that no extending project shares its object directory with
1053 -- the project(s) it extends.
1055 if Project
/= No_Project
then
1057 Project_Table
.First
.. Project_Table
.Last
(In_Tree
.Projects
)
1059 Extending
:= In_Tree
.Projects
.Table
(Proj
).Extended_By
;
1061 if Extending
/= No_Project
then
1062 Obj_Dir
:= In_Tree
.Projects
.Table
(Proj
).Object_Directory
;
1064 -- Check that a project being extended does not share its
1065 -- object directory with any project that extends it, directly
1066 -- or indirectly, including a virtual extending project.
1068 -- Start with the project directly extending it
1070 Extending2
:= Extending
;
1071 while Extending2
/= No_Project
loop
1072 if In_Tree
.Projects
.Table
(Extending2
).Ada_Sources_Present
1074 In_Tree
.Projects
.Table
(Extending2
).Object_Directory
=
1077 if In_Tree
.Projects
.Table
(Extending2
).Virtual
then
1079 In_Tree
.Projects
.Table
(Proj
).Display_Name
;
1081 if Error_Report
= null then
1083 ("project { cannot be extended by a virtual " &
1084 "project with the same object directory",
1085 In_Tree
.Projects
.Table
(Proj
).Location
);
1089 Get_Name_String
(Error_Msg_Name_1
) &
1090 """ cannot be extended by a virtual " &
1091 "project with the same object directory",
1097 In_Tree
.Projects
.Table
(Extending2
).Display_Name
;
1099 In_Tree
.Projects
.Table
(Proj
).Display_Name
;
1101 if Error_Report
= null then
1103 ("project { cannot extend project {",
1104 In_Tree
.Projects
.Table
(Extending2
).Location
);
1106 ("\they share the same object directory",
1107 In_Tree
.Projects
.Table
(Extending2
).Location
);
1112 Get_Name_String
(Error_Msg_Name_1
) &
1113 """ cannot extend project """ &
1114 Get_Name_String
(Error_Msg_Name_2
) & """",
1117 ("they share the same object directory",
1123 -- Continue with the next extending project, if any
1126 In_Tree
.Projects
.Table
(Extending2
).Extended_By
;
1132 Success
:= Total_Errors_Detected
<= 0;
1135 -------------------------------
1136 -- Process_Declarative_Items --
1137 -------------------------------
1139 procedure Process_Declarative_Items
1140 (Project
: Project_Id
;
1141 In_Tree
: Project_Tree_Ref
;
1142 From_Project_Node
: Project_Node_Id
;
1143 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
1145 Item
: Project_Node_Id
)
1147 Current_Declarative_Item
: Project_Node_Id
:= Item
;
1148 Current_Item
: Project_Node_Id
:= Empty_Node
;
1151 -- For each declarative item
1153 while Current_Declarative_Item
/= Empty_Node
loop
1159 (Current_Declarative_Item
, From_Project_Node_Tree
);
1161 -- And set Current_Declarative_Item to the next declarative item
1162 -- ready for the next iteration.
1164 Current_Declarative_Item
:=
1165 Next_Declarative_Item
1166 (Current_Declarative_Item
, From_Project_Node_Tree
);
1168 case Kind_Of
(Current_Item
, From_Project_Node_Tree
) is
1170 when N_Package_Declaration
=>
1171 -- Do not process a package declaration that should be ignored
1173 if Expression_Kind_Of
1174 (Current_Item
, From_Project_Node_Tree
) /= Ignored
1176 -- Create the new package
1178 Package_Table
.Increment_Last
(In_Tree
.Packages
);
1181 New_Pkg
: constant Package_Id
:=
1182 Package_Table
.Last
(In_Tree
.Packages
);
1183 The_New_Package
: Package_Element
;
1185 Project_Of_Renamed_Package
:
1186 constant Project_Node_Id
:=
1187 Project_Of_Renamed_Package_Of
1188 (Current_Item
, From_Project_Node_Tree
);
1191 -- Set the name of the new package
1193 The_New_Package
.Name
:=
1194 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1196 -- Insert the new package in the appropriate list
1198 if Pkg
/= No_Package
then
1199 The_New_Package
.Next
:=
1200 In_Tree
.Packages
.Table
(Pkg
).Decl
.Packages
;
1201 In_Tree
.Packages
.Table
(Pkg
).Decl
.Packages
:=
1204 The_New_Package
.Next
:=
1205 In_Tree
.Projects
.Table
(Project
).Decl
.Packages
;
1206 In_Tree
.Projects
.Table
(Project
).Decl
.Packages
:=
1210 In_Tree
.Packages
.Table
(New_Pkg
) :=
1213 if Project_Of_Renamed_Package
/= Empty_Node
then
1218 Project_Name
: constant Name_Id
:=
1220 (Project_Of_Renamed_Package
,
1221 From_Project_Node_Tree
);
1224 constant Project_Id
:=
1225 Imported_Or_Extended_Project_From
1226 (Project
, In_Tree
, Project_Name
);
1228 Renamed_Package
: constant Package_Id
:=
1230 (Renamed_Project
, In_Tree
,
1233 From_Project_Node_Tree
));
1236 -- For a renamed package, set declarations to
1237 -- the declarations of the renamed package.
1239 In_Tree
.Packages
.Table
(New_Pkg
).Decl
:=
1240 In_Tree
.Packages
.Table
(Renamed_Package
).Decl
;
1243 -- Standard package declaration, not renaming
1246 -- Set the default values of the attributes
1250 In_Tree
.Packages
.Table
(New_Pkg
).Decl
,
1253 (Current_Item
, From_Project_Node_Tree
)));
1255 -- And process declarative items of the new package
1257 Process_Declarative_Items
1258 (Project
=> Project
,
1260 From_Project_Node
=> From_Project_Node
,
1261 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1264 First_Declarative_Item_Of
1265 (Current_Item
, From_Project_Node_Tree
));
1270 when N_String_Type_Declaration
=>
1272 -- There is nothing to process
1276 when N_Attribute_Declaration |
1277 N_Typed_Variable_Declaration |
1278 N_Variable_Declaration
=>
1280 if Expression_Of
(Current_Item
, From_Project_Node_Tree
) =
1284 -- It must be a full associative array attribute declaration
1287 Current_Item_Name
: constant Name_Id
:=
1288 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1289 -- The name of the attribute
1291 New_Array
: Array_Id
;
1292 -- The new associative array created
1294 Orig_Array
: Array_Id
;
1295 -- The associative array value
1297 Orig_Project_Name
: Name_Id
:= No_Name
;
1298 -- The name of the project where the associative array
1301 Orig_Project
: Project_Id
:= No_Project
;
1302 -- The id of the project where the associative array
1305 Orig_Package_Name
: Name_Id
:= No_Name
;
1306 -- The name of the package, if any, where the associative
1309 Orig_Package
: Package_Id
:= No_Package
;
1310 -- The id of the package, if any, where the associative
1313 New_Element
: Array_Element_Id
:= No_Array_Element
;
1314 -- Id of a new array element created
1316 Prev_Element
: Array_Element_Id
:= No_Array_Element
;
1317 -- Last new element id created
1319 Orig_Element
: Array_Element_Id
:= No_Array_Element
;
1320 -- Current array element in the original associative
1323 Next_Element
: Array_Element_Id
:= No_Array_Element
;
1324 -- Id of the array element that follows the new element.
1325 -- This is not always nil, because values for the
1326 -- associative array attribute may already have been
1327 -- declared, and the array elements declared are reused.
1330 -- First, find if the associative array attribute already
1331 -- has elements declared.
1333 if Pkg
/= No_Package
then
1334 New_Array
:= In_Tree
.Packages
.Table
1338 New_Array
:= In_Tree
.Projects
.Table
1339 (Project
).Decl
.Arrays
;
1342 while New_Array
/= No_Array
1343 and then In_Tree
.Arrays
.Table
(New_Array
).Name
/=
1346 New_Array
:= In_Tree
.Arrays
.Table
(New_Array
).Next
;
1349 -- If the attribute has never been declared add new entry
1350 -- in the arrays of the project/package and link it.
1352 if New_Array
= No_Array
then
1353 Array_Table
.Increment_Last
(In_Tree
.Arrays
);
1354 New_Array
:= Array_Table
.Last
(In_Tree
.Arrays
);
1356 if Pkg
/= No_Package
then
1357 In_Tree
.Arrays
.Table
(New_Array
) :=
1358 (Name
=> Current_Item_Name
,
1359 Value
=> No_Array_Element
,
1361 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
);
1363 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
:=
1367 In_Tree
.Arrays
.Table
(New_Array
) :=
1368 (Name
=> Current_Item_Name
,
1369 Value
=> No_Array_Element
,
1371 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
);
1373 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
:=
1378 -- Find the project where the value is declared
1380 Orig_Project_Name
:=
1382 (Associative_Project_Of
1383 (Current_Item
, From_Project_Node_Tree
),
1384 From_Project_Node_Tree
);
1386 for Index
in Project_Table
.First
..
1390 if In_Tree
.Projects
.Table
(Index
).Name
=
1393 Orig_Project
:= Index
;
1398 pragma Assert
(Orig_Project
/= No_Project
,
1399 "original project not found");
1401 if Associative_Package_Of
1402 (Current_Item
, From_Project_Node_Tree
) = Empty_Node
1405 In_Tree
.Projects
.Table
1406 (Orig_Project
).Decl
.Arrays
;
1409 -- If in a package, find the package where the
1410 -- value is declared.
1412 Orig_Package_Name
:=
1414 (Associative_Package_Of
1415 (Current_Item
, From_Project_Node_Tree
),
1416 From_Project_Node_Tree
);
1419 In_Tree
.Projects
.Table
1420 (Orig_Project
).Decl
.Packages
;
1421 pragma Assert
(Orig_Package
/= No_Package
,
1422 "original package not found");
1424 while In_Tree
.Packages
.Table
1425 (Orig_Package
).Name
/= Orig_Package_Name
1427 Orig_Package
:= In_Tree
.Packages
.Table
1428 (Orig_Package
).Next
;
1429 pragma Assert
(Orig_Package
/= No_Package
,
1430 "original package not found");
1434 In_Tree
.Packages
.Table
1435 (Orig_Package
).Decl
.Arrays
;
1438 -- Now look for the array
1440 while Orig_Array
/= No_Array
and then
1441 In_Tree
.Arrays
.Table
(Orig_Array
).Name
/=
1444 Orig_Array
:= In_Tree
.Arrays
.Table
1448 if Orig_Array
= No_Array
then
1449 if Error_Report
= null then
1451 ("associative array value cannot be found",
1453 (Current_Item
, From_Project_Node_Tree
));
1457 ("associative array value cannot be found",
1463 In_Tree
.Arrays
.Table
(Orig_Array
).Value
;
1465 -- Copy each array element
1467 while Orig_Element
/= No_Array_Element
loop
1469 -- Case of first element
1471 if Prev_Element
= No_Array_Element
then
1473 -- And there is no array element declared yet,
1474 -- create a new first array element.
1476 if In_Tree
.Arrays
.Table
(New_Array
).Value
=
1479 Array_Element_Table
.Increment_Last
1480 (In_Tree
.Array_Elements
);
1481 New_Element
:= Array_Element_Table
.Last
1482 (In_Tree
.Array_Elements
);
1483 In_Tree
.Arrays
.Table
1484 (New_Array
).Value
:= New_Element
;
1485 Next_Element
:= No_Array_Element
;
1487 -- Otherwise, the new element is the first
1490 New_Element
:= In_Tree
.Arrays
.
1491 Table
(New_Array
).Value
;
1493 In_Tree
.Array_Elements
.Table
1497 -- Otherwise, reuse an existing element, or create
1498 -- one if necessary.
1502 In_Tree
.Array_Elements
.Table
1503 (Prev_Element
).Next
;
1505 if Next_Element
= No_Array_Element
then
1506 Array_Element_Table
.Increment_Last
1507 (In_Tree
.Array_Elements
);
1508 New_Element
:= Array_Element_Table
.Last
1509 (In_Tree
.Array_Elements
);
1512 New_Element
:= Next_Element
;
1514 In_Tree
.Array_Elements
.Table
1519 -- Copy the value of the element
1521 In_Tree
.Array_Elements
.Table
1523 In_Tree
.Array_Elements
.Table
1525 In_Tree
.Array_Elements
.Table
1526 (New_Element
).Value
.Project
:= Project
;
1528 -- Adjust the Next link
1530 In_Tree
.Array_Elements
.Table
1531 (New_Element
).Next
:= Next_Element
;
1533 -- Adjust the previous id for the next element
1535 Prev_Element
:= New_Element
;
1537 -- Go to the next element in the original array
1540 In_Tree
.Array_Elements
.Table
1541 (Orig_Element
).Next
;
1544 -- Make sure that the array ends here, in case there
1545 -- previously a greater number of elements.
1547 In_Tree
.Array_Elements
.Table
1548 (New_Element
).Next
:= No_Array_Element
;
1552 -- Declarations other that full associative arrays
1556 New_Value
: constant Variable_Value
:=
1558 (Project
=> Project
,
1560 From_Project_Node
=> From_Project_Node
,
1561 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1566 (Current_Item
, From_Project_Node_Tree
),
1567 From_Project_Node_Tree
),
1570 (Current_Item
, From_Project_Node_Tree
));
1571 -- The expression value
1573 The_Variable
: Variable_Id
:= No_Variable
;
1575 Current_Item_Name
: constant Name_Id
:=
1576 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1579 -- Process a typed variable declaration
1581 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) =
1582 N_Typed_Variable_Declaration
1584 -- Report an error for an empty string
1586 if New_Value
.Value
= Empty_String
then
1588 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1590 if Error_Report
= null then
1592 ("no value defined for %",
1594 (Current_Item
, From_Project_Node_Tree
));
1598 ("no value defined for " &
1599 Get_Name_String
(Error_Msg_Name_1
),
1605 Current_String
: Project_Node_Id
:=
1606 First_Literal_String
1609 From_Project_Node_Tree
),
1610 From_Project_Node_Tree
);
1613 -- Loop through all the valid strings for the
1614 -- string type and compare to the string value.
1616 while Current_String
/= Empty_Node
1619 (Current_String
, From_Project_Node_Tree
) /=
1624 (Current_String
, From_Project_Node_Tree
);
1627 -- Report an error if the string value is not
1628 -- one for the string type.
1630 if Current_String
= Empty_Node
then
1631 Error_Msg_Name_1
:= New_Value
.Value
;
1634 (Current_Item
, From_Project_Node_Tree
);
1636 if Error_Report
= null then
1638 ("value { is illegal for typed string %",
1641 From_Project_Node_Tree
));
1646 Get_Name_String
(Error_Msg_Name_1
) &
1647 """ is illegal for typed string """ &
1648 Get_Name_String
(Error_Msg_Name_2
) &
1657 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) /=
1658 N_Attribute_Declaration
1660 Associative_Array_Index_Of
1661 (Current_Item
, From_Project_Node_Tree
) = No_Name
1663 -- Case of a variable declaration or of a not
1664 -- associative array attribute.
1666 -- First, find the list where to find the variable
1669 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) =
1670 N_Attribute_Declaration
1672 if Pkg
/= No_Package
then
1674 In_Tree
.Packages
.Table
1675 (Pkg
).Decl
.Attributes
;
1678 In_Tree
.Projects
.Table
1679 (Project
).Decl
.Attributes
;
1683 if Pkg
/= No_Package
then
1685 In_Tree
.Packages
.Table
1686 (Pkg
).Decl
.Variables
;
1689 In_Tree
.Projects
.Table
1690 (Project
).Decl
.Variables
;
1695 -- Loop through the list, to find if it has already
1698 while The_Variable
/= No_Variable
1700 In_Tree
.Variable_Elements
.Table
1701 (The_Variable
).Name
/= Current_Item_Name
1704 In_Tree
.Variable_Elements
.Table
1705 (The_Variable
).Next
;
1708 -- If it has not been declared, create a new entry
1711 if The_Variable
= No_Variable
then
1713 -- All single string attribute should already have
1714 -- been declared with a default empty string value.
1717 (Kind_Of
(Current_Item
, From_Project_Node_Tree
) /=
1718 N_Attribute_Declaration
,
1719 "illegal attribute declaration");
1721 Variable_Element_Table
.Increment_Last
1722 (In_Tree
.Variable_Elements
);
1723 The_Variable
:= Variable_Element_Table
.Last
1724 (In_Tree
.Variable_Elements
);
1726 -- Put the new variable in the appropriate list
1728 if Pkg
/= No_Package
then
1729 In_Tree
.Variable_Elements
.Table
(The_Variable
) :=
1731 In_Tree
.Packages
.Table
1732 (Pkg
).Decl
.Variables
,
1733 Name
=> Current_Item_Name
,
1734 Value
=> New_Value
);
1735 In_Tree
.Packages
.Table
1736 (Pkg
).Decl
.Variables
:= The_Variable
;
1739 In_Tree
.Variable_Elements
.Table
(The_Variable
) :=
1741 In_Tree
.Projects
.Table
1742 (Project
).Decl
.Variables
,
1743 Name
=> Current_Item_Name
,
1744 Value
=> New_Value
);
1745 In_Tree
.Projects
.Table
1746 (Project
).Decl
.Variables
:=
1750 -- If the variable/attribute has already been
1751 -- declared, just change the value.
1754 In_Tree
.Variable_Elements
.Table
1755 (The_Variable
).Value
:=
1761 -- Associative array attribute
1763 -- Get the string index
1766 (Associative_Array_Index_Of
1767 (Current_Item
, From_Project_Node_Tree
));
1769 -- Put in lower case, if necessary
1772 (Current_Item
, From_Project_Node_Tree
)
1774 GNAT
.Case_Util
.To_Lower
1775 (Name_Buffer
(1 .. Name_Len
));
1779 The_Array
: Array_Id
;
1781 The_Array_Element
: Array_Element_Id
:=
1784 Index_Name
: constant Name_Id
:= Name_Find
;
1785 -- The name id of the index
1788 -- Look for the array in the appropriate list
1790 if Pkg
/= No_Package
then
1791 The_Array
:= In_Tree
.Packages
.Table
1795 The_Array
:= In_Tree
.Projects
.Table
1796 (Project
).Decl
.Arrays
;
1800 The_Array
/= No_Array
1801 and then In_Tree
.Arrays
.Table
1802 (The_Array
).Name
/= Current_Item_Name
1804 The_Array
:= In_Tree
.Arrays
.Table
1808 -- If the array cannot be found, create a new
1809 -- entry in the list. As The_Array_Element is
1810 -- initialized to No_Array_Element, a new element
1811 -- will be created automatically later.
1813 if The_Array
= No_Array
then
1814 Array_Table
.Increment_Last
1816 The_Array
:= Array_Table
.Last
1819 if Pkg
/= No_Package
then
1820 In_Tree
.Arrays
.Table
1822 (Name
=> Current_Item_Name
,
1823 Value
=> No_Array_Element
,
1825 In_Tree
.Packages
.Table
1828 In_Tree
.Packages
.Table
1829 (Pkg
).Decl
.Arrays
:=
1833 In_Tree
.Arrays
.Table
1835 (Name
=> Current_Item_Name
,
1836 Value
=> No_Array_Element
,
1838 In_Tree
.Projects
.Table
1839 (Project
).Decl
.Arrays
);
1841 In_Tree
.Projects
.Table
1842 (Project
).Decl
.Arrays
:=
1846 -- Otherwise, initialize The_Array_Element as the
1847 -- head of the element list.
1850 The_Array_Element
:=
1851 In_Tree
.Arrays
.Table
1855 -- Look in the list, if any, to find an element
1856 -- with the same index.
1858 while The_Array_Element
/= No_Array_Element
1860 In_Tree
.Array_Elements
.Table
1861 (The_Array_Element
).Index
/= Index_Name
1863 The_Array_Element
:=
1864 In_Tree
.Array_Elements
.Table
1865 (The_Array_Element
).Next
;
1868 -- If no such element were found, create a new
1869 -- one and insert it in the element list, with
1870 -- the propoer value.
1872 if The_Array_Element
= No_Array_Element
then
1873 Array_Element_Table
.Increment_Last
1874 (In_Tree
.Array_Elements
);
1875 The_Array_Element
:= Array_Element_Table
.Last
1876 (In_Tree
.Array_Elements
);
1878 In_Tree
.Array_Elements
.Table
1879 (The_Array_Element
) :=
1880 (Index
=> Index_Name
,
1883 (Current_Item
, From_Project_Node_Tree
),
1884 Index_Case_Sensitive
=>
1885 not Case_Insensitive
1886 (Current_Item
, From_Project_Node_Tree
),
1888 Next
=> In_Tree
.Arrays
.Table
1890 In_Tree
.Arrays
.Table
1891 (The_Array
).Value
:= The_Array_Element
;
1893 -- An element with the same index already exists,
1894 -- just replace its value with the new one.
1897 In_Tree
.Array_Elements
.Table
1898 (The_Array_Element
).Value
:= New_Value
;
1905 when N_Case_Construction
=>
1907 The_Project
: Project_Id
:= Project
;
1908 -- The id of the project of the case variable
1910 The_Package
: Package_Id
:= Pkg
;
1911 -- The id of the package, if any, of the case variable
1913 The_Variable
: Variable_Value
:= Nil_Variable_Value
;
1914 -- The case variable
1916 Case_Value
: Name_Id
:= No_Name
;
1917 -- The case variable value
1919 Case_Item
: Project_Node_Id
:= Empty_Node
;
1920 Choice_String
: Project_Node_Id
:= Empty_Node
;
1921 Decl_Item
: Project_Node_Id
:= Empty_Node
;
1925 Variable_Node
: constant Project_Node_Id
:=
1926 Case_Variable_Reference_Of
1928 From_Project_Node_Tree
);
1930 Var_Id
: Variable_Id
:= No_Variable
;
1931 Name
: Name_Id
:= No_Name
;
1934 -- If a project were specified for the case variable,
1938 (Variable_Node
, From_Project_Node_Tree
) /= Empty_Node
1943 (Variable_Node
, From_Project_Node_Tree
),
1944 From_Project_Node_Tree
);
1946 Imported_Or_Extended_Project_From
1947 (Project
, In_Tree
, Name
);
1950 -- If a package were specified for the case variable,
1954 (Variable_Node
, From_Project_Node_Tree
) /= Empty_Node
1959 (Variable_Node
, From_Project_Node_Tree
),
1960 From_Project_Node_Tree
);
1962 Package_From
(The_Project
, In_Tree
, Name
);
1965 Name
:= Name_Of
(Variable_Node
, From_Project_Node_Tree
);
1967 -- First, look for the case variable into the package,
1970 if The_Package
/= No_Package
then
1971 Var_Id
:= In_Tree
.Packages
.Table
1972 (The_Package
).Decl
.Variables
;
1974 Name_Of
(Variable_Node
, From_Project_Node_Tree
);
1975 while Var_Id
/= No_Variable
1977 In_Tree
.Variable_Elements
.Table
1978 (Var_Id
).Name
/= Name
1980 Var_Id
:= In_Tree
.Variable_Elements
.
1981 Table
(Var_Id
).Next
;
1985 -- If not found in the package, or if there is no
1986 -- package, look at the project level.
1988 if Var_Id
= No_Variable
1991 (Variable_Node
, From_Project_Node_Tree
) = Empty_Node
1993 Var_Id
:= In_Tree
.Projects
.Table
1994 (The_Project
).Decl
.Variables
;
1995 while Var_Id
/= No_Variable
1997 In_Tree
.Variable_Elements
.Table
1998 (Var_Id
).Name
/= Name
2000 Var_Id
:= In_Tree
.Variable_Elements
.
2001 Table
(Var_Id
).Next
;
2005 if Var_Id
= No_Variable
then
2007 -- Should never happen, because this has already been
2008 -- checked during parsing.
2010 Write_Line
("variable """ &
2011 Get_Name_String
(Name
) &
2013 raise Program_Error
;
2016 -- Get the case variable
2018 The_Variable
:= In_Tree
.Variable_Elements
.
2019 Table
(Var_Id
).Value
;
2021 if The_Variable
.Kind
/= Single
then
2023 -- Should never happen, because this has already been
2024 -- checked during parsing.
2026 Write_Line
("variable""" &
2027 Get_Name_String
(Name
) &
2028 """ is not a single string variable");
2029 raise Program_Error
;
2032 -- Get the case variable value
2033 Case_Value
:= The_Variable
.Value
;
2036 -- Now look into all the case items of the case construction
2039 First_Case_Item_Of
(Current_Item
, From_Project_Node_Tree
);
2041 while Case_Item
/= Empty_Node
loop
2043 First_Choice_Of
(Case_Item
, From_Project_Node_Tree
);
2045 -- When Choice_String is nil, it means that it is
2046 -- the "when others =>" alternative.
2048 if Choice_String
= Empty_Node
then
2050 First_Declarative_Item_Of
2051 (Case_Item
, From_Project_Node_Tree
);
2052 exit Case_Item_Loop
;
2055 -- Look into all the alternative of this case item
2058 while Choice_String
/= Empty_Node
loop
2061 (Choice_String
, From_Project_Node_Tree
)
2064 First_Declarative_Item_Of
2065 (Case_Item
, From_Project_Node_Tree
);
2066 exit Case_Item_Loop
;
2071 (Choice_String
, From_Project_Node_Tree
);
2072 end loop Choice_Loop
;
2075 Next_Case_Item
(Case_Item
, From_Project_Node_Tree
);
2076 end loop Case_Item_Loop
;
2078 -- If there is an alternative, then we process it
2080 if Decl_Item
/= Empty_Node
then
2081 Process_Declarative_Items
2082 (Project
=> Project
,
2084 From_Project_Node
=> From_Project_Node
,
2085 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2093 -- Should never happen
2095 Write_Line
("Illegal declarative item: " &
2096 Project_Node_Kind
'Image
2098 (Current_Item
, From_Project_Node_Tree
)));
2099 raise Program_Error
;
2102 end Process_Declarative_Items
;
2104 ---------------------
2105 -- Recursive_Check --
2106 ---------------------
2108 procedure Recursive_Check
2109 (Project
: Project_Id
;
2110 In_Tree
: Project_Tree_Ref
;
2111 Follow_Links
: Boolean)
2113 Data
: Project_Data
;
2114 Imported_Project_List
: Project_List
:= Empty_Project_List
;
2117 -- Do nothing if Project is No_Project, or Project has already
2118 -- been marked as checked.
2120 if Project
/= No_Project
2121 and then not In_Tree
.Projects
.Table
(Project
).Checked
2123 -- Mark project as checked, to avoid infinite recursion in
2124 -- ill-formed trees, where a project imports itself.
2126 In_Tree
.Projects
.Table
(Project
).Checked
:= True;
2128 Data
:= In_Tree
.Projects
.Table
(Project
);
2130 -- Call itself for a possible extended project.
2131 -- (if there is no extended project, then nothing happens).
2133 Recursive_Check
(Data
.Extends
, In_Tree
, Follow_Links
);
2135 -- Call itself for all imported projects
2137 Imported_Project_List
:= Data
.Imported_Projects
;
2138 while Imported_Project_List
/= Empty_Project_List
loop
2140 (In_Tree
.Project_Lists
.Table
2141 (Imported_Project_List
).Project
,
2142 In_Tree
, Follow_Links
);
2143 Imported_Project_List
:=
2144 In_Tree
.Project_Lists
.Table
2145 (Imported_Project_List
).Next
;
2148 if Opt
.Verbose_Mode
then
2149 Write_Str
("Checking project file """);
2150 Write_Str
(Get_Name_String
(Data
.Name
));
2154 Prj
.Nmsc
.Check
(Project
, In_Tree
, Error_Report
, Follow_Links
);
2156 end Recursive_Check
;
2158 -----------------------
2159 -- Recursive_Process --
2160 -----------------------
2162 procedure Recursive_Process
2163 (In_Tree
: Project_Tree_Ref
;
2164 Project
: out Project_Id
;
2165 From_Project_Node
: Project_Node_Id
;
2166 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
2167 Extended_By
: Project_Id
)
2169 With_Clause
: Project_Node_Id
;
2172 if From_Project_Node
= Empty_Node
then
2173 Project
:= No_Project
;
2177 Processed_Data
: Project_Data
:= Empty_Project
(In_Tree
);
2178 Imported
: Project_List
:= Empty_Project_List
;
2179 Declaration_Node
: Project_Node_Id
:= Empty_Node
;
2180 Tref
: Source_Buffer_Ptr
;
2181 Name
: constant Name_Id
:=
2183 (From_Project_Node
, From_Project_Node_Tree
);
2184 Location
: Source_Ptr
:=
2186 (From_Project_Node
, From_Project_Node_Tree
);
2189 Project
:= Processed_Projects
.Get
(Name
);
2191 if Project
/= No_Project
then
2195 Project_Table
.Increment_Last
(In_Tree
.Projects
);
2196 Project
:= Project_Table
.Last
(In_Tree
.Projects
);
2197 Processed_Projects
.Set
(Name
, Project
);
2199 Processed_Data
.Name
:= Name
;
2201 Get_Name_String
(Name
);
2203 -- If name starts with the virtual prefix, flag the project as
2204 -- being a virtual extending project.
2206 if Name_Len
> Virtual_Prefix
'Length
2207 and then Name_Buffer
(1 .. Virtual_Prefix
'Length) =
2210 Processed_Data
.Virtual
:= True;
2211 Processed_Data
.Display_Name
:= Name
;
2213 -- If there is no file, for example when the project node tree is
2214 -- built in memory by GPS, the Display_Name cannot be found in
2215 -- the source, so its value is the same as Name.
2217 elsif Location
= No_Location
then
2218 Processed_Data
.Display_Name
:= Name
;
2220 -- Get the spelling of the project name from the project file
2223 Tref
:= Source_Text
(Get_Source_File_Index
(Location
));
2225 for J
in 1 .. Name_Len
loop
2226 Name_Buffer
(J
) := Tref
(Location
);
2227 Location
:= Location
+ 1;
2230 Processed_Data
.Display_Name
:= Name_Find
;
2233 Processed_Data
.Display_Path_Name
:=
2234 Path_Name_Of
(From_Project_Node
, From_Project_Node_Tree
);
2235 Get_Name_String
(Processed_Data
.Display_Path_Name
);
2236 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
2237 Processed_Data
.Path_Name
:= Name_Find
;
2239 Processed_Data
.Location
:=
2240 Location_Of
(From_Project_Node
, From_Project_Node_Tree
);
2242 Processed_Data
.Display_Directory
:=
2243 Directory_Of
(From_Project_Node
, From_Project_Node_Tree
);
2244 Get_Name_String
(Processed_Data
.Display_Directory
);
2245 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
2246 Processed_Data
.Directory
:= Name_Find
;
2248 Processed_Data
.Extended_By
:= Extended_By
;
2251 (Project
, In_Tree
, Processed_Data
.Decl
, Attribute_First
);
2253 First_With_Clause_Of
(From_Project_Node
, From_Project_Node_Tree
);
2255 while With_Clause
/= Empty_Node
loop
2257 New_Project
: Project_Id
;
2258 New_Data
: Project_Data
;
2262 (In_Tree
=> In_Tree
,
2263 Project
=> New_Project
,
2264 From_Project_Node
=>
2265 Project_Node_Of
(With_Clause
, From_Project_Node_Tree
),
2266 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2267 Extended_By
=> No_Project
);
2269 In_Tree
.Projects
.Table
(New_Project
);
2271 -- If we were the first project to import it,
2272 -- set First_Referred_By to us.
2274 if New_Data
.First_Referred_By
= No_Project
then
2275 New_Data
.First_Referred_By
:= Project
;
2276 In_Tree
.Projects
.Table
(New_Project
) :=
2280 -- Add this project to our list of imported projects
2282 Project_List_Table
.Increment_Last
2283 (In_Tree
.Project_Lists
);
2284 In_Tree
.Project_Lists
.Table
2285 (Project_List_Table
.Last
2286 (In_Tree
.Project_Lists
)) :=
2287 (Project
=> New_Project
, Next
=> Empty_Project_List
);
2289 -- Imported is the id of the last imported project.
2290 -- If it is nil, then this imported project is our first.
2292 if Imported
= Empty_Project_List
then
2293 Processed_Data
.Imported_Projects
:=
2294 Project_List_Table
.Last
2295 (In_Tree
.Project_Lists
);
2298 In_Tree
.Project_Lists
.Table
2299 (Imported
).Next
:= Project_List_Table
.Last
2300 (In_Tree
.Project_Lists
);
2303 Imported
:= Project_List_Table
.Last
2304 (In_Tree
.Project_Lists
);
2307 Next_With_Clause_Of
(With_Clause
, From_Project_Node_Tree
);
2312 Project_Declaration_Of
2313 (From_Project_Node
, From_Project_Node_Tree
);
2316 (In_Tree
=> In_Tree
,
2317 Project
=> Processed_Data
.Extends
,
2318 From_Project_Node
=>
2320 (Declaration_Node
, From_Project_Node_Tree
),
2321 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2322 Extended_By
=> Project
);
2324 In_Tree
.Projects
.Table
(Project
) := Processed_Data
;
2326 Process_Declarative_Items
2327 (Project
=> Project
,
2329 From_Project_Node
=> From_Project_Node
,
2330 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2333 First_Declarative_Item_Of
2334 (Declaration_Node
, From_Project_Node_Tree
));
2336 -- If it is an extending project, inherit all packages
2337 -- from the extended project that are not explicitely defined
2338 -- or renamed. Also inherit the languages, if attribute Languages
2339 -- is not explicitely defined.
2341 if Processed_Data
.Extends
/= No_Project
then
2342 Processed_Data
:= In_Tree
.Projects
.Table
(Project
);
2345 Extended_Pkg
: Package_Id
:=
2346 In_Tree
.Projects
.Table
2347 (Processed_Data
.Extends
).Decl
.Packages
;
2348 Current_Pkg
: Package_Id
;
2349 Element
: Package_Element
;
2350 First
: constant Package_Id
:=
2351 Processed_Data
.Decl
.Packages
;
2352 Attribute1
: Variable_Id
;
2353 Attribute2
: Variable_Id
;
2354 Attr_Value1
: Variable
;
2355 Attr_Value2
: Variable
;
2358 while Extended_Pkg
/= No_Package
loop
2360 In_Tree
.Packages
.Table
(Extended_Pkg
);
2362 Current_Pkg
:= First
;
2365 exit when Current_Pkg
= No_Package
2366 or else In_Tree
.Packages
.Table
2367 (Current_Pkg
).Name
= Element
.Name
;
2368 Current_Pkg
:= In_Tree
.Packages
.Table
2372 if Current_Pkg
= No_Package
then
2373 Package_Table
.Increment_Last
2375 Current_Pkg
:= Package_Table
.Last
2377 In_Tree
.Packages
.Table
(Current_Pkg
) :=
2378 (Name
=> Element
.Name
,
2379 Decl
=> Element
.Decl
,
2380 Parent
=> No_Package
,
2381 Next
=> Processed_Data
.Decl
.Packages
);
2382 Processed_Data
.Decl
.Packages
:= Current_Pkg
;
2385 Extended_Pkg
:= Element
.Next
;
2388 -- Check if attribute Languages is declared in the
2389 -- extending project.
2391 Attribute1
:= Processed_Data
.Decl
.Attributes
;
2392 while Attribute1
/= No_Variable
loop
2393 Attr_Value1
:= In_Tree
.Variable_Elements
.
2395 exit when Attr_Value1
.Name
= Snames
.Name_Languages
;
2396 Attribute1
:= Attr_Value1
.Next
;
2399 if Attribute1
= No_Variable
or else
2400 Attr_Value1
.Value
.Default
2402 -- Attribute Languages is not declared in the extending
2403 -- project. Check if it is declared in the project being
2407 In_Tree
.Projects
.Table
2408 (Processed_Data
.Extends
).Decl
.Attributes
;
2410 while Attribute2
/= No_Variable
loop
2411 Attr_Value2
:= In_Tree
.Variable_Elements
.
2413 exit when Attr_Value2
.Name
= Snames
.Name_Languages
;
2414 Attribute2
:= Attr_Value2
.Next
;
2417 if Attribute2
/= No_Variable
and then
2418 not Attr_Value2
.Value
.Default
2420 -- As attribute Languages is declared in the project
2421 -- being extended, copy its value for the extending
2424 if Attribute1
= No_Variable
then
2425 Variable_Element_Table
.Increment_Last
2426 (In_Tree
.Variable_Elements
);
2427 Attribute1
:= Variable_Element_Table
.Last
2428 (In_Tree
.Variable_Elements
);
2429 Attr_Value1
.Next
:= Processed_Data
.Decl
.Attributes
;
2430 Processed_Data
.Decl
.Attributes
:= Attribute1
;
2433 Attr_Value1
.Name
:= Snames
.Name_Languages
;
2434 Attr_Value1
.Value
:= Attr_Value2
.Value
;
2435 In_Tree
.Variable_Elements
.Table
2436 (Attribute1
) := Attr_Value1
;
2441 In_Tree
.Projects
.Table
(Project
) := Processed_Data
;
2445 end Recursive_Process
;