- 积分
- 30825
- 威望
- 8492
- 金钱
- 2
- 阅读权限
- 110
- 来自
- 法兰克福
- 在线时间
- 1858 小时
|
18#
发表于 2007-3-28 01:01
| 只看该作者
希望有帮助,转贴自www.linuxforum.com
Linux 的中文化问题简介
作者按
底下这篇文章是我最近写程式的一点点心得,除了前段
部讨论了 Linux I18N 环境外 (已在 Linux 连线版贴
出),後半部还加了一些有关 I18N 程式写作的简介。
我想这篇文章就发表在 CLDP 上, 希望 CLDP 可以收
录。更希望这篇文章对有兴趣的朋友有帮助, 让大家
能早日进入 I18N 的世界 :-))
由於我所知很有限,所以文章中可能有很多错误,而关
於 Xi18n 的部分, 我也有很多因为没有去研究,故略
过不提了。 因此,希望各位高手能多多给我批评与建
议, 或帮忙我将不足之处补齐,让这篇文章更完美。
在此先谢谢各位。
谢东翰 (Tung-Han Hsieh) <thhsieh@twcpro.phys.ntu.edu.tw>
Linux 的中文化问题简介
一、前言:
最近这个话题大家吵得有点厉害,大家都希望 Linux 能在中文方面有
所进 步,各家有各家的说法,莫衷一是。由於我最近常与 CLE 的
group 有联系, 同时也正在写一些与中文相关的程式,因此我大略说
一下「我们正在做什麽」, 让大家参考。
我希望大家能将这篇文章当做技术性文章来读,不要再有情绪化的批
评,必境 我们要的是 solution, 情绪化的批评对我们实在没有帮
助。除此之外,我的观 点可能有错,也可能过份乐观,也欢迎大家能
就技术方面给予我指教。
二、 I18N 与 locale:
要将 Linux 中文化,朝著标准走才是长远之计。各位如果有见过近代
商业版的 UNIX 就会晓得,它们「中文化」之彻底,令人惊叹,诸如
中文选单、中文讯息 .... 您能想像得到,或说只能在 Win95/98/NT
OS/2 .... 等上头才见得到的 中文环境,它们都有。然而,它们的中
文并不是像目前 Linux 上常见到的那样, 由一堆程式七拼八凑出来
的,它们全部都是遵循一个标准: I18N 。
I18N 是 InternationalizatioN (国际化) 的缩写,第一个字 I 与最
後一个字 N 之间有 18 的字母,故名。 I18N 并不是只有表面上将 X
Window 「国际化」 而已,它是□基在最底层的 libc 上。 libc 必
须要有 locale 的支援,才能向 I18N 起步。
什麽是 locale? 简单说就是一组「地区语言」的资讯。它包括了 (详
见 man setlocale):
LC_CTYPE: 字元定义
LC_MESSAGES: 讯息显示
LC_TIME: 时间显示格式
LC_NUMERIC: 数字显示格式
LC_MONETARY: 货币显示格式
LC_COLLATE: 字母顺序与字串比较
其中,与一般使用者最有关系的,是 LC_CTYPE 与 LC_MESSAGES 。
LC_CTYPE 直 接关系到某些字元或内码在目前的 locale 下是否可印?
要如何转换? 对应到那 一个字? .... 等等。 LC_MESSAGES 则关系到
软体的讯息输出是什麽样的语文。真 正完整的 locale 支援,是当我
们在 shell prompt 下,直接设好环境变数,则我 们马上就能切换到
那个语文了。例如:
bash: export LC_CTYPE=zh_TW.Big5
有了 locale 的「协定」,使得任何地区的语文,只要在加入适当的
locale data 之後, libc 就能正确地处理它了,而我们的「中文」
当然也不例外。由於前人与 CLE group 的努力,目前我们已有自己的
locale data 了。有安装 CLE 的朋友可 以到 /usr/share/locale 下
看看, zh_TW.Big5 就是我们的 locale data, 虽然还 不够完整,但
已能 work。
目前 Linux 对於 locale 的支援如何? 可以大概地说,西方语系差不
多没问题了, 但东方语系还有不少问题。如果您的 Linux 系统是用
libc5 (例如 Slackware) 的话,那差不多可以说支援得相当差,几乎
只能靠「七拼八凑」的方法来有限度地 使用中文。如果是用 libc6
(glibc2) 的话,那就有相当的 locale 支援了。
然而,目前大部分使用 glibc2 的系统都是 glibc-2.0.7, 这一版对
东方语系的支 援还不够好,特别是 LC_CTYPE ,它无法辨认、转换我
们的 Big5 码,必须要等到 glibc-2.1 以後,才能完全解决这些问
题。但这并不是说使用 glibc-2.0.7 的广 大使用者都没希望了,事
实上有一个 libwcsmbs 的套件,它可以将 glibc 中有问 题的部分取
代掉,让我们的 LC_CTYPE 部分可以「几乎 90% 正确」地工作。而这
个 套件就是目前 CLE 的标准之一,也是很重要的一个部分,虽然大
家可能感受不到它 的存在。
最近 glibc-2.1 的 pre-release 已经出来,我个人已做过初步测
试, LC_CTYPE 在我们的 locale 下已经正常,虽然仍有其他问题存
在,但这已是一个好消息,我 预计在未来的一年内,等大部分的
Linux distribution 都换装了 glibc-2.1 之 後,我们就有了最底层
的「中文化」条件。
三、 X Window 的部分:
接著我们来看看上层, X Window 的「中文化」 (或「国际化」)。
X11R6 也有一 个 locale 的目录,放在 /usr/X11R6/lib/X11/locale
□头,如果是装 CLE 的朋 友,就会见到一个 zh_TW.Big5 的目录,
那就是我们的 XLC Locale data。在「标 准」的情况下, XLC
Locale 必须架构在 libc locale 之上运作,它□头除了定 义一些字
元对应,最重要的是内码与字型的对应。以我们的 locale 为例,我
们需 要两种字型,一是「半形 (单位元)」,显示 ASCII 码用,另一
是「全形 (双位元)」 用来显示中文。举一个例子,像以下这一串字:
这是一个 abcd .... 测试字串 string! OK!
那些要用全形显示? 那些要用半形显示? 这必须靠 libc 的 LC_CTYPE
来判断。因 此, LC_CTYPE 如果挂掉,可以说什麽都没辄。
我相信,有了上述的「配备」後,基本的 I18N 环境就已经具备了。
但一定有人会 问: 「看起来 CLE 在上述所说的都没问题,为什麽还
是到处都不是中文?」 没错, 那是因为目前 Linux 上大部分的程式
还不是用 I18N 的标准而写的。例如大家常用 的 Netscape, xcin,
crxvt .... 等等,它们都是用「自己」的招术来处理中文, 这也就
是为什麽 xcin 只能在 crxvt 上输入,为什麽我们要靠 CXWin 来看
中文 .... 等等。这些都不是正解,只是暂时的一个手段,最後都是
要放弃的。
目前,有越来越多程式将朝向 I18N 来发展,而我们目前最需要的工
作,就是弄 I18N 的 zh_TW.Big5 部分。举个例子,目前 CLE group
正忙於 GNOME 的中文化, 它算是目前 I18N 化相当彻底的一个 X
Disktop / Window Manager, Platin 预计 在下一版的 CLE 就是以
GNOME 为主,只要将其中的讯息都翻译成中文,做好 LC_MESSAGES 的
工作,未来在 GNOME 中,将不需要依靠 CXWin, 打开後就到处都 是
中文。
其他的 GNU 软体也是,有另一组人马正将一些常见指令如 ls, cp 等
的讯息中文 化,并将结果回报给 GNU, 期望未来新版的 GNU 软体
中,中文讯息就是标准的一 部分,我们不再需要每次人家更新版就急
急忙忙地做 patch 了。
中文输入就比较复杂,除了上述的 I18N 以外,还有一个 XIM (X
Input Method) 协定。我们必须要有 XIM server 来取代目前的
xcin, 而且还要 X Window 的应 用程式能够遵循 XIM 协定,才能做
到 "Chinese Input Anywhere"。目前 CLE 已 有一个 XIM server,
即 xcin-cxim 之类的程式,但麻烦的是遵循 XIM 协定的应 用程式仍
不多,最著名的就是 GNOME, xemacs, 以及一些 X11R6 所附的软体
(如 xedit, 由 Xt 及 Xaw 提供 I18N 支援)。而我个人目前正在写的
xcin-2.5 就是一个 XIM server, 我希望这个软体能在将来与「各路
人马」配合,做出一点贡献。
因此,「中文化」的工作,并不是那麽简单地说「因为 Linux 是免
费、没有人付 钱给程式设计师,所以做不好」,或者说「我们中国人
不团结,大家不肯合作发 展程式」,或者说「 Linux 是 server 导
向,不适合做中文」 .... 等等。 Linux 可以发展中文,而且有很多
人正努力地在工作,但是更重要的是,我们还得配合国 外 (或说软体
的原设计者) 的脚步。前面说过,我们要有完整 locale 支援的
libc, 这一切才有希望,我们也需要我们常用的软体 (如 Netscape,
window manager, 甚至 database, office ....) 的设计者觉悟到,
真正的标准是 I18N, 是 locale, 是 XIM, 我们才能跟进,将中文化
的部分加进去。更重要的一点,我们自己的程式 设计师在写软体时,
是不是也能遵循 I18N, locale, XI
供参考,也请各 位多多给予我批评与指教。
1.第一步: setlocale (详见 man setlocale 与其他相关 manpage)
程式的第一步必须要设定 locale, 而一般的写法是 locale 资料
是经由环境变数取 得,而不要写死在程式□头,例如:
#include <stdio.h>
main()
{
setlocale(LC_ALL, "");
.....
}
或分别设定:
setlocale(LC_CTYPE, "");
setlocale(LC_MESSAGES, "");
.....
我个人的建议是,在 setlocale() 时只要设我们程式中需要的项
目即可,而不要设 LC_ALL, 原因是在某些 locale 下 (如我们的
zh_TW.Big5), 并非所有的项目都能 正确运作。我想对大部分的
程式而言,设好 LC_CTYPE 与 LC_MESSAGES 就差不多了, 故以
下我针对这两个做说明。
2.wcs. vs. mbs. (详见 man mbstowcs 与相关 man page)
"wcs" 是 "wide-chararater string" 的缩写,而 "mbs" 是
"multi-byte string" 的缩写,二者分别代表字串的表现方式。
所谓的 multi-byte 是指数个 char 组成 一个字 (如全形字或中
文字是由两个 char 组成),而 wide-char 是指一个 wchar_t
type 就是一个字, 而 sizeof(wchar_t) 的大小与系统有关,一
般而言是 4 bytes。 一般我们可以直接看、输出输入等都是
multi-byte, 如:
char *str = "这是一个句子: abcd";
但我们会建议在程式内部,用 mbstowcs() 将它转成 wchar_t 来
统一处理,这个 转换其实是根据 locale 中的 LC_CTYPE 的机
制,它定义了 multi-byte 与 wide- char 值二者间的对应关
系。做这样转换的好处是,您不用担心全形、半形的问题, 因为
一个 wchar_t 矩阵元就是一个字。
wchar_t 有一组与 string.h 中相对应的字串处理函式 (目前在
Linux 中可能还没 有 man page 说明),就定义在 wchar.h 中,
让我们可以如同处理 (char *) 那样 地处理 (wchar_t *), 其部
分的对应关系如下,其他的可以直接看 wchar.h 的内容:
wcscpy() <====> strcpy()
wcsncpy() <====> strncpy()
wcslen() <====> strlen()
wcsdup() <====> strdup()
wcscmp() <====> strcmp()
wcsncmp() <====> strncmp()
........................................
由於 mbs 码与 wcs 码的对应关系是由该 locale 的 LC_CTYPE
来决定的,也就是不 同的 locale 写法其对应关系可能会不一
样。就我们的 glibc2, zh_TW.Big5 locale 而言,由 mbs 转成
的 wcs 即为 unicode (有关 unicode 的资讯可以在
http://www.unicode.org/ 中找到),但不能保证在其他的系统或
环境下也是如此。 故最保险的做法,是将字串储存成
multi-byte, 然後在 run-time 时才用 mbstowcs() 转成
wide-char 来运作。 |
|