enc2xs -- Perl Encode 模块生成器
enc2xs -[options]
enc2xs -M ModName mapfiles...
enc2xs -C
enc2xs 从 Unicode 字符映射文件 (.ucm) 或 Tcl 编码文件 (.enc) 生成供 Encode 使用的 Perl 扩展。除了在 Encode 模块的构建过程中内部使用外,您还可以使用 enc2xs 将自己的编码添加到 Perl 中。无需任何 XS 知识。
如果您想尽可能少地了解 Perl,但需要添加新的编码,只需阅读本章并忘记其余内容。
准备一个 .ucm 文件。您可以从某个地方获取它,也可以从头开始编写它,或者从 Encode 发行版中获取一个并对其进行自定义。有关 UCM 格式,请参见下一章。在下面的示例中,我将我的理论编码称为 myascii,它在 my.ucm 中定义。$
是一个 shell 提示符。
$ ls -F
my.ucm
执行以下命令:
$ enc2xs -M My my.ucm
generating Makefile.PL
generating My.pm
generating README
generating Changes
现在查看您的当前目录。它应该看起来像这样。
$ ls -F
Makefile.PL My.pm my.ucm t/
以下文件已创建。
Makefile.PL - MakeMaker script
My.pm - Encode submodule
t/My.t - test file
如果您希望将 *.ucm 与模块一起安装,请执行以下操作:
$ mkdir Encode
$ mv *.ucm Encode
$ enc2xs -M My Encode/*ucm
编辑生成的文件。如果您没有时间并且没有打算将其提供给其他人,则无需编辑。但是,编辑 pod 并添加更多测试是一个好主意。
现在执行所有 Perl Mongers 都喜欢的命令
$ perl Makefile.PL
Writing Makefile for Encode::My
现在您只需执行 make 即可。
$ make
cp My.pm blib/lib/Encode/My.pm
/usr/local/bin/perl /usr/local/bin/enc2xs -Q -O \
-o encode_t.c -f encode_t.fnm
Reading myascii (myascii)
Writing compiled form
128 bytes in string tables
384 bytes (75%) saved spotting duplicates
1 bytes (0.775%) saved using substrings
....
chmod 644 blib/arch/auto/Encode/My/My.bs
$
所需时间取决于机器的速度和编码的大小。除非您正在处理像 euc-tw 这样的大型编码,否则不会花费太长时间。
您现在可以执行 "make install",但您应该先进行测试。
$ make test
PERL_DL_NONLAZY=1 /usr/local/bin/perl -Iblib/arch -Iblib/lib \
-e 'use Test::Harness qw(&runtests $verbose); \
$verbose=0; runtests @ARGV;' t/*.t
t/My....ok
All tests successful.
Files=1, Tests=2, 0 wallclock secs
( 0.09 cusr + 0.01 csys = 0.09 CPU)
如果您对测试结果满意,只需执行 "make install" 即可。
如果您想将您的编码添加到 Encode 的按需加载列表中(这样您就不必 "use Encode::YourEncoding"),请运行
enc2xs -C
以更新 Encode::ConfigLocal,这是一个控制本地设置的模块。之后,"use Encode;" 就足以按需加载您的编码。
Encode 使用 Unicode 字符映射 (UCM) 格式进行源字符映射。此格式由 IBM 的 ICU 包使用,并被 Nick Ing-Simmons 采用以用于 Encode 模块。由于 UCM 比 Tcl 的编码映射更灵活,并且更易于使用,因此现在推荐使用此格式。
UCM 文件看起来像这样。
#
# Comments
#
<code_set_name> "US-ascii" # Required
<code_set_alias> "ascii" # Optional
<mb_cur_min> 1 # Required; usually 1
<mb_cur_max> 1 # Max. # of bytes/char
<subchar> \x3F # Substitution char
#
CHARMAP
<U0000> \x00 |0 # <control>
<U0001> \x01 |0 # <control>
<U0002> \x02 |0 # <control>
....
<U007C> \x7C |0 # VERTICAL LINE
<U007D> \x7D |0 # RIGHT CURLY BRACKET
<U007E> \x7E |0 # TILDE
<U007F> \x7F |0 # <control>
END CHARMAP
任何以 #
开头的内容都被视为注释。
标题部分一直持续到包含单词 CHARMAP 的一行。此部分采用 <关键字> 值 的形式,每行一对。用作值的字符串必须用引号括起来。裸词被视为数字。\xXX 表示一个字节。
大多数关键字不言自明。subchar 表示替换字符,而不是子字符。当您将 Unicode 序列解码为此编码但未找到匹配的字符时,将使用此处定义的字节序列。在大多数情况下,此处的值为 \x3F;在 ASCII 中,这是一个问号。
CHARMAP 开始字符映射部分。每行都具有以下形式
<UXXXX> \xXX.. |0 # comment
^ ^ ^
| | +- Fallback flag
| +-------- Encoded byte sequence
+-------------- Unicode Character ID in hex
格式与标题部分大致相同,除了回退标志:| 后面跟着 0..3。可能值的含义如下
最后,END OF CHARMAP 结束本节。
当您手动创建 UCM 文件时,您应该复制 ascii.ucm 或与您的编码相似的现有编码,而不是从头开始编写。
当您这样做时,请确保至少保留 U0000 到 U0020,除非您的环境是 EBCDIC。
警告:并非 UCM 中的所有功能都已实现。例如,icu:state 未使用。因此,如果您想支持算法编码,特别是 ISO-2022 系列,则需要编写一个 perl 模块。此类模块包括 Encode::JP::2022_JP、Encode::KR::2022_KR 和 Encode::TW::HZ。
当您创建映射时,您应该使您的映射成为双向安全的。也就是说,encode('your-encoding', decode('your-encoding', $data)) eq $data
代表所有标记为 |0
的字符。以下是如何确保
按 Unicode 顺序排序您的映射。
当您有重复条目时,用 '|1' 或 '|3' 标记其中一个。
并确保 '|1' 或 '|3' 条目位于 '|0' 条目之后。
以下是大五码-eten 的示例。
<U2550> \xF9\xF9 |0
<U2550> \xA2\xA4 |3
内部编码 -> Unicode 和 Unicode -> 编码映射如下所示;
E to U U to E
--------------------------------------
\xF9\xF9 => U2550 U2550 => \xF9\xF9
\xA2\xA4 => U2550
因此,它对于 \xF9\xF9 是双向安全的。但如果上面的行颠倒了,就会发生以下情况。
E to U U to E
--------------------------------------
\xA2\xA4 => U2550 U2550 => \xF9\xF9
(\xF9\xF9 => U2550 is now overwritten!)
Encode 包附带 ucmlint,这是一个粗略但足够实用的工具,用于检查 UCM 文件的完整性。在 Encode/bin 目录下检查此工具。
如有疑问,您可以使用 ucmsort,这是 Encode/bin 目录下的另一个实用程序。
ICU 主页 http://www.icu-project.org/
ICU:转换数据 http://www.icu-project.org/userguide/conversion-data.html