ENC2XS(1perl)

πŸ“¦
version 5.44.0 Β· 2 versions
, in arch rolling

πŸ’… ENC2XS β€” the Perl Encode Module Generator (yes bestie, this is from the perl man pages, 1perl section, and it's lowkey iconic)

okay so real talk: you know how you wanted your own encoding in perl and thought you'd have to learn XS and suffer? nope. not today. enc2xs is here and she does the heavy lifting. let's go πŸ¦‹


✨ SYNOPSIS ✨

enc2xs -[options]
enc2xs -M ModName mapfiles...
enc2xs -C

three whole moods, pick your fighter πŸ’–


🌸 DESCRIPTION 🌸

enc2xs builds a Perl extension for Encode to use, and she can build it from either Unicode Character Mapping files (.ucm) or Tcl Encoding Files (.enc). she's not just some internal build-process girlie for the Encode module β€” you can literally use enc2xs to add your own encoding to perl. and the best part? no XS knowledge needed. none. zero. absolutely none. periodt πŸ’…


πŸŽ€ Quick Guide πŸŽ€

if you want to know as little about Perl as humanly possible but still need to add a new encoding, read this chapter and then forget everything else exists. no cap, that's the whole strategy. πŸ’–

  1. 0. have a .ucm file ready. you can get it from somewhere, write your own from scratch, or grab one from the Encode distribution and customize it (that last one? chef's kiss, highly recommend). for the UCM format, check out the next chapter. in the example below, the theoretical encoding is called myascii, defined in my.ucm, and $ is the shell prompt.
$ ls -F
my.ucm
  1. 1. issue a command like this:
$ enc2xs -M My my.ucm
generating Makefile.PL
generating My.pm
generating README
generating Changes

now look at your current directory. it should look like this:

$ ls -F
Makefile.PL   My.pm         my.ucm        t/

the following files were created:

Makefile.PL - MakeMaker script
My.pm       - Encode submodule
t/My.t      - test file

1.1. if you want *.ucm installed together with the modules, do this:

$ mkdir Encode
$ mv *.ucm Encode
$ enc2xs -M My Encode/*ucm
  1. 2. edit the files you generated. you don't have to if you have no time AND no intention of giving it to someone else, but bestie… editing the pod and adding more tests is such a good idea. do it for the plot. πŸ“–
  2. 3. now issue the command every Perl Monger is obsessed with:
$ perl Makefile.PL
Writing Makefile for Encode::My
  1. 4. now all you have to do is 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
$

how long it takes depends on how fast your machine is and how big your encoding is. unless you're working on something huge like euc-tw, it won't take long. we stay efficient. ✨

  1. 5. you could already make install, but you should test first. always test first, it's giving responsible.
$ 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)
  1. 6. if you're content with the test result, just make install. slay. πŸ‘‘
  2. 7. if you want to add your encoding to Encode's demand-loading list (so you don't have to use Encode::YourEncoding β€” so extra, right?), run:
enc2xs -C

this updates Encode::ConfigLocal, a module that controls local settings. after that, use Encode; alone is enough to load your encodings on demand. main character energy fr fr. πŸ’«


🌈 The Unicode Character Map 🌈

Encode uses the Unicode Character Map (UCM) format for source character mappings. this format is used by IBM's ICU package and was adopted by Nick Ing-Simmons for use with the Encode module. and honestly? UCM is more flexible than Tcl's Encoding Map and far more user-friendly, so this is the recommended format for Encode now. it ate. πŸ’…

a UCM file looks like this:

#
# 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
  • anything that follows # is treated as a comment. yes, even the sassy ones.
  • the header section continues until a line containing the word CHARMAP. this section has a form of <keyword> value, one pair per line. strings used as values must be quoted. barewords are treated as numbers. \xXX represents a byte.

most of the keywords are self-explanatory. subchar means substitution character, not subcharacter β€” don't get it twisted. when you decode a Unicode sequence to this encoding but no matching character is found, the byte sequence defined here will be used. for most cases, the value here is \x3F; in ASCII, this is a question mark.

  • CHARMAP starts the character map section. each line has a form like this:
<UXXXX> \xXX.. |0 # comment
  ^     ^      ^
  |     |      +- Fallback flag
  |     +-------- Encoded byte sequence
  +-------------- Unicode Character ID in hex

the format is roughly the same as a header section, except for the fallback flag: | followed by 0..3. the meaning of the possible values is as follows:

  • |0 β€” round trip safe. a character decoded to Unicode encodes back to the same byte sequence. most characters have this flag.
  • |1 β€” fallback for unicode -> encoding. when seen, enc2xs adds this character for the encode map only.
  • |2 β€” skip sub-char mapping should there be no code point.
  • |3 β€” fallback for encoding -> unicode. when seen, enc2xs adds this character for the decode map only.
  • and finally, END OF CHARMAP ends the section. bye bestie πŸ‘‹

when you're manually creating a UCM file, you should copy ascii.ucm or an existing encoding that's close to yours, rather than write your own from scratch. trust the process. 🫢

when you do so, make sure you leave at least U0000 to U0020 as is β€” unless your environment is EBCDIC. then all bets are off, sorry babe.

CAVEAT: not all features in UCM are implemented. for example, icu:state is not used. because of that, you need to write a perl module if you want to support algorithmical encodings, notably the ISO-2022 series. such modules include Encode::JP::2022_JP, Encode::KR::2022_KR, and Encode::TW::HZ. πŸ’€

πŸ’œ Coping with duplicate mappings πŸ’œ

when you create a map, you SHOULD make your mappings round-trip safe. that is to say:

encode('your-encoding', decode('your-encoding', $data)) eq $data

…stands for all characters that are marked as "|0". here's how to make sure of that:

  • sort your map in Unicode order. ✨
  • when you have a duplicate entry, mark either one with '|1' or '|3'.
  • and make sure the '|1' or '|3' entry FOLLOWS the '|0' entry. order matters, babes.

here's an example from big5-eten:

<U2550> \xF9\xF9 |0
<U2550> \xA2\xA4 |3

internally, Encoding -> Unicode and Unicode -> Encoding Map look like this:

E to U               U to E
--------------------------------------
\xF9\xF9 => U2550    U2550 => \xF9\xF9
\xA2\xA4 => U2550

so it is round-trip safe for \xF9\xF9. but if the line above is upside down, here's what happens:

E to U               U to E
--------------------------------------
\xA2\xA4 => U2550    U2550 => \xF9\xF9
(\xF9\xF9 => U2550 is now overwritten!)

not it. 😭 the Encode package comes with ucmlint, a crude but sufficient utility to check the integrity of a UCM file. check under the Encode/bin directory for this.

when in doubt, you can use ucmsort, yet another utility under the Encode/bin directory.


⭐ Bookmarks ⭐


πŸ‘€ SEE ALSO πŸ‘€

Encode, perlmod, perlpod


perl v5.44.0 Β· 2026-10-17 Β· that's the whole ENC2XS(1perl) page bestie, go add your encoding, you're literally built for this πŸ’–βœ¨πŸŽ€πŸ¦‹πŸŒΈπŸ’…πŸ«Ά

πŸ“¦ where this page comes from
  • arch rolling: perl 5.44.0-1 Β· Artistic-1.0-Perl AND GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms