[comp.lang.perl] Perl keyboard processing

jukoff@imram.net.com (Steve Jukoff) (05/17/91)

This perl script is simply a loop to read and process keyboard input.
Some tricky problems arise:

1) I'd like a "read" routine to immediately process each character;
   I don't want the user to be required to hit <return>. 
2) I need to process all characters including:
   1) Control chars, and
   2) Special keyboard characters, i.e. UP-Arrow, HOME, etc.
3) I need "immediate flush mode" for the user prompt.
   (Something to do with select() but what I tried didn't work).

Here is a first try at the code.


# user_input is a "switch" to process keyboard input
sub user_input {
	open (TTY, "/dev/tty") || die "Can't open /dev/tty" ;

	# Perl idiom to force a per-write flush on FILEHANDLE --  Doesn't 
	# seem to work. 
	select((select(TTY), $| = 1)[$[]) ;		

	# Needed: immediately process single character input 

	# Set "non-canonical mode": do not (pre-)interpret control chars
	# system "stty raw"; 
	# works but now I need to know how to match control chars.  

	# And I need to catch signals in order to reset the terminal.

	for (;;) {
		print "Enter choice: " ;		# Needed: print *unbuffered*
		$char = getc(TTY) ;

		# A Perl switch construct 
		# Needed: capability to match control chars
		# and special keyboard characters, i.e. DOWN-ARROW, END, etc.
		$char =~ /\D+/ && do { print "non-digit entered\n" ; next ; } ;

		$char =~ /\d+/ && do { print "digit entered\n" ; next ; } 

# (?)	$char =~ /#Control-X#/ && do { print "Control-X entered\n" ; next ; }

# (?)	$char =~ /#UP-ARROW#/ && do { print "Up-arrow entered\n" ; next ; }

	}
	system "stty -raw" ; 
}	


I know this code is a rough draft.  Any help would be appreciated.


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Steven Jukoff                 DDN:   jukoff@net.com       
Phone: 415-780-5819           uucp:  ...!ames!unet!jukoff     
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

tchrist@convex.COM (Tom Christiansen) (05/19/91)

From the keyboard of jukoff@imram.net.com (Steve Jukoff):
:This perl script is simply a loop to read and process keyboard input.
:Some tricky problems arise:
:
:1) I'd like a "read" routine to immediately process each character;
:   I don't want the user to be required to hit <return>. 

stty cbreak, or raw, or whatever sysV wants you to incant.

:2) I need to process all characters including:
:   1) Control chars, and

easy.

:   2) Special keyboard characters, i.e. UP-Arrow, HOME, etc.

not too easy.

:3) I need "immediate flush mode" for the user prompt.
:   (Something to do with select() but what I tried didn't work).

you have the wrong handle.

:# user_input is a "switch" to process keyboard input
:sub user_input {
:	open (TTY, "/dev/tty") || die "Can't open /dev/tty" ;
:
:	# Perl idiom to force a per-write flush on FILEHANDLE --  Doesn't 
:	# seem to work. 
:	select((select(TTY), $| = 1)[$[]) ;		
:
:	# Needed: immediately process single character input 
:
:	# Set "non-canonical mode": do not (pre-)interpret control chars
:	# system "stty raw"; 
:	# works but now I need to know how to match control chars.  

:	# And I need to catch signals in order to reset the terminal.
:
:	for (;;) {
:		print "Enter choice: " ;		# Needed: print *unbuffered*

you unbuffered TTY, not STDOUT.  make sure not to use the same handle
for both in and out though.  this idiom is open seen:

	open (TTYIN,  "</dev/tty") || die "Can't open /dev/tty" ;
	open (TTYOUT, ">/dev/tty") || die "Can't open /dev/tty" ;

and then unbuffer TTYOUT as before.

:		$char = getc(TTY) ;
:
:		# A Perl switch construct 
:		# Needed: capability to match control chars
:		# and special keyboard characters, i.e. DOWN-ARROW, END, etc.
:		$char =~ /\D+/ && do { print "non-digit entered\n" ; next ; } ;
:
:		$char =~ /\d+/ && do { print "digit entered\n" ; next ; } 
:
:# (?)	$char =~ /#Control-X#/ && do { print "Control-X entered\n" ; next ; }

Using octal escapes is probably easiest.

    char eq "\030" &&  do { print "Control-X entered\n" ; |

(You probably want equality not /pattern/ tests.)

:
:# (?)	$char =~ /#UP-ARROW#/ && do { print "Up-arrow entered\n" ; next ; }

Much harder.  These are multi-char sequences.  You should probably parse
the current termcap to figure out what "up" really is, since "\033OA"
is probably a bad assumption.

--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time." 

rbj@uunet.uu.net (Root Boy Jim) (05/22/91)

tchrist@convex.COM (Tom Christiansen) writes:

>make sure not to use the same handle
>for both in and out though.  this idiom is open seen:
>
>	open (TTYIN,  "</dev/tty") || die "Can't open /dev/tty" ;
>	open (TTYOUT, ">/dev/tty") || die "Can't open /dev/tty" ;

Why should different FH be used?
Does the book discuss this anywhere?

>Using octal escapes is probably easiest.

I stopped thinking in octal when I left the PDP-11 world.
Hex is where it's at Tommy me boy!

But wait! What about those new escape sequences: \e, and \c?
I still want Larry to put in \m for metachars.

This must be "Tom Bashing Week". Sorry dude!
-- 
		[rbj@uunet 1] stty sane
		unknown mode: sane

tchrist@convex.COM (Tom Christiansen) (05/22/91)

From the keyboard of rbj@uunet.uu.net (Root Boy Jim):
:tchrist@convex.COM (Tom Christiansen) writes:
:
:>make sure not to use the same handle
:>for both in and out though.  this idiom is open seen:
:>
:>	open (TTYIN,  "</dev/tty") || die "Can't open /dev/tty" ;
:>	open (TTYOUT, ">/dev/tty") || die "Can't open /dev/tty" ;
:
:Why should different FH be used?
:Does the book discuss this anywhere?

I don't know whether it's in the book.  The problem is bidirectional
stdio buffers, I think.  Basically, it just doesn't work easily unless
you have two filehandles; at leat, it didn't last time I checked.

:>Using octal escapes is probably easiest.
:
:I stopped thinking in octal when I left the PDP-11 world.
:Hex is where it's at Tommy me boy!

Not my fault you've been hexed. :-)

:But wait! What about those new escape sequences: \e, and \c?
:I still want Larry to put in \m for metachars.

Ick.  You can still do it all in octal. :-)

:This must be "Tom Bashing Week". Sorry dude!

Catch me at Nashville and we'll grind the axe there at the bar.
(Gosh, do they drink in Nashville????)

--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time." 

lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (05/23/91)

In article <1991May21.200921.28300@convex.com> tchrist@convex.COM (Tom Christiansen) writes:
: From the keyboard of rbj@uunet.uu.net (Root Boy Jim):
: :tchrist@convex.COM (Tom Christiansen) writes:
: :
: :>make sure not to use the same handle
: :>for both in and out though.  this idiom is open seen:
: :>
: :>	open (TTYIN,  "</dev/tty") || die "Can't open /dev/tty" ;
: :>	open (TTYOUT, ">/dev/tty") || die "Can't open /dev/tty" ;
: :
: :Why should different FH be used?
: :Does the book discuss this anywhere?
: 
: I don't know whether it's in the book.  The problem is bidirectional
: stdio buffers, I think.  Basically, it just doesn't work easily unless
: you have two filehandles; at leat, it didn't last time I checked.

That's another thing that's already in patch 4.  Perl will give you
bidirectional stdio buffers on character special files as well as on sockets.

Did I mention that you can now differentiate system file descriptors from
private file descriptors?  $^F is the maximum system file descriptor, ordinarily
fd 2, standard error.  System file descriptors are kept open on exec.
On an open command, system file descriptors are preserved even if the
open fails, and any subprocesses started by the open get the old descriptors
rather than the new ones.

: :>Using octal escapes is probably easiest.
: :
: :I stopped thinking in octal when I left the PDP-11 world.
: :Hex is where it's at Tommy me boy!
: 
: Not my fault you've been hexed. :-)
: 
: :But wait! What about those new escape sequences: \e, and \c?

That's \x and \c.

: :I still want Larry to put in \m for metachars.
: 
: Ick.  You can still do it all in octal. :-)

Why not just hold down the meta key?

Larry