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 >
Text File  |  1996-09-28  |  15KB  |  513 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                                U N A M E                                 --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.40 $                             --
  10. --                                                                          --
  11. --        Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved        --
  12. --                                                                          --
  13. -- The GNAT library is free software; you can redistribute it and/or modify --
  14. -- it under terms of the GNU Library General Public License as published by --
  15. -- the Free Software  Foundation; either version 2, or (at your option) any --
  16. -- later version.  The GNAT library is distributed in the hope that it will --
  17. -- be useful, but WITHOUT ANY WARRANTY;  without even  the implied warranty --
  18. -- of MERCHANTABILITY  or  FITNESS FOR  A PARTICULAR PURPOSE.  See the  GNU --
  19. -- Library  General  Public  License for  more  details.  You  should  have --
  20. -- received  a copy of the GNU  Library  General Public License  along with --
  21. -- the GNAT library;  see the file  COPYING.LIB.  If not, write to the Free --
  22. -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. with Atree;  use Atree;
  27. with Casing; use Casing;
  28. with Einfo;  use Einfo;
  29. with Lib;    use Lib;
  30. with Namet;  use Namet;
  31. with Nlists; use Nlists;
  32. with Output; use Output;
  33. with Sinfo;  use Sinfo;
  34. with Sinput; use Sinput;
  35.  
  36. with System.Parameters;
  37.  
  38. package body Uname is
  39.  
  40.    System_Parameters_Max_Name_Length : constant :=
  41.                                          System.Parameters.Max_Name_Length;
  42.    --  ??? to deal with GNAT visibility problem
  43.  
  44.    -------------------
  45.    -- Get_Body_Name --
  46.    -------------------
  47.  
  48.    function Get_Body_Name (N : Unit_Name_Type) return Unit_Name_Type is
  49.    begin
  50.       Get_Name_String (N);
  51.  
  52.       pragma Assert (Name_Len > 2
  53.                        and then Name_Buffer (Name_Len - 1) = '%'
  54.                        and then Name_Buffer (Name_Len) = 's');
  55.  
  56.       Name_Buffer (Name_Len) := 'b';
  57.       return Name_Find;
  58.    end Get_Body_Name;
  59.  
  60.    --------------------------
  61.    -- Get_Parent_Body_Name --
  62.    --------------------------
  63.  
  64.    function Get_Parent_Body_Name (N : Unit_Name_Type) return Unit_Name_Type is
  65.    begin
  66.       Get_Name_String (N);
  67.  
  68.       while Name_Buffer (Name_Len) /= '.' loop
  69.          pragma Assert (Name_Len > 1); -- not a child or subunit name
  70.          Name_Len := Name_Len - 1;
  71.       end loop;
  72.  
  73.       Name_Buffer (Name_Len) := '%';
  74.       Name_Len := Name_Len + 1;
  75.       Name_Buffer (Name_Len) := 'b';
  76.       return Name_Find;
  77.  
  78.    end Get_Parent_Body_Name;
  79.  
  80.    --------------------------
  81.    -- Get_Parent_Spec_Name --
  82.    --------------------------
  83.  
  84.    function Get_Parent_Spec_Name (N : Unit_Name_Type) return Unit_Name_Type is
  85.    begin
  86.       Get_Name_String (N);
  87.  
  88.       while Name_Buffer (Name_Len) /= '.' loop
  89.          if Name_Len = 1 then
  90.             return No_Name; -- not a child or subunit name
  91.          else
  92.             Name_Len := Name_Len - 1;
  93.          end if;
  94.       end loop;
  95.  
  96.       Name_Buffer (Name_Len) := '%';
  97.       Name_Len := Name_Len + 1;
  98.       Name_Buffer (Name_Len) := 's';
  99.       return Name_Find;
  100.  
  101.    end Get_Parent_Spec_Name;
  102.  
  103.    -------------------
  104.    -- Get_Spec_Name --
  105.    -------------------
  106.  
  107.    function Get_Spec_Name (N : Unit_Name_Type) return Unit_Name_Type is
  108.    begin
  109.       Get_Name_String (N);
  110.  
  111.       pragma Assert (Name_Len > 2
  112.                        and then Name_Buffer (Name_Len - 1) = '%'
  113.                        and then Name_Buffer (Name_Len) = 'b');
  114.  
  115.       Name_Buffer (Name_Len) := 's';
  116.       return Name_Find;
  117.    end Get_Spec_Name;
  118.  
  119.    -------------------
  120.    -- Get_Unit_Name --
  121.    -------------------
  122.  
  123.    function Get_Unit_Name (N : Node_Id) return Unit_Name_Type is
  124.  
  125.       Unit_Name_Buffer : String (1 .. System_Parameters_Max_Name_Length);
  126.       --  Buffer used to build name of unit. Note that we cannot use the
  127.       --  Name_Buffer in package Name_Table because we use it to read
  128.       --  component names.
  129.  
  130.       Unit_Name_Length : Natural := 0;
  131.       --  Length of name stored in Unit_Name_Buffer
  132.  
  133.       Node : Node_Id;
  134.       --  Program unit node
  135.  
  136.       procedure Add_Char (C : Character);
  137.       --  Add a single character to stored unit name
  138.  
  139.       procedure Add_Name (Name : Name_Id);
  140.       --  Add the characters of a names table entry to stored unit name
  141.  
  142.       procedure Add_Node_Name (Node : Node_Id);
  143.       --  Recursive procedure adds characters associated with Node
  144.  
  145.       function Get_Parent (Node : Node_Id) return Node_Id;
  146.       --  Get parent compilation unit of a stub
  147.  
  148.       --------------
  149.       -- Add_Char --
  150.       --------------
  151.  
  152.       procedure Add_Char (C : Character) is
  153.       begin
  154.          --  Should really check for max length exceeded here
  155.          Unit_Name_Length := Unit_Name_Length + 1;
  156.          Unit_Name_Buffer (Unit_Name_Length) := C;
  157.       end Add_Char;
  158.  
  159.       --------------
  160.       -- Add_Name --
  161.       --------------
  162.  
  163.       procedure Add_Name (Name : Name_Id) is
  164.       begin
  165.          Get_Name_String (Name);
  166.  
  167.          for J in 1 .. Name_Len loop
  168.             Add_Char (Name_Buffer (J));
  169.          end loop;
  170.       end Add_Name;
  171.  
  172.       -------------------
  173.       -- Add_Node_Name --
  174.       -------------------
  175.  
  176.       procedure Add_Node_Name (Node : Node_Id) is
  177.          Kind : Node_Kind := Nkind (Node);
  178.  
  179.       begin
  180.          --  Just ignore an error node (someone else will give a message)
  181.  
  182.          if Node = Error then
  183.             return;
  184.  
  185.          --  Otherwise see what kind of node we have
  186.  
  187.          elsif Kind = N_Identifier or else Kind = N_Defining_Identifier then
  188.             Add_Name (Chars (Node));
  189.  
  190.          elsif Kind = N_Defining_Program_Unit_Name then
  191.             Add_Node_Name (Name (Node));
  192.             Add_Char ('.');
  193.             Add_Node_Name (Defining_Identifier (Node));
  194.  
  195.          elsif Kind = N_Selected_Component then
  196.             Add_Node_Name (Prefix (Node));
  197.             Add_Char ('.');
  198.             Add_Node_Name (Selector_Name (Node));
  199.  
  200.          elsif Kind in N_Subprogram_Specification
  201.            or else Kind = N_Package_Specification
  202.          then
  203.             Add_Node_Name (Defining_Unit_Name (Node));
  204.  
  205.          elsif Kind = N_Subprogram_Body
  206.            or else Kind = N_Subprogram_Declaration
  207.            or else Nkind (Node) = N_Package_Declaration
  208.            or else Nkind (Node) in N_Generic_Declaration
  209.          then
  210.             Add_Node_Name (Specification (Node));
  211.  
  212.          elsif Kind in N_Generic_Instantiation then
  213.             Add_Node_Name (Defining_Unit_Name (Node));
  214.  
  215.          elsif Kind = N_Package_Body then
  216.             Add_Node_Name (Defining_Unit_Name (Node));
  217.  
  218.          elsif Kind = N_Task_Body or else Kind = N_Protected_Body then
  219.             Add_Node_Name (Defining_Identifier (Node));
  220.  
  221.          elsif Kind = N_Package_Renaming_Declaration then
  222.             Add_Node_Name (Defining_Unit_Name (Node));
  223.  
  224.          elsif Kind = N_Subprogram_Renaming_Declaration then
  225.             Add_Node_Name (Specification (Node));
  226.  
  227.          elsif Kind in N_Generic_Renaming_Declaration then
  228.             Add_Node_Name (Defining_Unit_Name (Node));
  229.  
  230.          elsif Kind = N_Subprogram_Body_Stub then
  231.             Add_Node_Name (Get_Parent (Node));
  232.             Add_Char ('.');
  233.             Add_Node_Name (Specification (Node));
  234.  
  235.          elsif Kind = N_Compilation_Unit then
  236.             Add_Node_Name (Unit (Node));
  237.  
  238.          elsif Kind = N_Package_Body_Stub then
  239.             Add_Node_Name (Get_Parent (Node));
  240.             Add_Char ('.');
  241.             Add_Node_Name (Defining_Identifier (Node));
  242.  
  243.          elsif Kind = N_Task_Body_Stub
  244.            or else Kind = N_Protected_Body_Stub
  245.          then
  246.             Add_Node_Name (Get_Parent (Node));
  247.             Add_Char ('.');
  248.             Add_Node_Name (Defining_Identifier (Node));
  249.  
  250.          elsif Kind = N_Subunit then
  251.             Add_Node_Name (Name (Node));
  252.             Add_Char ('.');
  253.             Add_Node_Name (Proper_Body (Node));
  254.  
  255.          elsif Kind = N_With_Clause then
  256.             Add_Node_Name (Name (Node));
  257.  
  258.          elsif Kind = N_Pragma then
  259.             Add_Node_Name (Expression (First
  260.               (Pragma_Argument_Associations (Node))));
  261.  
  262.          else
  263.             pragma Assert (False);
  264.             null;
  265.          end if;
  266.       end Add_Node_Name;
  267.  
  268.       ----------------
  269.       -- Get_Parent --
  270.       ----------------
  271.  
  272.       function Get_Parent (Node : Node_Id) return Node_Id is
  273.          N : Node_Id := Node;
  274.  
  275.       begin
  276.          while Nkind (N) /= N_Compilation_Unit loop
  277.             N := Parent (N);
  278.          end loop;
  279.  
  280.          return N;
  281.       end Get_Parent;
  282.  
  283.    --------------------------------------------
  284.    --  Start of Processing for Get_Unit_Name --
  285.    --------------------------------------------
  286.  
  287.    begin
  288.       Node := N;
  289.  
  290.       --  If we have Defining_Identifier, find the associated unit node
  291.  
  292.       if Nkind (Node) = N_Defining_Identifier then
  293.          Node := Declaration_Node (Node);
  294.       end if;
  295.  
  296.       if Nkind (Node) = N_Package_Specification
  297.         or else Nkind (Node) in N_Subprogram_Specification
  298.       then
  299.          Node := Parent (Node);
  300.       end if;
  301.  
  302.       --  Node points to the unit, so get its name and add proper suffix
  303.  
  304.       Add_Node_Name (Node);
  305.       Add_Char ('%');
  306.  
  307.       if Nkind (Node) in N_Generic_Declaration
  308.         or else Nkind (Node) = N_Subprogram_Declaration
  309.         or else Nkind (Node) = N_Package_Declaration
  310.         or else Nkind (Node) = N_With_Clause
  311.         or else Nkind (Node) = N_Pragma
  312.         or else Nkind (Node) in N_Generic_Instantiation
  313.         or else Nkind (Node) = N_Package_Renaming_Declaration
  314.         or else Nkind (Node) = N_Subprogram_Renaming_Declaration
  315.         or else Nkind (Node) in N_Generic_Renaming_Declaration
  316.       then
  317.          Add_Char ('s');
  318.  
  319.       elsif Nkind (Node) = N_Subprogram_Body
  320.         or else Nkind (Node) = N_Package_Body
  321.         or else Nkind (Node) = N_Subunit
  322.         or else Nkind (Node) in N_Body_Stub
  323.       then
  324.          Add_Char ('b');
  325.  
  326.       else
  327.          pragma Assert (False);
  328.          null;
  329.       end if;
  330.  
  331.       Name_Buffer (1 .. Unit_Name_Length) :=
  332.         Unit_Name_Buffer (1 .. Unit_Name_Length);
  333.       Name_Len := Unit_Name_Length;
  334.       return Name_Find;
  335.  
  336.    end Get_Unit_Name;
  337.  
  338.    --------------------------
  339.    -- Get_Unit_Name_String --
  340.    --------------------------
  341.  
  342.    procedure Get_Unit_Name_String (N : Unit_Name_Type) is
  343.       Unit_Is_Body : Boolean;
  344.  
  345.    begin
  346.       Get_Decoded_Name_String (N);
  347.       Unit_Is_Body := Name_Buffer (Name_Len) = 'b';
  348.       Set_Casing (Identifier_Casing (Source_Index (Main_Unit)), Mixed_Case);
  349.  
  350.       if Unit_Is_Body then
  351.          Name_Buffer (Name_Len - 1 .. Name_Len + 5) := " (body)";
  352.       else
  353.          Name_Buffer (Name_Len - 1 .. Name_Len + 5) := " (spec)";
  354.       end if;
  355.  
  356.       for J in 1 .. Name_Len loop
  357.          if Name_Buffer (J) = '-' then
  358.             Name_Buffer (J) := '.';
  359.          end if;
  360.       end loop;
  361.  
  362.       Name_Len := Name_Len + (7 - 2);
  363.    end Get_Unit_Name_String;
  364.  
  365.    ------------------
  366.    -- Is_Body_Name --
  367.    ------------------
  368.  
  369.    function Is_Body_Name (N : Unit_Name_Type) return Boolean is
  370.    begin
  371.       Get_Name_String (N);
  372.       return Name_Len > 2
  373.         and then Name_Buffer (Name_Len - 1) = '%'
  374.         and then Name_Buffer (Name_Len) = 'b';
  375.    end Is_Body_Name;
  376.  
  377.    -------------------
  378.    -- Is_Child_Name --
  379.    -------------------
  380.  
  381.    function Is_Child_Name (N : Unit_Name_Type) return Boolean is
  382.       J : Natural;
  383.  
  384.    begin
  385.       Get_Name_String (N);
  386.       J := Name_Len;
  387.  
  388.       while Name_Buffer (J) /= '.' loop
  389.          if J = 1 then
  390.             return False; -- not a child or subunit name
  391.          else
  392.             J := J - 1;
  393.          end if;
  394.       end loop;
  395.  
  396.       return True;
  397.    end Is_Child_Name;
  398.  
  399.    ------------------
  400.    -- Is_Spec_Name --
  401.    ------------------
  402.  
  403.    function Is_Spec_Name (N : Unit_Name_Type) return Boolean is
  404.    begin
  405.       Get_Name_String (N);
  406.       return Name_Len > 2
  407.         and then Name_Buffer (Name_Len - 1) = '%'
  408.         and then Name_Buffer (Name_Len) = 's';
  409.    end Is_Spec_Name;
  410.  
  411.    -----------------------
  412.    -- Name_To_Unit_Name --
  413.    -----------------------
  414.  
  415.    function Name_To_Unit_Name (N : Name_Id) return Unit_Name_Type is
  416.    begin
  417.       Get_Name_String (N);
  418.       Name_Buffer (Name_Len + 1) := '%';
  419.       Name_Buffer (Name_Len + 2) := 's';
  420.       Name_Len := Name_Len + 2;
  421.       return Name_Find;
  422.    end Name_To_Unit_Name;
  423.  
  424.    --------------
  425.    -- Uname_Le --
  426.    --------------
  427.  
  428.    function Uname_Le (Left, Right : Unit_Name_Type) return Boolean is
  429.    begin
  430.       return Left = Right or else Uname_Lt (Left, Right);
  431.    end Uname_Le;
  432.  
  433.    --------------
  434.    -- Uname_Lt --
  435.    --------------
  436.  
  437.    function Uname_Lt (Left, Right : Unit_Name_Type) return Boolean is
  438.       Left_Name    : String (1 .. System_Parameters_Max_Name_Length);
  439.       Left_Length  : Natural;
  440.       Right_Name   : String renames Name_Buffer;
  441.       Right_Length : Natural renames Name_Len;
  442.       J            : Natural;
  443.  
  444.    begin
  445.       if Left = Right then
  446.          return False;
  447.       end if;
  448.  
  449.       Get_Name_String (Left);
  450.       Left_Name  (1 .. Name_Len + 1) := Name_Buffer (1 .. Name_Len + 1);
  451.       Left_Length := Name_Len;
  452.       Get_Name_String (Right);
  453.       J := 1;
  454.  
  455.       loop
  456.          exit when Left_Name (J) = '%';
  457.  
  458.          if Right_Name (J) = '%' then
  459.             return False; -- left name is longer
  460.          end if;
  461.  
  462.          pragma Assert (J <= Left_Length and then J <= Right_Length);
  463.  
  464.          if Left_Name (J) /= Right_Name (J) then
  465.             return Left_Name (J) < Right_Name (J); -- parent names different
  466.          end if;
  467.  
  468.          J := J + 1;
  469.       end loop;
  470.  
  471.       --  Come here pointing to % in left name
  472.  
  473.       if Right_Name (J) /= '%' then
  474.          return True; -- right name is longer
  475.       end if;
  476.  
  477.       --  Here the parent names are the same and specs sort low. If neither is
  478.       --  a spec, then we are comparing the same name and we want a result of
  479.       --  False in any case.
  480.  
  481.       return Left_Name (J + 1) = 's';
  482.    end Uname_Lt;
  483.  
  484.    --------------
  485.    -- Uname_Ge --
  486.    --------------
  487.  
  488.    function Uname_Ge (Left, Right : Unit_Name_Type) return Boolean is
  489.    begin
  490.       return Left = Right or else Uname_Gt (Left, Right);
  491.    end Uname_Ge;
  492.  
  493.    --------------
  494.    -- Uname_Gt --
  495.    --------------
  496.  
  497.    function Uname_Gt (Left, Right : Unit_Name_Type) return Boolean is
  498.    begin
  499.       return Left /= Right and then not Uname_Lt (Left, Right);
  500.    end Uname_Gt;
  501.  
  502.    ---------------------
  503.    -- Write_Unit_Name --
  504.    ---------------------
  505.  
  506.    procedure Write_Unit_Name (N : Unit_Name_Type) is
  507.    begin
  508.       Get_Unit_Name_String (N);
  509.       Write_Str (Name_Buffer (1 .. Name_Len));
  510.    end Write_Unit_Name;
  511.  
  512. end Uname;
  513.