with Interfaces.C_Streams; with Ada.Streams; with Ada.Streams.Stream_Io; with Ada.Text_Io; with Ada.Text_Io.C_Streams; procedure Standard_IO_Play is package ICS renames Interfaces.C_Streams; package AS renames Ada.Streams; package ASSIO renames Ada.Streams.Stream_Io; package TIO renames Ada.Text_Io; package TIOCS renames Ada.Text_Io.C_Streams; function Is_File_A_Tty ( File : Ada.Text_Io.File_Type ) return Boolean is begin return ( Interfaces.C_Streams.Isatty ( Interfaces.C_Streams.FileNo ( Ada.Text_Io.C_Streams.C_Stream (File) ) ) > 0 ); end Is_File_A_Tty; Buffer_Size : constant := 10240; -- 10k buffer size Buffer : String (1 .. Buffer_Size) := (Others => ' '); Last : Natural := Buffer'Last; Buffer_Address : constant ICS.Voids := Buffer(Buffer'First)'Address; Element_Size : constant := Character'Size / 8; Bytes_Read : ICS.Size_t := 0; Bytes_Written : ICS.Size_t := 0; Flush_Result : Integer; begin -- First, check whether Std_In is attached to a tty or is -- something else. -- If stdin is a tty, then expecting ketboard user input -- else (not a tty) assuming that the OS is piping a file -- to this procedure -- (Remember this is just an example and that it is prabably -- a bad assumption and oversimplification). -- if Is_File_A_Tty (TIO.Current_Input) then TIO.Put_Line ( File => TIO.Standard_Error, Item => "Trying to show piping. So please pipe into this procedure" ); TIO.Put_Line ( File => TIO.Standard_Error, Item => "ie # ""cat test-file | ./standard_io_play > result-file""" ); else Std_In_Read : loop exit Std_In_Read when TIO.End_Of_File (TIO.Current_Input); -- Read using ICS ... Bytes_Read := ICS.Fread ( Buffer => Buffer_Address, Size => Element_Size, Count => ICS.Size_t (Buffer'Length), Stream => TIOCS.C_Stream (TIO.Current_Input) ); -- Do your thing to the buffer ... (Note the possibility of -- incompatible ranges for Natural (Bytes_Read) and subsequent -- buffer overflows). Processing : for Char in Buffer'First .. Natural (Bytes_Read) loop if Buffer(Char) = ASCII.Lf then TIO.Put_Line ( File => TIO.Standard_Error, Item => "Found LF" ); elsif Buffer(Char) = ASCII.Cr then TIO.Put_Line ( File => TIO.Standard_Error, Item => "Found CR" ); elsif Buffer(Char) = ASCII.Ht then TIO.Put_Line ( File => TIO.Standard_Error, Item => "Found TAB" ); end if; end loop Processing; -- Write using ICS ... Bytes_Written := ICS.Fwrite ( Buffer => Buffer_Address, Size => Element_Size, Count => ICS.Size_t (Bytes_Read), Stream => TIOCS.C_Stream (TIO.Current_Output) ); end loop Std_In_Read; Flush_Result := ICS.Fflush (TIOCS.C_Stream (TIO.Current_Output)); end if; end Standard_IO_Play;