Term::ReadKey on Win? 5.005 vs 5.8.8?

D

Dr.Ruud

Ilya Zakharevich schreef:
Eh? All your message contained was "I tested THIS code". No
information about the testing was contained.

I assumed that merely running both! the tests (on the mentioned
perl-version) would show you what I noticed.
Did you run them? Add $in as the Filehandle parameter to each ReadKey,
if you think that is a better test.

I do not follow again. Is the result the same, or one `is "erratic"',
other not? And IS it the same as with getc?

The first works "erratic" (not really erratic, see perldoc -f getc), so
the same as with getc. The second works as I would expect (Enter and
Ctrl-M give 13, Ctrl-J gives 10, no delays, etc.) because it AFAIK
doesn't use getc.

Because T:R:p uses getc().

I assume that is Term::ReadLine::perl. What is the reason to do the test
with Term::ReadKey?

See perldoc Term::ReadKey, under ReadKey MODE [, Filehandle], at the
end it mentions Windows and getc.

Did not find any mention of what you suggest (0 vs 0e0, Win and getc)
in 2.30.

Not 0e0, but '0E0'.

if (0) { print "0: true\n" };
if ('0') { print "'0': true\n" };
if (0E0) { print "0E0: true\n" };
if ('0E0') { print "'0E0':true\n" };

Only the last one should print true. When MODE eq '0E0', ReadKey() takes
a subt(i)le different code path.

if ($_[0]) {
Win32PeekChar($File, $_[0]);
} else {
getc $File;
}

With '0E0' (I assume that) the $_0 tests true, so Win32PeekChar() is
used.

Again, this looks like contradicting the other parts of your message.

Not to me.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
I assumed that merely running both! the tests (on the mentioned
perl-version) would show you what I noticed.
Did you run them?

No such file or directory at -e line 1.
The first works "erratic" (not really erratic,

Sorry, but I cannot make head or tail of this sentence.
see perldoc -f getc),

Do not see anything relevant there (5.8.7).
The second works as I would expect (Enter and
Ctrl-M give 13, Ctrl-J gives 10, no delays, etc.) because it AFAIK
doesn't use getc.
Thanks.
I assume that is Term::ReadLine::perl. What is the reason to do the test
with Term::ReadKey?

Because T:R:p can use Term::ReadKey (if present).
See perldoc Term::ReadKey, under ReadKey MODE [, Filehandle], at the
end it mentions Windows and getc.

Did not find any mention of what you suggest (0 vs 0e0, Win and getc)
in 2.30.
Only the last one should print true. When MODE eq '0E0', ReadKey() takes
a subt(i)le different code path.

I see nothing in the docs; so a behaviour of a particular version is
can't be relied on...
if ($_[0]) {
Win32PeekChar($File, $_[0]);
} else {
getc $File;
}

The source of Win32PeekChar() is in T:RK... If `delay' parameter is
0, it does not Peek at all! But I have no idea what it returns if one
presses, e.g., Left key...
With '0E0' (I assume that) the $_0 tests true, so Win32PeekChar() is
used.

[One should better use '0 but true' in such a case.]
Not to me.

Well, after your explanations, it is more clear.

Still, a lot of questions remain. See above.

Thanks,
Ilya
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Dr.Ruud:
[tests]
Did you run them?

No such file or directory at -e line 1.

It is working code, just spread over more lines.
OK, different formatting:

#!/usr/bin/perl
use strict;
use warnings;

use Term::ReadKey;

local $\ = "\n";

open my $in, '+< CONIN$' or die $!;
ReadMode 4, $in;

$|=1;

print ord
while defined($_=ReadKey 0, $in) and 3!=ord;

ReadMode 0, $in; # change the number 0 to the string '0E0'
# (so with the quotes) for different behaviour
close $in;
__END__


Insert binmode at will.

Sorry, but I cannot make head or tail of this sentence.


Do not see anything relevant there (5.8.7).

Have you actually read it?
"However, it cannot be used by itself to fetch single characters
without waiting for the user to hit enter."

Further, getc() has other (probably related) problems on Windows, see
Readkey.pm:
There are currently some limitations with this call under Windows. It
may be possible that non-blocking reads will fail when reading repeating
keys from more then one console.

I see nothing in the docs; so a behaviour of a particular version is
can't be relied on...

The docs say you can use 0. The docs don't say you can use '0E0'. But
still I did, after reading the code, because I saw the different code
path it would take.
if ($_[0]) {
Win32PeekChar($File, $_[0]);
} else {
getc $File;
}

The source of Win32PeekChar() is in T:RK... If `delay' parameter is
0, it does not Peek at all!

But if its '0E0', it does.

I read the Win32PeekChar in the ReadKey.xs that comes with
Term::ReadKey-2.30.
If delay == 0 then Win32PeekChar() calls ReadConsoleInput().
http://en.wikipedia.org/wiki/Win32_console
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
It is working code,

Sure. But there is "No such file or directory"!

If it is not clear yet: if I had an access to Win* machines, I would
do experiments myself. Thanks.
Have you actually read it?

Dear Dr, Ruud; please be assured that the probability of myself
knowing what I talk about is not vanishingly small. Thanks. ;-)
"However, it cannot be used by itself to fetch single characters
without waiting for the user to hit enter."

Given that I do not "use it by itself", this carries no relevance.
Moreover, my dictionary would define "erratic" as "sometimes pink,
sometimes blue"; do not think this correlates any way with this
(unfortunate) sentence in the docs.
Further, getc() has other (probably related) problems on Windows, see
Readkey.pm:
There are currently some limitations with this call under Windows. It
may be possible that non-blocking reads will fail when reading repeating
keys from more then one console.

Sorry, but I cannot read this message as broad as your interpretation.
The docs say you can use 0. The docs don't say you can use '0E0'. But
still I did, after reading the code, because I saw the different code
path it would take.

The code changes every release (this is what releases are about, right?).
if ($_[0]) {
Win32PeekChar($File, $_[0]);
} else {
getc $File;
}
The source of Win32PeekChar() is in T:RK... If `delay' parameter is
0, it does not Peek at all!
But if its '0E0', it does.

The argument to Win32PeekChar() is int. There is no difference of
(int)0 and (int)0e0.

Thanks,
Ilya

P.S. Note that none of the questions in my preceeding message is
answered. Let me recall that they are about any guarantee (or
intent) to support non-blocking calls via Win32PeekChar(), and
what happens with "special keys"-presses if Win32PeekChar() is
used.
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Ruud:
Ilya:
[calling ReadKey with MODE 0 vs. '0E0']
I see nothing in the docs; so a behaviour of a particular version
can't be relied on...

The docs say you can use 0. The docs don't say you can use '0E0'. But
still I did, after reading the code, because I saw the different code
path it would take.

The code changes every release (this is what releases are about,
right?).

This is about 2.30, but mainly about unwanted getc()-behaviour.

if ($_[0]) {
Win32PeekChar($File, $_[0]);
} else {
getc $File;
}

The source of Win32PeekChar() is in T:RK... If `delay' parameter is
0, it does not Peek at all!

But if its '0E0', it does.

The argument to Win32PeekChar() is int. There is no difference of
(int)0 and (int)0e0.

The '0E0' thing is not about the C-code path inside Win32PeekChar(), it
is about the Perl-code path inside ReadKey(). You didn't call
Win32PeekChar() in your test, you called getc(). I changed that to an
undocumented ReadKey() call, to get rid of the getc().

P.S. Note that none of the questions in my preceeding message is
answered. Let me recall that they are about any guarantee (or
intent) to support non-blocking calls via Win32PeekChar(), and
what happens with "special keys"-presses if Win32PeekChar() is
used.

When MODE is 0, ReadKey() uses getc(), and you get getc()-behaviour.
When MODE is '0E0', ReadKey() uses Win32PeekChar, and behaves a lot
better.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
When MODE is 0, ReadKey() uses getc(), and you get getc()-behaviour.
When MODE is '0E0', ReadKey() uses Win32PeekChar, and behaves a lot
better.

Thanks for your replies. However, note that "a lot better" is not an
answer for the question `what happens with "special keys"-presses' (I
mean Left, Shift-F6 etc). [I do not even think it would be a
satisfactory answer on ANY technical question ;-) - but you already
provided some useful info about non-special keys before.]

Thanks for your patience,
Ilya
 
D

Dr.Ruud

Ilya Zakharevich schreef:
what happens with "special keys"-presses' (I
mean Left, Shift-F6 etc).

They all give only 0.

Alt doesn't alter anything, both [1] and [Alt]-[1] return 49.

Using binmode seems to only make a difference for ReadMode 0..2: Enter
becomes 13+10 with binmode, 10 without.

Win32PeekChar puts only the single unsigned char keycode 'AsciiChar' in
parameter 'key' (which is a *char).

It collects more information in the private 'INPUT_RECORD record', but
that information is not used. It would be easy to make Win32PeekChar()
return more information.

######

I haven't tried a console in ANSI-mode yet. Let me try now.

Start, Run, command
(screen changes to 80x25)

C:> prompt $e[1m$p$g$e[m
(ANSI gets understood)

*C:>* perl TRK1.pl

But in here also, F1 results in a 0. This ANSI is only involved in the
output.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
They all give only 0.
Alt doesn't alter anything, both [1] and [Alt]-[1] return 49.

What means that yours ReadKey '0 but true' workaround is not suitable
for T::R::p.
Using binmode seems to only make a difference for ReadMode 0..2: Enter
becomes 13+10 with binmode, 10 without.

As expected.
Win32PeekChar puts only the single unsigned char keycode 'AsciiChar' in
parameter 'key' (which is a *char).

This might be considered a bug in Win32PeekChar(). But until it is
fixed, one must make getc() work with \r.

Summary:

Thanks for your experiments, it is clear now how Perl 5.8.8 works on
Win with ReadMode. I expect pre-5.6.0 should work differently. I did
not get any feedback on my questions on the report on pre-5.8.8. so
the situation there is not clear yet (some of my patches made it into
5.8.8, so it has a significant chance to work better/differently than
5.8.7).

A lot of thanks,
Ilya
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Ruud:

This might be considered a bug in Win32PeekChar(). But until it is
fixed, one must make getc() work with \r.

I created a getc() test, which B.T.W. doesn't have the behaviour of
eating the first CR:

#!/usr/bin/perl
use strict;
use warnings;

use constant # Unix # Win32 #
{ USE_CONIN => 1 # 0 # 1 #
, USE_GETC => 0 # - # - #
, SET_BINMODE => 1 # 0 # 1 #
, SET_READMODE => 4 # 5 # 4/5 #
};

use Term::ReadKey; # if defined SET_READMODE;

sub my_getc {
my $in = @_ ? shift : <STDIN>;
return getc $in if USE_GETC;
my $buf;
return -1 if read($in, $buf, 1) < 1;
return substr($buf, 0, 1);
}

my $fname = USE_CONIN ? 'CONIN$' : '-';
open my $con, "+< $fname" or die "Can't open '$fname': $!";

if (defined SET_READMODE) {
ReadMode SET_READMODE, $con;
}
if (SET_BINMODE) {
binmode $con or die "Can't binmode '$fname': $!";
}

while ( defined($_ = my_getc($con)) ) {
my $ord = ord;
print "Esc " if $ord == 27;
print "|$_| " if $ord >= 32;
print "<", $ord, ">\n";
last if $ord == 3;
}

if (defined SET_READMODE) {
ReadMode 0, $con;
}
close $con;
__END__


AFAIK, the behaviour is the same (on both platforms) for USE_GETC set to
0 or to 1.

I now really like to have a more useful getc() for Win32.
Doesn't there really not already exist a module that replaces getc() by
a more useful one, for Win32?
Maybe Win32::Console::Input(). Term::ReadPassword::Win32 uses it.
Can I send you privately a first try, one of these days?

(some of my patches made it into
5.8.8, so it has a significant chance to work better/differently than
5.8.7).

Which patches are you addressing here?
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
I now really like to have a more useful getc() for Win32.

AFAIU, one should debug PerlIO; most probably, the bug is there. One
should check with pre-5.6.0 Perl first, which has no PerlIO. Or write
a simple C test with read(in, buf, 1) (the C code to replace TRK on
Win is provided in one of the (p5p?) threads I mentioned before;
google for CON CONIN ReadKey).
Which patches are you addressing here?

My patches for PerlIO. Should not be hard to google for.

Yours,
Ilya
 
R

robic0

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
I now really like to have a more useful getc() for Win32.

AFAIU, one should debug PerlIO; most probably, the bug is there. One
should check with pre-5.6.0 Perl first, which has no PerlIO. Or write
a simple C test with read(in, buf, 1) (the C code to replace TRK on
Win is provided in one of the (p5p?) threads I mentioned before;
google for CON CONIN ReadKey).
Which patches are you addressing here?

My patches for PerlIO. Should not be hard to google for.

Yours,
Ilya

I think you are in need of a brain transplant. There is no windows console module
that will do what you think it will.
You are lame, readkey is no more fucked up than windows itself.
Maybe you are ready to accuse Mshit of fucking up Perl, which is really fucked up!!
 
R

robic0

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
They all give only 0.
Alt doesn't alter anything, both [1] and [Alt]-[1] return 49.

What means that yours ReadKey '0 but true' workaround is not suitable
for T::R::p.
Using binmode seems to only make a difference for ReadMode 0..2: Enter
becomes 13+10 with binmode, 10 without.

As expected.
Win32PeekChar puts only the single unsigned char keycode 'AsciiChar' in
parameter 'key' (which is a *char).

This might be considered a bug in Win32PeekChar(). But until it is
fixed, one must make getc() work with \r.

Summary:

Thanks for your experiments, it is clear now how Perl 5.8.8 works on
Win with ReadMode. I expect pre-5.6.0 should work differently. I did
not get any feedback on my questions on the report on pre-5.8.8. so
the situation there is not clear yet (some of my patches made it into
5.8.8, so it has a significant chance to work better/differently than
5.8.7).

A lot of thanks,
Ilya

I think your new to windows console. I posted right after you first posted warning you of
the pathos. You did not reply. I sincerely hope you spent a wadd of hours on your experiment.
The fact that you rely on this or any module to resolve con io in windows is, I'm sorry to say
pathetic. You never asked why to me. I asume you have wishfull thinking and anything delivered
in Perl is perfect. Perhaps your ready to accuse Mshit now of fucking up Perl.
You are pathetic!!!
 
R

robic0

Very impressive Rude!
Have you ever actually done something? Maybe your gigantic brain
could mind meld with Mshit. Ever thought of actually doing what
you preach Kuhuna? When is the next Dr. Rude windows console parahimn
coming in Perl oh great one?
 
R

robic0

Ilya Zakharevich schreef:
what happens with "special keys"-presses' (I
mean Left, Shift-F6 etc).

They all give only 0.

Alt doesn't alter anything, both [1] and [Alt]-[1] return 49.

Using binmode seems to only make a difference for ReadMode 0..2: Enter
becomes 13+10 with binmode, 10 without.

Win32PeekChar puts only the single unsigned char keycode 'AsciiChar' in
parameter 'key' (which is a *char).

It collects more information in the private 'INPUT_RECORD record', but
that information is not used. It would be easy to make Win32PeekChar()
return more information.

######

I haven't tried a console in ANSI-mode yet. Let me try now.

Start, Run, command
(screen changes to 80x25)

C:> prompt $e[1m$p$g$e[m
(ANSI gets understood)

*C:>* perl TRK1.pl

But in here also, F1 results in a 0. This ANSI is only involved in the
output.

Give it up, your all just on fuckin drugs..........
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Dr.Ruud:

AFAIU, one should debug PerlIO; most probably, the bug is there.

It is not just the bug, but also the lack of support for Function-keys
and special combinations with Alt/Ctrl/Shift, etc.

I have a Dr.Rudimentary getc() (I called it getuc) here that returns
Unicode-codepoints, for example "\x{2193}" for Arrow-Down. These
return-values are in a table, so one can easily change that to Esc-[B,
or "\0\120", or dynamically to whatever the current Win32-console
dictates.
I have not yet looked into existing Unicode-console solutions, that may
well be already doing much of what I have in mind.

One
should check with pre-5.6.0 Perl first, which has no PerlIO. Or write
a simple C test with read(in, buf, 1) (the C code to replace TRK on
Win is provided in one of the (p5p?) threads I mentioned before;
google for CON CONIN ReadKey).

In the code in my previous post, the first-13-gets-eaten-bug is not
there, as long as you leave USE_GETC at 0.
With SET_BINMODE 1, there are no eaten or delayed 13s, even if USE_GETC
is 1 and/or USE_CONIN is 0.

My patches for PerlIO. Should not be hard to google for.

OK, PerlIO, I'll see.

Wow, that
http://search.cpan.org/src/ILYAZ/Term-ReadLine-Perl-1.03/ReadLine/readline.pm
is pretty loaded with externalizable stuff, like Vi-mode and keymaps
etc.


While googling around, I found
http://rt.cpan.org/Public/Bug/Display.html?id=17773
about the bug.
That thread also mentions "SetConsoleMode failed, LastError=|6| at ..."
which is indeed solved by the "+<" in the open, but which can also occur
if you got the console's explicit filehandle to close prematurely.
 
D

Dr.Ruud

Dr.Ruud schreef:
the first-13-gets-eaten-bug

Actually, a lonely <13> stays (buffered/pending), and gets displayed if
you press a different key.

Only when followed by one or two <13>s (as created with Ctrl-M or
Enter), one of the <13>s gets eaten.

The cycle restarts at display: the buffered <13>s (minus one if there
are more than one) are displayed, followed by the last key that was
pressed.

The fourth <13> (in a row) also results in display (so then three <13>s
are displayed).
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
It is not just the bug, but also the lack of support for Function-keys
and special combinations with Alt/Ctrl/Shift, etc.

I did not get this before. Do you say that the getc() version does
NOT produce useful output if you press, e.g., Left key, or Shift-F8?

I would expect to get 0/75 for Left, and 0/91 for Shift-F8.
In the code in my previous post, the first-13-gets-eaten-bug is not
there, as long as you leave USE_GETC at 0.
With SET_BINMODE 1, there are no eaten or delayed 13s, even if USE_GETC
is 1 and/or USE_CONIN is 0.

I assume this is with some pre-5.6.0 Perl, right? Could you also
post: which version, build by who?

Your mention of USE_GETC is confusing. AFAICS, all it does is
switching between getc and read(...,1). And IIRC, in all versions of
Perl getc() is just a shortcut for read(...,1). Could you recheck the
case where you see that getc vs read makes a difference? If true,
which case it is exactly?

Anyway, as this shows, CRTL has no problem with reading; so if the
newer build uses the same CRTL, this is yet-another-bug in PerlIO.
Wow, that
http://search.cpan.org/src/ILYAZ/Term-ReadLine-Perl-1.03/ReadLine/readline.pm
is pretty loaded with externalizable stuff, like Vi-mode and keymaps
etc.

Now if only I knew whether "externalizable" (in your usage) is for
good things, or for bad things... ;-)

Thanks,
Ilya
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Your mention of USE_GETC is confusing. AFAICS, all it does is
switching between getc and read(...,1). And IIRC, in all versions of
Perl getc() is just a shortcut for read(...,1). Could you recheck the
case where you see that getc vs read makes a difference? If true,
which case it is exactly?

I mentioned: "the behaviour is the same (on both platforms) for USE_GETC
set to 0 or to 1."
So I didn't notice any difference.

Now if only I knew whether "externalizable" (in your usage) is for
good things, or for bad things... ;-)

It really looks like it would be good to split it up.
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Dr.Ruud:

I did not get this before. Do you say that the getc() version does
NOT produce useful output if you press, e.g., Left key, or Shift-F8?

I would expect to get 0/75 for Left, and 0/91 for Shift-F8.

On the ActiveState 5.8.8 perl here, getc() returns nothing for function
keys and arrow keys, same as ReadKey(0, STDIN).
But if I replace getc by ReadKey(q{0E0}, STDIN), that returns a chr(0)
for function keys and arrow keys, and a chr(10) for Ctrl-J. I have
mentioned all that before.

Is the code below good enough for that test?

perl -MTerm::ReadKey
-le "binmode STDIN or die $!;
ReadMode 5, STDIN;
while(1) {
$_ = getc STDIN;
print length($_).q{:}.ord;
last if 3==ord
}; ReadMode 0, STDIN"

The lengths always come out as 1, as expected.

I assume this is with some pre-5.6.0 Perl, right?

No, in the Win32-corner I only have a perl, v5.8.8 built for
MSWin32-x86-multi-thread (AciveState) here.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
Is the code below good enough for that test?

perl -MTerm::ReadKey
-le "binmode STDIN or die $!;
ReadMode 5, STDIN;
while(1) {
$_ = getc STDIN;
print length($_).q{:}.ord;
last if 3==ord
}; ReadMode 0, STDIN"

The lengths always come out as 1, as expected.

On a "correctly set up" read() from "DOS console", pressing `Left'
should generate two characters, 0 and 75; likewise for other special
keys.
No, in the Win32-corner I only have a perl, v5.8.8 built for
MSWin32-x86-multi-thread (AciveState) here.

Then I have no idea what it is you write about in the part quoted with
"> >>"... And the fault of PerlIO is not yet proven...

Thanks,
Ilya
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top