comp.lang.ada
 help / color / mirror / Atom feed
* C getchar() functionality in Ada
@ 2009-02-16 20:36 Thomas Locke
  2009-02-16 21:43 ` Jeffrey R. Carter
                   ` (3 more replies)
  0 siblings, 4 replies; 28+ messages in thread
From: Thomas Locke @ 2009-02-16 20:36 UTC (permalink / raw)


Hey all,

I've started redoing all the K&R C examples in Ada, and I've already hit 
a wall that I'm not able to get around.

I have this C program:  http://pastebin.com/fbc6bec5

It's very simple, but still I fail to mimick it in Ada.

The C program happily accepts everything I throw at it, and it responds 
with the expected values, whereas my Ada version(s) either fail at 
linefeeds, throw End_Error exceptions at me, or spits out too many 
linefeeds!

My current Ada code looks like this: http://pastebin.com/f519f7e37

This version works with input from keyboard and when I pipe some data 
into it like this:  $ echo "FooBar" | ito

It craps out on files ($ cat SomeFile | ito), where it ignores linefeeds 
and throws End_Error exceptions at me when the last character in the 
file is a linefeed

I've tried with Get_Immediate, Look_Ahead, Get_Line and a mixture of 
Strings, Characters and Unbounded strings. I just can't make it work.

Any and all advice are more than welcome.

:o)
/Thomas



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-16 20:36 C getchar() functionality in Ada Thomas Locke
@ 2009-02-16 21:43 ` Jeffrey R. Carter
  2009-02-17  7:23   ` Thomas Locke
  2009-02-16 23:46 ` Adam Beneschan
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 28+ messages in thread
From: Jeffrey R. Carter @ 2009-02-16 21:43 UTC (permalink / raw)


Thomas Locke wrote:
> 
> I've started redoing all the K&R C examples in Ada, and I've already hit 
> a wall that I'm not able to get around.
> 
> I have this C program:  http://pastebin.com/fbc6bec5
> 
> It's very simple, but still I fail to mimick it in Ada.

This program duplicates standard input on standard output.

You are being mislead by the use of "char" in C. "char" sometimes refers to the 
equivalent of Ada's Character, and other times to the equivalent of 
System.Storage_Elements.Storage_Element or Ada.Streams.Stream_Element.

This is one of the latter cases. You should not be using Character, String, or 
Ada.Text_IO for this. I suggest you look at streams and Ada.Text_IO.Text_Streams.

-- 
Jeff Carter
"Help! Help! I'm being repressed!"
Monty Python & the Holy Grail
67



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-16 20:36 C getchar() functionality in Ada Thomas Locke
  2009-02-16 21:43 ` Jeffrey R. Carter
@ 2009-02-16 23:46 ` Adam Beneschan
  2009-02-17  7:19   ` Thomas Locke
  2009-02-17 14:55   ` Hibou57 (Yannick Duchêne)
  2009-02-17 10:37 ` m.collado
  2009-02-17 16:40 ` Jean-Pierre Rosen
  3 siblings, 2 replies; 28+ messages in thread
From: Adam Beneschan @ 2009-02-16 23:46 UTC (permalink / raw)


On Feb 16, 12:36 pm, Thomas Locke <tho...@kenshi.dk> wrote:
> Hey all,
>
> I've started redoing all the K&R C examples in Ada, and I've already hit
> a wall that I'm not able to get around.
>
> I have this C program:  http://pastebin.com/fbc6bec5
>
> It's very simple, but still I fail to mimick it in Ada.
>
> The C program happily accepts everything I throw at it, and it responds
> with the expected values, whereas my Ada version(s) either fail at
> linefeeds, throw End_Error exceptions at me, or spits out too many
> linefeeds!
>
> My current Ada code looks like this:http://pastebin.com/f519f7e37
>
> This version works with input from keyboard and when I pipe some data
> into it like this:  $ echo "FooBar" | ito
>
> It craps out on files ($ cat SomeFile | ito), where it ignores linefeeds
> and throws End_Error exceptions at me when the last character in the
> file is a linefeed

I'd be surprised if the program actually ignores *all* linefeeds---
that would indicate something is wrong with your compiler.  But you're
probably  seeing that blank lines get ignored---is that correct?

Ada doesn't think of Text_IO files just as streams of characters (with
linefeed being one of the characters); files are structured in terms
of lines and pages, without specifying just what form the line
separators and page separators look like.  Here, End_Of_Line tests to
see if the input file is at the end of the line, but it does *not*
"eat" the line separator.  You'll have to use Skip_Line for that.
Also, Get will skip over any line separators that it's facing.  So if
there are two or more line separators in a row, End_Of_Line will not
swallow any of them, and then Get will swallow all of them.
Furthermore, if there are multiple line separators followed by the end-
of-file, End_Of_File will not return True because there are additional
"empty" lines, but then Get will eat all the line separators and then
raise End_Error because there is no character to read.

I think that with this information you can probably figure out how to
make it work, as close as possible.  But keep in mind that you are
*still* not going to be reading and writing individual characters the
same as in C.  On Windows, the line separator is often CR LF (two
characters), and there's really no way in Ada (using Text_IO) to treat
that as two separate characters.  If you need that, you'll have to go
outside the standard Ada library.  Plus there's no telling what your
implementation will do if it sees CR or LF by itself, or LF CR, or
other mutant combinations of those control characters.

In any event, the program you're writing probably has no practical
use.  If you really want to read individual characters and treat
control characters just like all other characters, you probably don't
want to use Text_IO.  If that isn't what you want, then you likely
don't want to read individual characters.  I realize that this is not
a practical program that you're trying to mimic, but rather a example
to demonstrate some point.

Hope this helps,

                              -- Adam





^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-16 23:46 ` Adam Beneschan
@ 2009-02-17  7:19   ` Thomas Locke
  2009-02-17  8:37     ` Jacob Sparre Andersen
  2009-02-17 14:57     ` Hibou57 (Yannick Duchêne)
  2009-02-17 14:55   ` Hibou57 (Yannick Duchêne)
  1 sibling, 2 replies; 28+ messages in thread
From: Thomas Locke @ 2009-02-17  7:19 UTC (permalink / raw)


Adam Beneschan wrote:
> I'd be surprised if the program actually ignores *all* linefeeds---
> that would indicate something is wrong with your compiler.  But you're
> probably  seeing that blank lines get ignored---is that correct?


Yes, that is correct.

Just as you say, I've found that the Get and Get_Line functions ignore 
linefeeds.

Get_Immediate on the other hand, appears to be "aware" of linefeeds.


> 
> Ada doesn't think of Text_IO files just as streams of characters (with
> linefeed being one of the characters); files are structured in terms
> of lines and pages, without specifying just what form the line
> separators and page separators look like.  Here, End_Of_Line tests to
> see if the input file is at the end of the line, but it does *not*
> "eat" the line separator.  You'll have to use Skip_Line for that.
> Also, Get will skip over any line separators that it's facing.  So if
> there are two or more line separators in a row, End_Of_Line will not
> swallow any of them, and then Get will swallow all of them.
> Furthermore, if there are multiple line separators followed by the end-
> of-file, End_Of_File will not return True because there are additional
> "empty" lines, but then Get will eat all the line separators and then
> raise End_Error because there is no character to read.


That is *exactly* what I'm seeing.


> I think that with this information you can probably figure out how to
> make it work, as close as possible.  But keep in mind that you are
> *still* not going to be reading and writing individual characters the
> same as in C.  On Windows, the line separator is often CR LF (two
> characters), and there's really no way in Ada (using Text_IO) to treat
> that as two separate characters.  If you need that, you'll have to go
> outside the standard Ada library.  Plus there's no telling what your
> implementation will do if it sees CR or LF by itself, or LF CR, or
> other mutant combinations of those control characters.


Very good point. I wonder how the C getchar() program would handle 
itself with a file of CRLF terminated lines on a *nix machine.

Am I right in assuming that Ada handles itself uniformly across all 
supported platforms?


> In any event, the program you're writing probably has no practical
> use.  If you really want to read individual characters and treat
> control characters just like all other characters, you probably don't
> want to use Text_IO.  If that isn't what you want, then you likely
> don't want to read individual characters.  I realize that this is not
> a practical program that you're trying to mimic, but rather a example
> to demonstrate some point.


Yes, that was what Jeffrey also said. But now that I better understand 
why Text_IO behaves as it does, I think I'd rather build 2-3 small Ada 
programs to mimick the one C program, each program focusing on a 
specific area of behavior.

I'm really only doing this to learn Ada, so doing a bit more code is 
probably not the worst idea.  :o)

For now, I will leave Streams for the future. I can easily see myself 
failing miserably with Streams, as they are probably a bit more 
complicated than Text_IO, and understanding Text_IO is, currently, a big 
enough challenge.


> Hope this helps,
> 
>                               -- Adam


It did, very much. Thank you.

:o)
/Thomas



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-16 21:43 ` Jeffrey R. Carter
@ 2009-02-17  7:23   ` Thomas Locke
  2009-02-17  8:16     ` Niklas Holsti
  2009-02-17 20:48     ` Jeffrey R. Carter
  0 siblings, 2 replies; 28+ messages in thread
From: Thomas Locke @ 2009-02-17  7:23 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> This is one of the latter cases. You should not be using Character, 
> String, or Ada.Text_IO for this. I suggest you look at streams and 
> Ada.Text_IO.Text_Streams.


I will try this when my Ada skills have improved a bit. For now I will 
focus on learning how to best use Text_IO.

I wouldn't mind a smallish example on using Ada.Text_IO.Text_Streams 
though...  :D

/Thomas



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17  7:23   ` Thomas Locke
@ 2009-02-17  8:16     ` Niklas Holsti
  2009-02-17 13:01       ` Georg Bauhaus
  2009-02-17 20:48     ` Jeffrey R. Carter
  1 sibling, 1 reply; 28+ messages in thread
From: Niklas Holsti @ 2009-02-17  8:16 UTC (permalink / raw)


Thomas Locke wrote:
> Jeffrey R. Carter wrote:
> 
>> This is one of the latter cases. You should not be using Character, 
>> String, or Ada.Text_IO for this. I suggest you look at streams and 
>> Ada.Text_IO.Text_Streams.

Or Ada.Sequential_IO, instantiated for Character (or 
Storage_Element, etc.) which seems to me the best match to the 
original C program. However, Sequential_IO has the problem that the 
standard-input and standard-output channels are not accessible, you 
must Open named files.

> I will try this when my Ada skills have improved a bit. For now I will 
> focus on learning how to best use Text_IO.
> 
> I wouldn't mind a smallish example on using Ada.Text_IO.Text_Streams 
> though...  :D

Here is a copy-input-to-output program with Text_Streams and Character:

with Ada.Text_IO.Text_Streams;

procedure Acopy
is
    use Ada.Text_IO;
    use Ada.Text_IO.Text_Streams;

    Input  : constant Stream_Access := Stream (Standard_Input);
    Output : constant Stream_Access := Stream (Standard_Output);

    Item : Character;

begin

    while not End_Of_File (Standard_Input) loop

       Character'Read (Input , Item);
       Character'Write(Output, Item);

    end loop;

end Acopy;


-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17  7:19   ` Thomas Locke
@ 2009-02-17  8:37     ` Jacob Sparre Andersen
  2009-02-17 17:31       ` Keith Thompson
  2009-02-17 14:57     ` Hibou57 (Yannick Duchêne)
  1 sibling, 1 reply; 28+ messages in thread
From: Jacob Sparre Andersen @ 2009-02-17  8:37 UTC (permalink / raw)


Thomas Locke wrote:

> Am I right in assuming that Ada handles itself uniformly across all
> supported platforms?

Ada.Text_IO can be expected to operate uniformly on text files which
conform to the conventions of the individual platforms.

(I think the answer to your question is yes.)

Greetings,

Jacob
-- 
Who guards the guardians?



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-16 20:36 C getchar() functionality in Ada Thomas Locke
  2009-02-16 21:43 ` Jeffrey R. Carter
  2009-02-16 23:46 ` Adam Beneschan
@ 2009-02-17 10:37 ` m.collado
  2009-02-17 22:07   ` Thomas Locke
  2009-02-17 16:40 ` Jean-Pierre Rosen
  3 siblings, 1 reply; 28+ messages in thread
From: m.collado @ 2009-02-17 10:37 UTC (permalink / raw)


Thomas Locke escribi�:
> Hey all,
> 
> I've started redoing all the K&R C examples in Ada, and I've already hit 
> a wall that I'm not able to get around.
> 
> I have this C program:  http://pastebin.com/fbc6bec5
> 
> It's very simple, but still I fail to mimick it in Ada.
> 
> The C program happily accepts everything I throw at it, and it responds 
> with the expected values, whereas my Ada version(s) either fail at 
> linefeeds, throw End_Error exceptions at me, or spits out too many 
> linefeeds!
> 
> My current Ada code looks like this: http://pastebin.com/f519f7e37
> 
> This version works with input from keyboard and when I pipe some data 
> into it like this:  $ echo "FooBar" | ito
> 
> It craps out on files ($ cat SomeFile | ito), where it ignores linefeeds 
> and throws End_Error exceptions at me when the last character in the 
> file is a linefeed
> 
> I've tried with Get_Immediate, Look_Ahead, Get_Line and a mixture of 
> Strings, Characters and Unbounded strings. I just can't make it work.

The following seems to work:

with Ada.Text_IO;          use Ada.Text_IO;

procedure Ito is
    C : Character;
begin
    while not End_Of_File loop
       Get_Immediate (Item => C);
       Put (Item => C);
    end loop;
end Ito ;

> 
> Any and all advice are more than welcome.
> 
> :o)
> /Thomas


-- 
Manuel Collado - http://lml.ls.fi.upm.es/~mcollado



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17  8:16     ` Niklas Holsti
@ 2009-02-17 13:01       ` Georg Bauhaus
  2009-02-17 22:03         ` Thomas Locke
  2009-03-03  8:57         ` David Thompson
  0 siblings, 2 replies; 28+ messages in thread
From: Georg Bauhaus @ 2009-02-17 13:01 UTC (permalink / raw)


Niklas Holsti schrieb:
> Thomas Locke wrote:
>> Jeffrey R. Carter wrote:
>>
>>> This is one of the latter cases. You should not be using Character,
>>> String, or Ada.Text_IO for this. I suggest you look at streams and
>>> Ada.Text_IO.Text_Streams.
> 
> Or Ada.Sequential_IO, instantiated for Character (or Storage_Element,
> etc.) which seems to me the best match to the original C program.
> However, Sequential_IO has the problem that the standard-input and
> standard-output channels are not accessible, you must Open named files.
> 
>> I will try this when my Ada skills have improved a bit. For now I will
>> focus on learning how to best use Text_IO.
>>
>> I wouldn't mind a smallish example on using Ada.Text_IO.Text_Streams
>> though...  :D
> 
> Here is a copy-input-to-output program with Text_Streams and Character:
> 
> with Ada.Text_IO.Text_Streams;
> 
> procedure Acopy
> is
>    use Ada.Text_IO;
>    use Ada.Text_IO.Text_Streams;
> 
>    Input  : constant Stream_Access := Stream (Standard_Input);
>    Output : constant Stream_Access := Stream (Standard_Output);
> 
>    Item : Character;
> 
> begin
> 
>    while not End_Of_File (Standard_Input) loop
> 
>       Character'Read (Input , Item);
>       Character'Write(Output, Item);
> 
>    end loop;
> 
> end Acopy;


We can write the same program in Ada, of course. :-)
Only, the Ada version is likely written without
resorting to the C's idiomatic
"statement-used-as-expression-in-the-loop-conditional".

with Interfaces.C;

procedure C_1 is

   use Interfaces.C;

   function getchar return int;
   function putchar(item: int) return int;

   pragma Import(C, getchar);
   pragma Import(C, putchar);

   EOF: constant int := -1;             --  see <stdio.h>
   c, not_checked: int;

begin
   loop
      c := getchar;
      exit when C = EOF;
      not_checked := putchar(c);
   end loop;
end C_1;



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-16 23:46 ` Adam Beneschan
  2009-02-17  7:19   ` Thomas Locke
@ 2009-02-17 14:55   ` Hibou57 (Yannick Duchêne)
  1 sibling, 0 replies; 28+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2009-02-17 14:55 UTC (permalink / raw)


On 17 fév, 00:46, Adam Beneschan <a...@irvine.com> wrote:
> Plus there's no telling what your
> implementation will do if it sees CR or LF by itself, or LF CR, or
> other mutant combinations of those control characters.
>
>                               -- Adam

Here, execeptions legitimately comes into place (I suppose that's what
the implementation should do)



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17  7:19   ` Thomas Locke
  2009-02-17  8:37     ` Jacob Sparre Andersen
@ 2009-02-17 14:57     ` Hibou57 (Yannick Duchêne)
  1 sibling, 0 replies; 28+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2009-02-17 14:57 UTC (permalink / raw)


On 17 fév, 08:19, Thomas Locke <tho...@kenshi.dk> wrote:
> Very good point. I wonder how the C getchar() program would handle
> itself with a file of CRLF terminated lines on a *nix machine.
>
> /Thomas
It will return this as two consecutive characters




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-16 20:36 C getchar() functionality in Ada Thomas Locke
                   ` (2 preceding siblings ...)
  2009-02-17 10:37 ` m.collado
@ 2009-02-17 16:40 ` Jean-Pierre Rosen
  2009-02-17 19:46   ` Thomas Locke
  2009-02-17 20:38   ` Jeffrey R. Carter
  3 siblings, 2 replies; 28+ messages in thread
From: Jean-Pierre Rosen @ 2009-02-17 16:40 UTC (permalink / raw)


Thomas Locke a �crit :
A simple problem, a simple solution.

In Ada, an end of line is not a character. Full stop. We have operations
that deal with end of lines: new_line, skip_line, and end_of_line.

Therefore, your program should look like:
      with Ada.Text_IO;          use Ada.Text_IO;
      procedure Ito is
         C : Character;
      begin
         while not End_Of_File loop
            if End_Of_Line then
               Skip_Line;
               New_Line;
            else
               Get (Item => C);
               Put (Item => C);
            end if;
         end loop;
      end Ito;

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17  8:37     ` Jacob Sparre Andersen
@ 2009-02-17 17:31       ` Keith Thompson
  0 siblings, 0 replies; 28+ messages in thread
From: Keith Thompson @ 2009-02-17 17:31 UTC (permalink / raw)


Jacob Sparre Andersen <sparre@nbi.dk> writes:
> Thomas Locke wrote:
>> Am I right in assuming that Ada handles itself uniformly across all
>> supported platforms?
>
> Ada.Text_IO can be expected to operate uniformly on text files which
> conform to the conventions of the individual platforms.
>
> (I think the answer to your question is yes.)

And the same is true for C I/O in text mode.

For example, as has already been mentioned, on Windows the end-of-line
marker is a two-character sequence CR LF.  If you're using a C
implementation on a Windows system, and you're reading a text file
using a file opened in text mode, getchar() will consume both
characters and return a single '\n' character.  ('\n' is C's new-line
character; it's typically an ASCII LF, but the C language doesn't
specify that.)

If you open the same file in binary mode, you'll get the raw character
values CR and LF (probably '\r' and '\n', respectively).

Ada uses separate packages (Text_IO and Sequential_IO) for text and
binary input.  C uses a single interface for both, but a file can be
opened either in text mode or in binary mode, determined by the second
argument passed to fopen().  On Unix-like systems, there's no real
difference between text and binary modes, since the end-of-line marker
is a single LF ('\n').  On other systems, there might not even be an
end-of-line marker; a text file might be stored as a sequence of
fixed-length records.  C's I/O system, like Ada's is designed to deal
with such things.

-- 
Keith Thompson (The_Other_Keith) kst@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 16:40 ` Jean-Pierre Rosen
@ 2009-02-17 19:46   ` Thomas Locke
  2009-02-17 20:24     ` Hyman Rosen
  2009-02-18  7:43     ` Jean-Pierre Rosen
  2009-02-17 20:38   ` Jeffrey R. Carter
  1 sibling, 2 replies; 28+ messages in thread
From: Thomas Locke @ 2009-02-17 19:46 UTC (permalink / raw)


Jean-Pierre Rosen wrote:
> Thomas Locke a �crit :
> A simple problem, a simple solution.


That was exactly what I thought!  :o)


> In Ada, an end of line is not a character. Full stop. We have operations
> that deal with end of lines: new_line, skip_line, and end_of_line.
> 
> Therefore, your program should look like:
>       with Ada.Text_IO;          use Ada.Text_IO;
>       procedure Ito is
>          C : Character;
>       begin
>          while not End_Of_File loop
>             if End_Of_Line then
>                Skip_Line;
>                New_Line;
>             else
>                Get (Item => C);
>                Put (Item => C);
>             end if;
>          end loop;
>       end Ito;


This program *almost* work exactly as the C version, but not quite. It 
fails to recognize all EOL's in files, and it behaves a bit "odd" when 
feeding data to it using the keyboard.

But I understand what you're saying: No end of line characters in Ada!

Except perhaps when using Get_Immediate and Look_Ahead?

/Thomas



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 19:46   ` Thomas Locke
@ 2009-02-17 20:24     ` Hyman Rosen
  2009-02-17 23:44       ` Robert A Duff
  2009-02-18  0:39       ` Adam Beneschan
  2009-02-18  7:43     ` Jean-Pierre Rosen
  1 sibling, 2 replies; 28+ messages in thread
From: Hyman Rosen @ 2009-02-17 20:24 UTC (permalink / raw)


Thomas Locke wrote:
> But I understand what you're saying: No end of line characters in Ada!
> Except perhaps when using Get_Immediate and Look_Ahead?

The Ada design has the same error here as Pascal did.
End of Line and End of File are like a craps table;
you can know whether the table *was* hot or cold, but
you cannot know whether the table *will be* hot or
cold. Similarly, you cannot know whether you are at
end of line or end of file until you have tried reading
a character. Ada pretends otherwise, but behind the
scenes it's doing a secret character read-ahead, which
is what causes the odd behavior.

I speak about the various modern OSes. Presumably, once
upon a time input was such that this paradigm made sense,
just like Fortran had special output formatting characters
to rotate the roll of paper.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 16:40 ` Jean-Pierre Rosen
  2009-02-17 19:46   ` Thomas Locke
@ 2009-02-17 20:38   ` Jeffrey R. Carter
  2009-02-18  7:46     ` Jean-Pierre Rosen
  1 sibling, 1 reply; 28+ messages in thread
From: Jeffrey R. Carter @ 2009-02-17 20:38 UTC (permalink / raw)


Jean-Pierre Rosen wrote:
> 
> Therefore, your program should look like:
>       with Ada.Text_IO;          use Ada.Text_IO;
>       procedure Ito is
>          C : Character;
>       begin
>          while not End_Of_File loop
>             if End_Of_Line then
>                Skip_Line;
>                New_Line;
>             else
>                Get (Item => C);
>                Put (Item => C);
>             end if;
>          end loop;
>       end Ito;

Except that, given a file that ends with a blank line, Ada.Text_IO.End_Of_File 
may return True before the final blank line has been detected. The general rule 
is to not use Ada.Text_IO.End_Of_File, and handle the resulting End_Error.

-- 
Jeff Carter
"This trial is a travesty. It's a travesty of a mockery of a
sham of a mockery of a travesty of two mockeries of a sham. ...
Do you realize there's not a single homosexual on that jury?"
Bananas
27



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17  7:23   ` Thomas Locke
  2009-02-17  8:16     ` Niklas Holsti
@ 2009-02-17 20:48     ` Jeffrey R. Carter
  2009-02-17 21:59       ` Thomas Locke
  1 sibling, 1 reply; 28+ messages in thread
From: Jeffrey R. Carter @ 2009-02-17 20:48 UTC (permalink / raw)


Thomas Locke wrote:
> 
> I will try this when my Ada skills have improved a bit. For now I will 
> focus on learning how to best use Text_IO.

If you're interested in learning about Ada.Text_IO, that's fine. Your C example 
works equally well on text or other files; to mimic that in Ada you can't use 
Text_IO. If you limit your input to text, you can duplicate the functionality 
using Text_IO; the solution is similar to Rosen's, but with an infinite loop 
rather than the End_Of_File test, and with an exception handler for End_Error to 
exit the loop gracefully.

(Some people object to such a use of exceptions, but it's the only way to get 
Text_IO to correctly process a file that ends with a blank line. 
Ada.Text_IO.End_Of_File is broken.)

To learn about Ada, you shouldn't try to translate C programs. Rather, you 
should state the requirements and figure out how to implement them in Ada. It 
was not clear from your C program whether you wanted to know how to implement a 
program to copy any kind of file, and were simply mistaken in using Text_IO, or 
a program limited to text files, and the C simply couldn't express that limitation.

-- 
Jeff Carter
"This trial is a travesty. It's a travesty of a mockery of a
sham of a mockery of a travesty of two mockeries of a sham. ...
Do you realize there's not a single homosexual on that jury?"
Bananas
27



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 20:48     ` Jeffrey R. Carter
@ 2009-02-17 21:59       ` Thomas Locke
  0 siblings, 0 replies; 28+ messages in thread
From: Thomas Locke @ 2009-02-17 21:59 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> To learn about Ada, you shouldn't try to translate C programs. Rather, 
> you should state the requirements and figure out how to implement them 
> in Ada. It was not clear from your C program whether you wanted to know 
> how to implement a program to copy any kind of file, and were simply 
> mistaken in using Text_IO, or a program limited to text files, and the C 
> simply couldn't express that limitation.


I understand.

I'm not as such trying to "translate" C programs. I'm trying to redo 
them in Ada, the Ada way. So I guess you could say, that the 
functionality of the small C programs are my requirements, and I'm now 
trying to figure out how to implement that functionality in Ada.

It is pretty clear to me now, that Ada.Text_IO is not the way to mimic 
this specific functionality, so already I can say that I've learned 
something new and, probably, important.  :o)

I will try hard to better explain my intentions in the future.

Regards,
/Thomas



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 13:01       ` Georg Bauhaus
@ 2009-02-17 22:03         ` Thomas Locke
  2009-03-03  8:57         ` David Thompson
  1 sibling, 0 replies; 28+ messages in thread
From: Thomas Locke @ 2009-02-17 22:03 UTC (permalink / raw)


Georg Bauhaus wrote:
> We can write the same program in Ada, of course. :-)
> Only, the Ada version is likely written without
> resorting to the C's idiomatic
> "statement-used-as-expression-in-the-loop-conditional".
> 
> with Interfaces.C;
> 
> procedure C_1 is
> 
>    use Interfaces.C;
> 
>    function getchar return int;
>    function putchar(item: int) return int;
> 
>    pragma Import(C, getchar);
>    pragma Import(C, putchar);
> 
>    EOF: constant int := -1;             --  see <stdio.h>
>    c, not_checked: int;
> 
> begin
>    loop
>       c := getchar;
>       exit when C = EOF;
>       not_checked := putchar(c);
>    end loop;
> end C_1;


Thank you for this very nice example Georg!

I've experimented a bit on it, and the result is this:

-----
with Ada.Text_IO;  use Ada.Text_IO;

procedure Ito is

    function getchar return Integer;
    pragma Import (C, getchar);

    EOF   : constant Integer := -1;
    C     : Integer;

begin
    loop
       C := getchar;
       exit when C = EOF;
       Put (Character'Val (C));
    end loop;
end Ito;
-----

Basically I've just tried to get rid of the C putchar function, and 
instead use plain Put. Would the above be considered absolutely 
horrible, or?

/Thomas



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 10:37 ` m.collado
@ 2009-02-17 22:07   ` Thomas Locke
  0 siblings, 0 replies; 28+ messages in thread
From: Thomas Locke @ 2009-02-17 22:07 UTC (permalink / raw)


m.collado@domain.invalid wrote:
> The following seems to work:
> 
> with Ada.Text_IO;          use Ada.Text_IO;
> 
> procedure Ito is
>    C : Character;
> begin
>    while not End_Of_File loop
>       Get_Immediate (Item => C);
>       Put (Item => C);
>    end loop;
> end Ito ;

It works when piping data to the program, but it does not work with 
input from the keyboard. Data isn't copied when you just start the 
program, type in some characters and press enter. You just get a new 
blank line.

:o)
/Thomas



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 20:24     ` Hyman Rosen
@ 2009-02-17 23:44       ` Robert A Duff
  2009-02-18  5:44         ` anon
  2009-02-18  0:39       ` Adam Beneschan
  1 sibling, 1 reply; 28+ messages in thread
From: Robert A Duff @ 2009-02-17 23:44 UTC (permalink / raw)


Hyman Rosen <hyrosen@mail.com> writes:

> Thomas Locke wrote:
>> But I understand what you're saying: No end of line characters in Ada!
                                                                  ^^^^^^
...in Ada.Text_IO.

>> Except perhaps when using Get_Immediate and Look_Ahead?
>
> The Ada design has the same error here as Pascal did.
      ^^^^^^^^^^
...Ada.Text_IO design...

Text_IO is a bit broken, I agree.  But you can also use streams,
or you can interface directly to the underlying OS primitives.

Ada has a lot of strengths, but unfortunately, the design of the
Ada.Text_IO package is not one of them.

- Bob



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 20:24     ` Hyman Rosen
  2009-02-17 23:44       ` Robert A Duff
@ 2009-02-18  0:39       ` Adam Beneschan
  1 sibling, 0 replies; 28+ messages in thread
From: Adam Beneschan @ 2009-02-18  0:39 UTC (permalink / raw)


On Feb 17, 12:24 pm, Hyman Rosen <hyro...@mail.com> wrote:
> Thomas Locke wrote:
> > But I understand what you're saying: No end of line characters in Ada!
> > Except perhaps when using Get_Immediate and Look_Ahead?
>
> The Ada design has the same error here as Pascal did.
> End of Line and End of File are like a craps table;
> you can know whether the table *was* hot or cold, but
> you cannot know whether the table *will be* hot or
> cold. Similarly, you cannot know whether you are at
> end of line or end of file until you have tried reading
> a character. Ada pretends otherwise, but behind the
> scenes it's doing a secret character read-ahead, which
> is what causes the odd behavior.
>
> I speak about the various modern OSes. Presumably, once
> upon a time input was such that this paradigm made sense,
> just like Fortran had special output formatting characters
> to rotate the roll of paper.

I'm not sure if you're implying that VMS is one of those OS's that are
as outdated as Fortran's formatting characters and horse-drawn
carriages, but when Ada's Text_IO package was designed, VMS was a big
thing.  And VMS text files do not (or didn't) have end-of-line
"characters".  They weren't organized just as amorphous streams of
bytes as they are on Unix-like systems and on Windows, but the OS
itself structured the files into lines.  Ada was designed to be
portable, so in that context I don't think its design was a mistake; a
design that relied on text files to be viewed as having "characters"
to separate lines, pages, etc., *would* probably have been a mistake,
when the goal of portability is kept in mind.

                                -- Adam




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 23:44       ` Robert A Duff
@ 2009-02-18  5:44         ` anon
  0 siblings, 0 replies; 28+ messages in thread
From: anon @ 2009-02-18  5:44 UTC (permalink / raw)


Actually you can input "end of line" and "end of file" character in Ada you 
just use the "Get_Immediate" routine in "Ada.Text_IO" instead of Get.

with Ada.Text_IO ;
use  Ada.Text_IO ;

procedure a is
    Keystroke : character ;
    Ready     : Boolean ;
  begin
    Keystroke := ' ' ;
    while Keystroke /= 'q' loop   -- just away to stop program
      Get_Immediate ( Keystroke, Ready ) ;
      if ready then
        Put ( Keystroke ) ;
      end if ;
    end loop ;
  end ;

And is "Ada.Text_IO" broken? Not if you use the correct routine or the correct
job. And Ada in the pure form, is a base that one can create better and more 
useful packages for each job that one needs.

In <wccab8kbpdp.fsf@shell01.TheWorld.com>, Robert A Duff <bobduff@shell01.TheWorld.com> writes:
>Hyman Rosen <hyrosen@mail.com> writes:
>
>> Thomas Locke wrote:
>>> But I understand what you're saying: No end of line characters in Ada!
>                                                                  ^^^^^^
>....in Ada.Text_IO.
>
>>> Except perhaps when using Get_Immediate and Look_Ahead?
>>
>> The Ada design has the same error here as Pascal did.
>      ^^^^^^^^^^
>....Ada.Text_IO design...
>
>Text_IO is a bit broken, I agree.  But you can also use streams,
>or you can interface directly to the underlying OS primitives.
>
>Ada has a lot of strengths, but unfortunately, the design of the
>Ada.Text_IO package is not one of them.
>
>- Bob




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 19:46   ` Thomas Locke
  2009-02-17 20:24     ` Hyman Rosen
@ 2009-02-18  7:43     ` Jean-Pierre Rosen
  2009-02-18 11:42       ` christoph.grein
  1 sibling, 1 reply; 28+ messages in thread
From: Jean-Pierre Rosen @ 2009-02-18  7:43 UTC (permalink / raw)


Thomas Locke a �crit :
[...]
> This program *almost* work exactly as the C version, but not quite. It
> fails to recognize all EOL's in files, 
Could you tell in which cases?

> and it behaves a bit "odd" when
> feeding data to it using the keyboard.
> 
Depends on your definition of "odd". The time when you see the output
may not be what you expect in relation to your input, because Text_IO
needs some look-ahead to deal with page breaks; however, the output
should correspond to your input (with maybe a small shift in time).

Remember too that the model is a file, and the keyboard is a device. It
is in general acceptable to treat it as a file, but for things like
timing, it is not.

> But I understand what you're saying: No end of line characters in Ada!
> 
> Except perhaps when using Get_Immediate and Look_Ahead?
> 
> /Thomas
Look_Ahead has a parameter to tell when you are at end of line. The
behaviour of Get_Immediate is less clear from the RM.

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 20:38   ` Jeffrey R. Carter
@ 2009-02-18  7:46     ` Jean-Pierre Rosen
  2009-02-18 10:41       ` christoph.grein
  0 siblings, 1 reply; 28+ messages in thread
From: Jean-Pierre Rosen @ 2009-02-18  7:46 UTC (permalink / raw)


Jeffrey R. Carter a �crit :
> Except that, given a file that ends with a blank line,
> Ada.Text_IO.End_Of_File may return True before the final blank line has
> been detected. The general rule is to not use Ada.Text_IO.End_Of_File,
> and handle the resulting End_Error.
> 
I agree. Moreover, it behaves better in the case of ill-formed files
(from an Ada point of view), such as those that have no terminating LF.

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-18  7:46     ` Jean-Pierre Rosen
@ 2009-02-18 10:41       ` christoph.grein
  0 siblings, 0 replies; 28+ messages in thread
From: christoph.grein @ 2009-02-18 10:41 UTC (permalink / raw)


On Feb 18, 8:46 am, Jean-Pierre Rosen <ro...@adalog.fr> wrote:
> Jeffrey R. Carter a écrit :> Except that, given a file that ends with a blank line,
> > Ada.Text_IO.End_Of_File may return True before the final blank line has
> > been detected. The general rule is to not use Ada.Text_IO.End_Of_File,
> > and handle the resulting End_Error.
>
> I agree. Moreover, it behaves better in the case of ill-formed files
> (from an Ada point of view), such as those that have no terminating LF.

This includes what Jeffrey calls a blank line at end. Such a file is
not well-formed in the Ada sense. This is discussed in Text_IO RM A.
10.2(3) and A.10.5(16).



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-18  7:43     ` Jean-Pierre Rosen
@ 2009-02-18 11:42       ` christoph.grein
  0 siblings, 0 replies; 28+ messages in thread
From: christoph.grein @ 2009-02-18 11:42 UTC (permalink / raw)


On Feb 18, 8:43 am, Jean-Pierre Rosen <ro...@adalog.fr> wrote:
> Look_Ahead has a parameter to tell when you are at end of line. The
> behaviour of Get_Immediate is less clear from the RM.

Get_Immediate falls a bit out of Text_IO, since it does not update the
column, line and page counts.

It returns the next character in the file. If EoL is coded as
characters, it will return them, else it will silently skip to the
next line and return the first character. It simply returns any
Control characters that might be in the file, other than the Get
routines.



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: C getchar() functionality in Ada
  2009-02-17 13:01       ` Georg Bauhaus
  2009-02-17 22:03         ` Thomas Locke
@ 2009-03-03  8:57         ` David Thompson
  1 sibling, 0 replies; 28+ messages in thread
From: David Thompson @ 2009-03-03  8:57 UTC (permalink / raw)


On Tue, 17 Feb 2009 14:01:14 +0100, Georg Bauhaus
<rm.dash-bauhaus@futureapps.de> wrote:
<snip>
> We can write the same program in Ada, of course. :-)
> Only, the Ada version is likely written without
> resorting to the C's idiomatic
> "statement-used-as-expression-in-the-loop-conditional".
> 
Nit: not statement. In C assignment is an expression not a statement,
so you can use it in a condition. But not anything that C considers a
statement. (Even the 'new' C++ and C99 option of putting a declaration
in (the head of) a for-statement is specifically a declaration, which
is not a statement in C99.)




^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2009-03-03  8:57 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-16 20:36 C getchar() functionality in Ada Thomas Locke
2009-02-16 21:43 ` Jeffrey R. Carter
2009-02-17  7:23   ` Thomas Locke
2009-02-17  8:16     ` Niklas Holsti
2009-02-17 13:01       ` Georg Bauhaus
2009-02-17 22:03         ` Thomas Locke
2009-03-03  8:57         ` David Thompson
2009-02-17 20:48     ` Jeffrey R. Carter
2009-02-17 21:59       ` Thomas Locke
2009-02-16 23:46 ` Adam Beneschan
2009-02-17  7:19   ` Thomas Locke
2009-02-17  8:37     ` Jacob Sparre Andersen
2009-02-17 17:31       ` Keith Thompson
2009-02-17 14:57     ` Hibou57 (Yannick Duchêne)
2009-02-17 14:55   ` Hibou57 (Yannick Duchêne)
2009-02-17 10:37 ` m.collado
2009-02-17 22:07   ` Thomas Locke
2009-02-17 16:40 ` Jean-Pierre Rosen
2009-02-17 19:46   ` Thomas Locke
2009-02-17 20:24     ` Hyman Rosen
2009-02-17 23:44       ` Robert A Duff
2009-02-18  5:44         ` anon
2009-02-18  0:39       ` Adam Beneschan
2009-02-18  7:43     ` Jean-Pierre Rosen
2009-02-18 11:42       ` christoph.grein
2009-02-17 20:38   ` Jeffrey R. Carter
2009-02-18  7:46     ` Jean-Pierre Rosen
2009-02-18 10:41       ` christoph.grein

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox