+ ------------------
+ -- Is_Read_Only --
+ ------------------
+
+ function Is_Read_Only (Attribute : Attribute_Node_Id) return Boolean is
+ begin
+ return Attrs.Table (Attribute.Value).Read_Only;
+ end Is_Read_Only;
+
+ ----------------
+ -- Name_Id_Of --
+ ----------------
+
+ function Name_Id_Of (Name : String) return Name_Id is
+ begin
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Name);
+ To_Lower (Name_Buffer (1 .. Name_Len));
+ return Name_Find;
+ end Name_Id_Of;
+
+ --------------------
+ -- Next_Attribute --
+ --------------------
+
+ function Next_Attribute
+ (After : Attribute_Node_Id) return Attribute_Node_Id
+ is
+ begin
+ if After = Empty_Attribute then
+ return Empty_Attribute;
+ else
+ return (Value => Attrs.Table (After.Value).Next);
+ end if;
+ end Next_Attribute;
+
+ -----------------------
+ -- Optional_Index_Of --
+ -----------------------
+
+ function Optional_Index_Of (Attribute : Attribute_Node_Id) return Boolean is
+ begin
+ if Attribute = Empty_Attribute then
+ return False;
+ else
+ return Attrs.Table (Attribute.Value).Optional_Index;
+ end if;
+ end Optional_Index_Of;
+
+ function Others_Allowed_For
+ (Attribute : Attribute_Node_Id) return Boolean
+ is
+ begin
+ if Attribute = Empty_Attribute then
+ return False;
+ else
+ return Attrs.Table (Attribute.Value).Others_Allowed;
+ end if;
+ end Others_Allowed_For;
+
+ -----------------------
+ -- Package_Name_List --
+ -----------------------
+
+ function Package_Name_List return Strings.String_List is
+ begin
+ return Package_Names (1 .. Last_Package_Name);
+ end Package_Name_List;
+
+ ------------------------
+ -- Package_Node_Id_Of --
+ ------------------------
+
+ function Package_Node_Id_Of (Name : Name_Id) return Package_Node_Id is
+ begin
+ for Index in Package_Attributes.First .. Package_Attributes.Last loop
+ if Package_Attributes.Table (Index).Name = Name then
+ if Package_Attributes.Table (Index).Known then
+ return (Value => Index);
+ else
+ return Unknown_Package;
+ end if;
+ end if;
+ end loop;
+
+ -- If there is no package with this name, return Empty_Package
+
+ return Empty_Package;
+ end Package_Node_Id_Of;
+
+ ----------------------------
+ -- Register_New_Attribute --
+ ----------------------------
+
+ procedure Register_New_Attribute
+ (Name : String;
+ In_Package : Package_Node_Id;
+ Attr_Kind : Defined_Attribute_Kind;
+ Var_Kind : Defined_Variable_Kind;
+ Index_Is_File_Name : Boolean := False;
+ Opt_Index : Boolean := False)
+ is
+ Attr_Name : Name_Id;
+ First_Attr : Attr_Node_Id := Empty_Attr;
+ Curr_Attr : Attr_Node_Id;
+ Real_Attr_Kind : Attribute_Kind;
+
+ begin
+ if Name'Length = 0 then
+ Fail ("cannot register an attribute with no name");
+ raise Project_Error;
+ end if;
+
+ if In_Package = Empty_Package then
+ Fail ("attempt to add attribute """
+ & Name
+ & """ to an undefined package");
+ raise Project_Error;
+ end if;
+
+ Attr_Name := Name_Id_Of (Name);
+
+ First_Attr :=
+ Package_Attributes.Table (In_Package.Value).First_Attribute;
+
+ -- Check if attribute name is a duplicate
+
+ Curr_Attr := First_Attr;
+ while Curr_Attr /= Empty_Attr loop
+ if Attrs.Table (Curr_Attr).Name = Attr_Name then
+ Fail ("duplicate attribute name """
+ & Name
+ & """ in package """
+ & Get_Name_String
+ (Package_Attributes.Table (In_Package.Value).Name)
+ & """");
+ raise Project_Error;
+ end if;
+
+ Curr_Attr := Attrs.Table (Curr_Attr).Next;
+ end loop;
+
+ Real_Attr_Kind := Attr_Kind;
+
+ -- If Index_Is_File_Name, change the attribute kind if necessary
+
+ if Index_Is_File_Name and then not Osint.File_Names_Case_Sensitive then
+ case Attr_Kind is
+ when Associative_Array =>
+ Real_Attr_Kind := Case_Insensitive_Associative_Array;
+
+ when Optional_Index_Associative_Array =>
+ Real_Attr_Kind :=
+ Optional_Index_Case_Insensitive_Associative_Array;
+
+ when others =>
+ null;
+ end case;
+ end if;
+
+ -- Add the new attribute
+
+ Attrs.Increment_Last;
+ Attrs.Table (Attrs.Last) :=
+ (Name => Attr_Name,
+ Var_Kind => Var_Kind,
+ Optional_Index => Opt_Index,
+ Attr_Kind => Real_Attr_Kind,
+ Read_Only => False,
+ Others_Allowed => False,
+ Next => First_Attr);
+
+ Package_Attributes.Table (In_Package.Value).First_Attribute :=
+ Attrs.Last;
+ end Register_New_Attribute;
+
+ --------------------------
+ -- Register_New_Package --
+ --------------------------
+
+ procedure Register_New_Package (Name : String; Id : out Package_Node_Id) is
+ Pkg_Name : Name_Id;
+
+ begin
+ if Name'Length = 0 then
+ Fail ("cannot register a package with no name");
+ Id := Empty_Package;
+ return;
+ end if;
+
+ Pkg_Name := Name_Id_Of (Name);
+
+ for Index in Package_Attributes.First .. Package_Attributes.Last loop
+ if Package_Attributes.Table (Index).Name = Pkg_Name then
+ Fail ("cannot register a package with a non unique name"""
+ & Name
+ & """");
+ Id := Empty_Package;
+ return;
+ end if;
+ end loop;
+
+ Package_Attributes.Increment_Last;
+ Id := (Value => Package_Attributes.Last);
+ Package_Attributes.Table (Package_Attributes.Last) :=
+ (Name => Pkg_Name,
+ Known => True,
+ First_Attribute => Empty_Attr);
+
+ Add_Package_Name (Get_Name_String (Pkg_Name));
+ end Register_New_Package;
+
+ procedure Register_New_Package
+ (Name : String;
+ Attributes : Attribute_Data_Array)
+ is
+ Pkg_Name : Name_Id;
+ Attr_Name : Name_Id;
+ First_Attr : Attr_Node_Id := Empty_Attr;
+ Curr_Attr : Attr_Node_Id;
+ Attr_Kind : Attribute_Kind;
+
+ begin
+ if Name'Length = 0 then
+ Fail ("cannot register a package with no name");
+ raise Project_Error;
+ end if;
+
+ Pkg_Name := Name_Id_Of (Name);
+
+ for Index in Package_Attributes.First .. Package_Attributes.Last loop
+ if Package_Attributes.Table (Index).Name = Pkg_Name then
+ Fail ("cannot register a package with a non unique name"""
+ & Name
+ & """");
+ raise Project_Error;
+ end if;
+ end loop;
+
+ for Index in Attributes'Range loop
+ Attr_Name := Name_Id_Of (Attributes (Index).Name);
+
+ Curr_Attr := First_Attr;
+ while Curr_Attr /= Empty_Attr loop
+ if Attrs.Table (Curr_Attr).Name = Attr_Name then
+ Fail ("duplicate attribute name """
+ & Attributes (Index).Name
+ & """ in new package """
+ & Name
+ & """");
+ raise Project_Error;
+ end if;
+
+ Curr_Attr := Attrs.Table (Curr_Attr).Next;
+ end loop;
+
+ Attr_Kind := Attributes (Index).Attr_Kind;
+
+ if Attributes (Index).Index_Is_File_Name
+ and then not Osint.File_Names_Case_Sensitive
+ then
+ case Attr_Kind is
+ when Associative_Array =>
+ Attr_Kind := Case_Insensitive_Associative_Array;
+
+ when Optional_Index_Associative_Array =>
+ Attr_Kind :=
+ Optional_Index_Case_Insensitive_Associative_Array;
+
+ when others =>
+ null;
+ end case;
+ end if;
+
+ Attrs.Increment_Last;
+ Attrs.Table (Attrs.Last) :=
+ (Name => Attr_Name,
+ Var_Kind => Attributes (Index).Var_Kind,
+ Optional_Index => Attributes (Index).Opt_Index,
+ Attr_Kind => Attr_Kind,
+ Read_Only => False,
+ Others_Allowed => False,
+ Next => First_Attr);
+ First_Attr := Attrs.Last;
+ end loop;
+
+ Package_Attributes.Increment_Last;
+ Package_Attributes.Table (Package_Attributes.Last) :=
+ (Name => Pkg_Name,
+ Known => True,
+ First_Attribute => First_Attr);
+
+ Add_Package_Name (Get_Name_String (Pkg_Name));
+ end Register_New_Package;
+
+ ---------------------------
+ -- Set_Attribute_Kind_Of --
+ ---------------------------
+
+ procedure Set_Attribute_Kind_Of
+ (Attribute : Attribute_Node_Id;
+ To : Attribute_Kind)
+ is
+ begin
+ if Attribute /= Empty_Attribute then
+ Attrs.Table (Attribute.Value).Attr_Kind := To;
+ end if;
+ end Set_Attribute_Kind_Of;
+
+ --------------------------
+ -- Set_Variable_Kind_Of --
+ --------------------------
+
+ procedure Set_Variable_Kind_Of
+ (Attribute : Attribute_Node_Id;
+ To : Variable_Kind)
+ is
+ begin
+ if Attribute /= Empty_Attribute then
+ Attrs.Table (Attribute.Value).Var_Kind := To;
+ end if;
+ end Set_Variable_Kind_Of;
+
+ ----------------------
+ -- Variable_Kind_Of --
+ ----------------------
+
+ function Variable_Kind_Of
+ (Attribute : Attribute_Node_Id) return Variable_Kind
+ is
+ begin
+ if Attribute = Empty_Attribute then
+ return Undefined;
+ else
+ return Attrs.Table (Attribute.Value).Var_Kind;
+ end if;
+ end Variable_Kind_Of;
+
+ ------------------------
+ -- First_Attribute_Of --
+ ------------------------
+
+ function First_Attribute_Of
+ (Pkg : Package_Node_Id) return Attribute_Node_Id
+ is
+ begin
+ if Pkg = Empty_Package then
+ return Empty_Attribute;
+ else
+ return
+ (Value => Package_Attributes.Table (Pkg.Value).First_Attribute);
+ end if;
+ end First_Attribute_Of;
+