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-wtenau.adb < prev    next >
Text File  |  1996-09-28  |  11KB  |  355 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --                ADA.TEXT_IO.WIDE_TEXT_IO.ENUMERATION_AUX                  --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.1 $                              --
  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. with System.File_IO;          use System.File_IO;
  30. with System.WCh_Con;          use System.WCh_Con;
  31.  
  32. package body Ada.Text_IO.Wide_Text_IO.Enumeration_Aux is
  33.  
  34.    subtype TFT is Ada.Text_IO.File_Type;
  35.    --  File type required for calls to routines in Aux
  36.  
  37.    -----------------------
  38.    -- Local Subprograms --
  39.    -----------------------
  40.  
  41.    procedure Store_Char
  42.      (File : File_Type;
  43.       WC   : Wide_Character;
  44.       Buf  : out Wide_String;
  45.       Ptr  : in out Integer);
  46.    --  Store a single character in buffer, checking for overflow.
  47.  
  48.    --  These definitions replace the ones in Ada.Characters.Handling, which
  49.    --  do not seem to work for some strange not understood reason ??? at
  50.    --  least in the OS/2 version.
  51.  
  52.    function To_Lower (C : Character) return Character;
  53.    function To_Upper (C : Character) return Character;
  54.  
  55.    function To_Lower (C : Character) return Character is
  56.    begin
  57.       if C in 'A' .. 'Z' then
  58.          return Character'Val (Character'Pos (C) + 32);
  59.       else
  60.          return C;
  61.       end if;
  62.    end To_Lower;
  63.  
  64.    function To_Upper (C : Character) return Character is
  65.    begin
  66.       if C in 'a' .. 'z' then
  67.          return Character'Val (Character'Pos (C) - 32);
  68.       else
  69.          return C;
  70.       end if;
  71.    end To_Upper;
  72.  
  73.    ------------------
  74.    -- Get_Enum_Lit --
  75.    ------------------
  76.  
  77.    procedure Get_Enum_Lit
  78.      (File   : File_Type;
  79.       Buf    : out Wide_String;
  80.       Buflen : out Natural)
  81.    is
  82.       ch  : int;
  83.       WC  : Wide_Character;
  84.  
  85.    begin
  86.       Buflen := 0;
  87.       Load_Skip (TFT (File));
  88.       ch := Nextc (TFT (File));
  89.  
  90.       --  Character literal case. If the initial character is a quote, then
  91.       --  we read as far as we can without backup (see ACVC test CE3905L)
  92.  
  93.       if ch = Character'Pos (''') then
  94.          Get (File, WC);
  95.          Store_Char (File, WC, Buf, Buflen);
  96.  
  97.          ch := Nextc (TFT (File));
  98.  
  99.          if ch = LM or else ch = EOF then
  100.             return;
  101.          end if;
  102.  
  103.          Get (File, WC);
  104.          Store_Char (File, WC, Buf, Buflen);
  105.  
  106.          ch := Nextc (TFT (File));
  107.  
  108.          if ch /= Character'Pos (''') then
  109.             return;
  110.          end if;
  111.  
  112.          Get (File, WC);
  113.          Store_Char (File, WC, Buf, Buflen);
  114.  
  115.       --  Similarly for identifiers, read as far as we can, in particular,
  116.       --  do read a trailing underscore (again see ACVC test CE3905L to
  117.       --  understand why we do this, although it seems somewhat peculiar).
  118.  
  119.       else
  120.          --  Identifier must start with a letter. Any wide character value
  121.          --  outside the normal Latin-1 range counts as a letter for this.
  122.  
  123.          if ch < 255 and then not Is_Letter (Character'Val (ch)) then
  124.             return;
  125.          end if;
  126.  
  127.          --  If we do have a letter, loop through the characters quitting on
  128.          --  the first non-identifier character (note that this includes the
  129.          --  cases of hitting a line mark or page mark).
  130.  
  131.          loop
  132.             Get (File, WC);
  133.             Store_Char (File, WC, Buf, Buflen);
  134.  
  135.             ch := Nextc (TFT (File));
  136.  
  137.             exit when ch = EOF;
  138.  
  139.             if ch = Character'Pos ('_') then
  140.                exit when Buf (Buflen) = '_';
  141.             
  142.             elsif ch = Character'Pos (Ascii.ESC) then
  143.                null;
  144.  
  145.             elsif File.WC_Method in WC_Upper_Half_Encoding_Method
  146.               and then ch > 127
  147.             then
  148.                null;
  149.  
  150.             else
  151.                exit when Is_Letter (Character'Val (ch))
  152.                  and then not Is_Digit (Character'Val (ch));
  153.             end if;
  154.          end loop;
  155.       end if;
  156.    end Get_Enum_Lit;
  157.  
  158.    -------------------
  159.    -- Scan_Enum_Lit --
  160.    -------------------
  161.  
  162.    procedure Scan_Enum_Lit
  163.      (From  : Wide_String;
  164.       Start : out Natural;
  165.       Stop  : out Natural)
  166.    is
  167.       WC  : Wide_Character;
  168.  
  169.    --  Processing for Scan_Enum_Lit
  170.  
  171.    begin
  172.       Start := From'First;
  173.  
  174.       loop
  175.          if Start > From'Last then
  176.             raise End_Error;
  177.  
  178.          elsif Is_Character (From (Start))
  179.            and then not Is_Blank (To_Character (From (Start)))
  180.          then
  181.             exit;
  182.  
  183.          else
  184.             Start := Start + 1;
  185.          end if;
  186.       end loop;
  187.  
  188.       --  Character literal case. If the initial character is a quote, then
  189.       --  we read as far as we can without backup (see ACVC test CE3905L
  190.       --  which is for the analogous case for reading from a file).
  191.  
  192.       if From (Start) = ''' then
  193.          Stop := Start;
  194.  
  195.          if Stop = From'Last then
  196.             raise Data_Error;
  197.          else
  198.             Stop := Stop + 1;
  199.          end if;
  200.  
  201.          if From (Stop) in ' ' .. '~'
  202.            or else From (Stop) >= Wide_Character'Val (16#80#)
  203.          then
  204.             if Stop = From'Last then
  205.                raise Data_Error;
  206.             else
  207.                Stop := Stop + 1;
  208.  
  209.                if From (Stop) = ''' then
  210.                   return;
  211.                end if;
  212.             end if;
  213.          end if;
  214.  
  215.          Stop := Stop - 1;
  216.          raise Data_Error;
  217.  
  218.       --  Similarly for identifiers, read as far as we can, in particular,
  219.       --  do read a trailing underscore (again see ACVC test CE3905L to
  220.       --  understand why we do this, although it seems somewhat peculiar).
  221.  
  222.       else
  223.          --  Identifier must start with a letter, any wide character outside
  224.          --  the normal Latin-1 range is considered a letter for this test.
  225.  
  226.          if Is_Character (From (Start))
  227.            and then not Is_Letter (To_Character (From (Start)))
  228.          then
  229.             raise Data_Error;
  230.          end if;
  231.  
  232.          --  If we do have a letter, loop through the characters quitting on
  233.          --  the first non-identifier character (note that this includes the
  234.          --  cases of hitting a line mark or page mark).
  235.  
  236.          Stop := Start + 1;
  237.          while Stop < From'Last loop
  238.             WC := From (Stop + 1);
  239.  
  240.             exit when
  241.               Is_Character (WC)
  242.                 and then
  243.                   not Is_Letter (To_Character (WC))
  244.                 and then
  245.                   not Is_Letter (To_Character (WC))
  246.                 and then
  247.                   (WC /= '_' or else From (Stop - 1) = '_');
  248.  
  249.             Stop := Stop + 1;
  250.          end loop;
  251.       end if;
  252.  
  253.    end Scan_Enum_Lit;
  254.  
  255.    ---------
  256.    -- Put --
  257.    ---------
  258.  
  259.    procedure Put
  260.      (File  : File_Type;
  261.       Item  : Wide_String;
  262.       Width : Field;
  263.       Set   : Type_Set)
  264.    is
  265.       Actual_Width : constant Integer :=
  266.                        Integer'Max (Integer (Width), Item'Length);
  267.  
  268.    begin
  269.       Check_On_One_Line (TFT (File), Actual_Width);
  270.  
  271.       if Set = Lower_Case and then Item (1) /= ''' then
  272.          declare
  273.             Iteml : Wide_String (Item'First .. Item'Last);
  274.  
  275.          begin
  276.             for J in Item'Range loop
  277.                if Is_Character (Item (J)) then
  278.                   Iteml (J) :=
  279.                     To_Wide_Character (To_Lower (To_Character (Item (J))));
  280.                else
  281.                   Iteml (J) := Item (J);
  282.                end if;
  283.             end loop;
  284.  
  285.             Put (File, Iteml);
  286.          end;
  287.  
  288.       else
  289.          Put (File, Item);
  290.       end if;
  291.  
  292.       for J in 1 .. Actual_Width - Item'Length loop
  293.          Put (File, ' ');
  294.       end loop;
  295.    end Put;
  296.  
  297.    ----------
  298.    -- Puts --
  299.    ----------
  300.  
  301.    procedure Puts
  302.      (To    : out Wide_String;
  303.       Item  : in Wide_String;
  304.       Set   : Type_Set)
  305.    is
  306.       Ptr : Natural;
  307.  
  308.    begin
  309.       if Item'Length > To'Length then
  310.          raise Layout_Error;
  311.  
  312.       else
  313.          Ptr := To'First;
  314.          for J in Item'Range loop
  315.             if Set = Lower_Case
  316.               and then Item (1) /= '''
  317.               and then Is_Character (Item (J))
  318.             then
  319.                To (Ptr) :=
  320.                  To_Wide_Character (To_Lower (To_Character (Item (J))));
  321.             else
  322.                To (Ptr) := Item (J);
  323.             end if;
  324.  
  325.             Ptr := Ptr + 1;
  326.          end loop;
  327.  
  328.          while Ptr <= To'Last loop
  329.             To (Ptr) := ' ';
  330.             Ptr := Ptr + 1;
  331.          end loop;
  332.       end if;
  333.    end Puts;
  334.  
  335.    ----------------
  336.    -- Store_Char --
  337.    ----------------
  338.  
  339.    procedure Store_Char
  340.      (File : File_Type;
  341.       WC   : Wide_Character;
  342.       Buf  : out Wide_String;
  343.       Ptr  : in out Integer)
  344.    is
  345.    begin
  346.       if Ptr = Buf'Last then
  347.          raise Data_Error;
  348.       else
  349.          Ptr := Ptr + 1;
  350.          Buf (Ptr) := WC;
  351.       end if;
  352.    end Store_Char;
  353.  
  354. end Ada.Text_IO.Wide_Text_IO.Enumeration_Aux;
  355.