home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
gnat-2.06-src.tgz
/
tar.out
/
fsf
/
gnat
/
ada
/
uname.adb
< prev
next >
Wrap
Text File
|
1996-09-28
|
15KB
|
513 lines
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- U N A M E --
-- --
-- B o d y --
-- --
-- $Revision: 1.40 $ --
-- --
-- Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved --
-- --
-- The GNAT library is free software; you can redistribute it and/or modify --
-- it under terms of the GNU Library General Public License as published by --
-- the Free Software Foundation; either version 2, or (at your option) any --
-- later version. The GNAT library is distributed in the hope that it will --
-- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty --
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
-- Library General Public License for more details. You should have --
-- received a copy of the GNU Library General Public License along with --
-- the GNAT library; see the file COPYING.LIB. If not, write to the Free --
-- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
-- --
------------------------------------------------------------------------------
with Atree; use Atree;
with Casing; use Casing;
with Einfo; use Einfo;
with Lib; use Lib;
with Namet; use Namet;
with Nlists; use Nlists;
with Output; use Output;
with Sinfo; use Sinfo;
with Sinput; use Sinput;
with System.Parameters;
package body Uname is
System_Parameters_Max_Name_Length : constant :=
System.Parameters.Max_Name_Length;
-- ??? to deal with GNAT visibility problem
-------------------
-- Get_Body_Name --
-------------------
function Get_Body_Name (N : Unit_Name_Type) return Unit_Name_Type is
begin
Get_Name_String (N);
pragma Assert (Name_Len > 2
and then Name_Buffer (Name_Len - 1) = '%'
and then Name_Buffer (Name_Len) = 's');
Name_Buffer (Name_Len) := 'b';
return Name_Find;
end Get_Body_Name;
--------------------------
-- Get_Parent_Body_Name --
--------------------------
function Get_Parent_Body_Name (N : Unit_Name_Type) return Unit_Name_Type is
begin
Get_Name_String (N);
while Name_Buffer (Name_Len) /= '.' loop
pragma Assert (Name_Len > 1); -- not a child or subunit name
Name_Len := Name_Len - 1;
end loop;
Name_Buffer (Name_Len) := '%';
Name_Len := Name_Len + 1;
Name_Buffer (Name_Len) := 'b';
return Name_Find;
end Get_Parent_Body_Name;
--------------------------
-- Get_Parent_Spec_Name --
--------------------------
function Get_Parent_Spec_Name (N : Unit_Name_Type) return Unit_Name_Type is
begin
Get_Name_String (N);
while Name_Buffer (Name_Len) /= '.' loop
if Name_Len = 1 then
return No_Name; -- not a child or subunit name
else
Name_Len := Name_Len - 1;
end if;
end loop;
Name_Buffer (Name_Len) := '%';
Name_Len := Name_Len + 1;
Name_Buffer (Name_Len) := 's';
return Name_Find;
end Get_Parent_Spec_Name;
-------------------
-- Get_Spec_Name --
-------------------
function Get_Spec_Name (N : Unit_Name_Type) return Unit_Name_Type is
begin
Get_Name_String (N);
pragma Assert (Name_Len > 2
and then Name_Buffer (Name_Len - 1) = '%'
and then Name_Buffer (Name_Len) = 'b');
Name_Buffer (Name_Len) := 's';
return Name_Find;
end Get_Spec_Name;
-------------------
-- Get_Unit_Name --
-------------------
function Get_Unit_Name (N : Node_Id) return Unit_Name_Type is
Unit_Name_Buffer : String (1 .. System_Parameters_Max_Name_Length);
-- Buffer used to build name of unit. Note that we cannot use the
-- Name_Buffer in package Name_Table because we use it to read
-- component names.
Unit_Name_Length : Natural := 0;
-- Length of name stored in Unit_Name_Buffer
Node : Node_Id;
-- Program unit node
procedure Add_Char (C : Character);
-- Add a single character to stored unit name
procedure Add_Name (Name : Name_Id);
-- Add the characters of a names table entry to stored unit name
procedure Add_Node_Name (Node : Node_Id);
-- Recursive procedure adds characters associated with Node
function Get_Parent (Node : Node_Id) return Node_Id;
-- Get parent compilation unit of a stub
--------------
-- Add_Char --
--------------
procedure Add_Char (C : Character) is
begin
-- Should really check for max length exceeded here
Unit_Name_Length := Unit_Name_Length + 1;
Unit_Name_Buffer (Unit_Name_Length) := C;
end Add_Char;
--------------
-- Add_Name --
--------------
procedure Add_Name (Name : Name_Id) is
begin
Get_Name_String (Name);
for J in 1 .. Name_Len loop
Add_Char (Name_Buffer (J));
end loop;
end Add_Name;
-------------------
-- Add_Node_Name --
-------------------
procedure Add_Node_Name (Node : Node_Id) is
Kind : Node_Kind := Nkind (Node);
begin
-- Just ignore an error node (someone else will give a message)
if Node = Error then
return;
-- Otherwise see what kind of node we have
elsif Kind = N_Identifier or else Kind = N_Defining_Identifier then
Add_Name (Chars (Node));
elsif Kind = N_Defining_Program_Unit_Name then
Add_Node_Name (Name (Node));
Add_Char ('.');
Add_Node_Name (Defining_Identifier (Node));
elsif Kind = N_Selected_Component then
Add_Node_Name (Prefix (Node));
Add_Char ('.');
Add_Node_Name (Selector_Name (Node));
elsif Kind in N_Subprogram_Specification
or else Kind = N_Package_Specification
then
Add_Node_Name (Defining_Unit_Name (Node));
elsif Kind = N_Subprogram_Body
or else Kind = N_Subprogram_Declaration
or else Nkind (Node) = N_Package_Declaration
or else Nkind (Node) in N_Generic_Declaration
then
Add_Node_Name (Specification (Node));
elsif Kind in N_Generic_Instantiation then
Add_Node_Name (Defining_Unit_Name (Node));
elsif Kind = N_Package_Body then
Add_Node_Name (Defining_Unit_Name (Node));
elsif Kind = N_Task_Body or else Kind = N_Protected_Body then
Add_Node_Name (Defining_Identifier (Node));
elsif Kind = N_Package_Renaming_Declaration then
Add_Node_Name (Defining_Unit_Name (Node));
elsif Kind = N_Subprogram_Renaming_Declaration then
Add_Node_Name (Specification (Node));
elsif Kind in N_Generic_Renaming_Declaration then
Add_Node_Name (Defining_Unit_Name (Node));
elsif Kind = N_Subprogram_Body_Stub then
Add_Node_Name (Get_Parent (Node));
Add_Char ('.');
Add_Node_Name (Specification (Node));
elsif Kind = N_Compilation_Unit then
Add_Node_Name (Unit (Node));
elsif Kind = N_Package_Body_Stub then
Add_Node_Name (Get_Parent (Node));
Add_Char ('.');
Add_Node_Name (Defining_Identifier (Node));
elsif Kind = N_Task_Body_Stub
or else Kind = N_Protected_Body_Stub
then
Add_Node_Name (Get_Parent (Node));
Add_Char ('.');
Add_Node_Name (Defining_Identifier (Node));
elsif Kind = N_Subunit then
Add_Node_Name (Name (Node));
Add_Char ('.');
Add_Node_Name (Proper_Body (Node));
elsif Kind = N_With_Clause then
Add_Node_Name (Name (Node));
elsif Kind = N_Pragma then
Add_Node_Name (Expression (First
(Pragma_Argument_Associations (Node))));
else
pragma Assert (False);
null;
end if;
end Add_Node_Name;
----------------
-- Get_Parent --
----------------
function Get_Parent (Node : Node_Id) return Node_Id is
N : Node_Id := Node;
begin
while Nkind (N) /= N_Compilation_Unit loop
N := Parent (N);
end loop;
return N;
end Get_Parent;
--------------------------------------------
-- Start of Processing for Get_Unit_Name --
--------------------------------------------
begin
Node := N;
-- If we have Defining_Identifier, find the associated unit node
if Nkind (Node) = N_Defining_Identifier then
Node := Declaration_Node (Node);
end if;
if Nkind (Node) = N_Package_Specification
or else Nkind (Node) in N_Subprogram_Specification
then
Node := Parent (Node);
end if;
-- Node points to the unit, so get its name and add proper suffix
Add_Node_Name (Node);
Add_Char ('%');
if Nkind (Node) in N_Generic_Declaration
or else Nkind (Node) = N_Subprogram_Declaration
or else Nkind (Node) = N_Package_Declaration
or else Nkind (Node) = N_With_Clause
or else Nkind (Node) = N_Pragma
or else Nkind (Node) in N_Generic_Instantiation
or else Nkind (Node) = N_Package_Renaming_Declaration
or else Nkind (Node) = N_Subprogram_Renaming_Declaration
or else Nkind (Node) in N_Generic_Renaming_Declaration
then
Add_Char ('s');
elsif Nkind (Node) = N_Subprogram_Body
or else Nkind (Node) = N_Package_Body
or else Nkind (Node) = N_Subunit
or else Nkind (Node) in N_Body_Stub
then
Add_Char ('b');
else
pragma Assert (False);
null;
end if;
Name_Buffer (1 .. Unit_Name_Length) :=
Unit_Name_Buffer (1 .. Unit_Name_Length);
Name_Len := Unit_Name_Length;
return Name_Find;
end Get_Unit_Name;
--------------------------
-- Get_Unit_Name_String --
--------------------------
procedure Get_Unit_Name_String (N : Unit_Name_Type) is
Unit_Is_Body : Boolean;
begin
Get_Decoded_Name_String (N);
Unit_Is_Body := Name_Buffer (Name_Len) = 'b';
Set_Casing (Identifier_Casing (Source_Index (Main_Unit)), Mixed_Case);
if Unit_Is_Body then
Name_Buffer (Name_Len - 1 .. Name_Len + 5) := " (body)";
else
Name_Buffer (Name_Len - 1 .. Name_Len + 5) := " (spec)";
end if;
for J in 1 .. Name_Len loop
if Name_Buffer (J) = '-' then
Name_Buffer (J) := '.';
end if;
end loop;
Name_Len := Name_Len + (7 - 2);
end Get_Unit_Name_String;
------------------
-- Is_Body_Name --
------------------
function Is_Body_Name (N : Unit_Name_Type) return Boolean is
begin
Get_Name_String (N);
return Name_Len > 2
and then Name_Buffer (Name_Len - 1) = '%'
and then Name_Buffer (Name_Len) = 'b';
end Is_Body_Name;
-------------------
-- Is_Child_Name --
-------------------
function Is_Child_Name (N : Unit_Name_Type) return Boolean is
J : Natural;
begin
Get_Name_String (N);
J := Name_Len;
while Name_Buffer (J) /= '.' loop
if J = 1 then
return False; -- not a child or subunit name
else
J := J - 1;
end if;
end loop;
return True;
end Is_Child_Name;
------------------
-- Is_Spec_Name --
------------------
function Is_Spec_Name (N : Unit_Name_Type) return Boolean is
begin
Get_Name_String (N);
return Name_Len > 2
and then Name_Buffer (Name_Len - 1) = '%'
and then Name_Buffer (Name_Len) = 's';
end Is_Spec_Name;
-----------------------
-- Name_To_Unit_Name --
-----------------------
function Name_To_Unit_Name (N : Name_Id) return Unit_Name_Type is
begin
Get_Name_String (N);
Name_Buffer (Name_Len + 1) := '%';
Name_Buffer (Name_Len + 2) := 's';
Name_Len := Name_Len + 2;
return Name_Find;
end Name_To_Unit_Name;
--------------
-- Uname_Le --
--------------
function Uname_Le (Left, Right : Unit_Name_Type) return Boolean is
begin
return Left = Right or else Uname_Lt (Left, Right);
end Uname_Le;
--------------
-- Uname_Lt --
--------------
function Uname_Lt (Left, Right : Unit_Name_Type) return Boolean is
Left_Name : String (1 .. System_Parameters_Max_Name_Length);
Left_Length : Natural;
Right_Name : String renames Name_Buffer;
Right_Length : Natural renames Name_Len;
J : Natural;
begin
if Left = Right then
return False;
end if;
Get_Name_String (Left);
Left_Name (1 .. Name_Len + 1) := Name_Buffer (1 .. Name_Len + 1);
Left_Length := Name_Len;
Get_Name_String (Right);
J := 1;
loop
exit when Left_Name (J) = '%';
if Right_Name (J) = '%' then
return False; -- left name is longer
end if;
pragma Assert (J <= Left_Length and then J <= Right_Length);
if Left_Name (J) /= Right_Name (J) then
return Left_Name (J) < Right_Name (J); -- parent names different
end if;
J := J + 1;
end loop;
-- Come here pointing to % in left name
if Right_Name (J) /= '%' then
return True; -- right name is longer
end if;
-- Here the parent names are the same and specs sort low. If neither is
-- a spec, then we are comparing the same name and we want a result of
-- False in any case.
return Left_Name (J + 1) = 's';
end Uname_Lt;
--------------
-- Uname_Ge --
--------------
function Uname_Ge (Left, Right : Unit_Name_Type) return Boolean is
begin
return Left = Right or else Uname_Gt (Left, Right);
end Uname_Ge;
--------------
-- Uname_Gt --
--------------
function Uname_Gt (Left, Right : Unit_Name_Type) return Boolean is
begin
return Left /= Right and then not Uname_Lt (Left, Right);
end Uname_Gt;
---------------------
-- Write_Unit_Name --
---------------------
procedure Write_Unit_Name (N : Unit_Name_Type) is
begin
Get_Unit_Name_String (N);
Write_Str (Name_Buffer (1 .. Name_Len));
end Write_Unit_Name;
end Uname;