i use CMUCL and (read-char) expects to have a RETURN after the
character.
How can i change this to work without the RETURN ?
Thank you for help !
Matthias
| i use CMUCL and (read-char) expects to have a RETURN after the
| character.
Er, no, it does not. But terminal input is line buffered by default,
and this is probably what bites you.
| How can i change this to work without the RETURN ?
If there is a portable way to do it in Common Lisp, I am sure someone
will say so. I don't see one, though. And I don't see any ready-made
functions for it in CMUCL either, which means you must do the system
call yourself. So you will have to learn to use ioctl() to turn off
input line buffering, and to turn it back on afterwards. Thus this
turns into a unix question, which is probably not appropriate in this
newsgroup. Also, most likely the file descriptor hiding behind
*standard-input* is 0 - but whether or not you can fiddle with ioctl()
on file descriptor 0 behind cmucl's back without getting burnt, is
anybody's guess. So you may have to open /dev/tty explicitly for this
purpose. Check the Unix interface chapter in the CMUCL users manual,
read the man pages (ioctl and termios), and if you get stuck ask for
help on the cmucl mailing list.
--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- Yes it works in practice - but does it work in theory?
> i use CMUCL and (read-char) expects to have a RETURN after the
> character.
Actually, it doesn't:
* (cons (read-char) (read-char))
ab
(#\a . #\b)
*
> How can i change this to work without the RETURN ?
Do you want unbuffered I/O?
Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x42B32FC9
He probably wants the terminal driver to make its buffered input
available immediately, without accumulating it until a complete line
is formed.
A the C level, that's arranged using tcgetattr(), tcsetattr() and
struct termios.
My package "Line-Reader" uses the CMUCL/SBCL FFI to accomplish this,
in file setattr.c and terminfo.lisp. I decided not to implement the
termios structures in the FFI since they seem to be rather system-dependent.
See http://emu.res.cmu.edu/~mrd/line-reader/
Though this actually has problems on CMUCL, for some odd reason:
When you first compile and load the terminfo.lisp file it works fine,
but on subsequent reloads, it complains that "setupterm" is not a
defined foreign symbol. SBCL doesn't complain, go figure. I'm still
looking into it.
--
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Matthew Danish email: mda...@andrew.cmu.edu ;;
;; OpenPGP public key available from: 'finger m...@db.debian.org' ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
That works in CMUCL, too. Use functions as unix:unix-tcsetattr.
It's been a while since I used them, but they seemed to work
pretty well.
Regards,
--
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.
PGP key ID 0xC66D6E6F
;;; Function to get input without echoing---for inputting passwords and the like.
;;; Depends on CMUCL unix interface package.
(defun echo-off (fd)
(when (unix:unix-isatty fd)
(alien:with-alien ((tios (alien:struct unix:termios)))
(multiple-value-bind
(val err)
(unix:unix-tcgetattr fd (alien:alien-sap tios))
(when (null val)
(error "Could not tcgetattr, unix error ~S."
(unix:get-unix-error-msg err))))
(let ((old-c-lflag (alien:slot tios 'unix:c-lflag)))
(setf (alien:slot tios 'unix:c-lflag)
(logand (alien:slot tios 'unix:c-lflag)
(lognot (logior unix:tty-echo unix:tty-icanon))))
(multiple-value-bind
(val err)
(unix:unix-tcsetattr fd unix:tcsaflush (alien:alien-sap tios))
(when (null val)
(error "Could not tcsetattr, unix error ~S."
(unix:get-unix-error-msg err))))
old-c-lflag))))
(defun restore-c-lflag (fd old-c-lflag)
(when (unix:unix-isatty fd)
(alien:with-alien ((tios (alien:struct unix:termios)))
(multiple-value-bind
(val err)
(unix:unix-tcgetattr fd (alien:alien-sap tios))
(when (null val)
(error "Could not tcgetattr, unix error ~S."
(unix:get-unix-error-msg err))))
(setf (alien:slot tios 'unix:c-lflag) old-c-lflag)
(multiple-value-bind
(val err)
(unix:unix-tcsetattr fd unix:tcsaflush (alien:alien-sap tios))
(when (null val)
(error "Could not tcsetattr, unix error ~S."
(unix:get-unix-error-msg err))))))
(values))
(defun get-input-no-echo (stream)
(let ((input "")
(fd (system:fd-stream-fd (if (common-lisp::two-way-stream-p stream)
(two-way-stream-output-stream stream)
stream))))
(let ((old-c-lflag (echo-off fd)))
(unwind-protect
(setf input (read-line stream))
(restore-c-lflag fd old-c-lflag)))
input))
(defun prompt-and-read-reply (prompt)
(format t prompt)
(force-output)
(read-line))
(defun prompt-and-read-reply-no-echo (prompt)
(format t prompt)
(force-output)
(get-input-no-echo system:*tty*))
--
Fred Gilham gil...@csl.sri.com
"...If reason is no longer a faculty enabling us to discern some
cosmic design, then it is no longer clear what claim reason has upon
us, or upon our politics. On the contrary, the sorts of habits that we
associate with `reasoning' --- that is, reflecting and discussing and
trying to achieve some kind of coherence among our various opinions
--- can come to seem like nothing more than the mental preferences (or
prejudices) of a particular class of people --- the dogmatic
proceduralism of an educated elite." --- Steven D. Smith