1 ------------------------------------------------------------------------------
4 -- GNAT COMPILER COMPONENTS --
10 -- Copyright (C) 2001-2007, Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 3, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
20 -- http://www.gnu.org/licenses for a complete copy of the license. --
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
;
29 with Osint
; use Osint
;
30 with Output
; use Output
;
31 with Prj
.Attr
; use Prj
.Attr
;
32 with Prj
.Err
; use Prj
.Err
;
33 with Prj
.Ext
; use Prj
.Ext
;
34 with Prj
.Nmsc
; use Prj
.Nmsc
;
35 with Sinput
; use Sinput
;
38 with GNAT
.Case_Util
; use GNAT
.Case_Util
;
41 package body Prj
.Proc
is
43 Error_Report
: Put_Line_Access
:= null;
45 package Processed_Projects
is new GNAT
.HTable
.Simple_HTable
46 (Header_Num
=> Header_Num
,
47 Element
=> Project_Id
,
48 No_Element
=> No_Project
,
52 -- This hash table contains all processed projects
54 package Unit_Htable
is new GNAT
.HTable
.Simple_HTable
55 (Header_Num
=> Header_Num
,
57 No_Element
=> No_Source
,
61 -- This hash table contains all processed projects
63 procedure Add
(To_Exp
: in out Name_Id
; Str
: Name_Id
);
64 -- Concatenate two strings and returns another string if both
65 -- arguments are not null string.
67 procedure Add_Attributes
68 (Project
: Project_Id
;
69 Project_Name
: Name_Id
;
70 In_Tree
: Project_Tree_Ref
;
71 Decl
: in out Declarations
;
72 First
: Attribute_Node_Id
;
73 Project_Level
: Boolean);
74 -- Add all attributes, starting with First, with their default
75 -- values to the package or project with declarations Decl.
78 (In_Tree
: Project_Tree_Ref
;
81 When_No_Sources
: Error_Warning
);
82 -- Set all projects to not checked, then call Recursive_Check for the
83 -- main project Project. Project is set to No_Project if errors occurred.
84 -- Current_Dir is for optimization purposes, avoiding extra system calls.
86 procedure Copy_Package_Declarations
88 To
: in out Declarations
;
90 In_Tree
: Project_Tree_Ref
);
91 -- Copy a package declaration From to To for a renamed package. Change the
92 -- locations of all the attributes to New_Loc.
95 (Project
: Project_Id
;
96 In_Tree
: Project_Tree_Ref
;
97 From_Project_Node
: Project_Node_Id
;
98 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
100 First_Term
: Project_Node_Id
;
101 Kind
: Variable_Kind
) return Variable_Value
;
102 -- From N_Expression project node From_Project_Node, compute the value
103 -- of an expression and return it as a Variable_Value.
105 function Imported_Or_Extended_Project_From
106 (Project
: Project_Id
;
107 In_Tree
: Project_Tree_Ref
;
108 With_Name
: Name_Id
) return Project_Id
;
109 -- Find an imported or extended project of Project whose name is With_Name
111 function Package_From
112 (Project
: Project_Id
;
113 In_Tree
: Project_Tree_Ref
;
114 With_Name
: Name_Id
) return Package_Id
;
115 -- Find the package of Project whose name is With_Name
117 procedure Process_Declarative_Items
118 (Project
: Project_Id
;
119 In_Tree
: Project_Tree_Ref
;
120 From_Project_Node
: Project_Node_Id
;
121 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
123 Item
: Project_Node_Id
);
124 -- Process declarative items starting with From_Project_Node, and put them
125 -- in declarations Decl. This is a recursive procedure; it calls itself for
126 -- a package declaration or a case construction.
128 procedure Recursive_Process
129 (In_Tree
: Project_Tree_Ref
;
130 Project
: out Project_Id
;
131 From_Project_Node
: Project_Node_Id
;
132 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
133 Extended_By
: Project_Id
);
134 -- Process project with node From_Project_Node in the tree.
135 -- Do nothing if From_Project_Node is Empty_Node.
136 -- If project has already been processed, simply return its project id.
137 -- Otherwise create a new project id, mark it as processed, call itself
138 -- recursively for all imported projects and a extended project, if any.
139 -- Then process the declarative items of the project.
141 procedure Recursive_Check
142 (Project
: Project_Id
;
143 In_Tree
: Project_Tree_Ref
;
144 Current_Dir
: String;
145 When_No_Sources
: Error_Warning
);
146 -- If Project is not marked as checked, mark it as checked, call
147 -- Check_Naming_Scheme for the project, then call itself for a
148 -- possible extended project and all the imported projects of Project.
149 -- Current_Dir is for optimization purposes, avoiding extra system calls.
155 procedure Add
(To_Exp
: in out Name_Id
; Str
: Name_Id
) is
157 if To_Exp
= No_Name
or else To_Exp
= Empty_String
then
159 -- To_Exp is nil or empty. The result is Str
163 -- If Str is nil, then do not change To_Ext
165 elsif Str
/= No_Name
and then Str
/= Empty_String
then
167 S
: constant String := Get_Name_String
(Str
);
170 Get_Name_String
(To_Exp
);
171 Add_Str_To_Name_Buffer
(S
);
181 procedure Add_Attributes
182 (Project
: Project_Id
;
183 Project_Name
: Name_Id
;
184 In_Tree
: Project_Tree_Ref
;
185 Decl
: in out Declarations
;
186 First
: Attribute_Node_Id
;
187 Project_Level
: Boolean)
189 The_Attribute
: Attribute_Node_Id
:= First
;
192 while The_Attribute
/= Empty_Attribute
loop
193 if Attribute_Kind_Of
(The_Attribute
) = Single
then
195 New_Attribute
: Variable_Value
;
198 case Variable_Kind_Of
(The_Attribute
) is
200 -- Undefined should not happen
204 (False, "attribute with an undefined kind");
207 -- Single attributes have a default value of empty string
213 Location
=> No_Location
,
215 Value
=> Empty_String
,
218 -- Special case of <project>'Name
221 and then Attribute_Name_Of
(The_Attribute
) =
224 New_Attribute
.Value
:= Project_Name
;
227 -- List attributes have a default value of nil list
233 Location
=> No_Location
,
235 Values
=> Nil_String
);
239 Variable_Element_Table
.Increment_Last
240 (In_Tree
.Variable_Elements
);
241 In_Tree
.Variable_Elements
.Table
242 (Variable_Element_Table
.Last
243 (In_Tree
.Variable_Elements
)) :=
244 (Next
=> Decl
.Attributes
,
245 Name
=> Attribute_Name_Of
(The_Attribute
),
246 Value
=> New_Attribute
);
247 Decl
.Attributes
:= Variable_Element_Table
.Last
248 (In_Tree
.Variable_Elements
);
252 The_Attribute
:= Next_Attribute
(After
=> The_Attribute
);
261 (In_Tree
: Project_Tree_Ref
;
262 Project
: Project_Id
;
263 Current_Dir
: String;
264 When_No_Sources
: Error_Warning
)
267 -- Make sure that all projects are marked as not checked
269 for Index
in Project_Table
.First
..
270 Project_Table
.Last
(In_Tree
.Projects
)
272 In_Tree
.Projects
.Table
(Index
).Checked
:= False;
275 Recursive_Check
(Project
, In_Tree
, Current_Dir
, When_No_Sources
);
277 -- Set the Other_Part field for the units
287 Source1
:= In_Tree
.First_Source
;
288 while Source1
/= No_Source
loop
289 Name
:= In_Tree
.Sources
.Table
(Source1
).Unit
;
291 if Name
/= No_Name
then
292 Source2
:= Unit_Htable
.Get
(Name
);
294 if Source2
= No_Source
then
295 Unit_Htable
.Set
(K
=> Name
, E
=> Source1
);
298 Unit_Htable
.Remove
(Name
);
299 In_Tree
.Sources
.Table
(Source1
).Other_Part
:= Source2
;
300 In_Tree
.Sources
.Table
(Source2
).Other_Part
:= Source1
;
304 Source1
:= In_Tree
.Sources
.Table
(Source1
).Next_In_Sources
;
309 -------------------------------
310 -- Copy_Package_Declarations --
311 -------------------------------
313 procedure Copy_Package_Declarations
314 (From
: Declarations
;
315 To
: in out Declarations
;
316 New_Loc
: Source_Ptr
;
317 In_Tree
: Project_Tree_Ref
)
319 V1
: Variable_Id
:= From
.Attributes
;
320 V2
: Variable_Id
:= No_Variable
;
322 A1
: Array_Id
:= From
.Arrays
;
323 A2
: Array_Id
:= No_Array
;
325 E1
: Array_Element_Id
;
326 E2
: Array_Element_Id
:= No_Array_Element
;
330 -- To avoid references in error messages to attribute declarations in
331 -- an original package that has been renamed, copy all the attribute
332 -- declarations of the package and change all locations to New_Loc,
333 -- the location of the renamed package.
335 -- First single attributes
337 while V1
/= No_Variable
loop
339 -- Copy the attribute
341 Var
:= In_Tree
.Variable_Elements
.Table
(V1
);
344 -- Remove the Next component
346 Var
.Next
:= No_Variable
;
348 -- Change the location to New_Loc
350 Var
.Value
.Location
:= New_Loc
;
351 Variable_Element_Table
.Increment_Last
(In_Tree
.Variable_Elements
);
353 -- Put in new declaration
355 if To
.Attributes
= No_Variable
then
357 Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
360 In_Tree
.Variable_Elements
.Table
(V2
).Next
:=
361 Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
364 V2
:= Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
365 In_Tree
.Variable_Elements
.Table
(V2
) := Var
;
368 -- Then the associated array attributes
370 while A1
/= No_Array
loop
374 Arr
:= In_Tree
.Arrays
.Table
(A1
);
377 -- Remove the Next component
379 Arr
.Next
:= No_Array
;
381 Array_Table
.Increment_Last
(In_Tree
.Arrays
);
383 -- Create new Array declaration
384 if To
.Arrays
= No_Array
then
385 To
.Arrays
:= Array_Table
.Last
(In_Tree
.Arrays
);
388 In_Tree
.Arrays
.Table
(A2
).Next
:=
389 Array_Table
.Last
(In_Tree
.Arrays
);
392 A2
:= Array_Table
.Last
(In_Tree
.Arrays
);
394 -- Don't store the array, as its first element has not been set yet
396 -- Copy the array elements of the array
399 Arr
.Value
:= No_Array_Element
;
401 while E1
/= No_Array_Element
loop
403 -- Copy the array element
405 Elm
:= In_Tree
.Array_Elements
.Table
(E1
);
408 -- Remove the Next component
410 Elm
.Next
:= No_Array_Element
;
412 -- Change the location
414 Elm
.Value
.Location
:= New_Loc
;
415 Array_Element_Table
.Increment_Last
(In_Tree
.Array_Elements
);
417 -- Create new array element
419 if Arr
.Value
= No_Array_Element
then
420 Arr
.Value
:= Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
422 In_Tree
.Array_Elements
.Table
(E2
).Next
:=
423 Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
426 E2
:= Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
427 In_Tree
.Array_Elements
.Table
(E2
) := Elm
;
430 -- Finally, store the new array
432 In_Tree
.Arrays
.Table
(A2
) := Arr
;
434 end Copy_Package_Declarations
;
441 (Project
: Project_Id
;
442 In_Tree
: Project_Tree_Ref
;
443 From_Project_Node
: Project_Node_Id
;
444 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
446 First_Term
: Project_Node_Id
;
447 Kind
: Variable_Kind
) return Variable_Value
449 The_Term
: Project_Node_Id
:= First_Term
;
450 -- The term in the expression list
452 The_Current_Term
: Project_Node_Id
:= Empty_Node
;
453 -- The current term node id
455 Result
: Variable_Value
(Kind
=> Kind
);
456 -- The returned result
458 Last
: String_List_Id
:= Nil_String
;
459 -- Reference to the last string elements in Result, when Kind is List
462 Result
.Project
:= Project
;
463 Result
.Location
:= Location_Of
(First_Term
, From_Project_Node_Tree
);
465 -- Process each term of the expression, starting with First_Term
467 while The_Term
/= Empty_Node
loop
468 The_Current_Term
:= Current_Term
(The_Term
, From_Project_Node_Tree
);
470 case Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) is
472 when N_Literal_String
=>
478 -- Should never happen
480 pragma Assert
(False, "Undefined expression kind");
486 (The_Current_Term
, From_Project_Node_Tree
));
489 (The_Current_Term
, From_Project_Node_Tree
);
493 String_Element_Table
.Increment_Last
494 (In_Tree
.String_Elements
);
496 if Last
= Nil_String
then
498 -- This can happen in an expression like () & "toto"
500 Result
.Values
:= String_Element_Table
.Last
501 (In_Tree
.String_Elements
);
504 In_Tree
.String_Elements
.Table
505 (Last
).Next
:= String_Element_Table
.Last
506 (In_Tree
.String_Elements
);
509 Last
:= String_Element_Table
.Last
510 (In_Tree
.String_Elements
);
511 In_Tree
.String_Elements
.Table
(Last
) :=
515 From_Project_Node_Tree
),
518 (The_Current_Term
, From_Project_Node_Tree
),
519 Display_Value
=> No_Name
,
523 From_Project_Node_Tree
),
528 when N_Literal_String_List
=>
531 String_Node
: Project_Node_Id
:=
532 First_Expression_In_List
534 From_Project_Node_Tree
);
536 Value
: Variable_Value
;
539 if String_Node
/= Empty_Node
then
541 -- If String_Node is nil, it is an empty list,
542 -- there is nothing to do
547 From_Project_Node
=> From_Project_Node
,
548 From_Project_Node_Tree
=> From_Project_Node_Tree
,
552 (String_Node
, From_Project_Node_Tree
),
554 String_Element_Table
.Increment_Last
555 (In_Tree
.String_Elements
);
557 if Result
.Values
= Nil_String
then
559 -- This literal string list is the first term
560 -- in a string list expression
563 String_Element_Table
.Last
(In_Tree
.String_Elements
);
566 In_Tree
.String_Elements
.Table
568 String_Element_Table
.Last
(In_Tree
.String_Elements
);
572 String_Element_Table
.Last
(In_Tree
.String_Elements
);
574 In_Tree
.String_Elements
.Table
(Last
) :=
575 (Value
=> Value
.Value
,
576 Display_Value
=> No_Name
,
577 Location
=> Value
.Location
,
580 Index
=> Value
.Index
);
583 -- Add the other element of the literal string list
584 -- one after the other
587 Next_Expression_In_List
588 (String_Node
, From_Project_Node_Tree
);
590 exit when String_Node
= Empty_Node
;
596 From_Project_Node
=> From_Project_Node
,
597 From_Project_Node_Tree
=> From_Project_Node_Tree
,
601 (String_Node
, From_Project_Node_Tree
),
604 String_Element_Table
.Increment_Last
605 (In_Tree
.String_Elements
);
606 In_Tree
.String_Elements
.Table
607 (Last
).Next
:= String_Element_Table
.Last
608 (In_Tree
.String_Elements
);
609 Last
:= String_Element_Table
.Last
610 (In_Tree
.String_Elements
);
611 In_Tree
.String_Elements
.Table
(Last
) :=
612 (Value
=> Value
.Value
,
613 Display_Value
=> No_Name
,
614 Location
=> Value
.Location
,
617 Index
=> Value
.Index
);
622 when N_Variable_Reference | N_Attribute_Reference
=>
625 The_Project
: Project_Id
:= Project
;
626 The_Package
: Package_Id
:= Pkg
;
627 The_Name
: Name_Id
:= No_Name
;
628 The_Variable_Id
: Variable_Id
:= No_Variable
;
629 The_Variable
: Variable_Value
;
630 Term_Project
: constant Project_Node_Id
:=
633 From_Project_Node_Tree
);
634 Term_Package
: constant Project_Node_Id
:=
637 From_Project_Node_Tree
);
638 Index
: Name_Id
:= No_Name
;
641 if Term_Project
/= Empty_Node
and then
642 Term_Project
/= From_Project_Node
644 -- This variable or attribute comes from another project
647 Name_Of
(Term_Project
, From_Project_Node_Tree
);
648 The_Project
:= Imported_Or_Extended_Project_From
651 With_Name
=> The_Name
);
654 if Term_Package
/= Empty_Node
then
656 -- This is an attribute of a package
659 Name_Of
(Term_Package
, From_Project_Node_Tree
);
660 The_Package
:= In_Tree
.Projects
.Table
661 (The_Project
).Decl
.Packages
;
663 while The_Package
/= No_Package
664 and then In_Tree
.Packages
.Table
665 (The_Package
).Name
/= The_Name
668 In_Tree
.Packages
.Table
673 (The_Package
/= No_Package
,
674 "package not found.");
676 elsif Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
677 N_Attribute_Reference
679 The_Package
:= No_Package
;
683 Name_Of
(The_Current_Term
, From_Project_Node_Tree
);
685 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
686 N_Attribute_Reference
689 Associative_Array_Index_Of
690 (The_Current_Term
, From_Project_Node_Tree
);
693 -- If it is not an associative array attribute
695 if Index
= No_Name
then
697 -- It is not an associative array attribute
699 if The_Package
/= No_Package
then
701 -- First, if there is a package, look into the package
703 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
707 In_Tree
.Packages
.Table
708 (The_Package
).Decl
.Variables
;
711 In_Tree
.Packages
.Table
712 (The_Package
).Decl
.Attributes
;
715 while The_Variable_Id
/= No_Variable
717 In_Tree
.Variable_Elements
.Table
718 (The_Variable_Id
).Name
/= The_Name
721 In_Tree
.Variable_Elements
.Table
722 (The_Variable_Id
).Next
;
727 if The_Variable_Id
= No_Variable
then
729 -- If we have not found it, look into the project
731 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
735 In_Tree
.Projects
.Table
736 (The_Project
).Decl
.Variables
;
739 In_Tree
.Projects
.Table
740 (The_Project
).Decl
.Attributes
;
743 while The_Variable_Id
/= No_Variable
745 In_Tree
.Variable_Elements
.Table
746 (The_Variable_Id
).Name
/= The_Name
749 In_Tree
.Variable_Elements
.Table
750 (The_Variable_Id
).Next
;
755 pragma Assert
(The_Variable_Id
/= No_Variable
,
756 "variable or attribute not found");
759 In_Tree
.Variable_Elements
.Table
760 (The_Variable_Id
).Value
;
764 -- It is an associative array attribute
767 The_Array
: Array_Id
:= No_Array
;
768 The_Element
: Array_Element_Id
:= No_Array_Element
;
769 Array_Index
: Name_Id
:= No_Name
;
773 if The_Package
/= No_Package
then
775 In_Tree
.Packages
.Table
776 (The_Package
).Decl
.Arrays
;
779 In_Tree
.Projects
.Table
780 (The_Project
).Decl
.Arrays
;
783 while The_Array
/= No_Array
784 and then In_Tree
.Arrays
.Table
785 (The_Array
).Name
/= The_Name
787 The_Array
:= In_Tree
.Arrays
.Table
791 if The_Array
/= No_Array
then
792 The_Element
:= In_Tree
.Arrays
.Table
795 Get_Name_String
(Index
);
799 (The_Current_Term
, From_Project_Node_Tree
);
801 -- In multi-language mode (gprbuild), the index is
802 -- always case insensitive if it does not include
805 if Get_Mode
= Multi_Language
and then not Lower
then
808 for J
in 1 .. Name_Len
loop
809 if Name_Buffer
(J
) = '.' then
817 To_Lower
(Name_Buffer
(1 .. Name_Len
));
820 Array_Index
:= Name_Find
;
822 while The_Element
/= No_Array_Element
824 In_Tree
.Array_Elements
.Table
825 (The_Element
).Index
/= Array_Index
828 In_Tree
.Array_Elements
.Table
834 if The_Element
/= No_Array_Element
then
836 In_Tree
.Array_Elements
.Table
840 if Expression_Kind_Of
841 (The_Current_Term
, From_Project_Node_Tree
) =
847 Location
=> No_Location
,
849 Values
=> Nil_String
);
854 Location
=> No_Location
,
856 Value
=> Empty_String
,
867 -- Should never happen
869 pragma Assert
(False, "undefined expression kind");
874 case The_Variable
.Kind
is
880 Add
(Result
.Value
, The_Variable
.Value
);
884 -- Should never happen
888 "list cannot appear in single " &
889 "string expression");
894 case The_Variable
.Kind
is
900 String_Element_Table
.Increment_Last
901 (In_Tree
.String_Elements
);
903 if Last
= Nil_String
then
905 -- This can happen in an expression such as
909 String_Element_Table
.Last
910 (In_Tree
.String_Elements
);
913 In_Tree
.String_Elements
.Table
915 String_Element_Table
.Last
916 (In_Tree
.String_Elements
);
920 String_Element_Table
.Last
921 (In_Tree
.String_Elements
);
923 In_Tree
.String_Elements
.Table
(Last
) :=
924 (Value
=> The_Variable
.Value
,
925 Display_Value
=> No_Name
,
926 Location
=> Location_Of
928 From_Project_Node_Tree
),
936 The_List
: String_List_Id
:=
940 while The_List
/= Nil_String
loop
941 String_Element_Table
.Increment_Last
942 (In_Tree
.String_Elements
);
944 if Last
= Nil_String
then
946 String_Element_Table
.Last
952 String_Elements
.Table
(Last
).Next
:=
953 String_Element_Table
.Last
960 String_Element_Table
.Last
961 (In_Tree
.String_Elements
);
963 In_Tree
.String_Elements
.Table
(Last
) :=
965 In_Tree
.String_Elements
.Table
967 Display_Value
=> No_Name
,
971 From_Project_Node_Tree
),
977 In_Tree
. String_Elements
.Table
985 when N_External_Value
=>
988 (External_Reference_Of
989 (The_Current_Term
, From_Project_Node_Tree
),
990 From_Project_Node_Tree
));
993 Name
: constant Name_Id
:= Name_Find
;
994 Default
: Name_Id
:= No_Name
;
995 Value
: Name_Id
:= No_Name
;
997 Def_Var
: Variable_Value
;
999 Default_Node
: constant Project_Node_Id
:=
1001 (The_Current_Term
, From_Project_Node_Tree
);
1004 -- If there is a default value for the external reference,
1007 if Default_Node
/= Empty_Node
then
1008 Def_Var
:= Expression
1009 (Project
=> Project
,
1011 From_Project_Node
=> Default_Node
,
1012 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1016 (Default_Node
, From_Project_Node_Tree
),
1019 if Def_Var
/= Nil_Variable_Value
then
1020 Default
:= Def_Var
.Value
;
1024 Value
:= Prj
.Ext
.Value_Of
(Name
, Default
);
1026 if Value
= No_Name
then
1027 if not Quiet_Output
then
1028 if Error_Report
= null then
1030 ("?undefined external reference",
1032 (The_Current_Term
, From_Project_Node_Tree
));
1035 ("warning: """ & Get_Name_String
(Name
) &
1036 """ is an undefined external reference",
1041 Value
:= Empty_String
;
1050 Add
(Result
.Value
, Value
);
1053 String_Element_Table
.Increment_Last
1054 (In_Tree
.String_Elements
);
1056 if Last
= Nil_String
then
1057 Result
.Values
:= String_Element_Table
.Last
1058 (In_Tree
.String_Elements
);
1061 In_Tree
.String_Elements
.Table
1062 (Last
).Next
:= String_Element_Table
.Last
1063 (In_Tree
.String_Elements
);
1066 Last
:= String_Element_Table
.Last
1067 (In_Tree
.String_Elements
);
1068 In_Tree
.String_Elements
.Table
(Last
) :=
1070 Display_Value
=> No_Name
,
1073 (The_Current_Term
, From_Project_Node_Tree
),
1083 -- Should never happen
1087 "illegal node kind in an expression");
1088 raise Program_Error
;
1092 The_Term
:= Next_Term
(The_Term
, From_Project_Node_Tree
);
1098 ---------------------------------------
1099 -- Imported_Or_Extended_Project_From --
1100 ---------------------------------------
1102 function Imported_Or_Extended_Project_From
1103 (Project
: Project_Id
;
1104 In_Tree
: Project_Tree_Ref
;
1105 With_Name
: Name_Id
) return Project_Id
1107 Data
: constant Project_Data
:=
1108 In_Tree
.Projects
.Table
(Project
);
1109 List
: Project_List
:= Data
.Imported_Projects
;
1110 Result
: Project_Id
:= No_Project
;
1111 Temp_Result
: Project_Id
:= No_Project
;
1114 -- First check if it is the name of an extended project
1116 if Data
.Extends
/= No_Project
1117 and then In_Tree
.Projects
.Table
(Data
.Extends
).Name
=
1120 return Data
.Extends
;
1123 -- Then check the name of each imported project
1125 while List
/= Empty_Project_List
loop
1126 Result
:= In_Tree
.Project_Lists
.Table
(List
).Project
;
1128 -- If the project is directly imported, then returns its ID
1131 In_Tree
.Projects
.Table
(Result
).Name
= With_Name
1136 -- If a project extending the project is imported, then keep
1137 -- this extending project as a possibility. It will be the
1138 -- returned ID if the project is not imported directly.
1141 Proj
: Project_Id
:=
1142 In_Tree
.Projects
.Table
(Result
).Extends
;
1144 while Proj
/= No_Project
loop
1145 if In_Tree
.Projects
.Table
(Proj
).Name
=
1148 Temp_Result
:= Result
;
1152 Proj
:= In_Tree
.Projects
.Table
(Proj
).Extends
;
1156 List
:= In_Tree
.Project_Lists
.Table
(List
).Next
;
1160 (Temp_Result
/= No_Project
,
1161 "project not found");
1165 end Imported_Or_Extended_Project_From
;
1171 function Package_From
1172 (Project
: Project_Id
;
1173 In_Tree
: Project_Tree_Ref
;
1174 With_Name
: Name_Id
) return Package_Id
1176 Data
: constant Project_Data
:=
1177 In_Tree
.Projects
.Table
(Project
);
1178 Result
: Package_Id
:= Data
.Decl
.Packages
;
1181 -- Check the name of each existing package of Project
1183 while Result
/= No_Package
1184 and then In_Tree
.Packages
.Table
(Result
).Name
/= With_Name
1186 Result
:= In_Tree
.Packages
.Table
(Result
).Next
;
1189 if Result
= No_Package
then
1191 -- Should never happen
1193 Write_Line
("package """ & Get_Name_String
(With_Name
) &
1195 raise Program_Error
;
1207 (In_Tree
: Project_Tree_Ref
;
1208 Project
: out Project_Id
;
1209 Success
: out Boolean;
1210 From_Project_Node
: Project_Node_Id
;
1211 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
1212 Report_Error
: Put_Line_Access
;
1213 When_No_Sources
: Error_Warning
:= Error
;
1214 Reset_Tree
: Boolean := True;
1215 Current_Dir
: String := "")
1218 Process_Project_Tree_Phase_1
1219 (In_Tree
=> In_Tree
,
1222 From_Project_Node
=> From_Project_Node
,
1223 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1224 Report_Error
=> Report_Error
,
1225 Reset_Tree
=> Reset_Tree
);
1227 if not In_Configuration
then
1228 Process_Project_Tree_Phase_2
1229 (In_Tree
=> In_Tree
,
1232 From_Project_Node
=> From_Project_Node
,
1233 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1234 Report_Error
=> Report_Error
,
1235 When_No_Sources
=> When_No_Sources
,
1236 Current_Dir
=> Current_Dir
);
1240 -------------------------------
1241 -- Process_Declarative_Items --
1242 -------------------------------
1244 procedure Process_Declarative_Items
1245 (Project
: Project_Id
;
1246 In_Tree
: Project_Tree_Ref
;
1247 From_Project_Node
: Project_Node_Id
;
1248 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
1250 Item
: Project_Node_Id
)
1252 Current_Declarative_Item
: Project_Node_Id
;
1253 Current_Item
: Project_Node_Id
;
1256 -- Loop through declarative items
1258 Current_Item
:= Empty_Node
;
1260 Current_Declarative_Item
:= Item
;
1261 while Current_Declarative_Item
/= Empty_Node
loop
1267 (Current_Declarative_Item
, From_Project_Node_Tree
);
1269 -- And set Current_Declarative_Item to the next declarative item
1270 -- ready for the next iteration.
1272 Current_Declarative_Item
:=
1273 Next_Declarative_Item
1274 (Current_Declarative_Item
, From_Project_Node_Tree
);
1276 case Kind_Of
(Current_Item
, From_Project_Node_Tree
) is
1278 when N_Package_Declaration
=>
1280 -- Do not process a package declaration that should be ignored
1282 if Expression_Kind_Of
1283 (Current_Item
, From_Project_Node_Tree
) /= Ignored
1285 -- Create the new package
1287 Package_Table
.Increment_Last
(In_Tree
.Packages
);
1290 New_Pkg
: constant Package_Id
:=
1291 Package_Table
.Last
(In_Tree
.Packages
);
1292 The_New_Package
: Package_Element
;
1294 Project_Of_Renamed_Package
:
1295 constant Project_Node_Id
:=
1296 Project_Of_Renamed_Package_Of
1297 (Current_Item
, From_Project_Node_Tree
);
1300 -- Set the name of the new package
1302 The_New_Package
.Name
:=
1303 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1305 -- Insert the new package in the appropriate list
1307 if Pkg
/= No_Package
then
1308 The_New_Package
.Next
:=
1309 In_Tree
.Packages
.Table
(Pkg
).Decl
.Packages
;
1310 In_Tree
.Packages
.Table
(Pkg
).Decl
.Packages
:=
1314 The_New_Package
.Next
:=
1315 In_Tree
.Projects
.Table
(Project
).Decl
.Packages
;
1316 In_Tree
.Projects
.Table
(Project
).Decl
.Packages
:=
1320 In_Tree
.Packages
.Table
(New_Pkg
) :=
1323 if Project_Of_Renamed_Package
/= Empty_Node
then
1328 Project_Name
: constant Name_Id
:=
1330 (Project_Of_Renamed_Package
,
1331 From_Project_Node_Tree
);
1334 constant Project_Id
:=
1335 Imported_Or_Extended_Project_From
1336 (Project
, In_Tree
, Project_Name
);
1338 Renamed_Package
: constant Package_Id
:=
1340 (Renamed_Project
, In_Tree
,
1343 From_Project_Node_Tree
));
1346 -- For a renamed package, copy the declarations of
1347 -- the renamed package, but set all the locations
1348 -- to the location of the package name in the
1349 -- renaming declaration.
1351 Copy_Package_Declarations
1353 In_Tree
.Packages
.Table
(Renamed_Package
).Decl
,
1355 In_Tree
.Packages
.Table
(New_Pkg
).Decl
,
1358 (Current_Item
, From_Project_Node_Tree
),
1359 In_Tree
=> In_Tree
);
1362 -- Standard package declaration, not renaming
1365 -- Set the default values of the attributes
1369 In_Tree
.Projects
.Table
(Project
).Name
,
1371 In_Tree
.Packages
.Table
(New_Pkg
).Decl
,
1374 (Current_Item
, From_Project_Node_Tree
)),
1375 Project_Level
=> False);
1377 -- And process declarative items of the new package
1379 Process_Declarative_Items
1380 (Project
=> Project
,
1382 From_Project_Node
=> From_Project_Node
,
1383 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1386 First_Declarative_Item_Of
1387 (Current_Item
, From_Project_Node_Tree
));
1392 when N_String_Type_Declaration
=>
1394 -- There is nothing to process
1398 when N_Attribute_Declaration |
1399 N_Typed_Variable_Declaration |
1400 N_Variable_Declaration
=>
1402 if Expression_Of
(Current_Item
, From_Project_Node_Tree
) =
1406 -- It must be a full associative array attribute declaration
1409 Current_Item_Name
: constant Name_Id
:=
1412 From_Project_Node_Tree
);
1413 -- The name of the attribute
1415 New_Array
: Array_Id
;
1416 -- The new associative array created
1418 Orig_Array
: Array_Id
;
1419 -- The associative array value
1421 Orig_Project_Name
: Name_Id
:= No_Name
;
1422 -- The name of the project where the associative array
1425 Orig_Project
: Project_Id
:= No_Project
;
1426 -- The id of the project where the associative array
1429 Orig_Package_Name
: Name_Id
:= No_Name
;
1430 -- The name of the package, if any, where the associative
1433 Orig_Package
: Package_Id
:= No_Package
;
1434 -- The id of the package, if any, where the associative
1437 New_Element
: Array_Element_Id
:= No_Array_Element
;
1438 -- Id of a new array element created
1440 Prev_Element
: Array_Element_Id
:= No_Array_Element
;
1441 -- Last new element id created
1443 Orig_Element
: Array_Element_Id
:= No_Array_Element
;
1444 -- Current array element in original associative array
1446 Next_Element
: Array_Element_Id
:= No_Array_Element
;
1447 -- Id of the array element that follows the new element.
1448 -- This is not always nil, because values for the
1449 -- associative array attribute may already have been
1450 -- declared, and the array elements declared are reused.
1453 -- First find if the associative array attribute already
1454 -- has elements declared.
1456 if Pkg
/= No_Package
then
1457 New_Array
:= In_Tree
.Packages
.Table
1461 New_Array
:= In_Tree
.Projects
.Table
1462 (Project
).Decl
.Arrays
;
1465 while New_Array
/= No_Array
1466 and then In_Tree
.Arrays
.Table
(New_Array
).Name
/=
1469 New_Array
:= In_Tree
.Arrays
.Table
(New_Array
).Next
;
1472 -- If the attribute has never been declared add new entry
1473 -- in the arrays of the project/package and link it.
1475 if New_Array
= No_Array
then
1476 Array_Table
.Increment_Last
(In_Tree
.Arrays
);
1477 New_Array
:= Array_Table
.Last
(In_Tree
.Arrays
);
1479 if Pkg
/= No_Package
then
1480 In_Tree
.Arrays
.Table
(New_Array
) :=
1481 (Name
=> Current_Item_Name
,
1482 Value
=> No_Array_Element
,
1484 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
);
1486 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
:=
1490 In_Tree
.Arrays
.Table
(New_Array
) :=
1491 (Name
=> Current_Item_Name
,
1492 Value
=> No_Array_Element
,
1494 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
);
1496 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
:=
1501 -- Find the project where the value is declared
1503 Orig_Project_Name
:=
1505 (Associative_Project_Of
1506 (Current_Item
, From_Project_Node_Tree
),
1507 From_Project_Node_Tree
);
1509 for Index
in Project_Table
.First
..
1513 if In_Tree
.Projects
.Table
(Index
).Name
=
1516 Orig_Project
:= Index
;
1521 pragma Assert
(Orig_Project
/= No_Project
,
1522 "original project not found");
1524 if Associative_Package_Of
1525 (Current_Item
, From_Project_Node_Tree
) = Empty_Node
1528 In_Tree
.Projects
.Table
1529 (Orig_Project
).Decl
.Arrays
;
1532 -- If in a package, find the package where the value
1535 Orig_Package_Name
:=
1537 (Associative_Package_Of
1538 (Current_Item
, From_Project_Node_Tree
),
1539 From_Project_Node_Tree
);
1542 In_Tree
.Projects
.Table
1543 (Orig_Project
).Decl
.Packages
;
1544 pragma Assert
(Orig_Package
/= No_Package
,
1545 "original package not found");
1547 while In_Tree
.Packages
.Table
1548 (Orig_Package
).Name
/= Orig_Package_Name
1550 Orig_Package
:= In_Tree
.Packages
.Table
1551 (Orig_Package
).Next
;
1552 pragma Assert
(Orig_Package
/= No_Package
,
1553 "original package not found");
1557 In_Tree
.Packages
.Table
1558 (Orig_Package
).Decl
.Arrays
;
1561 -- Now look for the array
1563 while Orig_Array
/= No_Array
1564 and then In_Tree
.Arrays
.Table
(Orig_Array
).Name
/=
1567 Orig_Array
:= In_Tree
.Arrays
.Table
1571 if Orig_Array
= No_Array
then
1572 if Error_Report
= null then
1574 ("associative array value cannot be found",
1576 (Current_Item
, From_Project_Node_Tree
));
1579 ("associative array value cannot be found",
1585 In_Tree
.Arrays
.Table
(Orig_Array
).Value
;
1587 -- Copy each array element
1589 while Orig_Element
/= No_Array_Element
loop
1591 -- Case of first element
1593 if Prev_Element
= No_Array_Element
then
1595 -- And there is no array element declared yet,
1596 -- create a new first array element.
1598 if In_Tree
.Arrays
.Table
(New_Array
).Value
=
1601 Array_Element_Table
.Increment_Last
1602 (In_Tree
.Array_Elements
);
1603 New_Element
:= Array_Element_Table
.Last
1604 (In_Tree
.Array_Elements
);
1605 In_Tree
.Arrays
.Table
1606 (New_Array
).Value
:= New_Element
;
1607 Next_Element
:= No_Array_Element
;
1609 -- Otherwise, the new element is the first
1612 New_Element
:= In_Tree
.Arrays
.
1613 Table
(New_Array
).Value
;
1615 In_Tree
.Array_Elements
.Table
1619 -- Otherwise, reuse an existing element, or create
1620 -- one if necessary.
1624 In_Tree
.Array_Elements
.Table
1625 (Prev_Element
).Next
;
1627 if Next_Element
= No_Array_Element
then
1628 Array_Element_Table
.Increment_Last
1629 (In_Tree
.Array_Elements
);
1630 New_Element
:= Array_Element_Table
.Last
1631 (In_Tree
.Array_Elements
);
1634 New_Element
:= Next_Element
;
1636 In_Tree
.Array_Elements
.Table
1641 -- Copy the value of the element
1643 In_Tree
.Array_Elements
.Table
1645 In_Tree
.Array_Elements
.Table
1647 In_Tree
.Array_Elements
.Table
1648 (New_Element
).Value
.Project
:= Project
;
1650 -- Adjust the Next link
1652 In_Tree
.Array_Elements
.Table
1653 (New_Element
).Next
:= Next_Element
;
1655 -- Adjust the previous id for the next element
1657 Prev_Element
:= New_Element
;
1659 -- Go to the next element in the original array
1662 In_Tree
.Array_Elements
.Table
1663 (Orig_Element
).Next
;
1666 -- Make sure that the array ends here, in case there
1667 -- previously a greater number of elements.
1669 In_Tree
.Array_Elements
.Table
1670 (New_Element
).Next
:= No_Array_Element
;
1674 -- Declarations other that full associative arrays
1678 New_Value
: constant Variable_Value
:=
1680 (Project
=> Project
,
1682 From_Project_Node
=> From_Project_Node
,
1683 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1688 (Current_Item
, From_Project_Node_Tree
),
1689 From_Project_Node_Tree
),
1692 (Current_Item
, From_Project_Node_Tree
));
1693 -- The expression value
1695 The_Variable
: Variable_Id
:= No_Variable
;
1697 Current_Item_Name
: constant Name_Id
:=
1700 From_Project_Node_Tree
);
1703 -- Process a typed variable declaration
1705 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) =
1706 N_Typed_Variable_Declaration
1708 -- Report an error for an empty string
1710 if New_Value
.Value
= Empty_String
then
1712 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1714 if Error_Report
= null then
1716 ("no value defined for %%",
1718 (Current_Item
, From_Project_Node_Tree
));
1721 ("no value defined for " &
1722 Get_Name_String
(Error_Msg_Name_1
),
1728 Current_String
: Project_Node_Id
;
1731 -- Loop through all the valid strings for the
1732 -- string type and compare to the string value.
1735 First_Literal_String
1736 (String_Type_Of
(Current_Item
,
1737 From_Project_Node_Tree
),
1738 From_Project_Node_Tree
);
1739 while Current_String
/= Empty_Node
1742 (Current_String
, From_Project_Node_Tree
) /=
1747 (Current_String
, From_Project_Node_Tree
);
1750 -- Report an error if the string value is not
1751 -- one for the string type.
1753 if Current_String
= Empty_Node
then
1754 Error_Msg_Name_1
:= New_Value
.Value
;
1757 (Current_Item
, From_Project_Node_Tree
);
1759 if Error_Report
= null then
1761 ("value %% is illegal " &
1762 "for typed string %%",
1765 From_Project_Node_Tree
));
1770 Get_Name_String
(Error_Msg_Name_1
) &
1771 """ is illegal for typed string """ &
1772 Get_Name_String
(Error_Msg_Name_2
) &
1783 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) /=
1784 N_Attribute_Declaration
1786 Associative_Array_Index_Of
1787 (Current_Item
, From_Project_Node_Tree
) = No_Name
1789 -- Case of a variable declaration or of a not
1790 -- associative array attribute.
1792 -- First, find the list where to find the variable
1795 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) =
1796 N_Attribute_Declaration
1798 if Pkg
/= No_Package
then
1800 In_Tree
.Packages
.Table
1801 (Pkg
).Decl
.Attributes
;
1804 In_Tree
.Projects
.Table
1805 (Project
).Decl
.Attributes
;
1809 if Pkg
/= No_Package
then
1811 In_Tree
.Packages
.Table
1812 (Pkg
).Decl
.Variables
;
1815 In_Tree
.Projects
.Table
1816 (Project
).Decl
.Variables
;
1821 -- Loop through the list, to find if it has already
1824 while The_Variable
/= No_Variable
1826 In_Tree
.Variable_Elements
.Table
1827 (The_Variable
).Name
/= Current_Item_Name
1830 In_Tree
.Variable_Elements
.Table
1831 (The_Variable
).Next
;
1834 -- If it has not been declared, create a new entry
1837 if The_Variable
= No_Variable
then
1839 -- All single string attribute should already have
1840 -- been declared with a default empty string value.
1843 (Kind_Of
(Current_Item
, From_Project_Node_Tree
) /=
1844 N_Attribute_Declaration
,
1845 "illegal attribute declaration");
1847 Variable_Element_Table
.Increment_Last
1848 (In_Tree
.Variable_Elements
);
1849 The_Variable
:= Variable_Element_Table
.Last
1850 (In_Tree
.Variable_Elements
);
1852 -- Put the new variable in the appropriate list
1854 if Pkg
/= No_Package
then
1855 In_Tree
.Variable_Elements
.Table
(The_Variable
) :=
1857 In_Tree
.Packages
.Table
1858 (Pkg
).Decl
.Variables
,
1859 Name
=> Current_Item_Name
,
1860 Value
=> New_Value
);
1861 In_Tree
.Packages
.Table
1862 (Pkg
).Decl
.Variables
:= The_Variable
;
1865 In_Tree
.Variable_Elements
.Table
(The_Variable
) :=
1867 In_Tree
.Projects
.Table
1868 (Project
).Decl
.Variables
,
1869 Name
=> Current_Item_Name
,
1870 Value
=> New_Value
);
1871 In_Tree
.Projects
.Table
1872 (Project
).Decl
.Variables
:=
1876 -- If the variable/attribute has already been
1877 -- declared, just change the value.
1880 In_Tree
.Variable_Elements
.Table
1881 (The_Variable
).Value
:=
1886 -- Associative array attribute
1889 -- Get the string index
1892 (Associative_Array_Index_Of
1893 (Current_Item
, From_Project_Node_Tree
));
1895 -- Put in lower case, if necessary
1903 (Current_Item
, From_Project_Node_Tree
);
1905 -- In multi-language mode (gprbuild), the index is
1906 -- always case insensitive if it does not include
1909 if Get_Mode
= Multi_Language
and then not Lower
then
1910 for J
in 1 .. Name_Len
loop
1911 if Name_Buffer
(J
) = '.' then
1919 GNAT
.Case_Util
.To_Lower
1920 (Name_Buffer
(1 .. Name_Len
));
1925 The_Array
: Array_Id
;
1927 The_Array_Element
: Array_Element_Id
:=
1930 Index_Name
: constant Name_Id
:= Name_Find
;
1931 -- The name id of the index
1934 -- Look for the array in the appropriate list
1936 if Pkg
/= No_Package
then
1938 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
;
1942 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
;
1946 The_Array
/= No_Array
1948 In_Tree
.Arrays
.Table
(The_Array
).Name
/=
1951 The_Array
:= In_Tree
.Arrays
.Table
1955 -- If the array cannot be found, create a new entry
1956 -- in the list. As The_Array_Element is initialized
1957 -- to No_Array_Element, a new element will be
1958 -- created automatically later
1960 if The_Array
= No_Array
then
1961 Array_Table
.Increment_Last
(In_Tree
.Arrays
);
1962 The_Array
:= Array_Table
.Last
(In_Tree
.Arrays
);
1964 if Pkg
/= No_Package
then
1965 In_Tree
.Arrays
.Table
(The_Array
) :=
1966 (Name
=> Current_Item_Name
,
1967 Value
=> No_Array_Element
,
1969 In_Tree
.Packages
.Table
1972 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
:=
1976 In_Tree
.Arrays
.Table
(The_Array
) :=
1977 (Name
=> Current_Item_Name
,
1978 Value
=> No_Array_Element
,
1980 In_Tree
.Projects
.Table
1981 (Project
).Decl
.Arrays
);
1983 In_Tree
.Projects
.Table
1984 (Project
).Decl
.Arrays
:= The_Array
;
1987 -- Otherwise initialize The_Array_Element as the
1988 -- head of the element list.
1991 The_Array_Element
:=
1992 In_Tree
.Arrays
.Table
(The_Array
).Value
;
1995 -- Look in the list, if any, to find an element
1996 -- with the same index.
1998 while The_Array_Element
/= No_Array_Element
2000 In_Tree
.Array_Elements
.Table
2001 (The_Array_Element
).Index
/= Index_Name
2003 The_Array_Element
:=
2004 In_Tree
.Array_Elements
.Table
2005 (The_Array_Element
).Next
;
2008 -- If no such element were found, create a new one
2009 -- and insert it in the element list, with the
2012 if The_Array_Element
= No_Array_Element
then
2013 Array_Element_Table
.Increment_Last
2014 (In_Tree
.Array_Elements
);
2015 The_Array_Element
:= Array_Element_Table
.Last
2016 (In_Tree
.Array_Elements
);
2018 In_Tree
.Array_Elements
.Table
2019 (The_Array_Element
) :=
2020 (Index
=> Index_Name
,
2023 (Current_Item
, From_Project_Node_Tree
),
2024 Index_Case_Sensitive
=>
2025 not Case_Insensitive
2026 (Current_Item
, From_Project_Node_Tree
),
2028 Next
=> In_Tree
.Arrays
.Table
2030 In_Tree
.Arrays
.Table
2031 (The_Array
).Value
:= The_Array_Element
;
2033 -- An element with the same index already exists,
2034 -- just replace its value with the new one.
2037 In_Tree
.Array_Elements
.Table
2038 (The_Array_Element
).Value
:= New_Value
;
2045 when N_Case_Construction
=>
2047 The_Project
: Project_Id
:= Project
;
2048 -- The id of the project of the case variable
2050 The_Package
: Package_Id
:= Pkg
;
2051 -- The id of the package, if any, of the case variable
2053 The_Variable
: Variable_Value
:= Nil_Variable_Value
;
2054 -- The case variable
2056 Case_Value
: Name_Id
:= No_Name
;
2057 -- The case variable value
2059 Case_Item
: Project_Node_Id
:= Empty_Node
;
2060 Choice_String
: Project_Node_Id
:= Empty_Node
;
2061 Decl_Item
: Project_Node_Id
:= Empty_Node
;
2065 Variable_Node
: constant Project_Node_Id
:=
2066 Case_Variable_Reference_Of
2068 From_Project_Node_Tree
);
2070 Var_Id
: Variable_Id
:= No_Variable
;
2071 Name
: Name_Id
:= No_Name
;
2074 -- If a project was specified for the case variable,
2078 (Variable_Node
, From_Project_Node_Tree
) /= Empty_Node
2083 (Variable_Node
, From_Project_Node_Tree
),
2084 From_Project_Node_Tree
);
2086 Imported_Or_Extended_Project_From
2087 (Project
, In_Tree
, Name
);
2090 -- If a package were specified for the case variable,
2094 (Variable_Node
, From_Project_Node_Tree
) /= Empty_Node
2099 (Variable_Node
, From_Project_Node_Tree
),
2100 From_Project_Node_Tree
);
2102 Package_From
(The_Project
, In_Tree
, Name
);
2105 Name
:= Name_Of
(Variable_Node
, From_Project_Node_Tree
);
2107 -- First, look for the case variable into the package,
2110 if The_Package
/= No_Package
then
2111 Var_Id
:= In_Tree
.Packages
.Table
2112 (The_Package
).Decl
.Variables
;
2114 Name_Of
(Variable_Node
, From_Project_Node_Tree
);
2115 while Var_Id
/= No_Variable
2117 In_Tree
.Variable_Elements
.Table
2118 (Var_Id
).Name
/= Name
2120 Var_Id
:= In_Tree
.Variable_Elements
.
2121 Table
(Var_Id
).Next
;
2125 -- If not found in the package, or if there is no
2126 -- package, look at the project level.
2128 if Var_Id
= No_Variable
2131 (Variable_Node
, From_Project_Node_Tree
) = Empty_Node
2133 Var_Id
:= In_Tree
.Projects
.Table
2134 (The_Project
).Decl
.Variables
;
2135 while Var_Id
/= No_Variable
2137 In_Tree
.Variable_Elements
.Table
2138 (Var_Id
).Name
/= Name
2140 Var_Id
:= In_Tree
.Variable_Elements
.
2141 Table
(Var_Id
).Next
;
2145 if Var_Id
= No_Variable
then
2147 -- Should never happen, because this has already been
2148 -- checked during parsing.
2150 Write_Line
("variable """ &
2151 Get_Name_String
(Name
) &
2153 raise Program_Error
;
2156 -- Get the case variable
2158 The_Variable
:= In_Tree
.Variable_Elements
.
2159 Table
(Var_Id
).Value
;
2161 if The_Variable
.Kind
/= Single
then
2163 -- Should never happen, because this has already been
2164 -- checked during parsing.
2166 Write_Line
("variable""" &
2167 Get_Name_String
(Name
) &
2168 """ is not a single string variable");
2169 raise Program_Error
;
2172 -- Get the case variable value
2173 Case_Value
:= The_Variable
.Value
;
2176 -- Now look into all the case items of the case construction
2179 First_Case_Item_Of
(Current_Item
, From_Project_Node_Tree
);
2181 while Case_Item
/= Empty_Node
loop
2183 First_Choice_Of
(Case_Item
, From_Project_Node_Tree
);
2185 -- When Choice_String is nil, it means that it is
2186 -- the "when others =>" alternative.
2188 if Choice_String
= Empty_Node
then
2190 First_Declarative_Item_Of
2191 (Case_Item
, From_Project_Node_Tree
);
2192 exit Case_Item_Loop
;
2195 -- Look into all the alternative of this case item
2198 while Choice_String
/= Empty_Node
loop
2201 (Choice_String
, From_Project_Node_Tree
)
2204 First_Declarative_Item_Of
2205 (Case_Item
, From_Project_Node_Tree
);
2206 exit Case_Item_Loop
;
2211 (Choice_String
, From_Project_Node_Tree
);
2212 end loop Choice_Loop
;
2215 Next_Case_Item
(Case_Item
, From_Project_Node_Tree
);
2216 end loop Case_Item_Loop
;
2218 -- If there is an alternative, then we process it
2220 if Decl_Item
/= Empty_Node
then
2221 Process_Declarative_Items
2222 (Project
=> Project
,
2224 From_Project_Node
=> From_Project_Node
,
2225 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2233 -- Should never happen
2235 Write_Line
("Illegal declarative item: " &
2236 Project_Node_Kind
'Image
2238 (Current_Item
, From_Project_Node_Tree
)));
2239 raise Program_Error
;
2242 end Process_Declarative_Items
;
2244 ----------------------------------
2245 -- Process_Project_Tree_Phase_1 --
2246 ----------------------------------
2248 procedure Process_Project_Tree_Phase_1
2249 (In_Tree
: Project_Tree_Ref
;
2250 Project
: out Project_Id
;
2251 Success
: out Boolean;
2252 From_Project_Node
: Project_Node_Id
;
2253 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
2254 Report_Error
: Put_Line_Access
;
2255 Reset_Tree
: Boolean := True)
2258 Error_Report
:= Report_Error
;
2262 -- Make sure there are no projects in the data structure
2264 Project_Table
.Set_Last
(In_Tree
.Projects
, No_Project
);
2267 Processed_Projects
.Reset
;
2269 -- And process the main project and all of the projects it depends on,
2273 (Project
=> Project
,
2275 From_Project_Node
=> From_Project_Node
,
2276 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2277 Extended_By
=> No_Project
);
2280 Total_Errors_Detected
= 0
2282 (Warning_Mode
/= Treat_As_Error
or else Warnings_Detected
= 0);
2283 end Process_Project_Tree_Phase_1
;
2285 ----------------------------------
2286 -- Process_Project_Tree_Phase_2 --
2287 ----------------------------------
2289 procedure Process_Project_Tree_Phase_2
2290 (In_Tree
: Project_Tree_Ref
;
2291 Project
: Project_Id
;
2292 Success
: out Boolean;
2293 From_Project_Node
: Project_Node_Id
;
2294 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
2295 Report_Error
: Put_Line_Access
;
2296 When_No_Sources
: Error_Warning
:= Error
;
2297 Current_Dir
: String)
2299 Obj_Dir
: Path_Name_Type
;
2300 Extending
: Project_Id
;
2301 Extending2
: Project_Id
;
2303 -- Start of processing for Process_Project_Tree_Phase_2
2306 Error_Report
:= Report_Error
;
2309 if Project
/= No_Project
then
2310 Check
(In_Tree
, Project
, Current_Dir
, When_No_Sources
);
2313 -- If main project is an extending all project, set the object
2314 -- directory of all virtual extending projects to the object
2315 -- directory of the main project.
2317 if Project
/= No_Project
2319 Is_Extending_All
(From_Project_Node
, From_Project_Node_Tree
)
2322 Object_Dir
: constant Path_Name_Type
:=
2323 In_Tree
.Projects
.Table
2324 (Project
).Object_Directory
;
2327 Project_Table
.First
.. Project_Table
.Last
(In_Tree
.Projects
)
2329 if In_Tree
.Projects
.Table
(Index
).Virtual
then
2330 In_Tree
.Projects
.Table
(Index
).Object_Directory
:=
2337 -- Check that no extending project shares its object directory with
2338 -- the project(s) it extends.
2340 if Project
/= No_Project
then
2342 Project_Table
.First
.. Project_Table
.Last
(In_Tree
.Projects
)
2344 Extending
:= In_Tree
.Projects
.Table
(Proj
).Extended_By
;
2346 if Extending
/= No_Project
then
2347 Obj_Dir
:= In_Tree
.Projects
.Table
(Proj
).Object_Directory
;
2349 -- Check that a project being extended does not share its
2350 -- object directory with any project that extends it, directly
2351 -- or indirectly, including a virtual extending project.
2353 -- Start with the project directly extending it
2355 Extending2
:= Extending
;
2356 while Extending2
/= No_Project
loop
2357 if In_Tree
.Projects
.Table
(Extending2
).Ada_Sources
/=
2360 In_Tree
.Projects
.Table
(Extending2
).Object_Directory
=
2363 if In_Tree
.Projects
.Table
(Extending2
).Virtual
then
2365 In_Tree
.Projects
.Table
(Proj
).Display_Name
;
2367 if Error_Report
= null then
2369 ("project %% cannot be extended by a virtual" &
2370 " project with the same object directory",
2371 In_Tree
.Projects
.Table
(Proj
).Location
);
2375 Get_Name_String
(Error_Msg_Name_1
) &
2376 """ cannot be extended by a virtual " &
2377 "project with the same object directory",
2383 In_Tree
.Projects
.Table
(Extending2
).Display_Name
;
2385 In_Tree
.Projects
.Table
(Proj
).Display_Name
;
2387 if Error_Report
= null then
2389 ("project %% cannot extend project %%",
2390 In_Tree
.Projects
.Table
(Extending2
).Location
);
2392 ("\they share the same object directory",
2393 In_Tree
.Projects
.Table
(Extending2
).Location
);
2398 Get_Name_String
(Error_Msg_Name_1
) &
2399 """ cannot extend project """ &
2400 Get_Name_String
(Error_Msg_Name_2
) & """",
2403 ("they share the same object directory",
2409 -- Continue with the next extending project, if any
2412 In_Tree
.Projects
.Table
(Extending2
).Extended_By
;
2419 Total_Errors_Detected
= 0
2421 (Warning_Mode
/= Treat_As_Error
or else Warnings_Detected
= 0);
2422 end Process_Project_Tree_Phase_2
;
2424 ---------------------
2425 -- Recursive_Check --
2426 ---------------------
2428 procedure Recursive_Check
2429 (Project
: Project_Id
;
2430 In_Tree
: Project_Tree_Ref
;
2431 Current_Dir
: String;
2432 When_No_Sources
: Error_Warning
)
2434 Data
: Project_Data
;
2435 Imported_Project_List
: Project_List
:= Empty_Project_List
;
2438 -- Do nothing if Project is No_Project, or Project has already
2439 -- been marked as checked.
2441 if Project
/= No_Project
2442 and then not In_Tree
.Projects
.Table
(Project
).Checked
2444 -- Mark project as checked, to avoid infinite recursion in
2445 -- ill-formed trees, where a project imports itself.
2447 In_Tree
.Projects
.Table
(Project
).Checked
:= True;
2449 Data
:= In_Tree
.Projects
.Table
(Project
);
2451 -- Call itself for a possible extended project.
2452 -- (if there is no extended project, then nothing happens).
2454 Recursive_Check
(Data
.Extends
, In_Tree
, Current_Dir
, When_No_Sources
);
2456 -- Call itself for all imported projects
2458 Imported_Project_List
:= Data
.Imported_Projects
;
2459 while Imported_Project_List
/= Empty_Project_List
loop
2461 (In_Tree
.Project_Lists
.Table
2462 (Imported_Project_List
).Project
,
2463 In_Tree
, Current_Dir
, When_No_Sources
);
2464 Imported_Project_List
:=
2465 In_Tree
.Project_Lists
.Table
2466 (Imported_Project_List
).Next
;
2469 if Verbose_Mode
then
2470 Write_Str
("Checking project file """);
2471 Write_Str
(Get_Name_String
(Data
.Name
));
2476 (Project
, In_Tree
, Error_Report
, When_No_Sources
,
2479 end Recursive_Check
;
2481 -----------------------
2482 -- Recursive_Process --
2483 -----------------------
2485 procedure Recursive_Process
2486 (In_Tree
: Project_Tree_Ref
;
2487 Project
: out Project_Id
;
2488 From_Project_Node
: Project_Node_Id
;
2489 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
2490 Extended_By
: Project_Id
)
2492 With_Clause
: Project_Node_Id
;
2495 if From_Project_Node
= Empty_Node
then
2496 Project
:= No_Project
;
2500 Processed_Data
: Project_Data
:= Empty_Project
(In_Tree
);
2501 Imported
: Project_List
:= Empty_Project_List
;
2502 Declaration_Node
: Project_Node_Id
:= Empty_Node
;
2503 Tref
: Source_Buffer_Ptr
;
2504 Name
: constant Name_Id
:=
2506 (From_Project_Node
, From_Project_Node_Tree
);
2507 Location
: Source_Ptr
:=
2509 (From_Project_Node
, From_Project_Node_Tree
);
2512 Project
:= Processed_Projects
.Get
(Name
);
2514 if Project
/= No_Project
then
2516 -- Make sure that, when a project is extended, the project id
2517 -- of the project extending it is recorded in its data, even
2518 -- when it has already been processed as an imported project.
2519 -- This is for virtually extended projects.
2521 if Extended_By
/= No_Project
then
2522 In_Tree
.Projects
.Table
(Project
).Extended_By
:= Extended_By
;
2528 Project_Table
.Increment_Last
(In_Tree
.Projects
);
2529 Project
:= Project_Table
.Last
(In_Tree
.Projects
);
2530 Processed_Projects
.Set
(Name
, Project
);
2532 Processed_Data
.Name
:= Name
;
2534 Get_Name_String
(Name
);
2536 -- If name starts with the virtual prefix, flag the project as
2537 -- being a virtual extending project.
2539 if Name_Len
> Virtual_Prefix
'Length
2540 and then Name_Buffer
(1 .. Virtual_Prefix
'Length) =
2543 Processed_Data
.Virtual
:= True;
2544 Processed_Data
.Display_Name
:= Name
;
2546 -- If there is no file, for example when the project node tree is
2547 -- built in memory by GPS, the Display_Name cannot be found in
2548 -- the source, so its value is the same as Name.
2550 elsif Location
= No_Location
then
2551 Processed_Data
.Display_Name
:= Name
;
2553 -- Get the spelling of the project name from the project file
2556 Tref
:= Source_Text
(Get_Source_File_Index
(Location
));
2558 for J
in 1 .. Name_Len
loop
2559 Name_Buffer
(J
) := Tref
(Location
);
2560 Location
:= Location
+ 1;
2563 Processed_Data
.Display_Name
:= Name_Find
;
2566 Processed_Data
.Display_Path_Name
:=
2567 Path_Name_Of
(From_Project_Node
, From_Project_Node_Tree
);
2568 Get_Name_String
(Processed_Data
.Display_Path_Name
);
2569 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
2570 Processed_Data
.Path_Name
:= Name_Find
;
2572 Processed_Data
.Location
:=
2573 Location_Of
(From_Project_Node
, From_Project_Node_Tree
);
2575 Processed_Data
.Display_Directory
:=
2576 Directory_Of
(From_Project_Node
, From_Project_Node_Tree
);
2577 Get_Name_String
(Processed_Data
.Display_Directory
);
2578 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
2579 Processed_Data
.Directory
:= Name_Find
;
2581 Processed_Data
.Extended_By
:= Extended_By
;
2587 Processed_Data
.Decl
,
2588 Prj
.Attr
.Attribute_First
,
2589 Project_Level
=> True);
2592 First_With_Clause_Of
(From_Project_Node
, From_Project_Node_Tree
);
2593 while With_Clause
/= Empty_Node
loop
2595 New_Project
: Project_Id
;
2596 New_Data
: Project_Data
;
2600 (In_Tree
=> In_Tree
,
2601 Project
=> New_Project
,
2602 From_Project_Node
=>
2603 Project_Node_Of
(With_Clause
, From_Project_Node_Tree
),
2604 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2605 Extended_By
=> No_Project
);
2607 In_Tree
.Projects
.Table
(New_Project
);
2609 -- If we were the first project to import it,
2610 -- set First_Referred_By to us.
2612 if New_Data
.First_Referred_By
= No_Project
then
2613 New_Data
.First_Referred_By
:= Project
;
2614 In_Tree
.Projects
.Table
(New_Project
) :=
2618 -- Add this project to our list of imported projects
2620 Project_List_Table
.Increment_Last
2621 (In_Tree
.Project_Lists
);
2622 In_Tree
.Project_Lists
.Table
2623 (Project_List_Table
.Last
2624 (In_Tree
.Project_Lists
)) :=
2625 (Project
=> New_Project
, Next
=> Empty_Project_List
);
2627 -- Imported is the id of the last imported project.
2628 -- If it is nil, then this imported project is our first.
2630 if Imported
= Empty_Project_List
then
2631 Processed_Data
.Imported_Projects
:=
2632 Project_List_Table
.Last
2633 (In_Tree
.Project_Lists
);
2636 In_Tree
.Project_Lists
.Table
2637 (Imported
).Next
:= Project_List_Table
.Last
2638 (In_Tree
.Project_Lists
);
2641 Imported
:= Project_List_Table
.Last
2642 (In_Tree
.Project_Lists
);
2645 Next_With_Clause_Of
(With_Clause
, From_Project_Node_Tree
);
2650 Project_Declaration_Of
2651 (From_Project_Node
, From_Project_Node_Tree
);
2654 (In_Tree
=> In_Tree
,
2655 Project
=> Processed_Data
.Extends
,
2656 From_Project_Node
=> Extended_Project_Of
2658 From_Project_Node_Tree
),
2659 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2660 Extended_By
=> Project
);
2662 In_Tree
.Projects
.Table
(Project
) := Processed_Data
;
2664 Process_Declarative_Items
2665 (Project
=> Project
,
2667 From_Project_Node
=> From_Project_Node
,
2668 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2670 Item
=> First_Declarative_Item_Of
2672 From_Project_Node_Tree
));
2674 -- If it is an extending project, inherit all packages
2675 -- from the extended project that are not explicitely defined
2676 -- or renamed. Also inherit the languages, if attribute Languages
2677 -- is not explicitely defined.
2679 if Processed_Data
.Extends
/= No_Project
then
2680 Processed_Data
:= In_Tree
.Projects
.Table
(Project
);
2683 Extended_Pkg
: Package_Id
;
2684 Current_Pkg
: Package_Id
;
2685 Element
: Package_Element
;
2686 First
: constant Package_Id
:=
2687 Processed_Data
.Decl
.Packages
;
2688 Attribute1
: Variable_Id
;
2689 Attribute2
: Variable_Id
;
2690 Attr_Value1
: Variable
;
2691 Attr_Value2
: Variable
;
2695 In_Tree
.Projects
.Table
2696 (Processed_Data
.Extends
).Decl
.Packages
;
2697 while Extended_Pkg
/= No_Package
loop
2699 In_Tree
.Packages
.Table
(Extended_Pkg
);
2701 Current_Pkg
:= First
;
2702 while Current_Pkg
/= No_Package
2703 and then In_Tree
.Packages
.Table
(Current_Pkg
).Name
/=
2707 In_Tree
.Packages
.Table
(Current_Pkg
).Next
;
2710 if Current_Pkg
= No_Package
then
2711 Package_Table
.Increment_Last
2713 Current_Pkg
:= Package_Table
.Last
(In_Tree
.Packages
);
2714 In_Tree
.Packages
.Table
(Current_Pkg
) :=
2715 (Name
=> Element
.Name
,
2716 Decl
=> No_Declarations
,
2717 Parent
=> No_Package
,
2718 Next
=> Processed_Data
.Decl
.Packages
);
2719 Processed_Data
.Decl
.Packages
:= Current_Pkg
;
2720 Copy_Package_Declarations
2721 (From
=> Element
.Decl
,
2722 To
=> In_Tree
.Packages
.Table
(Current_Pkg
).Decl
,
2723 New_Loc
=> No_Location
,
2724 In_Tree
=> In_Tree
);
2727 Extended_Pkg
:= Element
.Next
;
2730 -- Check if attribute Languages is declared in the
2731 -- extending project.
2733 Attribute1
:= Processed_Data
.Decl
.Attributes
;
2734 while Attribute1
/= No_Variable
loop
2735 Attr_Value1
:= In_Tree
.Variable_Elements
.
2737 exit when Attr_Value1
.Name
= Snames
.Name_Languages
;
2738 Attribute1
:= Attr_Value1
.Next
;
2741 if Attribute1
= No_Variable
or else
2742 Attr_Value1
.Value
.Default
2744 -- Attribute Languages is not declared in the extending
2745 -- project. Check if it is declared in the project being
2749 In_Tree
.Projects
.Table
2750 (Processed_Data
.Extends
).Decl
.Attributes
;
2751 while Attribute2
/= No_Variable
loop
2752 Attr_Value2
:= In_Tree
.Variable_Elements
.
2754 exit when Attr_Value2
.Name
= Snames
.Name_Languages
;
2755 Attribute2
:= Attr_Value2
.Next
;
2758 if Attribute2
/= No_Variable
and then
2759 not Attr_Value2
.Value
.Default
2761 -- As attribute Languages is declared in the project
2762 -- being extended, copy its value for the extending
2765 if Attribute1
= No_Variable
then
2766 Variable_Element_Table
.Increment_Last
2767 (In_Tree
.Variable_Elements
);
2768 Attribute1
:= Variable_Element_Table
.Last
2769 (In_Tree
.Variable_Elements
);
2770 Attr_Value1
.Next
:= Processed_Data
.Decl
.Attributes
;
2771 Processed_Data
.Decl
.Attributes
:= Attribute1
;
2774 Attr_Value1
.Name
:= Snames
.Name_Languages
;
2775 Attr_Value1
.Value
:= Attr_Value2
.Value
;
2776 In_Tree
.Variable_Elements
.Table
2777 (Attribute1
) := Attr_Value1
;
2782 In_Tree
.Projects
.Table
(Project
) := Processed_Data
;
2786 end Recursive_Process
;