• wait does not perform as expected

    From Daniel Gaudry@21:1/5 to All on Wed Feb 22 08:34:17 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to Daniel Gaudry on Wed Feb 22 19:36:03 2023
    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.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to Daniel Gaudry on Thu Feb 23 06:39:55 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to All on Thu Feb 23 06:32:07 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to Niklas Holsti on Thu Feb 23 06:26:07 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Daniel Gaudry@21:1/5 to AdaMagica on Thu Feb 23 06:33:33 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to Daniel Gaudry on Thu Feb 23 19:15:57 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to Niklas Holsti on Thu Feb 23 19:49:04 2023
    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).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dmitry A. Kazakov@21:1/5 to Niklas Holsti on Thu Feb 23 19:14:38 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to AdaMagica on Thu Feb 23 19:35:46 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Daniel Gaudry@21:1/5 to Niklas Holsti on Thu Feb 23 10:47:57 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to Dmitry A. Kazakov on Thu Feb 23 20:29:32 2023
    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).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to Daniel Gaudry on Thu Feb 23 21:08:52 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to Daniel Gaudry on Thu Feb 23 21:31:52 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dmitry A. Kazakov@21:1/5 to Niklas Holsti on Thu Feb 23 21:41:14 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to Dmitry A. Kazakov on Fri Feb 24 07:10:13 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to AdaMagica on Fri Feb 24 20:23:49 2023
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeffrey R.Carter@21:1/5 to Daniel Gaudry on Fri Feb 24 22:16:48 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)