File : a-tigeau.adb


     ------------------------------------------------------------------------------
     --                                                                          --
     --                         GNAT RUNTIME COMPONENTS                          --
     --                                                                          --
   5 --              A D A . T E X T _ I O . G E N E R I C _ A U X               --
     --                                                                          --
     --                                 B o d y                                  --
     --                                                                          --
     --                            $Revision: 1.18 $
  10 --                                                                          --
     --          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
     --                                                                          --
     -- GNAT is free software;  you can  redistribute it  and/or modify it under --
     -- terms of the  GNU General Public License as published  by the Free Soft- --
  15 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
     -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
     -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
     -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
     -- for  more details.  You should have  received  a copy of the GNU General --
  20 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
     -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
     -- MA 02111-1307, USA.                                                      --
     --                                                                          --
     -- As a special exception,  if other files  instantiate  generics from this --
  25 -- unit, or you link  this unit with other files  to produce an executable, --
     -- this  unit  does not  by itself cause  the resulting  executable  to  be --
     -- covered  by the  GNU  General  Public  License.  This exception does not --
     -- however invalidate  any other reasons why  the executable file  might be --
     -- covered by the  GNU Public License.                                      --
  30 --                                                                          --
     -- GNAT was originally developed  by the GNAT team at  New York University. --
     -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
     --                                                                          --
     ------------------------------------------------------------------------------
  35 
     with Interfaces.C_Streams; use Interfaces.C_Streams;
     with System.File_IO;
     with System.File_Control_Block;
     
  40 package body Ada.Text_IO.Generic_Aux is
     
        package FIO renames System.File_IO;
        package FCB renames System.File_Control_Block;
        subtype AP is FCB.AFCB_Ptr;
  45 
        ------------------------
        -- Check_End_Of_Field --
        ------------------------
     
  50    procedure Check_End_Of_Field
          (Buf   : String;
           Stop  : Integer;
           Ptr   : Integer;
           Width : Field)
  55    is
        begin
           if Ptr > Stop then
              return;
     
  60       elsif Width = 0 then
              raise Data_Error;
     
           else
              for J in Ptr .. Stop loop
  65             if not Is_Blank (Buf (J)) then
                    raise Data_Error;
                 end if;
              end loop;
           end if;
  70    end Check_End_Of_Field;
     
        -----------------------
        -- Check_On_One_Line --
        -----------------------
  75 
        procedure Check_On_One_Line
          (File   : File_Type;
           Length : Integer)
        is
  80    begin
           FIO.Check_Write_Status (AP (File));
     
           if File.Line_Length /= 0 then
              if Count (Length) > File.Line_Length then
  85             raise Layout_Error;
              elsif File.Col + Count (Length) > File.Line_Length + 1 then
                 New_Line (File);
              end if;
           end if;
  90    end Check_On_One_Line;
     
        ----------
        -- Getc --
        ----------
  95 
        function Getc (File : File_Type) return int is
           ch : int;
     
        begin
 100       ch := fgetc (File.Stream);
     
           if ch = EOF and then ferror (File.Stream) /= 0 then
              raise Device_Error;
           else
 105          return ch;
           end if;
        end Getc;
     
        --------------
 110    -- Is_Blank --
        --------------
     
        function Is_Blank (C : Character) return Boolean is
        begin
 115       return C = ' ' or else C = ASCII.HT;
        end Is_Blank;
     
        ----------
        -- Load --
 120    ----------
     
        procedure Load
          (File   : File_Type;
           Buf    : out String;
 125       Ptr    : in out Integer;
           Char   : Character;
           Loaded : out Boolean)
        is
           ch : int;
 130 
        begin
           ch := Getc (File);
     
           if ch = Character'Pos (Char) then
 135          Store_Char (File, ch, Buf, Ptr);
              Loaded := True;
           else
              Ungetc (ch, File);
              Loaded := False;
 140       end if;
        end Load;
     
        procedure Load
          (File   : File_Type;
 145       Buf    : out String;
           Ptr    : in out Integer;
           Char   : Character)
        is
           ch : int;
 150 
        begin
           ch := Getc (File);
     
           if ch = Character'Pos (Char) then
 155          Store_Char (File, ch, Buf, Ptr);
           else
              Ungetc (ch, File);
           end if;
        end Load;
 160 
        procedure Load
          (File   : File_Type;
           Buf    : out String;
           Ptr    : in out Integer;
 165       Char1  : Character;
           Char2  : Character;
           Loaded : out Boolean)
        is
           ch : int;
 170 
        begin
           ch := Getc (File);
     
           if ch = Character'Pos (Char1) or else ch = Character'Pos (Char2) then
 175          Store_Char (File, ch, Buf, Ptr);
              Loaded := True;
           else
              Ungetc (ch, File);
              Loaded := False;
 180       end if;
        end Load;
     
        procedure Load
          (File   : File_Type;
 185       Buf    : out String;
           Ptr    : in out Integer;
           Char1  : Character;
           Char2  : Character)
        is
 190       ch : int;
     
        begin
           ch := Getc (File);
     
 195       if ch = Character'Pos (Char1) or else ch = Character'Pos (Char2) then
              Store_Char (File, ch, Buf, Ptr);
           else
              Ungetc (ch, File);
           end if;
 200    end Load;
     
        -----------------
        -- Load_Digits --
        -----------------
 205 
        procedure Load_Digits
          (File   : File_Type;
           Buf    : out String;
           Ptr    : in out Integer;
 210       Loaded : out Boolean)
        is
           ch          : int;
           After_Digit : Boolean;
     
 215    begin
           ch := Getc (File);
     
           if ch not in Character'Pos ('0') .. Character'Pos ('9') then
              Loaded := False;
 220 
           else
              Loaded := True;
              After_Digit := True;
     
 225          loop
                 Store_Char (File, ch, Buf, Ptr);
                 ch := Getc (File);
     
                 if ch in Character'Pos ('0') .. Character'Pos ('9') then
 230                After_Digit := True;
     
                 elsif ch = Character'Pos ('_') and then After_Digit then
                    After_Digit := False;
     
 235             else
                    exit;
                 end if;
              end loop;
           end if;
 240 
           Ungetc (ch, File);
        end Load_Digits;
     
        procedure Load_Digits
 245      (File   : File_Type;
           Buf    : out String;
           Ptr    : in out Integer)
        is
           ch          : int;
 250       After_Digit : Boolean;
     
        begin
           ch := Getc (File);
     
 255       if ch in Character'Pos ('0') .. Character'Pos ('9') then
              After_Digit := True;
     
              loop
                 Store_Char (File, ch, Buf, Ptr);
 260             ch := Getc (File);
     
                 if ch in Character'Pos ('0') .. Character'Pos ('9') then
                    After_Digit := True;
     
 265             elsif ch = Character'Pos ('_') and then After_Digit then
                    After_Digit := False;
     
                 else
                    exit;
 270             end if;
              end loop;
           end if;
     
           Ungetc (ch, File);
 275    end Load_Digits;
     
        --------------------------
        -- Load_Extended_Digits --
        --------------------------
 280 
        procedure Load_Extended_Digits
          (File   : File_Type;
           Buf    : out String;
           Ptr    : in out Integer;
 285       Loaded : out Boolean)
        is
           ch          : int;
           After_Digit : Boolean := False;
     
 290    begin
           Loaded := False;
     
           loop
              ch := Getc (File);
 295 
              if ch in Character'Pos ('0') .. Character'Pos ('9')
                   or else
                 ch in Character'Pos ('a') .. Character'Pos ('f')
                   or else
 300             ch in Character'Pos ('A') .. Character'Pos ('F')
              then
                 After_Digit := True;
     
              elsif ch = Character'Pos ('_') and then After_Digit then
 305             After_Digit := False;
     
              else
                 exit;
              end if;
 310 
              Store_Char (File, ch, Buf, Ptr);
              Loaded := True;
           end loop;
     
 315       Ungetc (ch, File);
        end Load_Extended_Digits;
     
        procedure Load_Extended_Digits
          (File   : File_Type;
 320       Buf    : out String;
           Ptr    : in out Integer)
        is
           Junk : Boolean;
     
 325    begin
           Load_Extended_Digits (File, Buf, Ptr, Junk);
        end Load_Extended_Digits;
     
        ---------------
 330    -- Load_Skip --
        ---------------
     
        procedure Load_Skip (File  : File_Type) is
           C : Character;
 335 
        begin
           FIO.Check_Read_Status (AP (File));
     
           --  Loop till we find a non-blank character (note that as usual in
 340       --  Text_IO, blank includes horizontal tab). Note that Get deals with
           --  the Before_LM and Before_LM_PM flags appropriately.
     
           loop
              Get (File, C);
 345          exit when not Is_Blank (C);
           end loop;
     
           Ungetc (Character'Pos (C), File);
           File.Col := File.Col - 1;
 350    end Load_Skip;
     
        ----------------
        -- Load_Width --
        ----------------
 355 
        procedure Load_Width
          (File  : File_Type;
           Width : Field;
           Buf   : out String;
 360       Ptr   : in out Integer)
        is
           ch : int;
     
        begin
 365       FIO.Check_Read_Status (AP (File));
     
           --  If we are immediately before a line mark, then we have no characters.
           --  This is always a data error, so we may as well raise it right away.
     
 370       if File.Before_LM then
              raise Data_Error;
     
           else
              for J in 1 .. Width loop
 375             ch := Getc (File);
     
                 if ch = EOF then
                    return;
     
 380             elsif ch = LM then
                    Ungetc (ch, File);
                    return;
     
                 else
 385                Store_Char (File, ch, Buf, Ptr);
                 end if;
              end loop;
           end if;
        end Load_Width;
 390 
        -----------
        -- Nextc --
        -----------
     
 395    function Nextc (File : File_Type) return int is
           ch : int;
     
        begin
           ch := fgetc (File.Stream);
 400 
           if ch = EOF then
              if ferror (File.Stream) /= 0 then
                 raise Device_Error;
              else
 405             return EOF;
              end if;
     
           else
              Ungetc (ch, File);
 410          return ch;
           end if;
        end Nextc;
     
        --------------
 415    -- Put_Item --
        --------------
     
        procedure Put_Item (File : File_Type; Str : String) is
        begin
 420       Check_On_One_Line (File, Str'Length);
           Put (File, Str);
        end Put_Item;
     
        ----------------
 425    -- Store_Char --
        ----------------
     
        procedure Store_Char
          (File : File_Type;
 430       ch   : int;
           Buf  : out String;
           Ptr  : in out Integer)
        is
        begin
 435       File.Col := File.Col + 1;
     
           if Ptr = Buf'Last then
              raise Data_Error;
           else
 440          Ptr := Ptr + 1;
              Buf (Ptr) := Character'Val (ch);
           end if;
        end Store_Char;
     
 445    -----------------
        -- String_Skip --
        -----------------
     
        procedure String_Skip (Str : String; Ptr : out Integer) is
 450    begin
           Ptr := Str'First;
     
           loop
              if Ptr > Str'Last then
 455             raise End_Error;
     
              elsif not Is_Blank (Str (Ptr)) then
                 return;
     
 460          else
                 Ptr := Ptr + 1;
              end if;
           end loop;
        end String_Skip;
 465 
        ------------
        -- Ungetc --
        ------------
     
 470    procedure Ungetc (ch : int; File : File_Type) is
        begin
           if ch /= EOF then
              if ungetc (ch, File.Stream) = EOF then
                 raise Device_Error;
 475          end if;
           end if;
        end Ungetc;
     
     end Ada.Text_IO.Generic_Aux;