Re: [Hla-stdlib-talk] non-buffered 'stdin.getc' function
Brought to you by:
evenbit
From: Frank K. <fbk...@ve...> - 2008-02-15 03:14:54
|
Nathan Baker wrote: > Just coded this real quick and haven't tested it, but this is close to > what a 'non-buffered' stdin.getc() function (for Windows) would look like: Okay... > unit StdInput; > #include( "../include/stdinunit.hhf" ) > > procedure nb_getc; > @nodisplay; > > var > hStdIn :dword; > curMode :dword; > newMode :dword; > > begin nb_getc; > > w.GetStdHandle( STD_INPUT_HANDLE ); > mov( eax, hStdIn ); You're opening a new stdin handle with every call of this puppy. "Herbert's version" of "Beth's game" checks to see if we've got an handle (which means it has to be initialized to zero), and if so, skips over acquiring a handle and "tweaking" it. Since you're "untweaking" it at the end, you'd only want to skip acquiring a new one. > w.GetConsoleMode( hStdIn, curMode ); > mov( curMode, eax ); > and( #$F9, al ); HLA knows the names of the bits in question. Why not use 'em? I don't know how to say " ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)" in HLAese, but I think that's what you want. > mov( eax, newMode ); > w.SetConsoleMode( hStdIn, newMode ); > > w.ReadFile( hStdIn, &InputBuffer, 1, InputIndex, 0 ); Who "InputIndex"? I'm thinking we want an address here (? remember I don't do Windows). Perhaps that's what you've got... > w.SetConsoleMode( hStdIn, curMode ); > mov( InputBuffer[ 0 ], al ); > ret(); > > end nb_getc; "Leaking handles" is a pretty bad problem. Other than that, it looks good to me! What I've got for Linux does a similar thing... we "get" a whole bleedin' structure for "current mode" - but only clear two bits, and "set" to that. It is not strictly "right". If the pesky user suspends the program with control-z, and restarts it with "fg", we're back reading one key... but waiting for "Enter" again! :( A similar problem may occur if the window size is changed (in an Xterm). We could fix that by blocking control-c/control-z entirely - handling it ourselves, perhaps. Or we can "catch" these signals and do the appropriate cleanup/restoration of our "tweak". (I'm not sure how to do that one). I'm fairly certain that this code is Linux-specific, and *won't* work with BSD... nor MacOSX, I imagine. I think they've got sys_ioctl, but I think "TCGETS" is Linux-specific. Dunno how they do it (and what issues we'd encounter). In any case - I agree that it's a nice thing to be able to do. Good start! Best, Frank |