comp.lang.ada
 help / color / mirror / Atom feed
* How to check for characters in input stream?
@ 1994-09-14 14:02 Norman W Cramer
  1994-09-14 23:55 ` Luke Teyssier
  1994-09-15 13:42 ` Robert Dewar
  0 siblings, 2 replies; 5+ messages in thread
From: Norman W Cramer @ 1994-09-14 14:02 UTC (permalink / raw)


I need to simulate the behavior of a serial port using Sun Ada.  The problem I
am having is that the functions in text_io block until a <CR> is entered.  I 
need to return each character as it is typed and some status code if there are
no characters available.  Is there a way to do this in Ada?



Thanks ,

Norm
cramer@dseg.ti.com




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

* Re: How to check for characters in input stream?
  1994-09-14 14:02 How to check for characters in input stream? Norman W Cramer
@ 1994-09-14 23:55 ` Luke Teyssier
  1994-09-15  8:26   ` David Emery
  1994-09-15 13:42 ` Robert Dewar
  1 sibling, 1 reply; 5+ messages in thread
From: Luke Teyssier @ 1994-09-14 23:55 UTC (permalink / raw)


In article <1994Sep14.140207.2304@mksol.dseg.ti.com> cramer@mksol.dseg.ti.com (Norman W Cramer) writes:
>am having is that the functions in text_io block until a <CR> is entered.  I 
>need to return each character as it is typed and some status code if there are

>cramer@dseg.ti.com
>

__Unix__ will wait for you to press a carriage return. I have not checked, 
but I suspect that is where your problem lies. Try using the "raw" mode
for character input. see the man page for stty.

To have the read return if no characters are available, change the
file descriptor to asynchrounous. Use fcntl to accomplish this.

If you talk to verdix technical support, they have a sample implementation of
non-blocking file-io. Ask them for the async_io patch.

luke_teyssier@smtp.esl.com

Luke



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

* Re: How to check for characters in input stream?
  1994-09-14 23:55 ` Luke Teyssier
@ 1994-09-15  8:26   ` David Emery
  0 siblings, 0 replies; 5+ messages in thread
From: David Emery @ 1994-09-15  8:26 UTC (permalink / raw)


--Here (again) is a package to do non-blocking character IO using
--POSIX/Ada.			dave

with POSIX;
package Inkey is

  type terminal_descriptor is private;

  function open_terminal (name : POSIX.POSIX_string 
			       := POSIX.to_POSIX_String("/dev/tty");
			  echo : boolean := false)
      return terminal_descriptor;
    -- if echo is true, then characters are echoed by the terminal
    -- driver.  Otherwise, no echoing of characters occurs.

  procedure read (td    : in     terminal_descriptor;
		  valid :    out boolean;
		  char  :    out POSIX.POSIX_Character);
    -- returns valid if a character is available from the terminal
    -- and returns the character itself in char.  Needless to
    -- say, if valid is false, then char is undefined.

  procedure write (td   : in    terminal_descriptor;
		   char : in    POSIX.POSIX_Character);
    -- writes the character immediately on the terminal.  No
    -- buffering.  Note that this can raise POSIX_Error with
    -- Resource_Temporarily_Unavailable if the write would block,
    -- the same way other calls to POSIX_IO.write can.

  procedure close (td : in out terminal_descriptor);
    -- closes the terminal (and restores its previous state)
    -- note that any copies of the terminal_descriptor are
    -- now invalid

private

  type terminal_stuff;
  type terminal_descriptor is access terminal_stuff;

end inkey;

------------------------------------------------------------------------
--with POSIX;
with POSIX_IO, POSIX_Terminal_Functions;
with Unchecked_Deallocation;
package body inkey is

  package TERM renames POSIX_Terminal_Functions;

  function "=" (l, r : POSIX.IO_Count) 
      return boolean   renames POSIX."=";

  type terminal_stuff is record
    fd : POSIX_IO.file_descriptor;
    original_chars : TERM.terminal_characteristics;
  end record;

  procedure free is new Unchecked_Deallocation 
	(terminal_stuff, terminal_descriptor);

  function open_terminal (name : POSIX.POSIX_string 
			       := POSIX.to_POSIX_String("/dev/tty");
			  echo : boolean := false)
      return terminal_descriptor
    -- if echo is true, then characters are echoed by the terminal
    -- driver.  Otherwise, no echoing of characters occurs.
  is
    answer : terminal_stuff;
    updated_chars : TERM.terminal_characteristics;
    modes : TERM.terminal_modes_set;
  begin
    answer.fd := POSIX_IO.open 
			(name => name, 
			 mode => POSIX_IO.Read_Write,
			 options => POSIX_IO.non_blocking);
    answer.original_chars := TERM.get_terminal_Characteristics
		(file => answer.fd);
    updated_chars := answer.original_chars;
    modes := TERM.terminal_modes_of (updated_chars);

      -- we want non-canonical mode, and whatever was provided
      -- for echo
    modes(TERM.canonical_input) := false;
    modes(TERM.echo) := echo;
    TERM.define_terminal_modes (updated_chars, modes);
      -- we also want the input time to be 0, and the min input count
      -- to be 0.
    TERM.define_input_time (updated_chars, duration'(0.0));
    TERM.define_minimum_input_count (updated_chars, 0);
    
    TERM.Set_Terminal_Characteristics
		(file => answer.fd,
		 characteristics => updated_chars, 
		 apply => TERM.immediately);

    RETURN new terminal_stuff'(answer);
  exception
    when others => 
      -- if terminal is open, then close it...
      begin
        POSIX_IO.close (answer.fd);
      exception
        when others => null;	 -- ignore any errors here
      end;
      RAISE;
  end open_terminal;

  procedure read (td    : in     terminal_descriptor;
		  valid :    out boolean;
		  char  :    out POSIX.POSIX_Character)
    -- returns valid if a character is available from the terminal
    -- and returns the character itself in char.  Needless to
    -- say, if valid is false, then char is undefined.
  is
    read_count : POSIX.IO_Count;
    buff : POSIX_IO.IO_Buffer(1..1);
  begin   
    POSIX_IO.read 
		(file => td.all.fd,
		 buffer => buff,
		 last => read_count);
    if (read_count = 0) then
      valid := false;
    else
      valid := true;
      char := buff(1);
    end if;
  exception
    when constraint_error =>  -- td is invalid, i.e. null;
      POSIX.Set_error_code (POSIX.invalid_argument);
      RAISE POSIX.POSIX_Error;
    when others => RAISE;  -- this will inc
  end read;

  procedure write (td   : in    terminal_descriptor;
		   char : in    POSIX.POSIX_Character)
    -- writes the character immediately on the terminal.  No
    -- buffering
  is  
    buff : POSIX_IO.IO_Buffer(1..1);
    last : POSIX.IO_Count;
  begin   
    buff(1) := char;
    POSIX_IO.write
		(file => td.all.fd,
		 buffer => buff,
		 last => last);	-- should be 0 or 1...
    if (last /= 1) then -- can't write.
      POSIX.set_error_code (POSIX.Resource_Temporarily_Unavailable);
      RAISE POSIX.POSIX_Error;
    end if;
  exception
    when constraint_error =>  -- td is invalid, i.e. null;
      POSIX.Set_error_code (POSIX.invalid_argument);
      RAISE POSIX.POSIX_Error;
    when others => RAISE;  -- this will inc
  end write;

  procedure close (td : in out terminal_descriptor)
    -- closes the terminal (and restores its previous state)
  is
  begin
    TERM.Set_Terminal_Characteristics
		(file => td.all.fd,
		 characteristics => td.all.original_chars,
		 apply => TERM.immediately);
    POSIX_IO.close (td.all.fd);
    free (td);
  exception
    when constraint_error =>  -- td is invalid, i.e. null;
      null;	-- already closed?!
    when others => RAISE;  -- this will inc
  end close;

end inkey;

--
--The preceeding opinions do not necessarily reflect the opinions of
--The MITRE Corporation or its sponsors. 
-- "A good plan violently executed -NOW- is better than a perfect plan
--  next week"                                      George Patton
-- "Any damn fool can write a plan.  It's the execution that gets you
--  all screwed up"                              James Hollingsworth
-------------------------------------------------------------------------



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

* Re: How to check for characters in input stream?
  1994-09-14 14:02 How to check for characters in input stream? Norman W Cramer
  1994-09-14 23:55 ` Luke Teyssier
@ 1994-09-15 13:42 ` Robert Dewar
  1994-09-16  9:23   ` David Emery
  1 sibling, 1 reply; 5+ messages in thread
From: Robert Dewar @ 1994-09-15 13:42 UTC (permalink / raw)


"is there a way to do this [get a character at a time] in Ada?"

there is in fact an explicit feature in 9X for doing this within text io,
but the best answer for Ada 83 is that of course there is a way, call the
appropriate getchar routine or whatever in C. Remember that pragma Interface
is part of Ada!




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

* Re: How to check for characters in input stream?
  1994-09-15 13:42 ` Robert Dewar
@ 1994-09-16  9:23   ` David Emery
  0 siblings, 0 replies; 5+ messages in thread
From: David Emery @ 1994-09-16  9:23 UTC (permalink / raw)


>call the appropriate getchar routine or whatever in C. 

Be careful!  Some of these routines make heavy use of cpp macros, and
of course you can't 'pragma interface' to a macro.

				dave
--
--The preceeding opinions do not necessarily reflect the opinions of
--The MITRE Corporation or its sponsors. 
-- "A good plan violently executed -NOW- is better than a perfect plan
--  next week"                                      George Patton
-- "Any damn fool can write a plan.  It's the execution that gets you
--  all screwed up"                              James Hollingsworth
-------------------------------------------------------------------------



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

end of thread, other threads:[~1994-09-16  9:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1994-09-14 14:02 How to check for characters in input stream? Norman W Cramer
1994-09-14 23:55 ` Luke Teyssier
1994-09-15  8:26   ` David Emery
1994-09-15 13:42 ` Robert Dewar
1994-09-16  9:23   ` David Emery

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