1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2011, 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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
27 with Prj.Com; use Prj.Com;
29 with GNAT.Case_Util; use GNAT.Case_Util;
31 package body Prj.Attr is
35 -- Data for predefined attributes and packages
37 -- Names are in lower case and end with '#'
39 -- Package names are preceded by 'P'
41 -- Attribute names are preceded by two or three letters:
43 -- The first letter is one of
45 -- 's' for Single with optional index
47 -- 'l' for List of strings with optional indexes
49 -- The second letter is one of
50 -- 'V' for single variable
51 -- 'A' for associative array
52 -- 'a' for case insensitive associative array
53 -- 'b' for associative array, case insensitive if file names are case
55 -- 'c' same as 'b', with optional index
57 -- The third optional letter is
58 -- 'R' to indicate that the attribute is read-only
59 -- 'O' to indicate that others is allowed as an index for an associative
62 -- End is indicated by two consecutive '#'
64 Initialization_Data : constant String :=
66 -- project level attributes
75 "SVexternally_built#" &
82 "Lainherit_source_path#" &
83 "LVexcluded_source_dirs#" &
84 "LVignore_source_sub_dirs#" &
89 "LVlocally_removed_files#" &
90 "LVexcluded_source_files#" &
91 "SVsource_list_file#" &
92 "SVexcluded_source_list_file#" &
95 -- Projects (in aggregate projects)
106 "SVlibrary_version#" &
107 "LVlibrary_interface#" &
108 "SVlibrary_standalone#" &
109 "LVlibrary_fully_standalone_options#" &
110 "SVlibrary_fully_standalone_supported#" &
111 "SVlibrary_auto_init#" &
112 "LVleading_library_options#" &
113 "LVlibrary_options#" &
114 "SVlibrary_src_dir#" &
115 "SVlibrary_ali_dir#" &
117 "SVlibrary_symbol_file#" &
118 "SVlibrary_symbol_policy#" &
119 "SVlibrary_reference_symbol_file#" &
121 -- Configuration - General
123 "SVdefault_language#" &
124 "LVrun_path_option#" &
125 "SVrun_path_origin#" &
126 "SVseparate_run_path_options#" &
127 "Satoolchain_version#" &
128 "Satoolchain_description#" &
129 "Saobject_generated#" &
130 "Saobjects_linked#" &
133 -- Configuration - Libraries
135 "SVlibrary_builder#" &
136 "SVlibrary_support#" &
138 -- Configuration - Archives
140 "LVarchive_builder#" &
141 "LVarchive_builder_append_option#" &
142 "LVarchive_indexer#" &
143 "SVarchive_suffix#" &
144 "LVlibrary_partial_linker#" &
146 -- Configuration - Shared libraries
148 "SVshared_library_prefix#" &
149 "SVshared_library_suffix#" &
150 "SVsymbolic_link_supported#" &
151 "SVlibrary_major_minor_id_supported#" &
152 "SVlibrary_auto_init_supported#" &
153 "LVshared_library_minimum_switches#" &
154 "LVlibrary_version_switches#" &
155 "SVlibrary_install_name_option#" &
156 "Saruntime_library_dir#" &
157 "Saruntime_source_dir#" &
160 -- Some attributes are obsolescent, and renamed in the tree (see
161 -- Prj.Dect.Rename_Obsolescent_Attributes).
164 "Saspecification_suffix#" & -- Always renamed to "spec_suffix" in tree
166 "Saimplementation_suffix#" & -- Always renamed to "body_suffix" in tree
168 "SVseparate_suffix#" &
170 "SVdot_replacement#" &
171 "saspecification#" & -- Always renamed to "spec" in project tree
173 "saimplementation#" & -- Always renamed to "body" in project tree
175 "Laspecification_exceptions#" &
176 "Laimplementation_exceptions#" &
181 "Ladefault_switches#" &
183 "SVlocal_configuration_pragmas#" &
184 "Salocal_config_file#" &
186 -- Configuration - Compiling
190 "Sadependency_kind#" &
191 "Larequired_switches#" &
192 "Laleading_required_switches#" &
193 "Latrailing_required_switches#" &
196 "Lasource_file_switches#" &
197 "Saobject_file_suffix#" &
198 "Laobject_file_switches#" &
199 "Lamulti_unit_switches#" &
200 "Samulti_unit_object_separator#" &
202 -- Configuration - Mapping files
204 "Lamapping_file_switches#" &
205 "Samapping_spec_suffix#" &
206 "Samapping_body_suffix#" &
208 -- Configuration - Config files
210 "Laconfig_file_switches#" &
211 "Saconfig_body_file_name#" &
212 "Saconfig_body_file_name_index#" &
213 "Saconfig_body_file_name_pattern#" &
214 "Saconfig_spec_file_name#" &
215 "Saconfig_spec_file_name_index#" &
216 "Saconfig_spec_file_name_pattern#" &
217 "Saconfig_file_unique#" &
219 -- Configuration - Dependencies
221 "Ladependency_switches#" &
222 "Ladependency_driver#" &
224 -- Configuration - Search paths
226 "Lainclude_switches#" &
228 "Sainclude_path_file#" &
233 "Ladefault_switches#" &
235 "Lcglobal_compilation_switches#" &
237 "SVexecutable_suffix#" &
238 "SVglobal_configuration_pragmas#" &
239 "Saglobal_config_file#" &
249 "Ladefault_switches#" &
252 -- Configuration - Binding
255 "Larequired_switches#" &
258 "Saobjects_path_file#" &
263 "LVrequired_switches#" &
264 "Ladefault_switches#" &
265 "LcOleading_switches#" &
267 "LVlinker_options#" &
268 "SVmap_file_option#" &
270 -- Configuration - Linking
273 "LVexecutable_switch#" &
274 "SVlib_dir_switch#" &
275 "SVlib_name_switch#" &
277 -- Configuration - Response files
279 "SVmax_command_line_length#" &
280 "SVresponse_file_format#" &
281 "LVresponse_file_switches#" &
283 -- package Cross_Reference
285 "Pcross_reference#" &
286 "Ladefault_switches#" &
292 "Ladefault_switches#" &
295 -- package Pretty_Printer
298 "Ladefault_switches#" &
304 "Ladefault_switches#" &
310 "Ladefault_switches#" &
313 -- package Synchronize
316 "Ladefault_switches#" &
322 "Ladefault_switches#" &
328 "Ladefault_switches#" &
334 "Ladefault_switches#" &
337 "SVcommunication_protocol#" &
338 "Sacompiler_command#" &
339 "SVdebugger_command#" &
342 "SVvcs_file_check#" &
344 "SVdocumentation_dir#" &
353 Initialized : Boolean := False;
354 -- A flag to avoid multiple initialization
356 Package_Names : String_List_Access := new Strings.String_List (1 .. 20);
357 Last_Package_Name : Natural := 0;
358 -- Package_Names (1 .. Last_Package_Name) contains the list of the known
359 -- package names, coming from the Initialization_Data string or from
360 -- calls to one of the two procedures Register_New_Package.
362 procedure Add_Package_Name (Name : String);
363 -- Add a package name in the Package_Name list, extending it, if necessary
365 function Name_Id_Of (Name : String) return Name_Id;
366 -- Returns the Name_Id for Name in lower case
368 ----------------------
369 -- Add_Package_Name --
370 ----------------------
372 procedure Add_Package_Name (Name : String) is
374 if Last_Package_Name = Package_Names'Last then
376 New_List : constant Strings.String_List_Access :=
377 new Strings.String_List (1 .. Package_Names'Last * 2);
379 New_List (Package_Names'Range) := Package_Names.all;
380 Package_Names := New_List;
384 Last_Package_Name := Last_Package_Name + 1;
385 Package_Names (Last_Package_Name) := new String'(Name);
386 end Add_Package_Name;
388 -----------------------
389 -- Attribute_Kind_Of --
390 -----------------------
392 function Attribute_Kind_Of
393 (Attribute : Attribute_Node_Id) return Attribute_Kind
396 if Attribute = Empty_Attribute then
399 return Attrs.Table (Attribute.Value).Attr_Kind;
401 end Attribute_Kind_Of;
403 -----------------------
404 -- Attribute_Name_Of --
405 -----------------------
407 function Attribute_Name_Of (Attribute : Attribute_Node_Id) return Name_Id is
409 if Attribute = Empty_Attribute then
412 return Attrs.Table (Attribute.Value).Name;
414 end Attribute_Name_Of;
416 --------------------------
417 -- Attribute_Node_Id_Of --
418 --------------------------
420 function Attribute_Node_Id_Of
422 Starting_At : Attribute_Node_Id) return Attribute_Node_Id
424 Id : Attr_Node_Id := Starting_At.Value;
427 while Id /= Empty_Attr
428 and then Attrs.Table (Id).Name /= Name
430 Id := Attrs.Table (Id).Next;
433 return (Value => Id);
434 end Attribute_Node_Id_Of;
440 procedure Initialize is
441 Start : Positive := Initialization_Data'First;
442 Finish : Positive := Start;
443 Current_Package : Pkg_Node_Id := Empty_Pkg;
444 Current_Attribute : Attr_Node_Id := Empty_Attr;
445 Is_An_Attribute : Boolean := False;
446 Var_Kind : Variable_Kind := Undefined;
447 Optional_Index : Boolean := False;
448 Attr_Kind : Attribute_Kind := Single;
449 Package_Name : Name_Id := No_Name;
450 Attribute_Name : Name_Id := No_Name;
451 First_Attribute : Attr_Node_Id := Attr.First_Attribute;
453 Others_Allowed : Boolean;
455 function Attribute_Location return String;
456 -- Returns a string depending if we are in the project level attributes
457 -- or in the attributes of a package.
459 ------------------------
460 -- Attribute_Location --
461 ------------------------
463 function Attribute_Location return String is
465 if Package_Name = No_Name then
466 return "project level attributes";
469 return "attribute of package """ &
470 Get_Name_String (Package_Name) & """";
472 end Attribute_Location;
474 -- Start of processing for Initialize
477 -- Don't allow Initialize action to be repeated
483 -- Make sure the two tables are empty
486 Package_Attributes.Init;
488 while Initialization_Data (Start) /= '#' loop
489 Is_An_Attribute := True;
490 case Initialization_Data (Start) is
493 -- New allowed package
498 while Initialization_Data (Finish) /= '#' loop
499 Finish := Finish + 1;
503 Name_Id_Of (Initialization_Data (Start .. Finish - 1));
505 for Index in First_Package .. Package_Attributes.Last loop
506 if Package_Name = Package_Attributes.Table (Index).Name then
507 Osint.Fail ("duplicate name """
508 & Initialization_Data (Start .. Finish - 1)
509 & """ in predefined packages.");
513 Is_An_Attribute := False;
514 Current_Attribute := Empty_Attr;
515 Package_Attributes.Increment_Last;
516 Current_Package := Package_Attributes.Last;
517 Package_Attributes.Table (Current_Package) :=
518 (Name => Package_Name,
520 First_Attribute => Empty_Attr);
523 Add_Package_Name (Get_Name_String (Package_Name));
527 Optional_Index := False;
531 Optional_Index := True;
535 Optional_Index := False;
539 Optional_Index := True;
545 if Is_An_Attribute then
550 case Initialization_Data (Start) is
555 Attr_Kind := Associative_Array;
558 Attr_Kind := Case_Insensitive_Associative_Array;
561 if Osint.File_Names_Case_Sensitive then
562 Attr_Kind := Associative_Array;
564 Attr_Kind := Case_Insensitive_Associative_Array;
568 if Osint.File_Names_Case_Sensitive then
569 Attr_Kind := Optional_Index_Associative_Array;
572 Optional_Index_Case_Insensitive_Associative_Array;
582 Others_Allowed := False;
584 if Initialization_Data (Start) = 'R' then
588 elsif Initialization_Data (Start) = 'O' then
589 Others_Allowed := True;
595 while Initialization_Data (Finish) /= '#' loop
596 Finish := Finish + 1;
600 Name_Id_Of (Initialization_Data (Start .. Finish - 1));
601 Attrs.Increment_Last;
603 if Current_Attribute = Empty_Attr then
604 First_Attribute := Attrs.Last;
606 if Current_Package /= Empty_Pkg then
607 Package_Attributes.Table (Current_Package).First_Attribute
612 -- Check that there are no duplicate attributes
614 for Index in First_Attribute .. Attrs.Last - 1 loop
615 if Attribute_Name = Attrs.Table (Index).Name then
616 Osint.Fail ("duplicate attribute """
617 & Initialization_Data (Start .. Finish - 1)
618 & """ in " & Attribute_Location);
622 Attrs.Table (Current_Attribute).Next :=
626 Current_Attribute := Attrs.Last;
627 Attrs.Table (Current_Attribute) :=
628 (Name => Attribute_Name,
629 Var_Kind => Var_Kind,
630 Optional_Index => Optional_Index,
631 Attr_Kind => Attr_Kind,
632 Read_Only => Read_Only,
633 Others_Allowed => Others_Allowed,
646 function Is_Read_Only (Attribute : Attribute_Node_Id) return Boolean is
648 return Attrs.Table (Attribute.Value).Read_Only;
655 function Name_Id_Of (Name : String) return Name_Id is
658 Add_Str_To_Name_Buffer (Name);
659 To_Lower (Name_Buffer (1 .. Name_Len));
667 function Next_Attribute
668 (After : Attribute_Node_Id) return Attribute_Node_Id
671 if After = Empty_Attribute then
672 return Empty_Attribute;
674 return (Value => Attrs.Table (After.Value).Next);
678 -----------------------
679 -- Optional_Index_Of --
680 -----------------------
682 function Optional_Index_Of (Attribute : Attribute_Node_Id) return Boolean is
684 if Attribute = Empty_Attribute then
687 return Attrs.Table (Attribute.Value).Optional_Index;
689 end Optional_Index_Of;
691 function Others_Allowed_For
692 (Attribute : Attribute_Node_Id) return Boolean
695 if Attribute = Empty_Attribute then
698 return Attrs.Table (Attribute.Value).Others_Allowed;
700 end Others_Allowed_For;
702 -----------------------
703 -- Package_Name_List --
704 -----------------------
706 function Package_Name_List return Strings.String_List is
708 return Package_Names (1 .. Last_Package_Name);
709 end Package_Name_List;
711 ------------------------
712 -- Package_Node_Id_Of --
713 ------------------------
715 function Package_Node_Id_Of (Name : Name_Id) return Package_Node_Id is
717 for Index in Package_Attributes.First .. Package_Attributes.Last loop
718 if Package_Attributes.Table (Index).Name = Name then
719 if Package_Attributes.Table (Index).Known then
720 return (Value => Index);
722 return Unknown_Package;
727 -- If there is no package with this name, return Empty_Package
729 return Empty_Package;
730 end Package_Node_Id_Of;
732 ----------------------------
733 -- Register_New_Attribute --
734 ----------------------------
736 procedure Register_New_Attribute
738 In_Package : Package_Node_Id;
739 Attr_Kind : Defined_Attribute_Kind;
740 Var_Kind : Defined_Variable_Kind;
741 Index_Is_File_Name : Boolean := False;
742 Opt_Index : Boolean := False)
745 First_Attr : Attr_Node_Id := Empty_Attr;
746 Curr_Attr : Attr_Node_Id;
747 Real_Attr_Kind : Attribute_Kind;
750 if Name'Length = 0 then
751 Fail ("cannot register an attribute with no name");
755 if In_Package = Empty_Package then
756 Fail ("attempt to add attribute """
758 & """ to an undefined package");
762 Attr_Name := Name_Id_Of (Name);
765 Package_Attributes.Table (In_Package.Value).First_Attribute;
767 -- Check if attribute name is a duplicate
769 Curr_Attr := First_Attr;
770 while Curr_Attr /= Empty_Attr loop
771 if Attrs.Table (Curr_Attr).Name = Attr_Name then
772 Fail ("duplicate attribute name """
776 (Package_Attributes.Table (In_Package.Value).Name)
781 Curr_Attr := Attrs.Table (Curr_Attr).Next;
784 Real_Attr_Kind := Attr_Kind;
786 -- If Index_Is_File_Name, change the attribute kind if necessary
788 if Index_Is_File_Name and then not Osint.File_Names_Case_Sensitive then
790 when Associative_Array =>
791 Real_Attr_Kind := Case_Insensitive_Associative_Array;
793 when Optional_Index_Associative_Array =>
795 Optional_Index_Case_Insensitive_Associative_Array;
802 -- Add the new attribute
804 Attrs.Increment_Last;
805 Attrs.Table (Attrs.Last) :=
807 Var_Kind => Var_Kind,
808 Optional_Index => Opt_Index,
809 Attr_Kind => Real_Attr_Kind,
811 Others_Allowed => False,
814 Package_Attributes.Table (In_Package.Value).First_Attribute :=
816 end Register_New_Attribute;
818 --------------------------
819 -- Register_New_Package --
820 --------------------------
822 procedure Register_New_Package (Name : String; Id : out Package_Node_Id) is
826 if Name'Length = 0 then
827 Fail ("cannot register a package with no name");
832 Pkg_Name := Name_Id_Of (Name);
834 for Index in Package_Attributes.First .. Package_Attributes.Last loop
835 if Package_Attributes.Table (Index).Name = Pkg_Name then
836 Fail ("cannot register a package with a non unique name"""
844 Package_Attributes.Increment_Last;
845 Id := (Value => Package_Attributes.Last);
846 Package_Attributes.Table (Package_Attributes.Last) :=
849 First_Attribute => Empty_Attr);
851 Add_Package_Name (Get_Name_String (Pkg_Name));
852 end Register_New_Package;
854 procedure Register_New_Package
856 Attributes : Attribute_Data_Array)
860 First_Attr : Attr_Node_Id := Empty_Attr;
861 Curr_Attr : Attr_Node_Id;
862 Attr_Kind : Attribute_Kind;
865 if Name'Length = 0 then
866 Fail ("cannot register a package with no name");
870 Pkg_Name := Name_Id_Of (Name);
872 for Index in Package_Attributes.First .. Package_Attributes.Last loop
873 if Package_Attributes.Table (Index).Name = Pkg_Name then
874 Fail ("cannot register a package with a non unique name"""
881 for Index in Attributes'Range loop
882 Attr_Name := Name_Id_Of (Attributes (Index).Name);
884 Curr_Attr := First_Attr;
885 while Curr_Attr /= Empty_Attr loop
886 if Attrs.Table (Curr_Attr).Name = Attr_Name then
887 Fail ("duplicate attribute name """
888 & Attributes (Index).Name
889 & """ in new package """
895 Curr_Attr := Attrs.Table (Curr_Attr).Next;
898 Attr_Kind := Attributes (Index).Attr_Kind;
900 if Attributes (Index).Index_Is_File_Name
901 and then not Osint.File_Names_Case_Sensitive
904 when Associative_Array =>
905 Attr_Kind := Case_Insensitive_Associative_Array;
907 when Optional_Index_Associative_Array =>
909 Optional_Index_Case_Insensitive_Associative_Array;
916 Attrs.Increment_Last;
917 Attrs.Table (Attrs.Last) :=
919 Var_Kind => Attributes (Index).Var_Kind,
920 Optional_Index => Attributes (Index).Opt_Index,
921 Attr_Kind => Attr_Kind,
923 Others_Allowed => False,
925 First_Attr := Attrs.Last;
928 Package_Attributes.Increment_Last;
929 Package_Attributes.Table (Package_Attributes.Last) :=
932 First_Attribute => First_Attr);
934 Add_Package_Name (Get_Name_String (Pkg_Name));
935 end Register_New_Package;
937 ---------------------------
938 -- Set_Attribute_Kind_Of --
939 ---------------------------
941 procedure Set_Attribute_Kind_Of
942 (Attribute : Attribute_Node_Id;
946 if Attribute /= Empty_Attribute then
947 Attrs.Table (Attribute.Value).Attr_Kind := To;
949 end Set_Attribute_Kind_Of;
951 --------------------------
952 -- Set_Variable_Kind_Of --
953 --------------------------
955 procedure Set_Variable_Kind_Of
956 (Attribute : Attribute_Node_Id;
960 if Attribute /= Empty_Attribute then
961 Attrs.Table (Attribute.Value).Var_Kind := To;
963 end Set_Variable_Kind_Of;
965 ----------------------
966 -- Variable_Kind_Of --
967 ----------------------
969 function Variable_Kind_Of
970 (Attribute : Attribute_Node_Id) return Variable_Kind
973 if Attribute = Empty_Attribute then
976 return Attrs.Table (Attribute.Value).Var_Kind;
978 end Variable_Kind_Of;
980 ------------------------
981 -- First_Attribute_Of --
982 ------------------------
984 function First_Attribute_Of
985 (Pkg : Package_Node_Id) return Attribute_Node_Id
988 if Pkg = Empty_Package then
989 return Empty_Attribute;
992 (Value => Package_Attributes.Table (Pkg.Value).First_Attribute);
994 end First_Attribute_Of;