comp.lang.ada
 help / color / mirror / Atom feed
* wait does not perform as expected
@ 2023-02-22 16:34 Daniel Gaudry
  2023-02-22 17:36 ` Niklas Holsti
  2023-02-24 21:16 ` Jeffrey R.Carter
  0 siblings, 2 replies; 18+ messages in thread
From: Daniel Gaudry @ 2023-02-22 16:34 UTC (permalink / raw)


hi
the following code :


with Gnat.Os_Lib;
with Ada.Strings;
with Ada.Strings.Fixed;
with Ada.Strings.Maps;
with Ada.Strings.Maps.Constants;
 with ada.text_io;
with Ada.Strings;


 procedure Hit_Return_To_Continue(Header     : in String   := "HIT RETURN TO CONTINUE";
                                    Mandatory  : in Boolean  := False;
                                    Skip_After : in Duration := 0.0)
      is

      Char  : Character := ' ';
      Hit   : Boolean   := True;
      Timer : Duration  := 0.0;

      begin

      -- ANYTHING TO DO ?
      if Mandatory
         then
          ada.text_io.Put(Header);

         -- ANY WAITING PERIOD TO DISPLAY ?
         if Skip_After > 0.0
            then

            -- KEEP THE USER'S ATTENTION
            while Timer < Skip_After loop
               Timer := 1.0 + @;
               delay 1.0;
               ada.text_io.Put(Natural(Skip_After - Timer)'Img);

               --USER ENDS THE WAITING PERIOD  BEFORE IT'S END ?


               TIO.LOOK_AHEAD(ITEM          => CHAR,
                              END_OF_LINE   => HIT);
               
                 ada.text_io.GET_IMMEDIATE(ITEM      => CHAR,
                                    AVAILABLE => HIT);
                  IF HIT THEN
                     RETURN;
                  END IF;

            end loop;

            -- USER WAITED FOR THE WHOLE  WAITING PERIOD
            -- LET HIM READ THE ZERO ON THE SCREEN

            delay 1.0;
            return;
         end if;

         Atio.Get_Immediate(Item      => Char,
                            Available => Hit);

         Atio.New_Line(Spacing => 1);

      end if;

   end Hit_Return_To_Continue;




the following call:

Hit_Return_To_Continue(Header        => "HIT RETURN TO CONTINUE",
                                           Mandatory  => true,
                                          Skip_After    => 5.0);

does not return if the user hits a key before the end of the countdown.

Can anybody help
Best regards

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

* Re: wait does not perform as expected
  2023-02-22 16:34 wait does not perform as expected Daniel Gaudry
@ 2023-02-22 17:36 ` Niklas Holsti
  2023-02-23 14:26   ` AdaMagica
  2023-02-24 21:16 ` Jeffrey R.Carter
  1 sibling, 1 reply; 18+ messages in thread
From: Niklas Holsti @ 2023-02-22 17:36 UTC (permalink / raw)


On 2023-02-22 18:34, Daniel Gaudry wrote:
> hi
> the following code :


(I include only the relevant parts:)


>      while Timer < Skip_After loop
>         Timer := 1.0 + @;
>         delay 1.0;
>         ada.text_io.Put(Natural(Skip_After - Timer)'Img);
> 
>         --USER ENDS THE WAITING PERIOD  BEFORE IT'S END ?
> 
> 
>          TIO.LOOK_AHEAD(ITEM          => CHAR,
>                         END_OF_LINE   => HIT); >
>
>          ada.text_io.GET_IMMEDIATE(ITEM      => CHAR,
>                                    AVAILABLE => HIT);
>          IF HIT THEN
>            RETURN;
>          END IF;
> 
>        end loop;

Why do you call both Look_Ahead and Get_Immediate, but throw away the 
result of Look_Ahead?

The behaviour may depend on how you configure (via OS calls) the 
behaviour of your terminal emulator (the "shell window"), but for me, on 
Mac OS/X with the default configuration, it behaves as follows.

The first time Look_Ahead is called (first loop iteration) it waits for 
the user to press Return (Enter) before it delivers the look-ahead 
character to the program. It must do so because it must see if the next 
input is an end-of-line (Return/Enter) or a character (assuming there is 
no "unconsumed" input when the loop starts).

The program is therefore suspended in the first Look_Ahead call, and the 
timer loop and remaining-time output are also suspended, until you at 
least press Return/Enter.

If you do press Return/Enter, perhaps after pressing some other keys, 
the waiting Look_Ahead call returns either the (first) character you 
pressed before Return/Enter, or End_Of_Line (Hit is True). However, your 
code then throws those results away, and instead calls Get_Immediate.

On my system, Get_Immediate does /not/ use the inputs collected (but not 
"consumed") by Look_Ahead, but instead checks if there are _new_ input 
keystrokes. If there are none, Get_Immediate returns "not Available" 
(Hit is False) and so the loop continues.

When Look_Ahead is called again, in the further loop iterations, it sees 
that there now is unconsumed input (from the first call of Look_Ahead) 
so it returns immediately (with the same results as on the first call). 
Therefore the loop now works are you intend: if the user presses any key 
before the Skip_After time is exhausted, the subprogram returns when 
Get_Immediate sees that keystroke.

To fix the problem, remove the Look_Ahead call from the loop.

(For goodness sake, also clean up your "with" clauses -- only 
Ada.Text_IO is relevant for your code -- and remove the multiple renames 
of Ada.Text_IO. You seem to have at least "Atio" and "TIO" as renames 
for Ada.Text_IO. One would be plenty.)

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

* Re: wait does not perform as expected
  2023-02-22 17:36 ` Niklas Holsti
@ 2023-02-23 14:26   ` AdaMagica
  2023-02-23 14:32     ` AdaMagica
                       ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: AdaMagica @ 2023-02-23 14:26 UTC (permalink / raw)


Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1:
> On my system, Get_Immediate does /not/ use the inputs collected (but not 
> "consumed") by Look_Ahead, but instead checks if there are _new_ input 
> keystrokes. If there are none, Get_Immediate returns "not Available" 
> (Hit is False) and so the loop continues.

Are you sure? With GNAT Community 2021 (20210519-103) targeting x86_64-w64-mingw32,

  loop
    Look_Ahead    (Char, EoL);  Put ("Look_Ahead:    '" & Char & "', End_of_Line => " & EoL'Image);  New_Line;
    Get_Immediate (Char, Avl);  Put ("Get_Immediate: '" & Char & "', Available   => " & Avl'Image);  New_Line;
  end loop;

I get:

ab x<RETRUN>
Look_Ahead:    'a', End_of_Line => FALSE
Get_Immediate: 'a', Available   => TRUE
Look_Ahead:    'b', End_of_Line => FALSE
Get_Immediate: 'b', Available   => TRUE
Look_Ahead:    ' ', End_of_Line => FALSE
Get_Immediate: ' ', Available   => TRUE
Look_Ahead:    'x', End_of_Line => FALSE
Get_Immediate: 'x', Available   => TRUE
Look_Ahead:    '0', End_of_Line => TRUE
Get_Immediate: '                                          <- This is the EoL
', Available   => TRUE

So Get_Immediate returns the next not yet consumed character. This is inline with A.10.7(12/3):
If a character, either control or graphic, is available from the specified File or the default input file, then the character is read; Available is True and Item contains the value of this character. If a character is not available, then Available is False and the value of Item is not specified.

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

* Re: wait does not perform as expected
  2023-02-23 14:26   ` AdaMagica
@ 2023-02-23 14:32     ` AdaMagica
  2023-02-23 14:33     ` Daniel Gaudry
  2023-02-23 17:35     ` Niklas Holsti
  2 siblings, 0 replies; 18+ messages in thread
From: AdaMagica @ 2023-02-23 14:32 UTC (permalink / raw)


Also A.10.7(23):
The Get_Immediate procedures should be implemented with unbuffered input. For a device such as a keyboard, input should be “available” if a key has already been typed, whereas for a disk file, input should always be available except at end of file. For a file associated with a keyboard-like device, any line-editing features of the underlying operating system should be disabled during the execution of Get_Immediate.

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

* Re: wait does not perform as expected
  2023-02-23 14:26   ` AdaMagica
  2023-02-23 14:32     ` AdaMagica
@ 2023-02-23 14:33     ` Daniel Gaudry
  2023-02-23 14:39       ` AdaMagica
  2023-02-23 17:15       ` Niklas Holsti
  2023-02-23 17:35     ` Niklas Holsti
  2 siblings, 2 replies; 18+ messages in thread
From: Daniel Gaudry @ 2023-02-23 14:33 UTC (permalink / raw)


On Thursday, February 23, 2023 at 3:26:09 PM UTC+1, AdaMagica wrote:
> Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1: 
> > On my system, Get_Immediate does /not/ use the inputs collected (but not 
> > "consumed") by Look_Ahead, but instead checks if there are _new_ input 
> > keystrokes. If there are none, Get_Immediate returns "not Available" 
> > (Hit is False) and so the loop continues.
> Are you sure? With GNAT Community 2021 (20210519-103) targeting x86_64-w64-mingw32, 
> 
> loop 
> Look_Ahead (Char, EoL); Put ("Look_Ahead: '" & Char & "', End_of_Line => " & EoL'Image); New_Line; 
> Get_Immediate (Char, Avl); Put ("Get_Immediate: '" & Char & "', Available => " & Avl'Image); New_Line; 
> end loop; 
> 
> I get: 
> 
> ab x<RETRUN> 
> Look_Ahead: 'a', End_of_Line => FALSE 
> Get_Immediate: 'a', Available => TRUE 
> Look_Ahead: 'b', End_of_Line => FALSE 
> Get_Immediate: 'b', Available => TRUE 
> Look_Ahead: ' ', End_of_Line => FALSE 
> Get_Immediate: ' ', Available => TRUE 
> Look_Ahead: 'x', End_of_Line => FALSE 
> Get_Immediate: 'x', Available => TRUE 
> Look_Ahead: '0', End_of_Line => TRUE 
> Get_Immediate: ' <- This is the EoL 
> ', Available => TRUE 
> 
> So Get_Immediate returns the next not yet consumed character. This is inline with A.10.7(12/3): 
> If a character, either control or graphic, is available from the specified File or the default input file, then the character is read; Available is True and Item contains the value of this character. If a character is not available, then Available is False and the value of Item is not specified.


Hi,
 Many thanks for your time and answers
My problem under ubuntu is that get_immediate pauses the program if no key is hit.
Therefore available is not set and this little routine cannot perform as I want.
Any idea on how i can write such a simple routine that works ??
Best regards

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

* Re: wait does not perform as expected
  2023-02-23 14:33     ` Daniel Gaudry
@ 2023-02-23 14:39       ` AdaMagica
  2023-02-23 17:15       ` Niklas Holsti
  1 sibling, 0 replies; 18+ messages in thread
From: AdaMagica @ 2023-02-23 14:39 UTC (permalink / raw)


Daniel Gaudry schrieb am Donnerstag, 23. Februar 2023 um 15:33:35 UTC+1:
> My problem under ubuntu is that get_immediate pauses the program if no key is hit. 
> Therefore available is not set and this little routine cannot perform as I want. 

There are essentially two different Get_Immediate, one that waits until a key is hit A.10.7(9),
the other does not A.10.7(11), but has a Boolean Available out-parameter.

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

* Re: wait does not perform as expected
  2023-02-23 14:33     ` Daniel Gaudry
  2023-02-23 14:39       ` AdaMagica
@ 2023-02-23 17:15       ` Niklas Holsti
  1 sibling, 0 replies; 18+ messages in thread
From: Niklas Holsti @ 2023-02-23 17:15 UTC (permalink / raw)


On 2023-02-23 16:33, Daniel Gaudry wrote:
> On Thursday, February 23, 2023 at 3:26:09 PM UTC+1, AdaMagica wrote:
>> Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1:


    [skip answers]


> Hi,
>   Many thanks for your time and answers
> My problem under ubuntu is that get_immediate pauses the program if no key is hit.
> Therefore available is not set and this little routine cannot perform as I want.
> Any idea on how i can write such a simple routine that works ??


Did you try it /without/ the Look_Ahead, as I suggested?

If you did, please post your new code and explain:

- how you want it to work, and

- how it behaves when you try it, and

- why that is not what you want.

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

* Re: wait does not perform as expected
  2023-02-23 14:26   ` AdaMagica
  2023-02-23 14:32     ` AdaMagica
  2023-02-23 14:33     ` Daniel Gaudry
@ 2023-02-23 17:35     ` Niklas Holsti
  2023-02-23 17:49       ` Niklas Holsti
  2023-02-23 18:14       ` Dmitry A. Kazakov
  2 siblings, 2 replies; 18+ messages in thread
From: Niklas Holsti @ 2023-02-23 17:35 UTC (permalink / raw)


On 2023-02-23 16:26, AdaMagica wrote:
> Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1:
>> On my system, Get_Immediate does /not/ use the inputs collected (but not
>> "consumed") by Look_Ahead, but instead checks if there are _new_ input
>> keystrokes. If there are none, Get_Immediate returns "not Available"
>> (Hit is False) and so the loop continues.
> 
> Are you sure?


That is what I observe.


> With GNAT Community 2021 (20210519-103) targeting x86_64-w64-mingw32,
> 
>    loop
>      Look_Ahead    (Char, EoL);  Put ("Look_Ahead:    '" & Char & "', End_of_Line => " & EoL'Image);  New_Line;
>      Get_Immediate (Char, Avl);  Put ("Get_Immediate: '" & Char & "', Available   => " & Avl'Image);  New_Line;
>    end loop;
> 
> I get:
> 
> ab x<RETRUN>
> Look_Ahead:    'a', End_of_Line => FALSE
> Get_Immediate: 'a', Available   => TRUE
> Look_Ahead:    'b', End_of_Line => FALSE
> Get_Immediate: 'b', Available   => TRUE
> Look_Ahead:    ' ', End_of_Line => FALSE
> Get_Immediate: ' ', Available   => TRUE
> Look_Ahead:    'x', End_of_Line => FALSE
> Get_Immediate: 'x', Available   => TRUE
> Look_Ahead:    '0', End_of_Line => TRUE
> Get_Immediate: '                                          <- This is the EoL
> ', Available   => TRUE
> 


On my system:

ab x<RETURN>
Look_Ahead:    'a', End_of_Line => FALSE
Get_Immediate: '', Available   => FALSE
Look_Ahead:    'a', End_of_Line => FALSE
Get_Immediate: '', Available   => FALSE
Look_Ahead:    'a', End_of_Line => FALSE
Get_Immediate: '', Available   => FALSE

and so on for ever, with Look_Ahead never waiting for new input.

The behaviour on my system is certainly different from yours. I can see 
that both behaviours could be useful, depending on the program's needs. 
However, I was certainly surprised to see my system's behaviour, and a 
priori I expected to get the behaviour you see.

My system is oldish:

GNAT Community 2019 (20190517-83)
macOS 10.14.6 Mojave

This difference appears when mixing Look_Ahead and Get_Immediate, which 
seems to make no sense for the original question, and which I advised 
the OP not to do. Using just Get_Immediate should give the OP what they 
want.

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

* Re: wait does not perform as expected
  2023-02-23 17:35     ` Niklas Holsti
@ 2023-02-23 17:49       ` Niklas Holsti
  2023-02-23 18:14       ` Dmitry A. Kazakov
  1 sibling, 0 replies; 18+ messages in thread
From: Niklas Holsti @ 2023-02-23 17:49 UTC (permalink / raw)


On 2023-02-23 19:35, Niklas Holsti wrote:
> On 2023-02-23 16:26, AdaMagica wrote:
>> Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1:
>>> On my system, Get_Immediate does /not/ use the inputs collected (but not
>>> "consumed") by Look_Ahead, but instead checks if there are _new_ input
>>> keystrokes. If there are none, Get_Immediate returns "not Available"
>>> (Hit is False) and so the loop continues.
>>
>> Are you sure?
> 
> 
> That is what I observe.
> 
> 
>> With GNAT Community 2021 (20210519-103) targeting x86_64-w64-mingw32,
>>
>>    loop
>>      Look_Ahead    (Char, EoL);  Put ("Look_Ahead:    '" & Char & "', 
>> End_of_Line => " & EoL'Image);  New_Line;
>>      Get_Immediate (Char, Avl);  Put ("Get_Immediate: '" & Char & "', 
>> Available   => " & Avl'Image);  New_Line;
>>    end loop;
>>
>> I get:
>>
>> ab x<RETRUN>
>> Look_Ahead:    'a', End_of_Line => FALSE
>> Get_Immediate: 'a', Available   => TRUE
>> Look_Ahead:    'b', End_of_Line => FALSE
>> Get_Immediate: 'b', Available   => TRUE
>> Look_Ahead:    ' ', End_of_Line => FALSE
>> Get_Immediate: ' ', Available   => TRUE
>> Look_Ahead:    'x', End_of_Line => FALSE
>> Get_Immediate: 'x', Available   => TRUE
>> Look_Ahead:    '0', End_of_Line => TRUE
>> Get_Immediate: '                                          <- This is 
>> the EoL
>> ', Available   => TRUE
>>
> 
> 
> On my system:
> 
> ab x<RETURN>
> Look_Ahead:    'a', End_of_Line => FALSE
> Get_Immediate: '', Available   => FALSE
> Look_Ahead:    'a', End_of_Line => FALSE
> Get_Immediate: '', Available   => FALSE
> Look_Ahead:    'a', End_of_Line => FALSE
> Get_Immediate: '', Available   => FALSE
> 
> and so on for ever, with Look_Ahead never waiting for new input.
> 
> The behaviour on my system is certainly different from yours. I can see 
> that both behaviours could be useful, depending on the program's needs. 
> However, I was certainly surprised to see my system's behaviour, and a 
> priori I expected to get the behaviour you see.
> 
> My system is oldish:
> 
> GNAT Community 2019 (20190517-83)
> macOS 10.14.6 Mojave
> 
> This difference appears when mixing Look_Ahead and Get_Immediate, 


Or (on my system) when mixing ordinary Get and Get_Immediate. If I 
replace the Look_Ahead call with just a test for End_Of_Line and then 
Get (Char), I get a similar effect, showing that on my system 
Get_Immediate ignores any previously buffered, unconsumed input line, 
whether it results from Look_Ahead or from Get:

ab x
Get          :    'a', End_of_Line => FALSE
Get_Immediate: '', Available   => FALSE
Get          :    'b', End_of_Line => FALSE
Get_Immediate: '', Available   => FALSE
Get          :    ' ', End_of_Line => FALSE
Get_Immediate: '', Available   => FALSE
Get          :    'x', End_of_Line => FALSE
Get_Immediate: '', Available   => FALSE
Get          :    '', End_of_Line => TRUE
Get_Immediate: '', Available   => FALSE

and then the Get call waits for new input (a new input line).

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

* Re: wait does not perform as expected
  2023-02-23 17:35     ` Niklas Holsti
  2023-02-23 17:49       ` Niklas Holsti
@ 2023-02-23 18:14       ` Dmitry A. Kazakov
  2023-02-23 18:29         ` Niklas Holsti
  1 sibling, 1 reply; 18+ messages in thread
From: Dmitry A. Kazakov @ 2023-02-23 18:14 UTC (permalink / raw)


On 2023-02-23 18:35, Niklas Holsti wrote:
> On 2023-02-23 16:26, AdaMagica wrote:
>> Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1:
>>> On my system, Get_Immediate does /not/ use the inputs collected (but not
>>> "consumed") by Look_Ahead, but instead checks if there are _new_ input
>>> keystrokes. If there are none, Get_Immediate returns "not Available"
>>> (Hit is False) and so the loop continues.
>>
>> Are you sure?
> 
> That is what I observe.

The implementation of Look_Ahead calls getc followed by ungetc. Thus it 
blocks until an input if there is no buffered. And not just input, but 
for a line or file end.

As for ungetc POSIX layer under Windows, ungetc probably does not work 
correctly, I am too lazy to verify. One possibility is that file 
positioning (fseek etc) kill unget buffer.

In any case, subprograms like Look_Ahead, End_Of_File etc exit strictly 
for decoration, not for any practical reason. As a rule of thumb no 
program should ever use them.

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

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

* Re: wait does not perform as expected
  2023-02-23 18:14       ` Dmitry A. Kazakov
@ 2023-02-23 18:29         ` Niklas Holsti
  2023-02-23 18:47           ` Daniel Gaudry
  2023-02-23 20:41           ` Dmitry A. Kazakov
  0 siblings, 2 replies; 18+ messages in thread
From: Niklas Holsti @ 2023-02-23 18:29 UTC (permalink / raw)


On 2023-02-23 20:14, Dmitry A. Kazakov wrote:
> On 2023-02-23 18:35, Niklas Holsti wrote:
>> On 2023-02-23 16:26, AdaMagica wrote:
>>> Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1:
>>>> On my system, Get_Immediate does /not/ use the inputs collected (but 
>>>> not
>>>> "consumed") by Look_Ahead, but instead checks if there are _new_ input
>>>> keystrokes. If there are none, Get_Immediate returns "not Available"
>>>> (Hit is False) and so the loop continues.
>>>
>>> Are you sure?
>>
>> That is what I observe.
> 
> The implementation of Look_Ahead calls getc followed by ungetc. Thus it 
> blocks until an input if there is no buffered. And not just input, but 
> for a line or file end.


That seems in order.

However, the crux of the question is in Get_Immediate. Do you know how 
that is implemented on various systems? It has to disable line buffering 
and line editing on the input stream. One question is whether and how 
such "tty" configuration changes affect whatever buffers getc/ungetc use.

On my system, if Look_Ahead uses getc and ungetc, it seems Get_Immediate 
does not use the same buffers, and has no effect on those buffers. That 
could be desirable behaviour in some cases, undesirable in others.

On AdaMagica's system, it seems that Get_Immediate uses the same buffers 
as Look_Ahead (getc/ungetc).

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

* Re: wait does not perform as expected
  2023-02-23 18:29         ` Niklas Holsti
@ 2023-02-23 18:47           ` Daniel Gaudry
  2023-02-23 19:08             ` Niklas Holsti
  2023-02-23 19:31             ` Niklas Holsti
  2023-02-23 20:41           ` Dmitry A. Kazakov
  1 sibling, 2 replies; 18+ messages in thread
From: Daniel Gaudry @ 2023-02-23 18:47 UTC (permalink / raw)


On Thursday, February 23, 2023 at 7:29:36 PM UTC+1, Niklas Holsti wrote:
> On 2023-02-23 20:14, Dmitry A. Kazakov wrote: 
> > On 2023-02-23 18:35, Niklas Holsti wrote: 
> >> On 2023-02-23 16:26, AdaMagica wrote: 
> >>> Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1: 
> >>>> On my system, Get_Immediate does /not/ use the inputs collected (but 
> >>>> not 
> >>>> "consumed") by Look_Ahead, but instead checks if there are _new_ input 
> >>>> keystrokes. If there are none, Get_Immediate returns "not Available" 
> >>>> (Hit is False) and so the loop continues. 
> >>> 
> >>> Are you sure? 
> >> 
> >> That is what I observe. 
> > 
> > The implementation of Look_Ahead calls getc followed by ungetc. Thus it 
> > blocks until an input if there is no buffered. And not just input, but 
> > for a line or file end.
> That seems in order. 
> 
> However, the crux of the question is in Get_Immediate. Do you know how 
> that is implemented on various systems? It has to disable line buffering 
> and line editing on the input stream. One question is whether and how 
> such "tty" configuration changes affect whatever buffers getc/ungetc use. 
> 
> On my system, if Look_Ahead uses getc and ungetc, it seems Get_Immediate 
> does not use the same buffers, and has no effect on those buffers. That 
> could be desirable behaviour in some cases, undesirable in others. 
> 
> On AdaMagica's system, it seems that Get_Immediate uses the same buffers 
> as Look_Ahead (getc/ungetc).


Hi,
On my ubuntu system the 
ada.text_io.GET_IMMEDIATE(ITEM => CHAR, AVAILABLE => HIT);
just pause the program regardless of any key being hit.
I just cannot use a wait  (several shorts one in a row) interrupted by a key hit.
Any possibility you may know of ??
My Best Regards

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

* Re: wait does not perform as expected
  2023-02-23 18:47           ` Daniel Gaudry
@ 2023-02-23 19:08             ` Niklas Holsti
  2023-02-23 19:31             ` Niklas Holsti
  1 sibling, 0 replies; 18+ messages in thread
From: Niklas Holsti @ 2023-02-23 19:08 UTC (permalink / raw)


On 2023-02-23 20:47, Daniel Gaudry wrote:
> On Thursday, February 23, 2023 at 7:29:36 PM UTC+1, Niklas Holsti wrote:
>> On 2023-02-23 20:14, Dmitry A. Kazakov wrote:
>>> On 2023-02-23 18:35, Niklas Holsti wrote:
>>>> On 2023-02-23 16:26, AdaMagica wrote:
>>>>> Niklas Holsti schrieb am Mittwoch, 22. Februar 2023 um 18:36:06 UTC+1:
>>>>>> On my system, Get_Immediate does /not/ use the inputs collected (but
>>>>>> not
>>>>>> "consumed") by Look_Ahead, but instead checks if there are _new_ input
>>>>>> keystrokes. If there are none, Get_Immediate returns "not Available"
>>>>>> (Hit is False) and so the loop continues.
>>>>>
>>>>> Are you sure?
>>>>
>>>> That is what I observe.
>>>
>>> The implementation of Look_Ahead calls getc followed by ungetc. Thus it
>>> blocks until an input if there is no buffered. And not just input, but
>>> for a line or file end.
>> That seems in order.
>>
>> However, the crux of the question is in Get_Immediate. Do you know how
>> that is implemented on various systems? It has to disable line buffering
>> and line editing on the input stream. One question is whether and how
>> such "tty" configuration changes affect whatever buffers getc/ungetc use.
>>
>> On my system, if Look_Ahead uses getc and ungetc, it seems Get_Immediate
>> does not use the same buffers, and has no effect on those buffers. That
>> could be desirable behaviour in some cases, undesirable in others.
>>
>> On AdaMagica's system, it seems that Get_Immediate uses the same buffers
>> as Look_Ahead (getc/ungetc).
> 
> 
> Hi,
> On my ubuntu system the
> ada.text_io.GET_IMMEDIATE(ITEM => CHAR, AVAILABLE => HIT);
> just pause the program regardless of any key being hit.
> I just cannot use a wait  (several shorts one in a row) interrupted by a key hit.
> Any possibility you may know of ??


Please show the Ada code you have now. I assume there is no Look_Ahead 
there, right?

Best if you can write, test and post a short, stand-alone program that 
just contains the wait-for-keystroke procedure, then we can be sure that 
there is nothing else in the program that might interfere.

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

* Re: wait does not perform as expected
  2023-02-23 18:47           ` Daniel Gaudry
  2023-02-23 19:08             ` Niklas Holsti
@ 2023-02-23 19:31             ` Niklas Holsti
  1 sibling, 0 replies; 18+ messages in thread
From: Niklas Holsti @ 2023-02-23 19:31 UTC (permalink / raw)


On 2023-02-23 20:47, Daniel Gaudry wrote:

> Hi,
> On my ubuntu system the
> ada.text_io.GET_IMMEDIATE(ITEM => CHAR, AVAILABLE => HIT);
> just pause the program regardless of any key being hit.


Hmm... it occurred to me to try to execute the program under GPS, not in 
a shell window.

If I run a Get_Immediate loop under GPS, within the input-output window 
of GPS, there is /no reaction/ to keystrokes until I press Return/Enter. 
Get_Immediate returns Available => False until Return/Enter is pressed, 
after which it returns the characters typed before Return/Enter, one by 
one in order.

So it seems that, on my system, Get_Immediate cannot disable the 
line-buffering of the standard-input "terminal", but must wait for 
Return/Enter until it sees any input. And line-editing too is still 
active under Get_Immediate, when running within GPS.

I am starting to suspect that the behaviour I see in my shell command 
window may be due partly to the terminal emulator that implements such 
windows on my system (MacOS "Terminal" app).

Daniel, how are you compiling and running your code? Under GPS, in a 
shell window, or in some other way (shell script)?

If you have been running within GPS, try to run your program in a normal 
shell command window.

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

* Re: wait does not perform as expected
  2023-02-23 18:29         ` Niklas Holsti
  2023-02-23 18:47           ` Daniel Gaudry
@ 2023-02-23 20:41           ` Dmitry A. Kazakov
  2023-02-24 15:10             ` AdaMagica
  1 sibling, 1 reply; 18+ messages in thread
From: Dmitry A. Kazakov @ 2023-02-23 20:41 UTC (permalink / raw)


On 2023-02-23 19:29, Niklas Holsti wrote:

> However, the crux of the question is in Get_Immediate. Do you know how 
> that is implemented on various systems?

No, but it is clear that Get_Immediate might be unimplementable in the 
sense that there may be no way to make it work with all sorts of weird 
files, e.g. under GPS console.

It is to expect it to work with the "standard" terminal [emulator]. 
Anything else is a long shot.

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

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

* Re: wait does not perform as expected
  2023-02-23 20:41           ` Dmitry A. Kazakov
@ 2023-02-24 15:10             ` AdaMagica
  2023-02-24 18:23               ` Niklas Holsti
  0 siblings, 1 reply; 18+ messages in thread
From: AdaMagica @ 2023-02-24 15:10 UTC (permalink / raw)


Dmitry A. Kazakov schrieb am Donnerstag, 23. Februar 2023 um 21:41:16 UTC+1:
> It is to expect it to work with the "standard" terminal [emulator]. 
> Anything else is a long shot.

Right, there may be weird file kinds where Get_Immediate fails.

Niklas Holsti schrieb am Donnerstag, 23. Februar 2023 um 19:29:36 UTC+1:
> On my system, if Look_Ahead uses getc and ungetc, it seems Get_Immediate 
> does not use the same buffers, and has no effect on those buffers. That 
> could be desirable behaviour in some cases, undesirable in others. 
> 
> On AdaMagica's system, it seems that Get_Immediate uses the same buffers 
> as Look_Ahead (getc/ungetc).

I further experimented.

  loop
    Get_Immediate (Char, Avl);  Put ("Get_Immediate: '" & Char & "', Available   => " & Avl'Image);  New_Line;
    delay 1.0;
  end loop;

Run in GPS, it behaves strangely (seems to be one of Dmitry's weird files)

ab c<return>
Get_Immediate: 'a', Available   => TRUE
Get_Immediate: 'b', Available   => TRUE
Get_Immediate: ' ', Available   => TRUE
Get_Immediate: 'c', Available   => TRUE
Get_Immediate: '
', Available   => TRUE                      long pause until:
<return>
Get_Immediate: '
', Available   => TRUE

It only reacts after <return> is pressed.

On a terminal window, the same executable reacts as I expect (this is why the delay statement is there).

Get_Immediate: ' ', Available   => FALSE
Get_Immediate: ' ', Available   => FALSE
Get_Immediate: ' ', Available   => FALSE       as long as no <return> is pressed
a                                                                         note: no <return>
Get_Immediate: 'a', Available   => TRUE
Get_Immediate: ' ', Available   => FALSE       and so on.

So bevore discussing how Get_Immediate is implemented on different hardware or different implementations, please read the RM paras I referenced and discuss them. Looks to me like the behaviour shown last is the correct one (let aside weird terminals).

Niklas, your GNAT is two years older than mine. I guess GNAT has been corrected (at least changed) in between.

If we all disagree how it should work, we should post this on Ada Comment.

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

* Re: wait does not perform as expected
  2023-02-24 15:10             ` AdaMagica
@ 2023-02-24 18:23               ` Niklas Holsti
  0 siblings, 0 replies; 18+ messages in thread
From: Niklas Holsti @ 2023-02-24 18:23 UTC (permalink / raw)


On 2023-02-24 17:10, AdaMagica wrote:
> Dmitry A. Kazakov schrieb am Donnerstag, 23. Februar 2023 um 21:41:16 UTC+1:
>> It is to expect it to work with the "standard" terminal [emulator].
>> Anything else is a long shot.
> 
> Right, there may be weird file kinds where Get_Immediate fails.


I would expect Get_Immediate to work on any kind of "file" for which 
isatty() returns 1, meanng "it is a tty".

Interestingly, this is the case for the execution input/output window 
under my GPS: isatty() returns 1, and ttyname() is 
"/dev/tty<something>", but still Get_Immediate requires a <return> 
keystroke before it sees anything as Available.

It seems to me that the natural implementation (on Unix-like systems) of 
Get_Immediate is for it to use isatty() to check if the input file is a 
"tty", and if so to call ioctl() to disable line buffering so that every 
keystroke is delivered immediately. Why that does not work under GPS 
(mine and yours) is not clear to me.


> Niklas Holsti schrieb am Donnerstag, 23. Februar 2023 um 19:29:36 UTC+1:
>> On my system, if Look_Ahead uses getc and ungetc, it seems Get_Immediate
>> does not use the same buffers, and has no effect on those buffers. That
>> could be desirable behaviour in some cases, undesirable in others.
>>
>> On AdaMagica's system, it seems that Get_Immediate uses the same buffers
>> as Look_Ahead (getc/ungetc).
> 
> I further experimented.
> 
>    loop
>      Get_Immediate (Char, Avl);  Put ("Get_Immediate: '" & Char & "', Available   => " & Avl'Image);  New_Line;
>      delay 1.0;
>    end loop;
> 
> Run in GPS, it behaves strangely (seems to be one of Dmitry's weird files)
> 
> ab c<return>
> Get_Immediate: 'a', Available   => TRUE
> Get_Immediate: 'b', Available   => TRUE
> Get_Immediate: ' ', Available   => TRUE
> Get_Immediate: 'c', Available   => TRUE
> Get_Immediate: '
> ', Available   => TRUE                      long pause until:
> <return>
> Get_Immediate: '
> ', Available   => TRUE
> 
> It only reacts after <return> is pressed.


Under my GPS, it returns Available => False until <return> is pressed, 
and then it returns the characters typed before the <return>, as for 
you. An interesting difference, and somehow it seems to me consistent 
with the difference between our systems in the interaction of 
Get_Immediate and Look_Ahead.


> On a terminal window, the same executable reacts as I expect
> (this is why the delay statement is there).
> 
> Get_Immediate: ' ', Available   => FALSE
> Get_Immediate: ' ', Available   => FALSE
> Get_Immediate: ' ', Available   => FALSE       as long as no <return> is pressed
> a                                                                         note: no <return>
> Get_Immediate: 'a', Available   => TRUE
> Get_Immediate: ' ', Available   => FALSE       and so on.


I see the same behaviour in my terminal window, and this is the 
behaviour I would expect (for Get_Immediate alone, without any 
Look_Ahead calls). It seems that this is also what the OP wants and 
should get, if the OP calls only Get_Immediate and runs in a terminal 
window (and not under GPS).


> Looks to me like the behaviour shown last is the correct one (let
> aside weird terminals).

I agree.


> Niklas, your GNAT is two years older than mine. I guess GNAT has been
> corrected (at least changed) in between.


Quite possible. But the behaviour differences (assuming a terminal 
window) concern only the interaction between normal input (including 
Look_Ahead) and Get_Immediate, which I think is very rarely important. 
However, the behaviour you see, where Get_Immediate inspects the normal, 
as-yet unconsumed input stream, is more in-line with the Ada RM text.


> If we all disagree how it should work, we should post this on Ada
> Comment.

I don't think we disagree: Get_Immediate should return each keystroke 
ASAP, without waiting for a <return>. And the RM text is good, IMO.

However, an enhancement request / minor bug report to AdaCore re the 
<return> dependency of Get_Immediate under GPS could be in order.

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

* Re: wait does not perform as expected
  2023-02-22 16:34 wait does not perform as expected Daniel Gaudry
  2023-02-22 17:36 ` Niklas Holsti
@ 2023-02-24 21:16 ` Jeffrey R.Carter
  1 sibling, 0 replies; 18+ messages in thread
From: Jeffrey R.Carter @ 2023-02-24 21:16 UTC (permalink / raw)


On 2023-02-22 17:34, Daniel Gaudry wrote:
> the following code :

Atio and Tio are undefined. Clearly this code is not what you are running.

The important bit:

>           if Skip_After > 0.0
>              then
> 
>              -- KEEP THE USER'S ATTENTION
>              while Timer < Skip_After loop
>                 Timer := 1.0 + @;
>                 delay 1.0;
>                 ada.text_io.Put(Natural(Skip_After - Timer)'Img);
> 
>                 --USER ENDS THE WAITING PERIOD  BEFORE IT'S END ?
> 
> 
>                 TIO.LOOK_AHEAD(ITEM          => CHAR,
>                                END_OF_LINE   => HIT);
>                 
>                   ada.text_io.GET_IMMEDIATE(ITEM      => CHAR,
>                                      AVAILABLE => HIT);
>                    IF HIT THEN
>                       RETURN;
>                    END IF;
> 
>              end loop;
> 
>              -- USER WAITED FOR THE WHOLE  WAITING PERIOD
>              -- LET HIM READ THE ZERO ON THE SCREEN
> 
>              delay 1.0;
>              return;
>           end if;

Let's simplify this. Without the countdown, this can be rewritten using ATC

Timed_Out : Boolean := False;
...
select
    delay Skip_After;

    Timed_Out := True;
then abort
    Ada.Text_IO.Get_Immediate (Item => Char);
end select;

if Timed_Out then
    delay 1.0;
end if;

return;

This should be simple enough to get right. If ATC doesn't work well with this, 
it should still be simple enough to get right without it.

To add the countdown, let's split that out into a task:

declare
    task Timer is
       entry Stop;
    end Timer;

    task body Timer is ...
    -- Does the countdown immediately (uses the global constant Skip_After)
    -- Stops the countdown if Stop is called
begin
    select
       delay Skip_After;

       Timed_Out := True;
    then abort
       Ada.Text_IO.Get_Immediate (Item => Char);
       Timer.Stop;
    end select;
end;

if Timed_Out then
    delay 1.0;
end if;

return;

The task should be simple enough to get right, too.

-- 
Jeff Carter
"Saving keystrokes is the job of the text editor,
not the programming language."
Preben Randhol
64

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

end of thread, other threads:[~2023-02-24 21:16 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-22 16:34 wait does not perform as expected Daniel Gaudry
2023-02-22 17:36 ` Niklas Holsti
2023-02-23 14:26   ` AdaMagica
2023-02-23 14:32     ` AdaMagica
2023-02-23 14:33     ` Daniel Gaudry
2023-02-23 14:39       ` AdaMagica
2023-02-23 17:15       ` Niklas Holsti
2023-02-23 17:35     ` Niklas Holsti
2023-02-23 17:49       ` Niklas Holsti
2023-02-23 18:14       ` Dmitry A. Kazakov
2023-02-23 18:29         ` Niklas Holsti
2023-02-23 18:47           ` Daniel Gaudry
2023-02-23 19:08             ` Niklas Holsti
2023-02-23 19:31             ` Niklas Holsti
2023-02-23 20:41           ` Dmitry A. Kazakov
2023-02-24 15:10             ` AdaMagica
2023-02-24 18:23               ` Niklas Holsti
2023-02-24 21:16 ` Jeffrey R.Carter

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