comp.lang.ada
 help / color / mirror / Atom feed
* problems with interfacing c
@ 2011-01-20 20:21 Stoik
  2011-01-20 20:56 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 13+ messages in thread
From: Stoik @ 2011-01-20 20:21 UTC (permalink / raw)


I need your help in finding a proper Ada code to simulate the
behaviour of the
following lines in C:
char *bufor = (char*)malloc(100000);
fread(bufor, 1, 100000, stdin);
I need to do it from inside of the Ada code. I tried to import fread,
use the package
interfaces.c.strings etc, but in the end I always get the same
message:
raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
Any ideas?



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

* Re: problems with interfacing c
  2011-01-20 20:21 problems with interfacing c Stoik
@ 2011-01-20 20:56 ` Dmitry A. Kazakov
  2011-01-20 21:31   ` Yannick Duchêne (Hibou57)
  2011-01-28  0:39   ` Stoik
  0 siblings, 2 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2011-01-20 20:56 UTC (permalink / raw)


On Thu, 20 Jan 2011 12:21:08 -0800 (PST), Stoik wrote:

> I need your help in finding a proper Ada code to simulate the behaviour of the
> following lines in C:
> char *bufor = (char*)malloc(100000);
> fread(bufor, 1, 100000, stdin);

That depends on what are going to achieve. Translating the above literally:

[ with Ada.Text_IO.Text_Streams;
  use Ada.Text_IO, Ada.Text_IO.Text_Streams; ]


   Buffer : String (1..100_000);
begin
   String'Read (Stream (Standard_Input), Buffer);

[ Which certainly nobody would do, but you didn't provide any information
about the actual problem. ]

> I need to do it from inside of the Ada code. I tried to import fread, use the package
> interfaces.c.strings etc, but in the end I always get the same message:
> raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
> Any ideas?

You are using C bindings improperly and you need not C bindings in order to
read the standard input.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: problems with interfacing c
  2011-01-20 20:56 ` Dmitry A. Kazakov
@ 2011-01-20 21:31   ` Yannick Duchêne (Hibou57)
  2011-01-20 23:03     ` Dmitry A. Kazakov
  2011-01-28  0:39   ` Stoik
  1 sibling, 1 reply; 13+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2011-01-20 21:31 UTC (permalink / raw)


Le Thu, 20 Jan 2011 21:56:52 +0100, Dmitry A. Kazakov  
<mailbox@dmitry-kazakov.de> a écrit:

> On Thu, 20 Jan 2011 12:21:08 -0800 (PST), Stoik wrote:
>
>> I need your help in finding a proper Ada code to simulate the behaviour  
>> of the
>> following lines in C:
>> char *bufor = (char*)malloc(100000);
>> fread(bufor, 1, 100000, stdin);
>
> That depends on what are going to achieve. Translating the above  
> literally:
>
> [ with Ada.Text_IO.Text_Streams;
>   use Ada.Text_IO, Ada.Text_IO.Text_Streams; ]
>
>
>    Buffer : String (1..100_000);
> begin
>    String'Read (Stream (Standard_Input), Buffer);
>
> [ Which certainly nobody would do, but you didn't provide any information
> about the actual problem. ]

Some body do, for some kind of raw IO. Just that this may be more oftenly  
something like
    Character'Read (Standard_Input), C);
in a loop instead (always wondered if there is a more efficient way, I do  
not know one), because most of time the buffer size may vary in 1..n (I  
suppose it may vary for the OP matter too).

>> I need to do it from inside of the Ada code. I tried to import fread,  
>> use the package
>> interfaces.c.strings etc, but in the end I always get the same message:
>> raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
>> Any ideas?
>
> You are using C bindings improperly and you need not C bindings in order  
> to
> read the standard input.
I feel the same. Strange to use C interface for an fread (however, for  
file mapping into memory or other specialized access, this would OK).


-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.

“I am fluent in ASCII” [Warren 2010]



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

* Re: problems with interfacing c
  2011-01-20 21:31   ` Yannick Duchêne (Hibou57)
@ 2011-01-20 23:03     ` Dmitry A. Kazakov
  2011-01-21  0:46       ` Yannick Duchêne (Hibou57)
  0 siblings, 1 reply; 13+ messages in thread
From: Dmitry A. Kazakov @ 2011-01-20 23:03 UTC (permalink / raw)


On Thu, 20 Jan 2011 22:31:47 +0100, Yannick Duch�ne (Hibou57) wrote:

> Le Thu, 20 Jan 2011 21:56:52 +0100, Dmitry A. Kazakov  
> <mailbox@dmitry-kazakov.de> a �crit:
> 
>> On Thu, 20 Jan 2011 12:21:08 -0800 (PST), Stoik wrote:
>>
>>> I need your help in finding a proper Ada code to simulate the behaviour  
>>> of the
>>> following lines in C:
>>> char *bufor = (char*)malloc(100000);
>>> fread(bufor, 1, 100000, stdin);
>>
>> That depends on what are going to achieve. Translating the above  
>> literally:
>>
>> [ with Ada.Text_IO.Text_Streams;
>>   use Ada.Text_IO, Ada.Text_IO.Text_Streams; ]
>>
>>
>>    Buffer : String (1..100_000);
>> begin
>>    String'Read (Stream (Standard_Input), Buffer);
>>
>> [ Which certainly nobody would do, but you didn't provide any information
>> about the actual problem. ]
> 
> Some body do, for some kind of raw IO. Just that this may be more oftenly  
> something like
>     Character'Read (Standard_Input), C);

That the point, when reading characters that suggests some character stream
oriented protocol. Dealing with such protocols one would never read 100K in
one chunk. Because if the client does something wrong that would deadlock
forever.

> in a loop instead (always wondered if there is a more efficient way, I do  
> not know one), because most of time the buffer size may vary in 1..n (I  
> suppose it may vary for the OP matter too).

The best way is full duplex I/O. You should always be prepared to read at
least one character, so that the client is never blocked when it writes
anything out.

P.S. It would be nice if Ada standard library provided asynchronous
in-place I/O facilities (like overlapped I/O). Ada's protected objects are
perfect candidates for this abstraction (as it was done with interrupts
handlers). But I doubt that would ever happen.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: problems with interfacing c
  2011-01-20 23:03     ` Dmitry A. Kazakov
@ 2011-01-21  0:46       ` Yannick Duchêne (Hibou57)
  2011-01-21  9:33         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 13+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2011-01-21  0:46 UTC (permalink / raw)


Le Fri, 21 Jan 2011 00:03:22 +0100, Dmitry A. Kazakov  
<mailbox@dmitry-kazakov.de> a écrit:
>> Some body do, for some kind of raw IO. Just that this may be more  
>> oftenly
>> something like
>>     Character'Read (Standard_Input), C);
>
> That the point, when reading characters that suggests some character  
> stream
> oriented protocol. Dealing with such protocols one would never read 100K  
> in
> one chunk. Because if the client does something wrong that would deadlock
> forever.
This could block for a single character as much. The only way to not block  
would be either to test before read; this implies to read an item at a  
time, before the condition must be checked before each item is read (so a  
loop), or else indeed to use asynchronous IO as you suggested later. With  
the latter choice, buffered IO is OK. You may use Overlapped IO in  
Windows, alternatively, there are nonblocking socket IO available (returns  
WSAEWOULDBLOCK error if a read access would block). Don't know about POSIX  
(oops).

(I feel to remember there was a talk here about buffered IO, I cannot  
remember the thread's title)

-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.

“I am fluent in ASCII” [Warren 2010]



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

* Re: problems with interfacing c
  2011-01-21  0:46       ` Yannick Duchêne (Hibou57)
@ 2011-01-21  9:33         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2011-01-21  9:33 UTC (permalink / raw)


On Fri, 21 Jan 2011 01:46:24 +0100, Yannick Duch�ne (Hibou57) wrote:

> Le Fri, 21 Jan 2011 00:03:22 +0100, Dmitry A. Kazakov  
> <mailbox@dmitry-kazakov.de> a �crit:
>>> Some body do, for some kind of raw IO. Just that this may be more  
>>> oftenly
>>> something like
>>>     Character'Read (Standard_Input), C);
>>
>> That the point, when reading characters that suggests some character stream
>> oriented protocol. Dealing with such protocols one would never read 100K in
>> one chunk. Because if the client does something wrong that would deadlock
>> forever.
> This could block for a single character as much.

Before you start reading the next character you check for the protocol
errors and the client state. One typical case of deadlock is that you
occasionally received some garbage (UDP, RS232 w/o handshake) or that the
client responded with an emergency "out-of-band" request waiting for
confirmation while you keep on reading the standard response of a longer
length.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: problems with interfacing c
  2011-01-20 20:56 ` Dmitry A. Kazakov
  2011-01-20 21:31   ` Yannick Duchêne (Hibou57)
@ 2011-01-28  0:39   ` Stoik
  2011-01-28  5:24     ` Yannick Duchêne (Hibou57)
                       ` (2 more replies)
  1 sibling, 3 replies; 13+ messages in thread
From: Stoik @ 2011-01-28  0:39 UTC (permalink / raw)


On Jan 20, 9:56 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Thu, 20 Jan 2011 12:21:08 -0800 (PST), Stoik wrote:
> > I need your help in finding a proper Ada code to simulate the behaviour of the
> > following lines in C:
> > char *bufor = (char*)malloc(100000);
> > fread(bufor, 1, 100000, stdin);
>
> That depends on what are going to achieve. Translating the above literally:
>
> [ with Ada.Text_IO.Text_Streams;
>   use Ada.Text_IO, Ada.Text_IO.Text_Streams; ]
>
>    Buffer : String (1..100_000);
> begin
>    String'Read (Stream (Standard_Input), Buffer);
>
> [ Which certainly nobody would do, but you didn't provide any information
> about the actual problem. ]
>
> > I need to do it from inside of the Ada code. I tried to import fread, use the package
> > interfaces.c.strings etc, but in the end I always get the same message:
> > raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
> > Any ideas?
>
> You are using C bindings improperly and you need not C bindings in order to
> read the standard input.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thanks for your suggestions and comments. The point is that I am
sending
a solution to a problem to a site managing programming contests, and
the stdin
is in fact redirected to some text file with data. I do not know how
big the data file
will be, I know only the upper limit. Quick reading of the data is the
key to success,
and the two lines of C work very well for the purpose. I have not
tried your solution,
is it not going to cause constraint_error when it meets the end of the
file?
The other question is - how to use the C bindings properly in such a
case?

Regards,
Staszek Goldstein



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

* Re: problems with interfacing c
  2011-01-28  0:39   ` Stoik
@ 2011-01-28  5:24     ` Yannick Duchêne (Hibou57)
  2011-01-28  9:41     ` Ludovic Brenta
  2011-01-28  9:44     ` Dmitry A. Kazakov
  2 siblings, 0 replies; 13+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2011-01-28  5:24 UTC (permalink / raw)


Le Fri, 28 Jan 2011 01:39:50 +0100, Stoik <staszek.goldstein@gmail.com> a  
écrit:
> Thanks for your suggestions and comments. The point is that I am sending
> a solution to a problem to a site managing programming contests, and the  
> stdin
> is in fact redirected to some text file with data. I do not know how
> big the data file will be, I know only the upper limit. Quick reading of 
> the data is the key to success, and the two lines of C work very well for
> the purpose. I have not tried your solution, is it not going to cause
> constraint_error when it meets the end of the file?
Why not simply get the file size before reading its content ? You seem to  
suggest you have to read from the file, not from the standard input  
stream, so should be OK (that's a very strange contest this one… the  
execution speed will more depend on runtime and platform than to your art).

> The other question is - how to use the C bindings properly in such a
> case?
For that purpose, there is no good way, because this is ... heuu... stupid  
(oops). There may be proper ways to bind to something else, not to this.

-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.

“I am fluent in ASCII” [Warren 2010]



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

* Re: problems with interfacing c
  2011-01-28  0:39   ` Stoik
  2011-01-28  5:24     ` Yannick Duchêne (Hibou57)
@ 2011-01-28  9:41     ` Ludovic Brenta
  2011-01-28  9:44     ` Dmitry A. Kazakov
  2 siblings, 0 replies; 13+ messages in thread
From: Ludovic Brenta @ 2011-01-28  9:41 UTC (permalink / raw)


Staszek Goldstein wrote on comp.lang.ada:
> I am sending a solution to a problem to a site managing programming contests, and
> the stdin is in fact redirected to some text file with data. I do not know how
> big the data file will be, I know only the upper limit. Quick reading of the data is the
> key to success, and the two lines of C work very well for the purpose. I have not
> tried your solution, is it not going to cause constraint_error when it meets the end of the
> file?

If you really read from Standard_Input, there is no upper limit to the
size of the file, so you should not depend on one. i.e. your program
should work if you say:

$ yes | my_program

The proper way to read a potentially infinite amount of data from
Standard_Input is to read one character at a time, buffer the input
for processing, and discard the buffer from time to time so your
program runs in constant memory. The points in time where you discard
the buffer depend on the algorithm.

Like Dmitry, I strongly suggest you use Ada.Streams, not Ada.Text_IO,
because the latter is much slower (it does a lot of unnecessary
bookkeeping behind the scenes).

Here is a small example where I process the input buffer whenever it
is full and then discard it. I also do that when I reach the end of
the input stream. Note that I have not compiled this example, so it
may contain (intentional :)) bugs.

with Ada.IO_Exceptions;
with Ada.Text_IO;
with Ada.Strings.Bounded;
procedure My_Program is
   Current_Input : constant Ada.Text_IO.Text_Streams.Stream_Access :=
     Ada.Text_IO.Text_Streams.Stream (Ada.Text_IO.Current_Input);
   package Buffers is new Ada.Strings.Bounded.Generic_Bounded_Length
(Max => 100_000);

   procedure Process_And_Discard (Buffer : in out
Buffers.Bounded_String) is
   begin
      -- actual processing left as an exercise for the reader :)
      Buffers.Delete (Source => Buffer, From => 1, Through =>
Buffers.Max_Length);
   end Process_And_Discard;

   Buffer : Buffers.Bounded_String;
begin
   loop
      declare
          C : Character;
      begin
          Character'Read (Current_Input, C);
          if Buffers.Length (Buffer) = Buffers.Max_Length then --
buffer is full
             Process_And_Discard (Buffer);
          end if;
          Buffers.Append (Source => Buffer, New_Item => C);
      exception
          when Ada.IO_Exceptions.End_Error => -- end of stream reached
             Process_And_Discard (Buffer); -- process whatever we read
last
             exit;
      end;
   end loop;
end My_Program;

> The other question is - how to use the C bindings properly in such a case?

Don't.

--
Ludovic Brenta.



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

* Re: problems with interfacing c
  2011-01-28  0:39   ` Stoik
  2011-01-28  5:24     ` Yannick Duchêne (Hibou57)
  2011-01-28  9:41     ` Ludovic Brenta
@ 2011-01-28  9:44     ` Dmitry A. Kazakov
  2011-01-31 21:46       ` Stoik
  2 siblings, 1 reply; 13+ messages in thread
From: Dmitry A. Kazakov @ 2011-01-28  9:44 UTC (permalink / raw)


On Thu, 27 Jan 2011 16:39:50 -0800 (PST), Stoik wrote:

> The other question is - how to use the C bindings properly in such a
> case?

You should probably use _read, because fread needs a file descriptor rather
than just number.

   with Interfaces.C;  use Interfaces.C;
   with System;        use System;
...
   function Read (FD : int; Buffer : Address; Count : size_t) return int;
   pragma Import (C, Read, "_read");
...

Now actual reading:

   Buffer : String (1..100_000);
   Bytes  : int;
begin
   Bytes := Read (0, Buffer'Address, Buffer'Length);

Buffer (1..Integer (Bytes)) is the data read, empty when error. Here I
assume that Character = char, so it might be non-portable, but who cares in
these meaningless contests?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: problems with interfacing c
  2011-01-28  9:44     ` Dmitry A. Kazakov
@ 2011-01-31 21:46       ` Stoik
  2011-01-31 23:06         ` Edward Fish
  2011-02-01  8:48         ` Dmitry A. Kazakov
  0 siblings, 2 replies; 13+ messages in thread
From: Stoik @ 2011-01-31 21:46 UTC (permalink / raw)


On Jan 28, 10:44 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Thu, 27 Jan 2011 16:39:50 -0800 (PST), Stoik wrote:
> > The other question is - how to use the C bindings properly in such a
> > case?
>
> You should probably use _read, because fread needs a file descriptor rather
> than just number.
>
>    with Interfaces.C;  use Interfaces.C;
>    with System;        use System;
> ...
>    function Read (FD : int; Buffer : Address; Count : size_t) return int;
>    pragma Import (C, Read, "_read");
> ...
>
> Now actual reading:
>
>    Buffer : String (1..100_000);
>    Bytes  : int;
> begin
>    Bytes := Read (0, Buffer'Address, Buffer'Length);
>
> Buffer (1..Integer (Bytes)) is the data read, empty when error. Here I
> assume that Character = char, so it might be non-portable, but who cares in
> these meaningless contests?
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thanks for all the tips. The word "contest" that I used is possibly
misleading, and the whole thing is not as stupid as it seems. This is
one of the sites where problems are checked automatically by the
computer, with no human intervention. The upper limit of the input
file is given, but the name is not, so one has to use the standard
input. Obviously, reading everything in one chunk is not really needed
for hard problems, but may be substantially quicker for easier ones. I
am especially grateful for the help with interfacing c (even if it
does not make much sense :)) because I would like to learn why things
do not work as expected.
Regards,
Stanislaw Goldstein



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

* Re: problems with interfacing c
  2011-01-31 21:46       ` Stoik
@ 2011-01-31 23:06         ` Edward Fish
  2011-02-01  8:48         ` Dmitry A. Kazakov
  1 sibling, 0 replies; 13+ messages in thread
From: Edward Fish @ 2011-01-31 23:06 UTC (permalink / raw)


On Jan 31, 2:46 pm, Stoik <staszek.goldst...@gmail.com> wrote:
>
> I am especially grateful for the help with interfacing c (even if it
> does not make much sense :)) because I would like to learn why things
> do not work as expected.
> Regards,
> Stanislaw Goldstein

Well, if you'll forgive the snarky comment:
C/C++ rarely behave as expected.

It's at such a point where there are many C-ism rules/tricks for
ensuring better chances of a successful compile, one of which is to
use "0==var" instead of "var==0" to mitigate the C-Syntax allowance of
assignments during condition-testing. Another is that the operator-
shortcut's (like -=, +=, *=, /=) regularity fails when you reach
logical-negation: != is a condition test, not a shortcut for "x = !x."



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

* Re: problems with interfacing c
  2011-01-31 21:46       ` Stoik
  2011-01-31 23:06         ` Edward Fish
@ 2011-02-01  8:48         ` Dmitry A. Kazakov
  1 sibling, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2011-02-01  8:48 UTC (permalink / raw)


On Mon, 31 Jan 2011 13:46:10 -0800 (PST), Stoik wrote:

> Obviously, reading everything in one chunk is not really needed
> for hard problems, but may be substantially quicker for easier ones.

I don't think so. Reading from the standard input presumes stream I/O, and
keyboard input as a possibility. This means that 1) you never know the
actual input length in advance. 2) The behavior on an unexpected input
length is undefined: it can block forever, spit an I/O error etc.

> because I would like to learn why things do not work as expected.

IMO, the problem why things may not work usually lies on the side of C. C
is a very complex language, very few people really understand C in full
detail. In order to map elements of C onto the corresponding Ada constructs
one should first clearly understand what exactly these elements do. The
Ada's part is then more or less trivial.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

end of thread, other threads:[~2011-02-01  8:48 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-20 20:21 problems with interfacing c Stoik
2011-01-20 20:56 ` Dmitry A. Kazakov
2011-01-20 21:31   ` Yannick Duchêne (Hibou57)
2011-01-20 23:03     ` Dmitry A. Kazakov
2011-01-21  0:46       ` Yannick Duchêne (Hibou57)
2011-01-21  9:33         ` Dmitry A. Kazakov
2011-01-28  0:39   ` Stoik
2011-01-28  5:24     ` Yannick Duchêne (Hibou57)
2011-01-28  9:41     ` Ludovic Brenta
2011-01-28  9:44     ` Dmitry A. Kazakov
2011-01-31 21:46       ` Stoik
2011-01-31 23:06         ` Edward Fish
2011-02-01  8:48         ` Dmitry A. Kazakov

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