1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2007, 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
;
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 procedure Add
(To_Exp
: in out Name_Id
; Str
: Name_Id
);
55 -- Concatenate two strings and returns another string if both
56 -- arguments are not null string.
58 procedure Add_Attributes
59 (Project
: Project_Id
;
60 In_Tree
: Project_Tree_Ref
;
61 Decl
: in out Declarations
;
62 First
: Attribute_Node_Id
);
63 -- Add all attributes, starting with First, with their default
64 -- values to the package or project with declarations Decl.
67 (In_Tree
: Project_Tree_Ref
;
68 Project
: in out Project_Id
;
69 Follow_Links
: Boolean;
70 When_No_Sources
: Error_Warning
);
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.
74 procedure Copy_Package_Declarations
76 To
: in out Declarations
;
78 In_Tree
: Project_Tree_Ref
);
79 -- Copy a package declaration From to To for a renamed package. Change the
80 -- locations of all the attributes to New_Loc.
83 (Project
: Project_Id
;
84 In_Tree
: Project_Tree_Ref
;
85 From_Project_Node
: Project_Node_Id
;
86 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
88 First_Term
: Project_Node_Id
;
89 Kind
: Variable_Kind
) return Variable_Value
;
90 -- From N_Expression project node From_Project_Node, compute the value
91 -- of an expression and return it as a Variable_Value.
93 function Imported_Or_Extended_Project_From
94 (Project
: Project_Id
;
95 In_Tree
: Project_Tree_Ref
;
96 With_Name
: Name_Id
) return Project_Id
;
97 -- Find an imported or extended project of Project whose name is With_Name
100 (Project
: Project_Id
;
101 In_Tree
: Project_Tree_Ref
;
102 With_Name
: Name_Id
) return Package_Id
;
103 -- Find the package of Project whose name is With_Name
105 procedure Process_Declarative_Items
106 (Project
: Project_Id
;
107 In_Tree
: Project_Tree_Ref
;
108 From_Project_Node
: Project_Node_Id
;
109 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
111 Item
: Project_Node_Id
);
112 -- Process declarative items starting with From_Project_Node, and put them
113 -- in declarations Decl. This is a recursive procedure; it calls itself for
114 -- a package declaration or a case construction.
116 procedure Recursive_Process
117 (In_Tree
: Project_Tree_Ref
;
118 Project
: out Project_Id
;
119 From_Project_Node
: Project_Node_Id
;
120 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
121 Extended_By
: Project_Id
);
122 -- Process project with node From_Project_Node in the tree.
123 -- Do nothing if From_Project_Node is Empty_Node.
124 -- If project has already been processed, simply return its project id.
125 -- Otherwise create a new project id, mark it as processed, call itself
126 -- recursively for all imported projects and a extended project, if any.
127 -- Then process the declarative items of the project.
129 procedure Recursive_Check
130 (Project
: Project_Id
;
131 In_Tree
: Project_Tree_Ref
;
132 Follow_Links
: Boolean;
133 When_No_Sources
: Error_Warning
);
134 -- If Project is not marked as checked, mark it as checked, call
135 -- Check_Naming_Scheme for the project, then call itself for a
136 -- possible extended project and all the imported projects of Project.
142 procedure Add
(To_Exp
: in out Name_Id
; Str
: Name_Id
) is
144 if To_Exp
= No_Name
or else To_Exp
= Empty_String
then
146 -- To_Exp is nil or empty. The result is Str
150 -- If Str is nil, then do not change To_Ext
152 elsif Str
/= No_Name
and then Str
/= Empty_String
then
154 S
: constant String := Get_Name_String
(Str
);
157 Get_Name_String
(To_Exp
);
158 Add_Str_To_Name_Buffer
(S
);
168 procedure Add_Attributes
169 (Project
: Project_Id
;
170 In_Tree
: Project_Tree_Ref
;
171 Decl
: in out Declarations
;
172 First
: Attribute_Node_Id
)
174 The_Attribute
: Attribute_Node_Id
:= First
;
177 while The_Attribute
/= Empty_Attribute
loop
178 if Attribute_Kind_Of
(The_Attribute
) = Single
then
180 New_Attribute
: Variable_Value
;
183 case Variable_Kind_Of
(The_Attribute
) is
185 -- Undefined should not happen
189 (False, "attribute with an undefined kind");
192 -- Single attributes have a default value of empty string
198 Location
=> No_Location
,
200 Value
=> Empty_String
,
203 -- List attributes have a default value of nil list
209 Location
=> No_Location
,
211 Values
=> Nil_String
);
215 Variable_Element_Table
.Increment_Last
216 (In_Tree
.Variable_Elements
);
217 In_Tree
.Variable_Elements
.Table
218 (Variable_Element_Table
.Last
219 (In_Tree
.Variable_Elements
)) :=
220 (Next
=> Decl
.Attributes
,
221 Name
=> Attribute_Name_Of
(The_Attribute
),
222 Value
=> New_Attribute
);
223 Decl
.Attributes
:= Variable_Element_Table
.Last
224 (In_Tree
.Variable_Elements
);
228 The_Attribute
:= Next_Attribute
(After
=> The_Attribute
);
237 (In_Tree
: Project_Tree_Ref
;
238 Project
: in out Project_Id
;
239 Follow_Links
: Boolean;
240 When_No_Sources
: Error_Warning
)
243 -- Make sure that all projects are marked as not checked
245 for Index
in Project_Table
.First
..
246 Project_Table
.Last
(In_Tree
.Projects
)
248 In_Tree
.Projects
.Table
(Index
).Checked
:= False;
251 Recursive_Check
(Project
, In_Tree
, Follow_Links
, When_No_Sources
);
254 -------------------------------
255 -- Copy_Package_Declarations --
256 -------------------------------
258 procedure Copy_Package_Declarations
259 (From
: Declarations
;
260 To
: in out Declarations
;
261 New_Loc
: Source_Ptr
;
262 In_Tree
: Project_Tree_Ref
)
264 V1
: Variable_Id
:= From
.Attributes
;
265 V2
: Variable_Id
:= No_Variable
;
267 A1
: Array_Id
:= From
.Arrays
;
268 A2
: Array_Id
:= No_Array
;
270 E1
: Array_Element_Id
;
271 E2
: Array_Element_Id
:= No_Array_Element
;
275 -- To avoid references in error messages to attribute declarations in
276 -- an original package that has been renamed, copy all the attribute
277 -- declarations of the package and change all locations to New_Loc,
278 -- the location of the renamed package.
280 -- First single attributes
282 while V1
/= No_Variable
loop
284 -- Copy the attribute
286 Var
:= In_Tree
.Variable_Elements
.Table
(V1
);
289 -- Remove the Next component
291 Var
.Next
:= No_Variable
;
293 -- Change the location to New_Loc
295 Var
.Value
.Location
:= New_Loc
;
296 Variable_Element_Table
.Increment_Last
(In_Tree
.Variable_Elements
);
298 -- Put in new declaration
300 if To
.Attributes
= No_Variable
then
302 Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
305 In_Tree
.Variable_Elements
.Table
(V2
).Next
:=
306 Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
309 V2
:= Variable_Element_Table
.Last
(In_Tree
.Variable_Elements
);
310 In_Tree
.Variable_Elements
.Table
(V2
) := Var
;
313 -- Then the associated array attributes
315 while A1
/= No_Array
loop
319 Arr
:= In_Tree
.Arrays
.Table
(A1
);
322 -- Remove the Next component
324 Arr
.Next
:= No_Array
;
326 Array_Table
.Increment_Last
(In_Tree
.Arrays
);
328 -- Create new Array declaration
329 if To
.Arrays
= No_Array
then
330 To
.Arrays
:= Array_Table
.Last
(In_Tree
.Arrays
);
333 In_Tree
.Arrays
.Table
(A2
).Next
:=
334 Array_Table
.Last
(In_Tree
.Arrays
);
337 A2
:= Array_Table
.Last
(In_Tree
.Arrays
);
339 -- Don't store the array, as its first element has not been set yet
341 -- Copy the array elements of the array
344 Arr
.Value
:= No_Array_Element
;
346 while E1
/= No_Array_Element
loop
348 -- Copy the array element
350 Elm
:= In_Tree
.Array_Elements
.Table
(E1
);
353 -- Remove the Next component
355 Elm
.Next
:= No_Array_Element
;
357 -- Change the location
359 Elm
.Value
.Location
:= New_Loc
;
360 Array_Element_Table
.Increment_Last
(In_Tree
.Array_Elements
);
362 -- Create new array element
364 if Arr
.Value
= No_Array_Element
then
365 Arr
.Value
:= Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
367 In_Tree
.Array_Elements
.Table
(E2
).Next
:=
368 Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
371 E2
:= Array_Element_Table
.Last
(In_Tree
.Array_Elements
);
372 In_Tree
.Array_Elements
.Table
(E2
) := Elm
;
375 -- Finally, store the new array
377 In_Tree
.Arrays
.Table
(A2
) := Arr
;
379 end Copy_Package_Declarations
;
386 (Project
: Project_Id
;
387 In_Tree
: Project_Tree_Ref
;
388 From_Project_Node
: Project_Node_Id
;
389 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
391 First_Term
: Project_Node_Id
;
392 Kind
: Variable_Kind
) return Variable_Value
394 The_Term
: Project_Node_Id
:= First_Term
;
395 -- The term in the expression list
397 The_Current_Term
: Project_Node_Id
:= Empty_Node
;
398 -- The current term node id
400 Result
: Variable_Value
(Kind
=> Kind
);
401 -- The returned result
403 Last
: String_List_Id
:= Nil_String
;
404 -- Reference to the last string elements in Result, when Kind is List
407 Result
.Project
:= Project
;
408 Result
.Location
:= Location_Of
(First_Term
, From_Project_Node_Tree
);
410 -- Process each term of the expression, starting with First_Term
412 while The_Term
/= Empty_Node
loop
413 The_Current_Term
:= Current_Term
(The_Term
, From_Project_Node_Tree
);
415 case Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) is
417 when N_Literal_String
=>
423 -- Should never happen
425 pragma Assert
(False, "Undefined expression kind");
431 (The_Current_Term
, From_Project_Node_Tree
));
434 (The_Current_Term
, From_Project_Node_Tree
);
438 String_Element_Table
.Increment_Last
439 (In_Tree
.String_Elements
);
441 if Last
= Nil_String
then
443 -- This can happen in an expression like () & "toto"
445 Result
.Values
:= String_Element_Table
.Last
446 (In_Tree
.String_Elements
);
449 In_Tree
.String_Elements
.Table
450 (Last
).Next
:= String_Element_Table
.Last
451 (In_Tree
.String_Elements
);
454 Last
:= String_Element_Table
.Last
455 (In_Tree
.String_Elements
);
456 In_Tree
.String_Elements
.Table
(Last
) :=
460 From_Project_Node_Tree
),
463 (The_Current_Term
, From_Project_Node_Tree
),
464 Display_Value
=> No_Name
,
468 From_Project_Node_Tree
),
473 when N_Literal_String_List
=>
476 String_Node
: Project_Node_Id
:=
477 First_Expression_In_List
479 From_Project_Node_Tree
);
481 Value
: Variable_Value
;
484 if String_Node
/= Empty_Node
then
486 -- If String_Node is nil, it is an empty list,
487 -- there is nothing to do
492 From_Project_Node
=> From_Project_Node
,
493 From_Project_Node_Tree
=> From_Project_Node_Tree
,
497 (String_Node
, From_Project_Node_Tree
),
499 String_Element_Table
.Increment_Last
500 (In_Tree
.String_Elements
);
502 if Result
.Values
= Nil_String
then
504 -- This literal string list is the first term
505 -- in a string list expression
508 String_Element_Table
.Last
(In_Tree
.String_Elements
);
511 In_Tree
.String_Elements
.Table
513 String_Element_Table
.Last
(In_Tree
.String_Elements
);
517 String_Element_Table
.Last
(In_Tree
.String_Elements
);
519 In_Tree
.String_Elements
.Table
(Last
) :=
520 (Value
=> Value
.Value
,
521 Display_Value
=> No_Name
,
522 Location
=> Value
.Location
,
525 Index
=> Value
.Index
);
528 -- Add the other element of the literal string list
529 -- one after the other
532 Next_Expression_In_List
533 (String_Node
, From_Project_Node_Tree
);
535 exit when String_Node
= Empty_Node
;
541 From_Project_Node
=> From_Project_Node
,
542 From_Project_Node_Tree
=> From_Project_Node_Tree
,
546 (String_Node
, From_Project_Node_Tree
),
549 String_Element_Table
.Increment_Last
550 (In_Tree
.String_Elements
);
551 In_Tree
.String_Elements
.Table
552 (Last
).Next
:= String_Element_Table
.Last
553 (In_Tree
.String_Elements
);
554 Last
:= String_Element_Table
.Last
555 (In_Tree
.String_Elements
);
556 In_Tree
.String_Elements
.Table
(Last
) :=
557 (Value
=> Value
.Value
,
558 Display_Value
=> No_Name
,
559 Location
=> Value
.Location
,
562 Index
=> Value
.Index
);
567 when N_Variable_Reference | N_Attribute_Reference
=>
570 The_Project
: Project_Id
:= Project
;
571 The_Package
: Package_Id
:= Pkg
;
572 The_Name
: Name_Id
:= No_Name
;
573 The_Variable_Id
: Variable_Id
:= No_Variable
;
574 The_Variable
: Variable_Value
;
575 Term_Project
: constant Project_Node_Id
:=
578 From_Project_Node_Tree
);
579 Term_Package
: constant Project_Node_Id
:=
582 From_Project_Node_Tree
);
583 Index
: Name_Id
:= No_Name
;
586 if Term_Project
/= Empty_Node
and then
587 Term_Project
/= From_Project_Node
589 -- This variable or attribute comes from another project
592 Name_Of
(Term_Project
, From_Project_Node_Tree
);
594 The_Project
:= Imported_Or_Extended_Project_From
597 With_Name
=> The_Name
);
600 if Term_Package
/= Empty_Node
then
602 -- This is an attribute of a package
605 Name_Of
(Term_Package
, From_Project_Node_Tree
);
607 The_Package
:= In_Tree
.Projects
.Table
608 (The_Project
).Decl
.Packages
;
610 while The_Package
/= No_Package
611 and then In_Tree
.Packages
.Table
612 (The_Package
).Name
/= The_Name
615 In_Tree
.Packages
.Table
620 (The_Package
/= No_Package
,
621 "package not found.");
623 elsif Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
624 N_Attribute_Reference
626 The_Package
:= No_Package
;
630 Name_Of
(The_Current_Term
, From_Project_Node_Tree
);
632 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
633 N_Attribute_Reference
636 Associative_Array_Index_Of
637 (The_Current_Term
, From_Project_Node_Tree
);
640 -- If it is not an associative array attribute
642 if Index
= No_Name
then
644 -- It is not an associative array attribute
646 if The_Package
/= No_Package
then
648 -- First, if there is a package, look into the package
650 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
654 In_Tree
.Packages
.Table
655 (The_Package
).Decl
.Variables
;
658 In_Tree
.Packages
.Table
659 (The_Package
).Decl
.Attributes
;
662 while The_Variable_Id
/= No_Variable
664 In_Tree
.Variable_Elements
.Table
665 (The_Variable_Id
).Name
/= The_Name
668 In_Tree
.Variable_Elements
.Table
669 (The_Variable_Id
).Next
;
674 if The_Variable_Id
= No_Variable
then
676 -- If we have not found it, look into the project
678 if Kind_Of
(The_Current_Term
, From_Project_Node_Tree
) =
682 In_Tree
.Projects
.Table
683 (The_Project
).Decl
.Variables
;
686 In_Tree
.Projects
.Table
687 (The_Project
).Decl
.Attributes
;
690 while The_Variable_Id
/= No_Variable
692 In_Tree
.Variable_Elements
.Table
693 (The_Variable_Id
).Name
/= The_Name
696 In_Tree
.Variable_Elements
.Table
697 (The_Variable_Id
).Next
;
702 pragma Assert
(The_Variable_Id
/= No_Variable
,
703 "variable or attribute not found");
706 In_Tree
.Variable_Elements
.Table
707 (The_Variable_Id
).Value
;
711 -- It is an associative array attribute
714 The_Array
: Array_Id
:= No_Array
;
715 The_Element
: Array_Element_Id
:= No_Array_Element
;
716 Array_Index
: Name_Id
:= No_Name
;
719 if The_Package
/= No_Package
then
721 In_Tree
.Packages
.Table
722 (The_Package
).Decl
.Arrays
;
725 In_Tree
.Projects
.Table
726 (The_Project
).Decl
.Arrays
;
729 while The_Array
/= No_Array
730 and then In_Tree
.Arrays
.Table
731 (The_Array
).Name
/= The_Name
733 The_Array
:= In_Tree
.Arrays
.Table
737 if The_Array
/= No_Array
then
738 The_Element
:= In_Tree
.Arrays
.Table
741 Get_Name_String
(Index
);
744 (The_Current_Term
, From_Project_Node_Tree
)
746 To_Lower
(Name_Buffer
(1 .. Name_Len
));
749 Array_Index
:= Name_Find
;
751 while The_Element
/= No_Array_Element
753 In_Tree
.Array_Elements
.Table
754 (The_Element
).Index
/= Array_Index
757 In_Tree
.Array_Elements
.Table
763 if The_Element
/= No_Array_Element
then
765 In_Tree
.Array_Elements
.Table
769 if Expression_Kind_Of
770 (The_Current_Term
, From_Project_Node_Tree
) =
776 Location
=> No_Location
,
778 Values
=> Nil_String
);
783 Location
=> No_Location
,
785 Value
=> Empty_String
,
796 -- Should never happen
798 pragma Assert
(False, "undefined expression kind");
803 case The_Variable
.Kind
is
809 Add
(Result
.Value
, The_Variable
.Value
);
813 -- Should never happen
817 "list cannot appear in single " &
818 "string expression");
823 case The_Variable
.Kind
is
829 String_Element_Table
.Increment_Last
830 (In_Tree
.String_Elements
);
832 if Last
= Nil_String
then
834 -- This can happen in an expression such as
838 String_Element_Table
.Last
839 (In_Tree
.String_Elements
);
842 In_Tree
.String_Elements
.Table
844 String_Element_Table
.Last
845 (In_Tree
.String_Elements
);
849 String_Element_Table
.Last
850 (In_Tree
.String_Elements
);
852 In_Tree
.String_Elements
.Table
(Last
) :=
853 (Value
=> The_Variable
.Value
,
854 Display_Value
=> No_Name
,
855 Location
=> Location_Of
857 From_Project_Node_Tree
),
865 The_List
: String_List_Id
:=
869 while The_List
/= Nil_String
loop
870 String_Element_Table
.Increment_Last
871 (In_Tree
.String_Elements
);
873 if Last
= Nil_String
then
875 String_Element_Table
.Last
881 String_Elements
.Table
(Last
).Next
:=
882 String_Element_Table
.Last
889 String_Element_Table
.Last
890 (In_Tree
.String_Elements
);
892 In_Tree
.String_Elements
.Table
(Last
) :=
894 In_Tree
.String_Elements
.Table
896 Display_Value
=> No_Name
,
900 From_Project_Node_Tree
),
906 In_Tree
. String_Elements
.Table
914 when N_External_Value
=>
917 (External_Reference_Of
918 (The_Current_Term
, From_Project_Node_Tree
),
919 From_Project_Node_Tree
));
922 Name
: constant Name_Id
:= Name_Find
;
923 Default
: Name_Id
:= No_Name
;
924 Value
: Name_Id
:= No_Name
;
926 Def_Var
: Variable_Value
;
928 Default_Node
: constant Project_Node_Id
:=
930 (The_Current_Term
, From_Project_Node_Tree
);
933 -- If there is a default value for the external reference,
936 if Default_Node
/= Empty_Node
then
937 Def_Var
:= Expression
940 From_Project_Node
=> Default_Node
,
941 From_Project_Node_Tree
=> From_Project_Node_Tree
,
945 (Default_Node
, From_Project_Node_Tree
),
948 if Def_Var
/= Nil_Variable_Value
then
949 Default
:= Def_Var
.Value
;
953 Value
:= Prj
.Ext
.Value_Of
(Name
, Default
);
955 if Value
= No_Name
then
956 if not Quiet_Output
then
957 if Error_Report
= null then
959 ("?undefined external reference",
961 (The_Current_Term
, From_Project_Node_Tree
));
964 ("warning: """ & Get_Name_String
(Name
) &
965 """ is an undefined external reference",
970 Value
:= Empty_String
;
979 Add
(Result
.Value
, Value
);
982 String_Element_Table
.Increment_Last
983 (In_Tree
.String_Elements
);
985 if Last
= Nil_String
then
986 Result
.Values
:= String_Element_Table
.Last
987 (In_Tree
.String_Elements
);
990 In_Tree
.String_Elements
.Table
991 (Last
).Next
:= String_Element_Table
.Last
992 (In_Tree
.String_Elements
);
995 Last
:= String_Element_Table
.Last
996 (In_Tree
.String_Elements
);
997 In_Tree
.String_Elements
.Table
(Last
) :=
999 Display_Value
=> No_Name
,
1002 (The_Current_Term
, From_Project_Node_Tree
),
1012 -- Should never happen
1016 "illegal node kind in an expression");
1017 raise Program_Error
;
1021 The_Term
:= Next_Term
(The_Term
, From_Project_Node_Tree
);
1027 ---------------------------------------
1028 -- Imported_Or_Extended_Project_From --
1029 ---------------------------------------
1031 function Imported_Or_Extended_Project_From
1032 (Project
: Project_Id
;
1033 In_Tree
: Project_Tree_Ref
;
1034 With_Name
: Name_Id
) return Project_Id
1036 Data
: constant Project_Data
:=
1037 In_Tree
.Projects
.Table
(Project
);
1038 List
: Project_List
:= Data
.Imported_Projects
;
1039 Result
: Project_Id
:= No_Project
;
1040 Temp_Result
: Project_Id
:= No_Project
;
1043 -- First check if it is the name of an extended project
1045 if Data
.Extends
/= No_Project
1046 and then In_Tree
.Projects
.Table
(Data
.Extends
).Name
=
1049 return Data
.Extends
;
1052 -- Then check the name of each imported project
1054 while List
/= Empty_Project_List
loop
1055 Result
:= In_Tree
.Project_Lists
.Table
(List
).Project
;
1057 -- If the project is directly imported, then returns its ID
1060 In_Tree
.Projects
.Table
(Result
).Name
= With_Name
1065 -- If a project extending the project is imported, then keep
1066 -- this extending project as a possibility. It will be the
1067 -- returned ID if the project is not imported directly.
1070 Proj
: Project_Id
:=
1071 In_Tree
.Projects
.Table
(Result
).Extends
;
1073 while Proj
/= No_Project
loop
1074 if In_Tree
.Projects
.Table
(Proj
).Name
=
1077 Temp_Result
:= Result
;
1081 Proj
:= In_Tree
.Projects
.Table
(Proj
).Extends
;
1085 List
:= In_Tree
.Project_Lists
.Table
(List
).Next
;
1089 (Temp_Result
/= No_Project
,
1090 "project not found");
1094 end Imported_Or_Extended_Project_From
;
1100 function Package_From
1101 (Project
: Project_Id
;
1102 In_Tree
: Project_Tree_Ref
;
1103 With_Name
: Name_Id
) return Package_Id
1105 Data
: constant Project_Data
:=
1106 In_Tree
.Projects
.Table
(Project
);
1107 Result
: Package_Id
:= Data
.Decl
.Packages
;
1110 -- Check the name of each existing package of Project
1112 while Result
/= No_Package
1113 and then In_Tree
.Packages
.Table
(Result
).Name
/= With_Name
1115 Result
:= In_Tree
.Packages
.Table
(Result
).Next
;
1118 if Result
= No_Package
then
1120 -- Should never happen
1122 Write_Line
("package """ & Get_Name_String
(With_Name
) &
1124 raise Program_Error
;
1136 (In_Tree
: Project_Tree_Ref
;
1137 Project
: out Project_Id
;
1138 Success
: out Boolean;
1139 From_Project_Node
: Project_Node_Id
;
1140 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
1141 Report_Error
: Put_Line_Access
;
1142 Follow_Links
: Boolean := True;
1143 When_No_Sources
: Error_Warning
:= Error
)
1145 Obj_Dir
: Path_Name_Type
;
1146 Extending
: Project_Id
;
1147 Extending2
: Project_Id
;
1150 Error_Report
:= Report_Error
;
1153 -- Make sure there is no projects in the data structure
1155 Project_Table
.Set_Last
(In_Tree
.Projects
, No_Project
);
1156 Processed_Projects
.Reset
;
1158 -- And process the main project and all of the projects it depends on,
1162 (Project
=> Project
,
1164 From_Project_Node
=> From_Project_Node
,
1165 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1166 Extended_By
=> No_Project
);
1168 if Project
/= No_Project
then
1169 Check
(In_Tree
, Project
, Follow_Links
, When_No_Sources
);
1172 -- If main project is an extending all project, set the object
1173 -- directory of all virtual extending projects to the object directory
1174 -- of the main project.
1176 if Project
/= No_Project
1177 and then Is_Extending_All
(From_Project_Node
, From_Project_Node_Tree
)
1180 Object_Dir
: constant Path_Name_Type
:=
1181 In_Tree
.Projects
.Table
(Project
).Object_Directory
;
1184 Project_Table
.First
.. Project_Table
.Last
(In_Tree
.Projects
)
1186 if In_Tree
.Projects
.Table
(Index
).Virtual
then
1187 In_Tree
.Projects
.Table
(Index
).Object_Directory
:=
1194 -- Check that no extending project shares its object directory with
1195 -- the project(s) it extends.
1197 if Project
/= No_Project
then
1199 Project_Table
.First
.. Project_Table
.Last
(In_Tree
.Projects
)
1201 Extending
:= In_Tree
.Projects
.Table
(Proj
).Extended_By
;
1203 if Extending
/= No_Project
then
1204 Obj_Dir
:= In_Tree
.Projects
.Table
(Proj
).Object_Directory
;
1206 -- Check that a project being extended does not share its
1207 -- object directory with any project that extends it, directly
1208 -- or indirectly, including a virtual extending project.
1210 -- Start with the project directly extending it
1212 Extending2
:= Extending
;
1213 while Extending2
/= No_Project
loop
1214 if In_Tree
.Projects
.Table
(Extending2
).Ada_Sources_Present
1216 In_Tree
.Projects
.Table
(Extending2
).Object_Directory
=
1219 if In_Tree
.Projects
.Table
(Extending2
).Virtual
then
1221 In_Tree
.Projects
.Table
(Proj
).Display_Name
;
1223 if Error_Report
= null then
1225 ("project % cannot be extended by a virtual " &
1226 "project with the same object directory",
1227 In_Tree
.Projects
.Table
(Proj
).Location
);
1231 Get_Name_String
(Error_Msg_Name_1
) &
1232 """ cannot be extended by a virtual " &
1233 "project with the same object directory",
1239 In_Tree
.Projects
.Table
(Extending2
).Display_Name
;
1241 In_Tree
.Projects
.Table
(Proj
).Display_Name
;
1243 if Error_Report
= null then
1245 ("project %% cannot extend project %%",
1246 In_Tree
.Projects
.Table
(Extending2
).Location
);
1248 ("\they share the same object directory",
1249 In_Tree
.Projects
.Table
(Extending2
).Location
);
1254 Get_Name_String
(Error_Msg_Name_1
) &
1255 """ cannot extend project """ &
1256 Get_Name_String
(Error_Msg_Name_2
) & """",
1259 ("they share the same object directory",
1265 -- Continue with the next extending project, if any
1268 In_Tree
.Projects
.Table
(Extending2
).Extended_By
;
1275 Total_Errors_Detected
= 0
1277 (Warning_Mode
/= Treat_As_Error
or else Warnings_Detected
= 0);
1280 -------------------------------
1281 -- Process_Declarative_Items --
1282 -------------------------------
1284 procedure Process_Declarative_Items
1285 (Project
: Project_Id
;
1286 In_Tree
: Project_Tree_Ref
;
1287 From_Project_Node
: Project_Node_Id
;
1288 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
1290 Item
: Project_Node_Id
)
1292 Current_Declarative_Item
: Project_Node_Id
:= Item
;
1293 Current_Item
: Project_Node_Id
:= Empty_Node
;
1296 -- For each declarative item
1298 while Current_Declarative_Item
/= Empty_Node
loop
1304 (Current_Declarative_Item
, From_Project_Node_Tree
);
1306 -- And set Current_Declarative_Item to the next declarative item
1307 -- ready for the next iteration.
1309 Current_Declarative_Item
:=
1310 Next_Declarative_Item
1311 (Current_Declarative_Item
, From_Project_Node_Tree
);
1313 case Kind_Of
(Current_Item
, From_Project_Node_Tree
) is
1315 when N_Package_Declaration
=>
1316 -- Do not process a package declaration that should be ignored
1318 if Expression_Kind_Of
1319 (Current_Item
, From_Project_Node_Tree
) /= Ignored
1321 -- Create the new package
1323 Package_Table
.Increment_Last
(In_Tree
.Packages
);
1326 New_Pkg
: constant Package_Id
:=
1327 Package_Table
.Last
(In_Tree
.Packages
);
1328 The_New_Package
: Package_Element
;
1330 Project_Of_Renamed_Package
:
1331 constant Project_Node_Id
:=
1332 Project_Of_Renamed_Package_Of
1333 (Current_Item
, From_Project_Node_Tree
);
1336 -- Set the name of the new package
1338 The_New_Package
.Name
:=
1339 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1341 -- Insert the new package in the appropriate list
1343 if Pkg
/= No_Package
then
1344 The_New_Package
.Next
:=
1345 In_Tree
.Packages
.Table
(Pkg
).Decl
.Packages
;
1346 In_Tree
.Packages
.Table
(Pkg
).Decl
.Packages
:=
1349 The_New_Package
.Next
:=
1350 In_Tree
.Projects
.Table
(Project
).Decl
.Packages
;
1351 In_Tree
.Projects
.Table
(Project
).Decl
.Packages
:=
1355 In_Tree
.Packages
.Table
(New_Pkg
) :=
1358 if Project_Of_Renamed_Package
/= Empty_Node
then
1363 Project_Name
: constant Name_Id
:=
1365 (Project_Of_Renamed_Package
,
1366 From_Project_Node_Tree
);
1369 constant Project_Id
:=
1370 Imported_Or_Extended_Project_From
1371 (Project
, In_Tree
, Project_Name
);
1373 Renamed_Package
: constant Package_Id
:=
1375 (Renamed_Project
, In_Tree
,
1378 From_Project_Node_Tree
));
1381 -- For a renamed package, copy the declarations of
1382 -- the renamed package, but set all the locations
1383 -- to the location of the package name in the
1384 -- renaming declaration.
1386 Copy_Package_Declarations
1388 In_Tree
.Packages
.Table
(Renamed_Package
).Decl
,
1390 In_Tree
.Packages
.Table
(New_Pkg
).Decl
,
1393 (Current_Item
, From_Project_Node_Tree
),
1394 In_Tree
=> In_Tree
);
1397 -- Standard package declaration, not renaming
1400 -- Set the default values of the attributes
1404 In_Tree
.Packages
.Table
(New_Pkg
).Decl
,
1407 (Current_Item
, From_Project_Node_Tree
)));
1409 -- And process declarative items of the new package
1411 Process_Declarative_Items
1412 (Project
=> Project
,
1414 From_Project_Node
=> From_Project_Node
,
1415 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1418 First_Declarative_Item_Of
1419 (Current_Item
, From_Project_Node_Tree
));
1424 when N_String_Type_Declaration
=>
1426 -- There is nothing to process
1430 when N_Attribute_Declaration |
1431 N_Typed_Variable_Declaration |
1432 N_Variable_Declaration
=>
1434 if Expression_Of
(Current_Item
, From_Project_Node_Tree
) =
1438 -- It must be a full associative array attribute declaration
1441 Current_Item_Name
: constant Name_Id
:=
1444 From_Project_Node_Tree
);
1445 -- The name of the attribute
1447 New_Array
: Array_Id
;
1448 -- The new associative array created
1450 Orig_Array
: Array_Id
;
1451 -- The associative array value
1453 Orig_Project_Name
: Name_Id
:= No_Name
;
1454 -- The name of the project where the associative array
1457 Orig_Project
: Project_Id
:= No_Project
;
1458 -- The id of the project where the associative array
1461 Orig_Package_Name
: Name_Id
:= No_Name
;
1462 -- The name of the package, if any, where the associative
1465 Orig_Package
: Package_Id
:= No_Package
;
1466 -- The id of the package, if any, where the associative
1469 New_Element
: Array_Element_Id
:= No_Array_Element
;
1470 -- Id of a new array element created
1472 Prev_Element
: Array_Element_Id
:= No_Array_Element
;
1473 -- Last new element id created
1475 Orig_Element
: Array_Element_Id
:= No_Array_Element
;
1476 -- Current array element in the original associative
1479 Next_Element
: Array_Element_Id
:= No_Array_Element
;
1480 -- Id of the array element that follows the new element.
1481 -- This is not always nil, because values for the
1482 -- associative array attribute may already have been
1483 -- declared, and the array elements declared are reused.
1486 -- First, find if the associative array attribute already
1487 -- has elements declared.
1489 if Pkg
/= No_Package
then
1490 New_Array
:= In_Tree
.Packages
.Table
1494 New_Array
:= In_Tree
.Projects
.Table
1495 (Project
).Decl
.Arrays
;
1498 while New_Array
/= No_Array
1499 and then In_Tree
.Arrays
.Table
(New_Array
).Name
/=
1502 New_Array
:= In_Tree
.Arrays
.Table
(New_Array
).Next
;
1505 -- If the attribute has never been declared add new entry
1506 -- in the arrays of the project/package and link it.
1508 if New_Array
= No_Array
then
1509 Array_Table
.Increment_Last
(In_Tree
.Arrays
);
1510 New_Array
:= Array_Table
.Last
(In_Tree
.Arrays
);
1512 if Pkg
/= No_Package
then
1513 In_Tree
.Arrays
.Table
(New_Array
) :=
1514 (Name
=> Current_Item_Name
,
1515 Value
=> No_Array_Element
,
1517 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
);
1519 In_Tree
.Packages
.Table
(Pkg
).Decl
.Arrays
:=
1523 In_Tree
.Arrays
.Table
(New_Array
) :=
1524 (Name
=> Current_Item_Name
,
1525 Value
=> No_Array_Element
,
1527 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
);
1529 In_Tree
.Projects
.Table
(Project
).Decl
.Arrays
:=
1534 -- Find the project where the value is declared
1536 Orig_Project_Name
:=
1538 (Associative_Project_Of
1539 (Current_Item
, From_Project_Node_Tree
),
1540 From_Project_Node_Tree
);
1542 for Index
in Project_Table
.First
..
1546 if In_Tree
.Projects
.Table
(Index
).Name
=
1549 Orig_Project
:= Index
;
1554 pragma Assert
(Orig_Project
/= No_Project
,
1555 "original project not found");
1557 if Associative_Package_Of
1558 (Current_Item
, From_Project_Node_Tree
) = Empty_Node
1561 In_Tree
.Projects
.Table
1562 (Orig_Project
).Decl
.Arrays
;
1565 -- If in a package, find the package where the
1566 -- value is declared.
1568 Orig_Package_Name
:=
1570 (Associative_Package_Of
1571 (Current_Item
, From_Project_Node_Tree
),
1572 From_Project_Node_Tree
);
1575 In_Tree
.Projects
.Table
1576 (Orig_Project
).Decl
.Packages
;
1577 pragma Assert
(Orig_Package
/= No_Package
,
1578 "original package not found");
1580 while In_Tree
.Packages
.Table
1581 (Orig_Package
).Name
/= Orig_Package_Name
1583 Orig_Package
:= In_Tree
.Packages
.Table
1584 (Orig_Package
).Next
;
1585 pragma Assert
(Orig_Package
/= No_Package
,
1586 "original package not found");
1590 In_Tree
.Packages
.Table
1591 (Orig_Package
).Decl
.Arrays
;
1594 -- Now look for the array
1596 while Orig_Array
/= No_Array
and then
1597 In_Tree
.Arrays
.Table
(Orig_Array
).Name
/=
1600 Orig_Array
:= In_Tree
.Arrays
.Table
1604 if Orig_Array
= No_Array
then
1605 if Error_Report
= null then
1607 ("associative array value cannot be found",
1609 (Current_Item
, From_Project_Node_Tree
));
1613 ("associative array value cannot be found",
1619 In_Tree
.Arrays
.Table
(Orig_Array
).Value
;
1621 -- Copy each array element
1623 while Orig_Element
/= No_Array_Element
loop
1625 -- Case of first element
1627 if Prev_Element
= No_Array_Element
then
1629 -- And there is no array element declared yet,
1630 -- create a new first array element.
1632 if In_Tree
.Arrays
.Table
(New_Array
).Value
=
1635 Array_Element_Table
.Increment_Last
1636 (In_Tree
.Array_Elements
);
1637 New_Element
:= Array_Element_Table
.Last
1638 (In_Tree
.Array_Elements
);
1639 In_Tree
.Arrays
.Table
1640 (New_Array
).Value
:= New_Element
;
1641 Next_Element
:= No_Array_Element
;
1643 -- Otherwise, the new element is the first
1646 New_Element
:= In_Tree
.Arrays
.
1647 Table
(New_Array
).Value
;
1649 In_Tree
.Array_Elements
.Table
1653 -- Otherwise, reuse an existing element, or create
1654 -- one if necessary.
1658 In_Tree
.Array_Elements
.Table
1659 (Prev_Element
).Next
;
1661 if Next_Element
= No_Array_Element
then
1662 Array_Element_Table
.Increment_Last
1663 (In_Tree
.Array_Elements
);
1664 New_Element
:= Array_Element_Table
.Last
1665 (In_Tree
.Array_Elements
);
1668 New_Element
:= Next_Element
;
1670 In_Tree
.Array_Elements
.Table
1675 -- Copy the value of the element
1677 In_Tree
.Array_Elements
.Table
1679 In_Tree
.Array_Elements
.Table
1681 In_Tree
.Array_Elements
.Table
1682 (New_Element
).Value
.Project
:= Project
;
1684 -- Adjust the Next link
1686 In_Tree
.Array_Elements
.Table
1687 (New_Element
).Next
:= Next_Element
;
1689 -- Adjust the previous id for the next element
1691 Prev_Element
:= New_Element
;
1693 -- Go to the next element in the original array
1696 In_Tree
.Array_Elements
.Table
1697 (Orig_Element
).Next
;
1700 -- Make sure that the array ends here, in case there
1701 -- previously a greater number of elements.
1703 In_Tree
.Array_Elements
.Table
1704 (New_Element
).Next
:= No_Array_Element
;
1708 -- Declarations other that full associative arrays
1712 New_Value
: constant Variable_Value
:=
1714 (Project
=> Project
,
1716 From_Project_Node
=> From_Project_Node
,
1717 From_Project_Node_Tree
=> From_Project_Node_Tree
,
1722 (Current_Item
, From_Project_Node_Tree
),
1723 From_Project_Node_Tree
),
1726 (Current_Item
, From_Project_Node_Tree
));
1727 -- The expression value
1729 The_Variable
: Variable_Id
:= No_Variable
;
1731 Current_Item_Name
: constant Name_Id
:=
1732 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1735 -- Process a typed variable declaration
1737 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) =
1738 N_Typed_Variable_Declaration
1740 -- Report an error for an empty string
1742 if New_Value
.Value
= Empty_String
then
1744 Name_Of
(Current_Item
, From_Project_Node_Tree
);
1746 if Error_Report
= null then
1748 ("no value defined for %",
1750 (Current_Item
, From_Project_Node_Tree
));
1754 ("no value defined for " &
1755 Get_Name_String
(Error_Msg_Name_1
),
1761 Current_String
: Project_Node_Id
:=
1762 First_Literal_String
1765 From_Project_Node_Tree
),
1766 From_Project_Node_Tree
);
1769 -- Loop through all the valid strings for the
1770 -- string type and compare to the string value.
1772 while Current_String
/= Empty_Node
1775 (Current_String
, From_Project_Node_Tree
) /=
1780 (Current_String
, From_Project_Node_Tree
);
1783 -- Report an error if the string value is not
1784 -- one for the string type.
1786 if Current_String
= Empty_Node
then
1787 Error_Msg_Name_1
:= New_Value
.Value
;
1790 (Current_Item
, From_Project_Node_Tree
);
1792 if Error_Report
= null then
1794 ("value %% is illegal for "
1798 From_Project_Node_Tree
));
1803 Get_Name_String
(Error_Msg_Name_1
) &
1804 """ is illegal for typed string """ &
1805 Get_Name_String
(Error_Msg_Name_2
) &
1808 -- Calls like this to Error_Report are
1809 -- wrong, since they don't properly case
1810 -- and decode names corresponding to the
1811 -- ordinary case of % insertion ???
1818 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) /=
1819 N_Attribute_Declaration
1821 Associative_Array_Index_Of
1822 (Current_Item
, From_Project_Node_Tree
) = No_Name
1824 -- Case of a variable declaration or of a not
1825 -- associative array attribute.
1827 -- First, find the list where to find the variable
1830 if Kind_Of
(Current_Item
, From_Project_Node_Tree
) =
1831 N_Attribute_Declaration
1833 if Pkg
/= No_Package
then
1835 In_Tree
.Packages
.Table
1836 (Pkg
).Decl
.Attributes
;
1839 In_Tree
.Projects
.Table
1840 (Project
).Decl
.Attributes
;
1844 if Pkg
/= No_Package
then
1846 In_Tree
.Packages
.Table
1847 (Pkg
).Decl
.Variables
;
1850 In_Tree
.Projects
.Table
1851 (Project
).Decl
.Variables
;
1856 -- Loop through the list, to find if it has already
1859 while The_Variable
/= No_Variable
1861 In_Tree
.Variable_Elements
.Table
1862 (The_Variable
).Name
/= Current_Item_Name
1865 In_Tree
.Variable_Elements
.Table
1866 (The_Variable
).Next
;
1869 -- If it has not been declared, create a new entry
1872 if The_Variable
= No_Variable
then
1874 -- All single string attribute should already have
1875 -- been declared with a default empty string value.
1878 (Kind_Of
(Current_Item
, From_Project_Node_Tree
) /=
1879 N_Attribute_Declaration
,
1880 "illegal attribute declaration");
1882 Variable_Element_Table
.Increment_Last
1883 (In_Tree
.Variable_Elements
);
1884 The_Variable
:= Variable_Element_Table
.Last
1885 (In_Tree
.Variable_Elements
);
1887 -- Put the new variable in the appropriate list
1889 if Pkg
/= No_Package
then
1890 In_Tree
.Variable_Elements
.Table
(The_Variable
) :=
1892 In_Tree
.Packages
.Table
1893 (Pkg
).Decl
.Variables
,
1894 Name
=> Current_Item_Name
,
1895 Value
=> New_Value
);
1896 In_Tree
.Packages
.Table
1897 (Pkg
).Decl
.Variables
:= The_Variable
;
1900 In_Tree
.Variable_Elements
.Table
(The_Variable
) :=
1902 In_Tree
.Projects
.Table
1903 (Project
).Decl
.Variables
,
1904 Name
=> Current_Item_Name
,
1905 Value
=> New_Value
);
1906 In_Tree
.Projects
.Table
1907 (Project
).Decl
.Variables
:=
1911 -- If the variable/attribute has already been
1912 -- declared, just change the value.
1915 In_Tree
.Variable_Elements
.Table
1916 (The_Variable
).Value
:=
1922 -- Associative array attribute
1924 -- Get the string index
1927 (Associative_Array_Index_Of
1928 (Current_Item
, From_Project_Node_Tree
));
1930 -- Put in lower case, if necessary
1933 (Current_Item
, From_Project_Node_Tree
)
1935 GNAT
.Case_Util
.To_Lower
1936 (Name_Buffer
(1 .. Name_Len
));
1940 The_Array
: Array_Id
;
1942 The_Array_Element
: Array_Element_Id
:=
1945 Index_Name
: constant Name_Id
:= Name_Find
;
1946 -- The name id of the index
1949 -- Look for the array in the appropriate list
1951 if Pkg
/= No_Package
then
1952 The_Array
:= In_Tree
.Packages
.Table
1956 The_Array
:= In_Tree
.Projects
.Table
1957 (Project
).Decl
.Arrays
;
1961 The_Array
/= No_Array
1962 and then In_Tree
.Arrays
.Table
1963 (The_Array
).Name
/= Current_Item_Name
1965 The_Array
:= In_Tree
.Arrays
.Table
1969 -- If the array cannot be found, create a new
1970 -- entry in the list. As The_Array_Element is
1971 -- initialized to No_Array_Element, a new element
1972 -- will be created automatically later.
1974 if The_Array
= No_Array
then
1975 Array_Table
.Increment_Last
1977 The_Array
:= Array_Table
.Last
1980 if Pkg
/= No_Package
then
1981 In_Tree
.Arrays
.Table
1983 (Name
=> Current_Item_Name
,
1984 Value
=> No_Array_Element
,
1986 In_Tree
.Packages
.Table
1989 In_Tree
.Packages
.Table
1990 (Pkg
).Decl
.Arrays
:=
1994 In_Tree
.Arrays
.Table
1996 (Name
=> Current_Item_Name
,
1997 Value
=> No_Array_Element
,
1999 In_Tree
.Projects
.Table
2000 (Project
).Decl
.Arrays
);
2002 In_Tree
.Projects
.Table
2003 (Project
).Decl
.Arrays
:=
2007 -- Otherwise, initialize The_Array_Element as the
2008 -- head of the element list.
2011 The_Array_Element
:=
2012 In_Tree
.Arrays
.Table
2016 -- Look in the list, if any, to find an element
2017 -- with the same index.
2019 while The_Array_Element
/= No_Array_Element
2021 In_Tree
.Array_Elements
.Table
2022 (The_Array_Element
).Index
/= Index_Name
2024 The_Array_Element
:=
2025 In_Tree
.Array_Elements
.Table
2026 (The_Array_Element
).Next
;
2029 -- If no such element were found, create a new
2030 -- one and insert it in the element list, with
2031 -- the propoer value.
2033 if The_Array_Element
= No_Array_Element
then
2034 Array_Element_Table
.Increment_Last
2035 (In_Tree
.Array_Elements
);
2036 The_Array_Element
:= Array_Element_Table
.Last
2037 (In_Tree
.Array_Elements
);
2039 In_Tree
.Array_Elements
.Table
2040 (The_Array_Element
) :=
2041 (Index
=> Index_Name
,
2044 (Current_Item
, From_Project_Node_Tree
),
2045 Index_Case_Sensitive
=>
2046 not Case_Insensitive
2047 (Current_Item
, From_Project_Node_Tree
),
2049 Next
=> In_Tree
.Arrays
.Table
2051 In_Tree
.Arrays
.Table
2052 (The_Array
).Value
:= The_Array_Element
;
2054 -- An element with the same index already exists,
2055 -- just replace its value with the new one.
2058 In_Tree
.Array_Elements
.Table
2059 (The_Array_Element
).Value
:= New_Value
;
2066 when N_Case_Construction
=>
2068 The_Project
: Project_Id
:= Project
;
2069 -- The id of the project of the case variable
2071 The_Package
: Package_Id
:= Pkg
;
2072 -- The id of the package, if any, of the case variable
2074 The_Variable
: Variable_Value
:= Nil_Variable_Value
;
2075 -- The case variable
2077 Case_Value
: Name_Id
:= No_Name
;
2078 -- The case variable value
2080 Case_Item
: Project_Node_Id
:= Empty_Node
;
2081 Choice_String
: Project_Node_Id
:= Empty_Node
;
2082 Decl_Item
: Project_Node_Id
:= Empty_Node
;
2086 Variable_Node
: constant Project_Node_Id
:=
2087 Case_Variable_Reference_Of
2089 From_Project_Node_Tree
);
2091 Var_Id
: Variable_Id
:= No_Variable
;
2092 Name
: Name_Id
:= No_Name
;
2095 -- If a project were specified for the case variable,
2099 (Variable_Node
, From_Project_Node_Tree
) /= Empty_Node
2104 (Variable_Node
, From_Project_Node_Tree
),
2105 From_Project_Node_Tree
);
2107 Imported_Or_Extended_Project_From
2108 (Project
, In_Tree
, Name
);
2111 -- If a package were specified for the case variable,
2115 (Variable_Node
, From_Project_Node_Tree
) /= Empty_Node
2120 (Variable_Node
, From_Project_Node_Tree
),
2121 From_Project_Node_Tree
);
2123 Package_From
(The_Project
, In_Tree
, Name
);
2126 Name
:= Name_Of
(Variable_Node
, From_Project_Node_Tree
);
2128 -- First, look for the case variable into the package,
2131 if The_Package
/= No_Package
then
2132 Var_Id
:= In_Tree
.Packages
.Table
2133 (The_Package
).Decl
.Variables
;
2135 Name_Of
(Variable_Node
, From_Project_Node_Tree
);
2136 while Var_Id
/= No_Variable
2138 In_Tree
.Variable_Elements
.Table
2139 (Var_Id
).Name
/= Name
2141 Var_Id
:= In_Tree
.Variable_Elements
.
2142 Table
(Var_Id
).Next
;
2146 -- If not found in the package, or if there is no
2147 -- package, look at the project level.
2149 if Var_Id
= No_Variable
2152 (Variable_Node
, From_Project_Node_Tree
) = Empty_Node
2154 Var_Id
:= In_Tree
.Projects
.Table
2155 (The_Project
).Decl
.Variables
;
2156 while Var_Id
/= No_Variable
2158 In_Tree
.Variable_Elements
.Table
2159 (Var_Id
).Name
/= Name
2161 Var_Id
:= In_Tree
.Variable_Elements
.
2162 Table
(Var_Id
).Next
;
2166 if Var_Id
= No_Variable
then
2168 -- Should never happen, because this has already been
2169 -- checked during parsing.
2171 Write_Line
("variable """ &
2172 Get_Name_String
(Name
) &
2174 raise Program_Error
;
2177 -- Get the case variable
2179 The_Variable
:= In_Tree
.Variable_Elements
.
2180 Table
(Var_Id
).Value
;
2182 if The_Variable
.Kind
/= Single
then
2184 -- Should never happen, because this has already been
2185 -- checked during parsing.
2187 Write_Line
("variable""" &
2188 Get_Name_String
(Name
) &
2189 """ is not a single string variable");
2190 raise Program_Error
;
2193 -- Get the case variable value
2194 Case_Value
:= The_Variable
.Value
;
2197 -- Now look into all the case items of the case construction
2200 First_Case_Item_Of
(Current_Item
, From_Project_Node_Tree
);
2202 while Case_Item
/= Empty_Node
loop
2204 First_Choice_Of
(Case_Item
, From_Project_Node_Tree
);
2206 -- When Choice_String is nil, it means that it is
2207 -- the "when others =>" alternative.
2209 if Choice_String
= Empty_Node
then
2211 First_Declarative_Item_Of
2212 (Case_Item
, From_Project_Node_Tree
);
2213 exit Case_Item_Loop
;
2216 -- Look into all the alternative of this case item
2219 while Choice_String
/= Empty_Node
loop
2222 (Choice_String
, From_Project_Node_Tree
)
2225 First_Declarative_Item_Of
2226 (Case_Item
, From_Project_Node_Tree
);
2227 exit Case_Item_Loop
;
2232 (Choice_String
, From_Project_Node_Tree
);
2233 end loop Choice_Loop
;
2236 Next_Case_Item
(Case_Item
, From_Project_Node_Tree
);
2237 end loop Case_Item_Loop
;
2239 -- If there is an alternative, then we process it
2241 if Decl_Item
/= Empty_Node
then
2242 Process_Declarative_Items
2243 (Project
=> Project
,
2245 From_Project_Node
=> From_Project_Node
,
2246 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2254 -- Should never happen
2256 Write_Line
("Illegal declarative item: " &
2257 Project_Node_Kind
'Image
2259 (Current_Item
, From_Project_Node_Tree
)));
2260 raise Program_Error
;
2263 end Process_Declarative_Items
;
2265 ---------------------
2266 -- Recursive_Check --
2267 ---------------------
2269 procedure Recursive_Check
2270 (Project
: Project_Id
;
2271 In_Tree
: Project_Tree_Ref
;
2272 Follow_Links
: Boolean;
2273 When_No_Sources
: Error_Warning
)
2275 Data
: Project_Data
;
2276 Imported_Project_List
: Project_List
:= Empty_Project_List
;
2279 -- Do nothing if Project is No_Project, or Project has already
2280 -- been marked as checked.
2282 if Project
/= No_Project
2283 and then not In_Tree
.Projects
.Table
(Project
).Checked
2285 -- Mark project as checked, to avoid infinite recursion in
2286 -- ill-formed trees, where a project imports itself.
2288 In_Tree
.Projects
.Table
(Project
).Checked
:= True;
2290 Data
:= In_Tree
.Projects
.Table
(Project
);
2292 -- Call itself for a possible extended project.
2293 -- (if there is no extended project, then nothing happens).
2296 (Data
.Extends
, In_Tree
, Follow_Links
, When_No_Sources
);
2298 -- Call itself for all imported projects
2300 Imported_Project_List
:= Data
.Imported_Projects
;
2301 while Imported_Project_List
/= Empty_Project_List
loop
2303 (In_Tree
.Project_Lists
.Table
2304 (Imported_Project_List
).Project
,
2305 In_Tree
, Follow_Links
, When_No_Sources
);
2306 Imported_Project_List
:=
2307 In_Tree
.Project_Lists
.Table
2308 (Imported_Project_List
).Next
;
2311 if Verbose_Mode
then
2312 Write_Str
("Checking project file """);
2313 Write_Str
(Get_Name_String
(Data
.Name
));
2318 (Project
, In_Tree
, Error_Report
, Follow_Links
, When_No_Sources
);
2320 end Recursive_Check
;
2322 -----------------------
2323 -- Recursive_Process --
2324 -----------------------
2326 procedure Recursive_Process
2327 (In_Tree
: Project_Tree_Ref
;
2328 Project
: out Project_Id
;
2329 From_Project_Node
: Project_Node_Id
;
2330 From_Project_Node_Tree
: Project_Node_Tree_Ref
;
2331 Extended_By
: Project_Id
)
2333 With_Clause
: Project_Node_Id
;
2336 if From_Project_Node
= Empty_Node
then
2337 Project
:= No_Project
;
2341 Processed_Data
: Project_Data
:= Empty_Project
(In_Tree
);
2342 Imported
: Project_List
:= Empty_Project_List
;
2343 Declaration_Node
: Project_Node_Id
:= Empty_Node
;
2344 Tref
: Source_Buffer_Ptr
;
2345 Name
: constant Name_Id
:=
2347 (From_Project_Node
, From_Project_Node_Tree
);
2348 Location
: Source_Ptr
:=
2350 (From_Project_Node
, From_Project_Node_Tree
);
2353 Project
:= Processed_Projects
.Get
(Name
);
2355 if Project
/= No_Project
then
2357 -- Make sure that, when a project is extended, the project id
2358 -- of the project extending it is recorded in its data, even
2359 -- when it has already been processed as an imported project.
2360 -- This is for virtually extended projects.
2362 if Extended_By
/= No_Project
then
2363 In_Tree
.Projects
.Table
(Project
).Extended_By
:= Extended_By
;
2369 Project_Table
.Increment_Last
(In_Tree
.Projects
);
2370 Project
:= Project_Table
.Last
(In_Tree
.Projects
);
2371 Processed_Projects
.Set
(Name
, Project
);
2373 Processed_Data
.Name
:= Name
;
2375 Get_Name_String
(Name
);
2377 -- If name starts with the virtual prefix, flag the project as
2378 -- being a virtual extending project.
2380 if Name_Len
> Virtual_Prefix
'Length
2381 and then Name_Buffer
(1 .. Virtual_Prefix
'Length) =
2384 Processed_Data
.Virtual
:= True;
2385 Processed_Data
.Display_Name
:= Name
;
2387 -- If there is no file, for example when the project node tree is
2388 -- built in memory by GPS, the Display_Name cannot be found in
2389 -- the source, so its value is the same as Name.
2391 elsif Location
= No_Location
then
2392 Processed_Data
.Display_Name
:= Name
;
2394 -- Get the spelling of the project name from the project file
2397 Tref
:= Source_Text
(Get_Source_File_Index
(Location
));
2399 for J
in 1 .. Name_Len
loop
2400 Name_Buffer
(J
) := Tref
(Location
);
2401 Location
:= Location
+ 1;
2404 Processed_Data
.Display_Name
:= Name_Find
;
2407 Processed_Data
.Display_Path_Name
:=
2408 Path_Name_Of
(From_Project_Node
, From_Project_Node_Tree
);
2409 Get_Name_String
(Processed_Data
.Display_Path_Name
);
2410 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
2411 Processed_Data
.Path_Name
:= Name_Find
;
2413 Processed_Data
.Location
:=
2414 Location_Of
(From_Project_Node
, From_Project_Node_Tree
);
2416 Processed_Data
.Display_Directory
:=
2418 (Directory_Of
(From_Project_Node
, From_Project_Node_Tree
));
2419 Get_Name_String
(Processed_Data
.Display_Directory
);
2420 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
2421 Processed_Data
.Directory
:= Name_Find
;
2423 Processed_Data
.Extended_By
:= Extended_By
;
2426 (Project
, In_Tree
, Processed_Data
.Decl
, Attribute_First
);
2428 First_With_Clause_Of
(From_Project_Node
, From_Project_Node_Tree
);
2430 while With_Clause
/= Empty_Node
loop
2432 New_Project
: Project_Id
;
2433 New_Data
: Project_Data
;
2437 (In_Tree
=> In_Tree
,
2438 Project
=> New_Project
,
2439 From_Project_Node
=>
2440 Project_Node_Of
(With_Clause
, From_Project_Node_Tree
),
2441 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2442 Extended_By
=> No_Project
);
2444 In_Tree
.Projects
.Table
(New_Project
);
2446 -- If we were the first project to import it,
2447 -- set First_Referred_By to us.
2449 if New_Data
.First_Referred_By
= No_Project
then
2450 New_Data
.First_Referred_By
:= Project
;
2451 In_Tree
.Projects
.Table
(New_Project
) :=
2455 -- Add this project to our list of imported projects
2457 Project_List_Table
.Increment_Last
2458 (In_Tree
.Project_Lists
);
2459 In_Tree
.Project_Lists
.Table
2460 (Project_List_Table
.Last
2461 (In_Tree
.Project_Lists
)) :=
2462 (Project
=> New_Project
, Next
=> Empty_Project_List
);
2464 -- Imported is the id of the last imported project.
2465 -- If it is nil, then this imported project is our first.
2467 if Imported
= Empty_Project_List
then
2468 Processed_Data
.Imported_Projects
:=
2469 Project_List_Table
.Last
2470 (In_Tree
.Project_Lists
);
2473 In_Tree
.Project_Lists
.Table
2474 (Imported
).Next
:= Project_List_Table
.Last
2475 (In_Tree
.Project_Lists
);
2478 Imported
:= Project_List_Table
.Last
2479 (In_Tree
.Project_Lists
);
2482 Next_With_Clause_Of
(With_Clause
, From_Project_Node_Tree
);
2487 Project_Declaration_Of
2488 (From_Project_Node
, From_Project_Node_Tree
);
2491 (In_Tree
=> In_Tree
,
2492 Project
=> Processed_Data
.Extends
,
2493 From_Project_Node
=>
2495 (Declaration_Node
, From_Project_Node_Tree
),
2496 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2497 Extended_By
=> Project
);
2499 In_Tree
.Projects
.Table
(Project
) := Processed_Data
;
2501 Process_Declarative_Items
2502 (Project
=> Project
,
2504 From_Project_Node
=> From_Project_Node
,
2505 From_Project_Node_Tree
=> From_Project_Node_Tree
,
2508 First_Declarative_Item_Of
2509 (Declaration_Node
, From_Project_Node_Tree
));
2511 -- If it is an extending project, inherit all packages
2512 -- from the extended project that are not explicitely defined
2513 -- or renamed. Also inherit the languages, if attribute Languages
2514 -- is not explicitely defined.
2516 if Processed_Data
.Extends
/= No_Project
then
2517 Processed_Data
:= In_Tree
.Projects
.Table
(Project
);
2520 Extended_Pkg
: Package_Id
:=
2521 In_Tree
.Projects
.Table
2522 (Processed_Data
.Extends
).Decl
.Packages
;
2523 Current_Pkg
: Package_Id
;
2524 Element
: Package_Element
;
2525 First
: constant Package_Id
:=
2526 Processed_Data
.Decl
.Packages
;
2527 Attribute1
: Variable_Id
;
2528 Attribute2
: Variable_Id
;
2529 Attr_Value1
: Variable
;
2530 Attr_Value2
: Variable
;
2533 while Extended_Pkg
/= No_Package
loop
2535 In_Tree
.Packages
.Table
(Extended_Pkg
);
2537 Current_Pkg
:= First
;
2540 exit when Current_Pkg
= No_Package
2541 or else In_Tree
.Packages
.Table
2542 (Current_Pkg
).Name
= Element
.Name
;
2543 Current_Pkg
:= In_Tree
.Packages
.Table
2547 if Current_Pkg
= No_Package
then
2548 Package_Table
.Increment_Last
2550 Current_Pkg
:= Package_Table
.Last
2552 In_Tree
.Packages
.Table
(Current_Pkg
) :=
2553 (Name
=> Element
.Name
,
2554 Decl
=> Element
.Decl
,
2555 Parent
=> No_Package
,
2556 Next
=> Processed_Data
.Decl
.Packages
);
2557 Processed_Data
.Decl
.Packages
:= Current_Pkg
;
2560 Extended_Pkg
:= Element
.Next
;
2563 -- Check if attribute Languages is declared in the
2564 -- extending project.
2566 Attribute1
:= Processed_Data
.Decl
.Attributes
;
2567 while Attribute1
/= No_Variable
loop
2568 Attr_Value1
:= In_Tree
.Variable_Elements
.
2570 exit when Attr_Value1
.Name
= Snames
.Name_Languages
;
2571 Attribute1
:= Attr_Value1
.Next
;
2574 if Attribute1
= No_Variable
or else
2575 Attr_Value1
.Value
.Default
2577 -- Attribute Languages is not declared in the extending
2578 -- project. Check if it is declared in the project being
2582 In_Tree
.Projects
.Table
2583 (Processed_Data
.Extends
).Decl
.Attributes
;
2585 while Attribute2
/= No_Variable
loop
2586 Attr_Value2
:= In_Tree
.Variable_Elements
.
2588 exit when Attr_Value2
.Name
= Snames
.Name_Languages
;
2589 Attribute2
:= Attr_Value2
.Next
;
2592 if Attribute2
/= No_Variable
and then
2593 not Attr_Value2
.Value
.Default
2595 -- As attribute Languages is declared in the project
2596 -- being extended, copy its value for the extending
2599 if Attribute1
= No_Variable
then
2600 Variable_Element_Table
.Increment_Last
2601 (In_Tree
.Variable_Elements
);
2602 Attribute1
:= Variable_Element_Table
.Last
2603 (In_Tree
.Variable_Elements
);
2604 Attr_Value1
.Next
:= Processed_Data
.Decl
.Attributes
;
2605 Processed_Data
.Decl
.Attributes
:= Attribute1
;
2608 Attr_Value1
.Name
:= Snames
.Name_Languages
;
2609 Attr_Value1
.Value
:= Attr_Value2
.Value
;
2610 In_Tree
.Variable_Elements
.Table
2611 (Attribute1
) := Attr_Value1
;
2616 In_Tree
.Projects
.Table
(Project
) := Processed_Data
;
2620 end Recursive_Process
;