【发布时间】:2014-07-12 07:32:10
【问题描述】:
我有一个嵌入式系统,带有一个 vt52u(unicode)终端仿真器,它可以正确显示 UTF-8 字符,但我有交叉编译的程序(vim 和 python)在使用 ncursesw 时无法在该终端上正确显示 unicode 字符图书馆。
我已经进行了搜索,但网络上似乎没有任何可用的帮助...
Bash shell 设置了以下变量:
LANG=en_US.UTF-8
LD_LIBRARY_PATH=/mnt/sd/lib # all libraries, cross compiled, are located here
TERM=vt52u
TERMCAP='vt52u|vt52 with UTF-8:am:eo:rs=\Ee\Eb0\Eco:is=\EE\Ee:nl=^j:sr=\Ei:bl=^g:ta=^i:ho=\EH:cr=^m:le=\ED:nd=\EC:do=\EB:up=\EA:ta=^i:nw=^m:xn:cm=\EY%+ %+ :it#8:co#75:li#24:sc=\Ej:rc=\Ek:vi=\Ef:ve=\Ee:so=\Eb0\Ec4:se=\Eb0\Eco:mh=\Eb8\Eco:mr=\Ebo\Ec0:me=\Eb0\Eco:cl=\EH\EJ:cd=\EJ:ce=\EK:km:ku=^p:kd=^n:kr=^f:kl=^b:kb=^h:'
LOCALE=
而且我知道 unicode 终端很好,因为我可以运行以下程序让它完美地显示 UTF-8 字符。
#!/bin/env python
#coding=UTF-8
charset = [
0x2205, 0x2629, 0x00B2, 0x2663, 0x2666, 0x00B1, 0x221A, 0x266B,
0x2190, 0x2524, 0x2500, 0x2534, 0x253C, 0x251C, 0x2193, 0x2191,
0x00B0, 0x2665, 0x00AE, 0x2660, 0x00B7, 0x00A4, 0x00A4, 0x00A4,
0x00D7, 0x00B5, 0x2126, 0x252C, 0x250C, 0x2510, 0x2514, 0x2518
]
for i in charset:
print unichr( i ).encode("UTF-8"),
if i == 0x2191: print
print
bash-4.3#./testunicode
bash-4.3# ∅ ☩ ² ♣ ♦ ± √ ♫ ← ┤ ─ ┴ ┼ ├ ↓ ↑
bash-4.3# ° ♥ ® ♠ · ¤ ¤ ¤ × µ Ω ┬ ┌ ┐ └ ┘
但是当我尝试在 python 程序中使用 curses (ncursesw) 显示方框图字符,或使用 vim(链接到 ncursesw)编辑 UTF-8 文本文件时;我最终在屏幕上打印了一个无效的 unicode 框,然后是额外的符号,如 ~T~B、~T~L,以及每个 unicode 字符的许多其他变体。所以,出于某种原因,ncursesw 正在输出无效的 UTF-8 字符....
我知道它的链接是正确的,并且没有冲突的 ncurses 库;只有 ncursesw 存在。
我为编译配置了 ncurses-5.9 库,如下所示:
./configure --prefix=/mnt/sd --without-cxx --without-cxx-binding --without-ada --without-manpages --without-progs --without-tests --without-curses-h --with-build-cc=gcc --with-shared --without-normal --without-debug --without-profile --without-gpm --without-dlsym --without-sysmouse --build=i686-linux --host=arm-linux-gnueabi --without-pthread --enable-widec --with-fallbacks=vt52 --with-terminfo-dirs=/etc/terminfo --disable-big-core --enable-termcap --with-termpath=/Data/termcap
例如:以下程序在我的桌面 linux ~VT102 上运行良好——但在 vt52u 上运行时在嵌入式系统上出现故障:
#!/bin/env python
# coding=UTF-8
board=[
"","",
u" ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐",
u" │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │",
u" │ │ ├───→───→───→ │ │ │ │ │ │ ├───→───→───→ │ │ │" ]
board = ( i.encode("utf-8") for i in board )
import curses
import locale
locale.setlocale( locale.LC_ALL,"" )
screen = curses.initscr()
curses.noecho() # no echoing
curses.cbreak() # no keyboard buffering
# Setup the playing board screen.
for i,s in enumerate( board ): screen.addstr( i,0,s )
screen.refresh()
import time
time.sleep(2)
# Return everything to normal
curses.echo()
curses.nocbreak()
curses.endwin()
编辑:我发现了该错误的一个可能原因——glibc,被交叉编译,没有到 /mnt/sd/share/i18n/charmap 或 /mnt/sd/share/i18n/locales 的正确路径目录。它只有部分路径以错误的“/”为前缀,而不是目标系统的实际根路径 /mnt/sd。当没有找到文件时,glibc 显然默认回到“C”或“POSIX”语言环境并忽略环境变量。
我不确定是否必须重新编译glibc并手动编辑makefile,或者是否有办法在系统构建后手动设置路径....??有任何想法吗。 ???
【问题讨论】:
-
您是否尝试将示例移植到 Python 3?使用 3 的文本模型的情况可能会有所不同。 Python Mailing List也有一些这方面能力过强的人,你可以去那里问问。
-
不,尽管我可能会在下周晚些时候尝试。我知道错误出在 NCURSES 上,因为我使用 Python 还是“C”程序都没有关系;他们都失败了。您可以通过将上述 python 测试程序中的语言环境变量设置为“C”来模拟正在运行的 Linux xterm 或控制台终端上的故障。这会产生我在嵌入式系统上看到的“~T~L”符号,并以几乎相同的方式使显示出现乱码;所以我倾向于认为问题出在语言环境变量......或标准 C 库。
-
等等,“VT52U”?这是一回事?!
-
:) 是的!它是。你想要源代码吗?它在 linux 帧缓冲区上绘制 ascii 字体并模拟 DEC VT52,但具有 unicode UTF-8 解码能力。它的主要目的是成为电子纸设备上的控制台,如 arm 处理器下的索尼 PRS-900 (E-Brook)。
-
错字:那是 innsbrook,就像用于电子墨水电子纸显示器的宽幅 linux 内核驱动程序一样。对不起。
标签: python vim unicode utf-8 ncurses