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_auto_init#" &
109 "LVleading_library_options#" &
110 "LVlibrary_options#" &
111 "SVlibrary_src_dir#" &
112 "SVlibrary_ali_dir#" &
114 "SVlibrary_symbol_file#" &
115 "SVlibrary_symbol_policy#" &
116 "SVlibrary_reference_symbol_file#" &
118 -- Configuration - General
120 "SVdefault_language#" &
121 "LVrun_path_option#" &
122 "SVrun_path_origin#" &
123 "SVseparate_run_path_options#" &
124 "Satoolchain_version#" &
125 "Satoolchain_description#" &
126 "Saobject_generated#" &
127 "Saobjects_linked#" &
130 -- Configuration - Libraries
132 "SVlibrary_builder#" &
133 "SVlibrary_support#" &
135 -- Configuration - Archives
137 "LVarchive_builder#" &
138 "LVarchive_builder_append_option#" &
139 "LVarchive_indexer#" &
140 "SVarchive_suffix#" &
141 "LVlibrary_partial_linker#" &
143 -- Configuration - Shared libraries
145 "SVshared_library_prefix#" &
146 "SVshared_library_suffix#" &
147 "SVsymbolic_link_supported#" &
148 "SVlibrary_major_minor_id_supported#" &
149 "SVlibrary_auto_init_supported#" &
150 "LVshared_library_minimum_switches#" &
151 "LVlibrary_version_switches#" &
152 "SVlibrary_install_name_option#" &
153 "Saruntime_library_dir#" &
154 "Saruntime_source_dir#" &
157 -- Some attributes are obsolescent, and renamed in the tree (see
158 -- Prj.Dect.Rename_Obsolescent_Attributes).
161 "Saspecification_suffix#" & -- Always renamed to "spec_suffix" in tree
163 "Saimplementation_suffix#" & -- Always renamed to "body_suffix" in tree
165 "SVseparate_suffix#" &
167 "SVdot_replacement#" &
168 "saspecification#" & -- Always renamed to "spec" in project tree
170 "saimplementation#" & -- Always renamed to "body" in project tree
172 "Laspecification_exceptions#" &
173 "Laimplementation_exceptions#" &
178 "Ladefault_switches#" &
180 "SVlocal_configuration_pragmas#" &
181 "Salocal_config_file#" &
183 -- Configuration - Compiling
187 "Sadependency_kind#" &
188 "Larequired_switches#" &
189 "Laleading_required_switches#" &
190 "Latrailing_required_switches#" &
193 "Lasource_file_switches#" &
194 "Saobject_file_suffix#" &
195 "Laobject_file_switches#" &
196 "Lamulti_unit_switches#" &
197 "Samulti_unit_object_separator#" &
199 -- Configuration - Mapping files
201 "Lamapping_file_switches#" &
202 "Samapping_spec_suffix#" &
203 "Samapping_body_suffix#" &
205 -- Configuration - Config files
207 "Laconfig_file_switches#" &
208 "Saconfig_body_file_name#" &
209 "Saconfig_body_file_name_index#" &
210 "Saconfig_body_file_name_pattern#" &
211 "Saconfig_spec_file_name#" &
212 "Saconfig_spec_file_name_index#" &
213 "Saconfig_spec_file_name_pattern#" &
214 "Saconfig_file_unique#" &
216 -- Configuration - Dependencies
218 "Ladependency_switches#" &
219 "Ladependency_driver#" &
221 -- Configuration - Search paths
223 "Lainclude_switches#" &
225 "Sainclude_path_file#" &
230 "Ladefault_switches#" &
232 "Lcglobal_compilation_switches#" &
234 "SVexecutable_suffix#" &
235 "SVglobal_configuration_pragmas#" &
236 "Saglobal_config_file#" &
246 "Ladefault_switches#" &
249 -- Configuration - Binding
252 "Larequired_switches#" &
255 "Saobjects_path_file#" &
260 "LVrequired_switches#" &
261 "Ladefault_switches#" &
262 "LcOleading_switches#" &
264 "LVlinker_options#" &
265 "SVmap_file_option#" &
267 -- Configuration - Linking
270 "LVexecutable_switch#" &
271 "SVlib_dir_switch#" &
272 "SVlib_name_switch#" &
274 -- Configuration - Response files
276 "SVmax_command_line_length#" &
277 "SVresponse_file_format#" &
278 "LVresponse_file_switches#" &
280 -- package Cross_Reference
282 "Pcross_reference#" &
283 "Ladefault_switches#" &
289 "Ladefault_switches#" &
292 -- package Pretty_Printer
295 "Ladefault_switches#" &
301 "Ladefault_switches#" &
307 "Ladefault_switches#" &
310 -- package Synchronize
313 "Ladefault_switches#" &
319 "Ladefault_switches#" &
325 "Ladefault_switches#" &
331 "Ladefault_switches#" &
334 "SVcommunication_protocol#" &
335 "Sacompiler_command#" &
336 "SVdebugger_command#" &
339 "SVvcs_file_check#" &
341 "SVdocumentation_dir#" &
350 Initialized : Boolean := False;
351 -- A flag to avoid multiple initialization
353 Package_Names : String_List_Access := new Strings.String_List (1 .. 20);
354 Last_Package_Name : Natural := 0;
355 -- Package_Names (1 .. Last_Package_Name) contains the list of the known
356 -- package names, coming from the Initialization_Data string or from
357 -- calls to one of the two procedures Register_New_Package.
359 procedure Add_Package_Name (Name : String);
360 -- Add a package name in the Package_Name list, extending it, if necessary
362 function Name_Id_Of (Name : String) return Name_Id;
363 -- Returns the Name_Id for Name in lower case
365 ----------------------
366 -- Add_Package_Name --
367 ----------------------
369 procedure Add_Package_Name (Name : String) is
371 if Last_Package_Name = Package_Names'Last then
373 New_List : constant Strings.String_List_Access :=
374 new Strings.String_List (1 .. Package_Names'Last * 2);
376 New_List (Package_Names'Range) := Package_Names.all;
377 Package_Names := New_List;
381 Last_Package_Name := Last_Package_Name + 1;
382 Package_Names (Last_Package_Name) := new String'(Name);
383 end Add_Package_Name;
385 -----------------------
386 -- Attribute_Kind_Of --
387 -----------------------
389 function Attribute_Kind_Of
390 (Attribute : Attribute_Node_Id) return Attribute_Kind
393 if Attribute = Empty_Attribute then
396 return Attrs.Table (Attribute.Value).Attr_Kind;
398 end Attribute_Kind_Of;
400 -----------------------
401 -- Attribute_Name_Of --
402 -----------------------
404 function Attribute_Name_Of (Attribute : Attribute_Node_Id) return Name_Id is
406 if Attribute = Empty_Attribute then
409 return Attrs.Table (Attribute.Value).Name;
411 end Attribute_Name_Of;
413 --------------------------
414 -- Attribute_Node_Id_Of --
415 --------------------------
417 function Attribute_Node_Id_Of
419 Starting_At : Attribute_Node_Id) return Attribute_Node_Id
421 Id : Attr_Node_Id := Starting_At.Value;
424 while Id /= Empty_Attr
425 and then Attrs.Table (Id).Name /= Name
427 Id := Attrs.Table (Id).Next;
430 return (Value => Id);
431 end Attribute_Node_Id_Of;
437 procedure Initialize is
438 Start : Positive := Initialization_Data'First;
439 Finish : Positive := Start;
440 Current_Package : Pkg_Node_Id := Empty_Pkg;
441 Current_Attribute : Attr_Node_Id := Empty_Attr;
442 Is_An_Attribute : Boolean := False;
443 Var_Kind : Variable_Kind := Undefined;
444 Optional_Index : Boolean := False;
445 Attr_Kind : Attribute_Kind := Single;
446 Package_Name : Name_Id := No_Name;
447 Attribute_Name : Name_Id := No_Name;
448 First_Attribute : Attr_Node_Id := Attr.First_Attribute;
450 Others_Allowed : Boolean;
452 function Attribute_Location return String;
453 -- Returns a string depending if we are in the project level attributes
454 -- or in the attributes of a package.
456 ------------------------
457 -- Attribute_Location --
458 ------------------------
460 function Attribute_Location return String is
462 if Package_Name = No_Name then
463 return "project level attributes";
466 return "attribute of package """ &
467 Get_Name_String (Package_Name) & """";
469 end Attribute_Location;
471 -- Start of processing for Initialize
474 -- Don't allow Initialize action to be repeated
480 -- Make sure the two tables are empty
483 Package_Attributes.Init;
485 while Initialization_Data (Start) /= '#' loop
486 Is_An_Attribute := True;
487 case Initialization_Data (Start) is
490 -- New allowed package
495 while Initialization_Data (Finish) /= '#' loop
496 Finish := Finish + 1;
500 Name_Id_Of (Initialization_Data (Start .. Finish - 1));
502 for Index in First_Package .. Package_Attributes.Last loop
503 if Package_Name = Package_Attributes.Table (Index).Name then
504 Osint.Fail ("duplicate name """
505 & Initialization_Data (Start .. Finish - 1)
506 & """ in predefined packages.");
510 Is_An_Attribute := False;
511 Current_Attribute := Empty_Attr;
512 Package_Attributes.Increment_Last;
513 Current_Package := Package_Attributes.Last;
514 Package_Attributes.Table (Current_Package) :=
515 (Name => Package_Name,
517 First_Attribute => Empty_Attr);
520 Add_Package_Name (Get_Name_String (Package_Name));
524 Optional_Index := False;
528 Optional_Index := True;
532 Optional_Index := False;
536 Optional_Index := True;
542 if Is_An_Attribute then
547 case Initialization_Data (Start) is
552 Attr_Kind := Associative_Array;
555 Attr_Kind := Case_Insensitive_Associative_Array;
558 if Osint.File_Names_Case_Sensitive then
559 Attr_Kind := Associative_Array;
561 Attr_Kind := Case_Insensitive_Associative_Array;
565 if Osint.File_Names_Case_Sensitive then
566 Attr_Kind := Optional_Index_Associative_Array;
569 Optional_Index_Case_Insensitive_Associative_Array;
579 Others_Allowed := False;
581 if Initialization_Data (Start) = 'R' then
585 elsif Initialization_Data (Start) = 'O' then
586 Others_Allowed := True;
592 while Initialization_Data (Finish) /= '#' loop
593 Finish := Finish + 1;
597 Name_Id_Of (Initialization_Data (Start .. Finish - 1));
598 Attrs.Increment_Last;
600 if Current_Attribute = Empty_Attr then
601 First_Attribute := Attrs.Last;
603 if Current_Package /= Empty_Pkg then
604 Package_Attributes.Table (Current_Package).First_Attribute
609 -- Check that there are no duplicate attributes
611 for Index in First_Attribute .. Attrs.Last - 1 loop
612 if Attribute_Name = Attrs.Table (Index).Name then
613 Osint.Fail ("duplicate attribute """
614 & Initialization_Data (Start .. Finish - 1)
615 & """ in " & Attribute_Location);
619 Attrs.Table (Current_Attribute).Next :=
623 Current_Attribute := Attrs.Last;
624 Attrs.Table (Current_Attribute) :=
625 (Name => Attribute_Name,
626 Var_Kind => Var_Kind,
627 Optional_Index => Optional_Index,
628 Attr_Kind => Attr_Kind,
629 Read_Only => Read_Only,
630 Others_Allowed => Others_Allowed,
643 function Is_Read_Only (Attribute : Attribute_Node_Id) return Boolean is
645 return Attrs.Table (Attribute.Value).Read_Only;
652 function Name_Id_Of (Name : String) return Name_Id is
655 Add_Str_To_Name_Buffer (Name);
656 To_Lower (Name_Buffer (1 .. Name_Len));
664 function Next_Attribute
665 (After : Attribute_Node_Id) return Attribute_Node_Id
668 if After = Empty_Attribute then
669 return Empty_Attribute;
671 return (Value => Attrs.Table (After.Value).Next);
675 -----------------------
676 -- Optional_Index_Of --
677 -----------------------
679 function Optional_Index_Of (Attribute : Attribute_Node_Id) return Boolean is
681 if Attribute = Empty_Attribute then
684 return Attrs.Table (Attribute.Value).Optional_Index;
686 end Optional_Index_Of;
688 function Others_Allowed_For
689 (Attribute : Attribute_Node_Id) return Boolean
692 if Attribute = Empty_Attribute then
695 return Attrs.Table (Attribute.Value).Others_Allowed;
697 end Others_Allowed_For;
699 -----------------------
700 -- Package_Name_List --
701 -----------------------
703 function Package_Name_List return Strings.String_List is
705 return Package_Names (1 .. Last_Package_Name);
706 end Package_Name_List;
708 ------------------------
709 -- Package_Node_Id_Of --
710 ------------------------
712 function Package_Node_Id_Of (Name : Name_Id) return Package_Node_Id is
714 for Index in Package_Attributes.First .. Package_Attributes.Last loop
715 if Package_Attributes.Table (Index).Name = Name then
716 if Package_Attributes.Table (Index).Known then
717 return (Value => Index);
719 return Unknown_Package;
724 -- If there is no package with this name, return Empty_Package
726 return Empty_Package;
727 end Package_Node_Id_Of;
729 ----------------------------
730 -- Register_New_Attribute --
731 ----------------------------
733 procedure Register_New_Attribute
735 In_Package : Package_Node_Id;
736 Attr_Kind : Defined_Attribute_Kind;
737 Var_Kind : Defined_Variable_Kind;
738 Index_Is_File_Name : Boolean := False;
739 Opt_Index : Boolean := False)
742 First_Attr : Attr_Node_Id := Empty_Attr;
743 Curr_Attr : Attr_Node_Id;
744 Real_Attr_Kind : Attribute_Kind;
747 if Name'Length = 0 then
748 Fail ("cannot register an attribute with no name");
752 if In_Package = Empty_Package then
753 Fail ("attempt to add attribute """
755 & """ to an undefined package");
759 Attr_Name := Name_Id_Of (Name);
762 Package_Attributes.Table (In_Package.Value).First_Attribute;
764 -- Check if attribute name is a duplicate
766 Curr_Attr := First_Attr;
767 while Curr_Attr /= Empty_Attr loop
768 if Attrs.Table (Curr_Attr).Name = Attr_Name then
769 Fail ("duplicate attribute name """
773 (Package_Attributes.Table (In_Package.Value).Name)
778 Curr_Attr := Attrs.Table (Curr_Attr).Next;
781 Real_Attr_Kind := Attr_Kind;
783 -- If Index_Is_File_Name, change the attribute kind if necessary
785 if Index_Is_File_Name and then not Osint.File_Names_Case_Sensitive then
787 when Associative_Array =>
788 Real_Attr_Kind := Case_Insensitive_Associative_Array;
790 when Optional_Index_Associative_Array =>
792 Optional_Index_Case_Insensitive_Associative_Array;
799 -- Add the new attribute
801 Attrs.Increment_Last;
802 Attrs.Table (Attrs.Last) :=
804 Var_Kind => Var_Kind,
805 Optional_Index => Opt_Index,
806 Attr_Kind => Real_Attr_Kind,
808 Others_Allowed => False,
811 Package_Attributes.Table (In_Package.Value).First_Attribute :=
813 end Register_New_Attribute;
815 --------------------------
816 -- Register_New_Package --
817 --------------------------
819 procedure Register_New_Package (Name : String; Id : out Package_Node_Id) is
823 if Name'Length = 0 then
824 Fail ("cannot register a package with no name");
829 Pkg_Name := Name_Id_Of (Name);
831 for Index in Package_Attributes.First .. Package_Attributes.Last loop
832 if Package_Attributes.Table (Index).Name = Pkg_Name then
833 Fail ("cannot register a package with a non unique name"""
841 Package_Attributes.Increment_Last;
842 Id := (Value => Package_Attributes.Last);
843 Package_Attributes.Table (Package_Attributes.Last) :=
846 First_Attribute => Empty_Attr);
848 Add_Package_Name (Get_Name_String (Pkg_Name));
849 end Register_New_Package;
851 procedure Register_New_Package
853 Attributes : Attribute_Data_Array)
857 First_Attr : Attr_Node_Id := Empty_Attr;
858 Curr_Attr : Attr_Node_Id;
859 Attr_Kind : Attribute_Kind;
862 if Name'Length = 0 then
863 Fail ("cannot register a package with no name");
867 Pkg_Name := Name_Id_Of (Name);
869 for Index in Package_Attributes.First .. Package_Attributes.Last loop
870 if Package_Attributes.Table (Index).Name = Pkg_Name then
871 Fail ("cannot register a package with a non unique name"""
878 for Index in Attributes'Range loop
879 Attr_Name := Name_Id_Of (Attributes (Index).Name);
881 Curr_Attr := First_Attr;
882 while Curr_Attr /= Empty_Attr loop
883 if Attrs.Table (Curr_Attr).Name = Attr_Name then
884 Fail ("duplicate attribute name """
885 & Attributes (Index).Name
886 & """ in new package """
892 Curr_Attr := Attrs.Table (Curr_Attr).Next;
895 Attr_Kind := Attributes (Index).Attr_Kind;
897 if Attributes (Index).Index_Is_File_Name
898 and then not Osint.File_Names_Case_Sensitive
901 when Associative_Array =>
902 Attr_Kind := Case_Insensitive_Associative_Array;
904 when Optional_Index_Associative_Array =>
906 Optional_Index_Case_Insensitive_Associative_Array;
913 Attrs.Increment_Last;
914 Attrs.Table (Attrs.Last) :=
916 Var_Kind => Attributes (Index).Var_Kind,
917 Optional_Index => Attributes (Index).Opt_Index,
918 Attr_Kind => Attr_Kind,
920 Others_Allowed => False,
922 First_Attr := Attrs.Last;
925 Package_Attributes.Increment_Last;
926 Package_Attributes.Table (Package_Attributes.Last) :=
929 First_Attribute => First_Attr);
931 Add_Package_Name (Get_Name_String (Pkg_Name));
932 end Register_New_Package;
934 ---------------------------
935 -- Set_Attribute_Kind_Of --
936 ---------------------------
938 procedure Set_Attribute_Kind_Of
939 (Attribute : Attribute_Node_Id;
943 if Attribute /= Empty_Attribute then
944 Attrs.Table (Attribute.Value).Attr_Kind := To;
946 end Set_Attribute_Kind_Of;
948 --------------------------
949 -- Set_Variable_Kind_Of --
950 --------------------------
952 procedure Set_Variable_Kind_Of
953 (Attribute : Attribute_Node_Id;
957 if Attribute /= Empty_Attribute then
958 Attrs.Table (Attribute.Value).Var_Kind := To;
960 end Set_Variable_Kind_Of;
962 ----------------------
963 -- Variable_Kind_Of --
964 ----------------------
966 function Variable_Kind_Of
967 (Attribute : Attribute_Node_Id) return Variable_Kind
970 if Attribute = Empty_Attribute then
973 return Attrs.Table (Attribute.Value).Var_Kind;
975 end Variable_Kind_Of;
977 ------------------------
978 -- First_Attribute_Of --
979 ------------------------
981 function First_Attribute_Of
982 (Pkg : Package_Node_Id) return Attribute_Node_Id
985 if Pkg = Empty_Package then
986 return Empty_Attribute;
989 (Value => Package_Attributes.Table (Pkg.Value).First_Attribute);
991 end First_Attribute_Of;