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 / a-tienau.adb < prev    next >
Text File  |  1996-09-28  |  8KB  |  283 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --          A D A . T E X T _ I O . E N U M E R A T I O N _ A U X           --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.11 $                             --
  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 Ada.Text_IO.Generic_Aux; use Ada.Text_IO.Generic_Aux;
  27. with Ada.Characters.Handling; use Ada.Characters.Handling;
  28. with Interfaces.C_Streams;    use Interfaces.C_Streams;
  29.  
  30. --  Note: this package does not yet deal properly with wide characters ???
  31.  
  32. package body Ada.Text_IO.Enumeration_Aux is
  33.  
  34.    --  These definitions replace the ones in Ada.Characters.Handling, which
  35.    --  do not seem to work for some strange not understood reason ??? at
  36.    --  least in the OS/2 version.
  37.  
  38.    function To_Lower (C : Character) return Character;
  39.    function To_Upper (C : Character) return Character;
  40.  
  41.    function To_Lower (C : Character) return Character is
  42.    begin
  43.       if C in 'A' .. 'Z' then
  44.          return Character'Val (Character'Pos (C) + 32);
  45.       else
  46.          return C;
  47.       end if;
  48.    end To_Lower;
  49.  
  50.    function To_Upper (C : Character) return Character is
  51.    begin
  52.       if C in 'a' .. 'z' then
  53.          return Character'Val (Character'Pos (C) - 32);
  54.       else
  55.          return C;
  56.       end if;
  57.    end To_Upper;
  58.  
  59.    ------------------
  60.    -- Get_Enum_Lit --
  61.    ------------------
  62.  
  63.    procedure Get_Enum_Lit
  64.      (File   : File_Type;
  65.       Buf    : out String;
  66.       Buflen : out Natural)
  67.    is
  68.       ch  : int;
  69.       C   : Character;
  70.  
  71.    begin
  72.       Buflen := 0;
  73.       Load_Skip (File);
  74.       ch := Getc (File);
  75.       C := Character'Val (ch);
  76.  
  77.       --  Character literal case. If the initial character is a quote, then
  78.       --  we read as far as we can without backup (see ACVC test CE3905L)
  79.  
  80.       if C = ''' then
  81.          Store_Char (File, ch, Buf, Buflen);
  82.  
  83.          ch := Getc (File);
  84.  
  85.          if ch in 16#20# .. 16#7E# or else ch >= 16#80# then
  86.             Store_Char (File, ch, Buf, Buflen);
  87.  
  88.             ch := Getc (File);
  89.  
  90.             if ch = Character'Pos (''') then
  91.                Store_Char (File, ch, Buf, Buflen);
  92.             else
  93.                Ungetc (ch, File);
  94.             end if;
  95.  
  96.          else
  97.             Ungetc (ch, File);
  98.          end if;
  99.  
  100.       --  Similarly for identifiers, read as far as we can, in particular,
  101.       --  do read a trailing underscore (again see ACVC test CE3905L to
  102.       --  understand why we do this, although it seems somewhat peculiar).
  103.  
  104.       else
  105.          --  Identifier must start with a letter
  106.  
  107.          if not Is_Letter (C) then
  108.             Ungetc (ch, File);
  109.             return;
  110.          end if;
  111.  
  112.          --  If we do have a letter, loop through the characters quitting on
  113.          --  the first non-identifier character (note that this includes the
  114.          --  cases of hitting a line mark or page mark).
  115.  
  116.          loop
  117.             C := Character'Val (ch);
  118.             Store_Char (File, Character'Pos (To_Upper (C)), Buf, Buflen);
  119.  
  120.             ch := Getc (File);
  121.             exit when ch = EOF;
  122.             C := Character'Val (ch);
  123.  
  124.             exit when not Is_Letter (C)
  125.               and then not Is_Digit (C)
  126.               and then C /= '_';
  127.  
  128.             exit when C = '_'
  129.               and then Buf (Buflen) = '_';
  130.          end loop;
  131.  
  132.          Ungetc (ch, File);
  133.       end if;
  134.    end Get_Enum_Lit;
  135.  
  136.    -------------------
  137.    -- Scan_Enum_Lit --
  138.    -------------------
  139.  
  140.    procedure Scan_Enum_Lit
  141.      (From  : String;
  142.       Start : out Natural;
  143.       Stop  : out Natural)
  144.    is
  145.       C  : Character;
  146.  
  147.    --  Processing for Scan_Enum_Lit
  148.  
  149.    begin
  150.       String_Skip (From, Start);
  151.  
  152.       --  Character literal case. If the initial character is a quote, then
  153.       --  we read as far as we can without backup (see ACVC test CE3905L
  154.       --  which is for the analogous case for reading from a file).
  155.  
  156.       if From (Start) = ''' then
  157.          Stop := Start;
  158.  
  159.          if Stop = From'Last then
  160.             raise Data_Error;
  161.          else
  162.             Stop := Stop + 1;
  163.          end if;
  164.  
  165.          if From (Stop) in ' ' .. '~'
  166.            or else From (Stop) >= Character'Val (16#80#)
  167.          then
  168.             if Stop = From'Last then
  169.                raise Data_Error;
  170.             else
  171.                Stop := Stop + 1;
  172.  
  173.                if From (Stop) = ''' then
  174.                   return;
  175.                end if;
  176.             end if;
  177.          end if;
  178.  
  179.          Stop := Stop - 1;
  180.          raise Data_Error;
  181.  
  182.       --  Similarly for identifiers, read as far as we can, in particular,
  183.       --  do read a trailing underscore (again see ACVC test CE3905L to
  184.       --  understand why we do this, although it seems somewhat peculiar).
  185.  
  186.       else
  187.          --  Identifier must start with a letter
  188.  
  189.          if not Is_Letter (From (Start)) then
  190.             raise Data_Error;
  191.          end if;
  192.  
  193.          --  If we do have a letter, loop through the characters quitting on
  194.          --  the first non-identifier character (note that this includes the
  195.          --  cases of hitting a line mark or page mark).
  196.  
  197.          Stop := Start + 1;
  198.          while Stop < From'Last loop
  199.             C := From (Stop + 1);
  200.  
  201.             exit when not Is_Letter (C)
  202.               and then not Is_Digit (C)
  203.               and then C /= '_';
  204.  
  205.             exit when C = '_'
  206.               and then From (Stop - 1) = '_';
  207.  
  208.             Stop := Stop + 1;
  209.          end loop;
  210.       end if;
  211.  
  212.    end Scan_Enum_Lit;
  213.  
  214.    ---------
  215.    -- Put --
  216.    ---------
  217.  
  218.    procedure Put
  219.      (File  : File_Type;
  220.       Item  : String;
  221.       Width : Field;
  222.       Set   : Type_Set)
  223.    is
  224.       Actual_Width : constant Count := Count'Max (Count (Width), Item'Length);
  225.  
  226.    begin
  227.       if Set = Lower_Case and then Item (1) /= ''' then
  228.          declare
  229.             Iteml : String (Item'First .. Item'Last);
  230.  
  231.          begin
  232.             for J in Item'Range loop
  233.                Iteml (J) := To_Lower (Item (J));
  234.             end loop;
  235.  
  236.             Put_Item (File, Iteml);
  237.          end;
  238.  
  239.       else
  240.          Put_Item (File, Item);
  241.       end if;
  242.  
  243.       for J in 1 .. Actual_Width - Item'Length loop
  244.          Put (File, ' ');
  245.       end loop;
  246.    end Put;
  247.  
  248.    ----------
  249.    -- Puts --
  250.    ----------
  251.  
  252.    procedure Puts
  253.      (To    : out String;
  254.       Item  : in String;
  255.       Set   : Type_Set)
  256.    is
  257.       Ptr : Natural;
  258.  
  259.    begin
  260.       if Item'Length > To'Length then
  261.          raise Layout_Error;
  262.  
  263.       else
  264.          Ptr := To'First;
  265.          for J in Item'Range loop
  266.             if Set = Lower_Case and then Item (1) /= ''' then
  267.                To (Ptr) := To_Lower (Item (J));
  268.             else
  269.                To (Ptr) := Item (J);
  270.             end if;
  271.  
  272.             Ptr := Ptr + 1;
  273.          end loop;
  274.  
  275.          while Ptr <= To'Last loop
  276.             To (Ptr) := ' ';
  277.             Ptr := Ptr + 1;
  278.          end loop;
  279.       end if;
  280.    end Puts;
  281.  
  282. end Ada.Text_IO.Enumeration_Aux;
  283.