From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=unavailable autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,ac3fc59590c9d4cd X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-08-24 16:48:20 PST Path: archiver1.google.com!newsfeed.google.com!newsfeed.stanford.edu!news.tele.dk!small.news.tele.dk!193.251.151.101!opentransit.net!jussieu.fr!enst!enst.fr!not-for-mail From: sk Newsgroups: comp.lang.ada Subject: Re: Unix text handling on stdin Date: Fri, 24 Aug 2001 18:44:36 -0500 Organization: ENST, France Sender: comp.lang.ada-admin@ada.eu.org Message-ID: References: <9m6hcj$aai1@news.cis.okstate.edu> Reply-To: comp.lang.ada@ada.eu.org NNTP-Posting-Host: marvin.enst.fr Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------36D9E93F8C2AB6A0DB116D59" X-Trace: avanie.enst.fr 998696899 32736 137.194.161.2 (24 Aug 2001 23:48:19 GMT) X-Complaints-To: usenet@enst.fr NNTP-Posting-Date: Fri, 24 Aug 2001 23:48:19 +0000 (UTC) To: comp.lang.ada@ada.eu.org Return-Path: X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.2.19-4.3mdk i686) X-Accept-Language: en Errors-To: comp.lang.ada-admin@ada.eu.org X-BeenThere: comp.lang.ada@ada.eu.org X-Mailman-Version: 2.0.4 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: comp.lang.ada mail<->news gateway List-Unsubscribe: , List-Archive: Errors-To: comp.lang.ada-admin@ada.eu.org X-BeenThere: comp.lang.ada@ada.eu.org Xref: archiver1.google.com comp.lang.ada:12403 Date: 2001-08-24T18:44:36-05:00 This is a multi-part message in MIME format. --------------36D9E93F8C2AB6A0DB116D59 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, I tried the ICFP thing for S&G's (didn't, and didn't intend to, really enter) and ran into the same problem ... So, my solution involved Ada.Text_Io; Ada.Text_Io.C_Streams; Interfaces.C_Streams; and here is a distilled way to take std in and copy it to stdout without TIO adding extra Line feeds when closing the file etc. I fully intended to look up the issue in both the LRM and Ada Issues to see if the compiler was behaving according to spec, but once I found a work-around, I never got round to checking about the legitimacy of this TIO behaviour. The output of this procedure will be of exactly the same size as the input ... unlike when exclusively using TIO which always added an extra byte or two when closing. sknipe@ktc.com PS. Please note that this is a QAD[1] and not very careful such that exceptions can and will be raised by going out of range [1] Quick and Dirty :-) PPS. Text attachment, sorry, to preserve formatting ... PPPS. Linux, GNAT 3.13p ---------------------------------------------------------------- --------------36D9E93F8C2AB6A0DB116D59 Content-Type: text/plain; charset=us-ascii; name="standard_io_play.adb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="standard_io_play.adb" 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; --------------36D9E93F8C2AB6A0DB116D59--