From: Jerry on
[Sorry for the cross-post.]

I have a loop which is doing a repetitive calculation. Sometimes the
loop runs a long time and I want to manually cause the loop to be
exited but have the program continue running, for example to save some
results to a file or do other calculations. Preferably I would just
hit a key or key combination.

I thought Get_Immediate would work (reading Cohen's book) but it does
not do what I want. For example, the following program stops looping
and requires me to hit RETURN even if I hit another key first. It
continues looping (very slowly) if I hold down the RETURN key.

I don't mind using GNAT-specific stuff as long as it gets the job
done.

Thanks.

Jerry


with Ada.Text_IO;
use Ada.Text_IO;
procedure key is
i : Integer;
Keystroke : Character;
Available : Boolean;
begin
i := 0;
loop
Put(Integer'Image(i));
Get_Immediate(Keystroke, Available);
if Available then
if Keystroke = 'q' then
exit;
end if;
end if;
i := i + 1;
end loop;
Put_Line("Finished");
end key;
From: Georg Bauhaus on
Jerry schrieb:

>
> with Ada.Text_IO;
> use Ada.Text_IO;
> procedure key is
> i : Integer;
> Keystroke : Character;
> Available : Boolean;
> begin
> i := 0;
> loop
> Put(Integer'Image(i));
> Get_Immediate(Keystroke, Available);
> if Available then
> if Keystroke = 'q' then
> exit;
> end if;
> end if;
> i := i + 1;
> end loop;
> Put_Line("Finished");
> end key;


Works as desired on Debian GNU/Linux stable.
From: Manuel Collado on
Georg Bauhaus escribi�:
> Jerry schrieb:
>
>> with Ada.Text_IO;
>> use Ada.Text_IO;
>> procedure key is
>> i : Integer;
>> Keystroke : Character;
>> Available : Boolean;
>> begin
>> i := 0;
>> loop
>> Put(Integer'Image(i));
>> Get_Immediate(Keystroke, Available);
>> if Available then
>> if Keystroke = 'q' then
>> exit;
>> end if;
>> end if;
>> i := i + 1;
>> end loop;
>> Put_Line("Finished");
>> end key;
>
>
> Works as desired on Debian GNU/Linux stable.

Also in Windows XP with GNAT GPL 2005

--
Manuel Collado - http://lml.ls.fi.upm.es/~mcollado
From: Jerry on
Thanks, Georg and Manuel, for testing. I'm on OS X 10.5.8 and:

MBPro:/ me$ gnat
GNAT 4.4.0 20080314 (experimental) [trunk revision 133226]
Copyright 1996-2007, Free Software Foundation, Inc.

I've tried the program on three different terminal programs with the
same result: it prints out 0 and waits for RETURN, then prints out 1,
etc. If I hit q then RETURN the loop is exited. But the loop never
"free-runs."

Jerry
From: John McCormick on
On Apr 12, 5:36 am, Jerry <lancebo...(a)qwest.net> wrote:
> Thanks, Georg and Manuel, for testing. I'm on OS X 10.5.8 and:
>
> MBPro:/ me$ gnat
> GNAT 4.4.0 20080314 (experimental) [trunk revision 133226]
> Copyright 1996-2007, Free Software Foundation, Inc.
>
> I've tried the program on three different terminal programs with the
> same result: it prints out 0 and waits for RETURN, then prints out 1,
> etc. If I hit q then RETURN the loop is exited. But the loop never
> "free-runs."
>
> Jerry

Perhaps the Asynchronous Transfer of Control mechanism would be
appropriate. Here is some GNAT code that runs under Windows XP in
which the input loop is interrutpted by Ctrl-c. The interrupt handler
must be at the library level so I put it in its own package.

select
Ctrl_C_Interrupt.Wait;
Put_Line ("Handled Ctrl C");
then abort
loop
Put_Line ("Enter an integer (Ctrl C to exit)");
Get (Value);
Put (Value);
New_Line;
end loop;
end select;

-----------------------------------------------------------
with Ada.Interrupts.Names;
package Ctrl_C is

protected Ctrl_C_Interrupt is
entry Wait;
procedure Handler;
pragma Attach_Handler (Handler, Ada.Interrupts.Names.SIGINT);
pragma Interrupt_Priority;
private
Received : Boolean := False;
end Ctrl_C_Interrupt;
end Ctrl_C;

-----------------------------------------------------------
package body Ctrl_C is

protected body Ctrl_C_Interrupt is
procedure Handler is
begin
Received := True;
end Handler;

entry Wait when Received is
begin
Received := False;
end Wait;
end Ctrl_C_Interrupt;

end Ctrl_C;

John