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 ------------------------------------------------------------------------------
28 with Prj.Com; use Prj.Com;
29 with System.Case_Util; use System.Case_Util;
31 package body Prj.Attr is
33 -- Data for predefined attributes and packages
35 -- Names are in lower case and end with '#'
37 -- Package names are preceded by 'P'
39 -- Attribute names are preceded by two or three letters:
41 -- The first letter is one of
43 -- 's' for Single with optional index
45 -- 'l' for List of strings with optional indexes
47 -- The second letter is one of
48 -- 'V' for single variable
49 -- 'A' for associative array
50 -- 'a' for case insensitive associative array
51 -- 'b' for associative array, case insensitive if file names are case
53 -- 'c' same as 'b', with optional index
55 -- The third optional letter is
56 -- 'R' to indicate that the attribute is read-only
58 -- End is indicated by two consecutive '#'
60 Initialization_Data : constant String :=
62 -- project level attributes
71 "SVexternally_built#" &
82 "LVlocally_removed_files#" &
83 "SVsource_list_file#" &
90 "SVlibrary_version#" &
91 "LVlibrary_interface#" &
92 "SVlibrary_auto_init#" &
93 "LVlibrary_options#" &
94 "SVlibrary_src_dir#" &
95 "SVlibrary_ali_dir#" &
97 "SVlibrary_symbol_file#" &
98 "SVlibrary_symbol_policy#" &
99 "SVlibrary_reference_symbol_file#" &
101 -- Configuration - General
103 "SVdefault_language#" &
104 "LVrun_path_option#" &
105 "Satoolchain_version#" &
106 "Satoolchain_description#" &
108 -- Configuration - Libraries
110 "SVlibrary_builder#" &
111 "SVlibrary_support#" &
113 -- Configuration - Archives
115 "LVarchive_builder#" &
116 "LVarchive_indexer#" &
117 "SVarchive_suffix#" &
118 "LVlibrary_partial_linker#" &
120 -- Configuration - Shared libraries
122 "SVshared_library_prefix#" &
123 "SVshared_library_suffix#" &
124 "SVsymbolic_link_supported#" &
125 "SVlibrary_major_minor_id_supported#" &
126 "SVlibrary_auto_init_supported#" &
127 "LVshared_library_minimum_switches#" &
128 "LVlibrary_version_switches#" &
133 "Saspecification_suffix#" &
135 "Saimplementation_suffix#" &
137 "SVseparate_suffix#" &
139 "SVdot_replacement#" &
142 "sAimplementation#" &
144 "Laspecification_exceptions#" &
145 "Laimplementation_exceptions#" &
150 "Ladefault_switches#" &
152 "SVlocal_configuration_pragmas#" &
153 "Salocal_config_file#" &
155 -- Configuration - Compiling
160 -- Configuration - Mapping files
162 "Lamapping_file_switches#" &
163 "Samapping_spec_suffix#" &
164 "Samapping_body_suffix#" &
166 -- Configuration - Config files
168 "Laconfig_file_switches#" &
169 "Saconfig_body_file_name#" &
170 "Saconfig_spec_file_name#" &
171 "Saconfig_body_file_name_pattern#" &
172 "Saconfig_spec_file_name_pattern#" &
173 "Saconfig_file_unique#" &
175 -- Configuration - Dependencies
177 "Ladependency_switches#" &
178 "Lacompute_dependency#" &
180 -- Configuration - Search paths
182 "Lainclude_switches#" &
184 "Sainclude_path_file#" &
189 "Ladefault_switches#" &
192 "SVexecutable_suffix#" &
193 "SVglobal_configuration_pragmas#" &
194 "Saglobal_config_file#" &
204 "Ladefault_switches#" &
207 -- Configuration - Binding
212 "Saobjects_path_file#" &
217 "LVrequired_switches#" &
218 "Ladefault_switches#" &
220 "LVlinker_options#" &
222 -- Configuration - Linking
225 "LVexecutable_switch#" &
226 "SVlib_dir_switch#" &
227 "SVlib_name_switch#" &
229 -- package Cross_Reference
231 "Pcross_reference#" &
232 "Ladefault_switches#" &
238 "Ladefault_switches#" &
241 -- package Pretty_Printer
244 "Ladefault_switches#" &
250 "Ladefault_switches#" &
256 "Ladefault_switches#" &
262 "Ladefault_switches#" &
268 "Ladefault_switches#" &
274 "Ladefault_switches#" &
277 "SVcommunication_protocol#" &
278 "Sacompiler_command#" &
279 "SVdebugger_command#" &
282 "SVvcs_file_check#" &
292 Initialized : Boolean := False;
293 -- A flag to avoid multiple initialization
295 function Name_Id_Of (Name : String) return Name_Id;
296 -- Returns the Name_Id for Name in lower case
298 -----------------------
299 -- Attribute_Kind_Of --
300 -----------------------
302 function Attribute_Kind_Of
303 (Attribute : Attribute_Node_Id) return Attribute_Kind
306 if Attribute = Empty_Attribute then
309 return Attrs.Table (Attribute.Value).Attr_Kind;
311 end Attribute_Kind_Of;
313 -----------------------
314 -- Attribute_Name_Of --
315 -----------------------
317 function Attribute_Name_Of (Attribute : Attribute_Node_Id) return Name_Id is
319 if Attribute = Empty_Attribute then
322 return Attrs.Table (Attribute.Value).Name;
324 end Attribute_Name_Of;
326 --------------------------
327 -- Attribute_Node_Id_Of --
328 --------------------------
330 function Attribute_Node_Id_Of
332 Starting_At : Attribute_Node_Id) return Attribute_Node_Id
334 Id : Attr_Node_Id := Starting_At.Value;
337 while Id /= Empty_Attr
338 and then Attrs.Table (Id).Name /= Name
340 Id := Attrs.Table (Id).Next;
343 return (Value => Id);
344 end Attribute_Node_Id_Of;
350 procedure Initialize is
351 Start : Positive := Initialization_Data'First;
352 Finish : Positive := Start;
353 Current_Package : Pkg_Node_Id := Empty_Pkg;
354 Current_Attribute : Attr_Node_Id := Empty_Attr;
355 Is_An_Attribute : Boolean := False;
356 Var_Kind : Variable_Kind := Undefined;
357 Optional_Index : Boolean := False;
358 Attr_Kind : Attribute_Kind := Single;
359 Package_Name : Name_Id := No_Name;
360 Attribute_Name : Name_Id := No_Name;
361 First_Attribute : Attr_Node_Id := Attr.First_Attribute;
364 function Attribute_Location return String;
365 -- Returns a string depending if we are in the project level attributes
366 -- or in the attributes of a package.
368 ------------------------
369 -- Attribute_Location --
370 ------------------------
372 function Attribute_Location return String is
374 if Package_Name = No_Name then
375 return "project level attributes";
378 return "attribute of package """ &
379 Get_Name_String (Package_Name) & """";
381 end Attribute_Location;
383 -- Start of processing for Initialize
386 -- Don't allow Initialize action to be repeated
392 -- Make sure the two tables are empty
395 Package_Attributes.Init;
397 while Initialization_Data (Start) /= '#' loop
398 Is_An_Attribute := True;
399 case Initialization_Data (Start) is
402 -- New allowed package
407 while Initialization_Data (Finish) /= '#' loop
408 Finish := Finish + 1;
412 Name_Id_Of (Initialization_Data (Start .. Finish - 1));
414 for Index in First_Package .. Package_Attributes.Last loop
415 if Package_Name = Package_Attributes.Table (Index).Name then
416 Osint.Fail ("duplicate name """,
417 Initialization_Data (Start .. Finish - 1),
418 """ in predefined packages.");
422 Is_An_Attribute := False;
423 Current_Attribute := Empty_Attr;
424 Package_Attributes.Increment_Last;
425 Current_Package := Package_Attributes.Last;
426 Package_Attributes.Table (Current_Package) :=
427 (Name => Package_Name,
429 First_Attribute => Empty_Attr);
434 Optional_Index := False;
438 Optional_Index := True;
442 Optional_Index := False;
446 Optional_Index := True;
452 if Is_An_Attribute then
457 case Initialization_Data (Start) is
462 Attr_Kind := Associative_Array;
465 Attr_Kind := Case_Insensitive_Associative_Array;
468 if Osint.File_Names_Case_Sensitive then
469 Attr_Kind := Associative_Array;
471 Attr_Kind := Case_Insensitive_Associative_Array;
475 if Osint.File_Names_Case_Sensitive then
476 Attr_Kind := Optional_Index_Associative_Array;
479 Optional_Index_Case_Insensitive_Associative_Array;
488 if Initialization_Data (Start) = 'R' then
498 while Initialization_Data (Finish) /= '#' loop
499 Finish := Finish + 1;
503 Name_Id_Of (Initialization_Data (Start .. Finish - 1));
504 Attrs.Increment_Last;
506 if Current_Attribute = Empty_Attr then
507 First_Attribute := Attrs.Last;
509 if Current_Package /= Empty_Pkg then
510 Package_Attributes.Table (Current_Package).First_Attribute
515 -- Check that there are no duplicate attributes
517 for Index in First_Attribute .. Attrs.Last - 1 loop
518 if Attribute_Name = Attrs.Table (Index).Name then
519 Osint.Fail ("duplicate attribute """,
520 Initialization_Data (Start .. Finish - 1),
521 """ in " & Attribute_Location);
525 Attrs.Table (Current_Attribute).Next :=
529 Current_Attribute := Attrs.Last;
530 Attrs.Table (Current_Attribute) :=
531 (Name => Attribute_Name,
532 Var_Kind => Var_Kind,
533 Optional_Index => Optional_Index,
534 Attr_Kind => Attr_Kind,
535 Read_Only => Read_Only,
548 function Is_Read_Only (Attribute : Attribute_Node_Id) return Boolean is
550 return Attrs.Table (Attribute.Value).Read_Only;
557 function Name_Id_Of (Name : String) return Name_Id is
560 Add_Str_To_Name_Buffer (Name);
561 To_Lower (Name_Buffer (1 .. Name_Len));
569 function Next_Attribute
570 (After : Attribute_Node_Id) return Attribute_Node_Id
573 if After = Empty_Attribute then
574 return Empty_Attribute;
576 return (Value => Attrs.Table (After.Value).Next);
580 -----------------------
581 -- Optional_Index_Of --
582 -----------------------
584 function Optional_Index_Of (Attribute : Attribute_Node_Id) return Boolean is
586 if Attribute = Empty_Attribute then
589 return Attrs.Table (Attribute.Value).Optional_Index;
591 end Optional_Index_Of;
593 ------------------------
594 -- Package_Node_Id_Of --
595 ------------------------
597 function Package_Node_Id_Of (Name : Name_Id) return Package_Node_Id is
599 for Index in Package_Attributes.First .. Package_Attributes.Last loop
600 if Package_Attributes.Table (Index).Name = Name then
601 return (Value => Index);
605 -- If there is no package with this name, return Empty_Package
607 return Empty_Package;
608 end Package_Node_Id_Of;
610 ----------------------------
611 -- Register_New_Attribute --
612 ----------------------------
614 procedure Register_New_Attribute
616 In_Package : Package_Node_Id;
617 Attr_Kind : Defined_Attribute_Kind;
618 Var_Kind : Defined_Variable_Kind;
619 Index_Is_File_Name : Boolean := False;
620 Opt_Index : Boolean := False)
623 First_Attr : Attr_Node_Id := Empty_Attr;
624 Curr_Attr : Attr_Node_Id;
625 Real_Attr_Kind : Attribute_Kind;
628 if Name'Length = 0 then
629 Fail ("cannot register an attribute with no name");
633 if In_Package = Empty_Package then
634 Fail ("attempt to add attribute """, Name,
635 """ to an undefined package");
639 Attr_Name := Name_Id_Of (Name);
642 Package_Attributes.Table (In_Package.Value).First_Attribute;
644 -- Check if attribute name is a duplicate
646 Curr_Attr := First_Attr;
647 while Curr_Attr /= Empty_Attr loop
648 if Attrs.Table (Curr_Attr).Name = Attr_Name then
649 Fail ("duplicate attribute name """, Name,
652 (Package_Attributes.Table (In_Package.Value).Name) &
657 Curr_Attr := Attrs.Table (Curr_Attr).Next;
660 Real_Attr_Kind := Attr_Kind;
662 -- If Index_Is_File_Name, change the attribute kind if necessary
664 if Index_Is_File_Name and then not Osint.File_Names_Case_Sensitive then
666 when Associative_Array =>
667 Real_Attr_Kind := Case_Insensitive_Associative_Array;
669 when Optional_Index_Associative_Array =>
671 Optional_Index_Case_Insensitive_Associative_Array;
678 -- Add the new attribute
680 Attrs.Increment_Last;
681 Attrs.Table (Attrs.Last) :=
683 Var_Kind => Var_Kind,
684 Optional_Index => Opt_Index,
685 Attr_Kind => Real_Attr_Kind,
688 Package_Attributes.Table (In_Package.Value).First_Attribute :=
690 end Register_New_Attribute;
692 --------------------------
693 -- Register_New_Package --
694 --------------------------
696 procedure Register_New_Package (Name : String; Id : out Package_Node_Id) is
700 if Name'Length = 0 then
701 Fail ("cannot register a package with no name");
706 Pkg_Name := Name_Id_Of (Name);
708 for Index in Package_Attributes.First .. Package_Attributes.Last loop
709 if Package_Attributes.Table (Index).Name = Pkg_Name then
710 Fail ("cannot register a package with a non unique name""",
717 Package_Attributes.Increment_Last;
718 Id := (Value => Package_Attributes.Last);
719 Package_Attributes.Table (Package_Attributes.Last) :=
722 First_Attribute => Empty_Attr);
723 end Register_New_Package;
725 procedure Register_New_Package
727 Attributes : Attribute_Data_Array)
731 First_Attr : Attr_Node_Id := Empty_Attr;
732 Curr_Attr : Attr_Node_Id;
733 Attr_Kind : Attribute_Kind;
736 if Name'Length = 0 then
737 Fail ("cannot register a package with no name");
741 Pkg_Name := Name_Id_Of (Name);
743 for Index in Package_Attributes.First .. Package_Attributes.Last loop
744 if Package_Attributes.Table (Index).Name = Pkg_Name then
745 Fail ("cannot register a package with a non unique name""",
751 for Index in Attributes'Range loop
752 Attr_Name := Name_Id_Of (Attributes (Index).Name);
754 Curr_Attr := First_Attr;
755 while Curr_Attr /= Empty_Attr loop
756 if Attrs.Table (Curr_Attr).Name = Attr_Name then
757 Fail ("duplicate attribute name """, Attributes (Index).Name,
758 """ in new package """ & Name & """");
762 Curr_Attr := Attrs.Table (Curr_Attr).Next;
765 Attr_Kind := Attributes (Index).Attr_Kind;
767 if Attributes (Index).Index_Is_File_Name
768 and then not Osint.File_Names_Case_Sensitive
771 when Associative_Array =>
772 Attr_Kind := Case_Insensitive_Associative_Array;
774 when Optional_Index_Associative_Array =>
776 Optional_Index_Case_Insensitive_Associative_Array;
783 Attrs.Increment_Last;
784 Attrs.Table (Attrs.Last) :=
786 Var_Kind => Attributes (Index).Var_Kind,
787 Optional_Index => Attributes (Index).Opt_Index,
788 Attr_Kind => Attr_Kind,
791 First_Attr := Attrs.Last;
794 Package_Attributes.Increment_Last;
795 Package_Attributes.Table (Package_Attributes.Last) :=
798 First_Attribute => First_Attr);
799 end Register_New_Package;
801 ---------------------------
802 -- Set_Attribute_Kind_Of --
803 ---------------------------
805 procedure Set_Attribute_Kind_Of
806 (Attribute : Attribute_Node_Id;
810 if Attribute /= Empty_Attribute then
811 Attrs.Table (Attribute.Value).Attr_Kind := To;
813 end Set_Attribute_Kind_Of;
815 --------------------------
816 -- Set_Variable_Kind_Of --
817 --------------------------
819 procedure Set_Variable_Kind_Of
820 (Attribute : Attribute_Node_Id;
824 if Attribute /= Empty_Attribute then
825 Attrs.Table (Attribute.Value).Var_Kind := To;
827 end Set_Variable_Kind_Of;
829 ----------------------
830 -- Variable_Kind_Of --
831 ----------------------
833 function Variable_Kind_Of
834 (Attribute : Attribute_Node_Id) return Variable_Kind
837 if Attribute = Empty_Attribute then
840 return Attrs.Table (Attribute.Value).Var_Kind;
842 end Variable_Kind_Of;
844 ------------------------
845 -- First_Attribute_Of --
846 ------------------------
848 function First_Attribute_Of
849 (Pkg : Package_Node_Id) return Attribute_Node_Id
852 if Pkg = Empty_Package then
853 return Empty_Attribute;
856 (Value => Package_Attributes.Table (Pkg.Value).First_Attribute);
858 end First_Attribute_Of;