Exploring terminfo
Grant Edwards
grant.b.edwards at gmail.com
Fri Jan 15 16:17:22 EST 2021
On 2021-01-15, Alan Gauld via Python-list <python-list at python.org> wrote:
> On 15/01/2021 17:31, Grant Edwards wrote:
>
>>>> cur.putp(cls)
>>>> name = input("Hello, what's your name? ")
>>>>
>>>> cur.putp(bold)
>>>> print("Nice to meet you ", name)
>
>
>>> putp(clr);
>>> putp(bold);
>>> printf("Enter a name: ");
>>> fgets(line, sizeof(line),stdin);
>>>
>>> printf("Hello %s\n", line);
>>> exit(0);
>
>> One difference is that the name prompt is being written to stdout in
>> the C version and stderr in the Python version. But I don't see why
>> that would matter.
>
> That could make a big difference, the putp() function specifically
> states that it writes to stdout.
>
>> I suspect that the problem is that putp is writing to the libc
>> "stdout" FILE stream that's declaredin <stdio.h>. That stream
>> layer/object has buffering that is invisible to Python.
>
> That would indeed explain it.
>
>> Now the question: is there a way to tell the curses module to flush
>> its stdout FILE stream?
>
> Indeed. But unless it's trivial it rather defeats the concept of
> using the terminfo functions to create text effects without
> diving into full curses screen control! And that was what I
> was hoping to uncover.
>
> I wonder if I can use the os module to mess with the
> file descriptors.... hmmm.
Yes, but that doesn't help. You need to flush the libc FILE *stdio not
the underlying file descriptor. Here's how you do it:
import os,ctypes,sys,time
libc = ctypes.CDLL(None, use_errno=True)
import curses as cur
cur.setupterm()
bold = cur.tigetstr('bold')
norm = cur.tigetstr('sgr0')
cls = cur.tigetstr('clear')
cur.putp(cls)
libc.fflush(None)
name = input("Enter your name: ")
cur.putp(bold)
libc.fflush(None)
sys.stdout.write("\nNice to meet you " + name + "\n")
cur.putp(norm);
libc.fflush(None)
input("Hit enter to exit")
The call to libc.fflush(None) flushes all output FILE * streams. If
you really just want to flush stdout, to flush just stdout:
import os,ctypes,sys,time
libc = ctypes.CDLL(None, use_errno=True)
stdout = ctypes.c_void_p.in_dll(libc, 'stdout')
import curses as cur
cur.setupterm()
bold = cur.tigetstr('bold')
norm = cur.tigetstr('sgr0')
cls = cur.tigetstr('clear')
cur.putp(cls)
libc.fflush(stdout)
name = input("Enter your name: ")
cur.putp(bold)
libc.fflush(stdout)
sys.stdout.write("\nNice to meet you " + name + "\n")
cur.putp(norm);
libc.fflush(stdout)
input("Hit enter to exit")
I'd wrap cur.putp() to make it less ugly:
import os,ctypes,sys,time
libc = ctypes.CDLL(None, use_errno=True)
stdout = ctypes.c_void_p.in_dll(libc, 'stdout')
import curses as cur
cur.setupterm()
def putp(*args):
sys.stderr.flush()
sys.stdout.flush()
cur.putp(*args)
libc.fflush(stdout)
bold = cur.tigetstr('bold')
norm = cur.tigetstr('sgr0')
cls = cur.tigetstr('clear')
putp(cls)
name = input("Enter your name: ")
putp(bold)
print("Nice to meet you",name)
putp(norm);
input("Hit enter to exit")
More information about the Python-list
mailing list