This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
a4223341a51a9c587de06ba5fc8eeae4c347d6c7
[perl5.git] / lib / Unicode / UCD.pm
1 package Unicode::UCD;
2
3 use strict;
4 use warnings;
5 no warnings 'surrogate';    # surrogates can be inputs to this
6 use charnames ();
7
8 our $VERSION = '0.57';
9
10 require Exporter;
11
12 our @ISA = qw(Exporter);
13
14 our @EXPORT_OK = qw(charinfo
15                     charblock charscript
16                     charblocks charscripts
17                     charinrange
18                     general_categories bidi_types
19                     compexcl
20                     casefold all_casefolds casespec
21                     namedseq
22                     num
23                     prop_aliases
24                     prop_value_aliases
25                     prop_invlist
26                     prop_invmap
27                     search_invlist
28                     MAX_CP
29                 );
30
31 use Carp;
32
33 sub IS_ASCII_PLATFORM { ord("A") == 65 }
34
35 =head1 NAME
36
37 Unicode::UCD - Unicode character database
38
39 =head1 SYNOPSIS
40
41     use Unicode::UCD 'charinfo';
42     my $charinfo   = charinfo($codepoint);
43
44     use Unicode::UCD 'casefold';
45     my $casefold = casefold(0xFB00);
46
47     use Unicode::UCD 'all_casefolds';
48     my $all_casefolds_ref = all_casefolds();
49
50     use Unicode::UCD 'casespec';
51     my $casespec = casespec(0xFB00);
52
53     use Unicode::UCD 'charblock';
54     my $charblock  = charblock($codepoint);
55
56     use Unicode::UCD 'charscript';
57     my $charscript = charscript($codepoint);
58
59     use Unicode::UCD 'charblocks';
60     my $charblocks = charblocks();
61
62     use Unicode::UCD 'charscripts';
63     my $charscripts = charscripts();
64
65     use Unicode::UCD qw(charscript charinrange);
66     my $range = charscript($script);
67     print "looks like $script\n" if charinrange($range, $codepoint);
68
69     use Unicode::UCD qw(general_categories bidi_types);
70     my $categories = general_categories();
71     my $types = bidi_types();
72
73     use Unicode::UCD 'prop_aliases';
74     my @space_names = prop_aliases("space");
75
76     use Unicode::UCD 'prop_value_aliases';
77     my @gc_punct_names = prop_value_aliases("Gc", "Punct");
78
79     use Unicode::UCD 'prop_invlist';
80     my @puncts = prop_invlist("gc=punctuation");
81
82     use Unicode::UCD 'prop_invmap';
83     my ($list_ref, $map_ref, $format, $missing)
84                                       = prop_invmap("General Category");
85
86     use Unicode::UCD 'search_invlist';
87     my $index = search_invlist(\@invlist, $code_point);
88
89     use Unicode::UCD 'compexcl';
90     my $compexcl = compexcl($codepoint);
91
92     use Unicode::UCD 'namedseq';
93     my $namedseq = namedseq($named_sequence_name);
94
95     my $unicode_version = Unicode::UCD::UnicodeVersion();
96
97     my $convert_to_numeric =
98               Unicode::UCD::num("\N{RUMI DIGIT ONE}\N{RUMI DIGIT TWO}");
99
100 =head1 DESCRIPTION
101
102 The Unicode::UCD module offers a series of functions that
103 provide a simple interface to the Unicode
104 Character Database.
105
106 =head2 code point argument
107
108 Some of the functions are called with a I<code point argument>, which is either
109 a decimal or a hexadecimal scalar designating a code point in the platform's
110 native character set (extended to Unicode), or C<U+> followed by hexadecimals
111 designating a Unicode code point.  A leading 0 will force a hexadecimal
112 interpretation, as will a hexadecimal digit that isn't a decimal digit.
113
114 Examples:
115
116     223     # Decimal 223 in native character set
117     0223    # Hexadecimal 223, native (= 547 decimal)
118     0xDF    # Hexadecimal DF, native (= 223 decimal
119     U+DF    # Hexadecimal DF, in Unicode's character set
120                               (= LATIN SMALL LETTER SHARP S)
121
122 Note that the largest code point in Unicode is U+10FFFF.
123
124 =cut
125
126 my $BLOCKSFH;
127 my $VERSIONFH;
128 my $CASEFOLDFH;
129 my $CASESPECFH;
130 my $NAMEDSEQFH;
131 my $v_unicode_version;  # v-string.
132
133 sub openunicode {
134     my ($rfh, @path) = @_;
135     my $f;
136     unless (defined $$rfh) {
137         for my $d (@INC) {
138             use File::Spec;
139             $f = File::Spec->catfile($d, "unicore", @path);
140             last if open($$rfh, $f);
141             undef $f;
142         }
143         croak __PACKAGE__, ": failed to find ",
144               File::Spec->catfile(@path), " in @INC"
145             unless defined $f;
146     }
147     return $f;
148 }
149
150 sub _dclone ($) {   # Use Storable::dclone if available; otherwise emulate it.
151
152     use if defined &DynaLoader::boot_DynaLoader, Storable => qw(dclone);
153
154     return dclone(shift) if defined &dclone;
155
156     my $arg = shift;
157     my $type = ref $arg;
158     return $arg unless $type;   # No deep cloning needed for scalars
159
160     if ($type eq 'ARRAY') {
161         my @return;
162         foreach my $element (@$arg) {
163             push @return, &_dclone($element);
164         }
165         return \@return;
166     }
167     elsif ($type eq 'HASH') {
168         my %return;
169         foreach my $key (keys %$arg) {
170             $return{$key} = &_dclone($arg->{$key});
171         }
172         return \%return;
173     }
174     else {
175         croak "_dclone can't handle " . $type;
176     }
177 }
178
179 =head2 B<charinfo()>
180
181     use Unicode::UCD 'charinfo';
182
183     my $charinfo = charinfo(0x41);
184
185 This returns information about the input L</code point argument>
186 as a reference to a hash of fields as defined by the Unicode
187 standard.  If the L</code point argument> is not assigned in the standard
188 (i.e., has the general category C<Cn> meaning C<Unassigned>)
189 or is a non-character (meaning it is guaranteed to never be assigned in
190 the standard),
191 C<undef> is returned.
192
193 Fields that aren't applicable to the particular code point argument exist in the
194 returned hash, and are empty. 
195
196 The keys in the hash with the meanings of their values are:
197
198 =over
199
200 =item B<code>
201
202 the input native L</code point argument> expressed in hexadecimal, with
203 leading zeros
204 added if necessary to make it contain at least four hexdigits
205
206 =item B<name>
207
208 name of I<code>, all IN UPPER CASE.
209 Some control-type code points do not have names.
210 This field will be empty for C<Surrogate> and C<Private Use> code points,
211 and for the others without a name,
212 it will contain a description enclosed in angle brackets, like
213 C<E<lt>controlE<gt>>.
214
215
216 =item B<category>
217
218 The short name of the general category of I<code>.
219 This will match one of the keys in the hash returned by L</general_categories()>.
220
221 The L</prop_value_aliases()> function can be used to get all the synonyms
222 of the category name.
223
224 =item B<combining>
225
226 the combining class number for I<code> used in the Canonical Ordering Algorithm.
227 For Unicode 5.1, this is described in Section 3.11 C<Canonical Ordering Behavior>
228 available at
229 L<http://www.unicode.org/versions/Unicode5.1.0/>
230
231 The L</prop_value_aliases()> function can be used to get all the synonyms
232 of the combining class number.
233
234 =item B<bidi>
235
236 bidirectional type of I<code>.
237 This will match one of the keys in the hash returned by L</bidi_types()>.
238
239 The L</prop_value_aliases()> function can be used to get all the synonyms
240 of the bidi type name.
241
242 =item B<decomposition>
243
244 is empty if I<code> has no decomposition; or is one or more codes
245 (separated by spaces) that, taken in order, represent a decomposition for
246 I<code>.  Each has at least four hexdigits.
247 The codes may be preceded by a word enclosed in angle brackets then a space,
248 like C<E<lt>compatE<gt> >, giving the type of decomposition
249
250 This decomposition may be an intermediate one whose components are also
251 decomposable.  Use L<Unicode::Normalize> to get the final decomposition.
252
253 =item B<decimal>
254
255 if I<code> is a decimal digit this is its integer numeric value
256
257 =item B<digit>
258
259 if I<code> represents some other digit-like number, this is its integer
260 numeric value
261
262 =item B<numeric>
263
264 if I<code> represents a whole or rational number, this is its numeric value.
265 Rational values are expressed as a string like C<1/4>.
266
267 =item B<mirrored>
268
269 C<Y> or C<N> designating if I<code> is mirrored in bidirectional text
270
271 =item B<unicode10>
272
273 name of I<code> in the Unicode 1.0 standard if one
274 existed for this code point and is different from the current name
275
276 =item B<comment>
277
278 As of Unicode 6.0, this is always empty.
279
280 =item B<upper>
281
282 is empty if there is no single code point uppercase mapping for I<code>
283 (its uppercase mapping is itself);
284 otherwise it is that mapping expressed as at least four hexdigits.
285 (L</casespec()> should be used in addition to B<charinfo()>
286 for case mappings when the calling program can cope with multiple code point
287 mappings.)
288
289 =item B<lower>
290
291 is empty if there is no single code point lowercase mapping for I<code>
292 (its lowercase mapping is itself);
293 otherwise it is that mapping expressed as at least four hexdigits.
294 (L</casespec()> should be used in addition to B<charinfo()>
295 for case mappings when the calling program can cope with multiple code point
296 mappings.)
297
298 =item B<title>
299
300 is empty if there is no single code point titlecase mapping for I<code>
301 (its titlecase mapping is itself);
302 otherwise it is that mapping expressed as at least four hexdigits.
303 (L</casespec()> should be used in addition to B<charinfo()>
304 for case mappings when the calling program can cope with multiple code point
305 mappings.)
306
307 =item B<block>
308
309 the block I<code> belongs to (used in C<\p{Blk=...}>).
310 See L</Blocks versus Scripts>.
311
312
313 =item B<script>
314
315 the script I<code> belongs to.
316 See L</Blocks versus Scripts>.
317
318 =back
319
320 Note that you cannot do (de)composition and casing based solely on the
321 I<decomposition>, I<combining>, I<lower>, I<upper>, and I<title> fields;
322 you will need also the L</compexcl()>, and L</casespec()> functions.
323
324 =cut
325
326 # NB: This function is nearly duplicated in charnames.pm
327 sub _getcode {
328     my $arg = shift;
329
330     if ($arg =~ /^[1-9]\d*$/) {
331         return $arg;
332     }
333     elsif ($arg =~ /^(?:0[xX])?([[:xdigit:]]+)$/) {
334         return CORE::hex($1);
335     }
336     elsif ($arg =~ /^[Uu]\+([[:xdigit:]]+)$/) { # Is of form U+0000, means
337                                                 # wants the Unicode code
338                                                 # point, not the native one
339         my $decimal = CORE::hex($1);
340         return $decimal if IS_ASCII_PLATFORM;
341         return utf8::unicode_to_native($decimal);
342     }
343
344     return;
345 }
346
347 # Populated by _num.  Converts real number back to input rational
348 my %real_to_rational;
349
350 # To store the contents of files found on disk.
351 my @BIDIS;
352 my @CATEGORIES;
353 my @DECOMPOSITIONS;
354 my @NUMERIC_TYPES;
355 my %SIMPLE_LOWER;
356 my %SIMPLE_TITLE;
357 my %SIMPLE_UPPER;
358 my %UNICODE_1_NAMES;
359 my %ISO_COMMENT;
360
361 sub charinfo {
362
363     # This function has traditionally mimicked what is in UnicodeData.txt,
364     # warts and all.  This is a re-write that avoids UnicodeData.txt so that
365     # it can be removed to save disk space.  Instead, this assembles
366     # information gotten by other methods that get data from various other
367     # files.  It uses charnames to get the character name; and various
368     # mktables tables.
369
370     use feature 'unicode_strings';
371
372     # Will fail if called under minitest
373     use if defined &DynaLoader::boot_DynaLoader, "Unicode::Normalize" => qw(getCombinClass NFD);
374
375     my $arg  = shift;
376     my $code = _getcode($arg);
377     croak __PACKAGE__, "::charinfo: unknown code '$arg'" unless defined $code;
378
379     # Non-unicode implies undef.
380     return if $code > 0x10FFFF;
381
382     my %prop;
383     my $char = chr($code);
384
385     @CATEGORIES =_read_table("To/Gc.pl") unless @CATEGORIES;
386     $prop{'category'} = _search(\@CATEGORIES, 0, $#CATEGORIES, $code)
387                         // $utf8::SwashInfo{'ToGc'}{'missing'};
388
389     return if $prop{'category'} eq 'Cn';    # Unassigned code points are undef
390
391     $prop{'code'} = sprintf "%04X", $code;
392     $prop{'name'} = ($char =~ /\p{Cntrl}/) ? '<control>'
393                                            : (charnames::viacode($code) // "");
394
395     $prop{'combining'} = getCombinClass($code);
396
397     @BIDIS =_read_table("To/Bc.pl") unless @BIDIS;
398     $prop{'bidi'} = _search(\@BIDIS, 0, $#BIDIS, $code)
399                     // $utf8::SwashInfo{'ToBc'}{'missing'};
400
401     # For most code points, we can just read in "unicore/Decomposition.pl", as
402     # its contents are exactly what should be output.  But that file doesn't
403     # contain the data for the Hangul syllable decompositions, which can be
404     # algorithmically computed, and NFD() does that, so we call NFD() for
405     # those.  We can't use NFD() for everything, as it does a complete
406     # recursive decomposition, and what this function has always done is to
407     # return what's in UnicodeData.txt which doesn't show that recursiveness.
408     # Fortunately, the NFD() of the Hanguls doesn't have any recursion
409     # issues.
410     # Having no decomposition implies an empty field; otherwise, all but
411     # "Canonical" imply a compatible decomposition, and the type is prefixed
412     # to that, as it is in UnicodeData.txt
413     UnicodeVersion() unless defined $v_unicode_version;
414     if ($v_unicode_version ge v2.0.0 && $char =~ /\p{Block=Hangul_Syllables}/) {
415         # The code points of the decomposition are output in standard Unicode
416         # hex format, separated by blanks.
417         $prop{'decomposition'} = join " ", map { sprintf("%04X", $_)}
418                                            unpack "U*", NFD($char);
419     }
420     else {
421         @DECOMPOSITIONS = _read_table("Decomposition.pl")
422                           unless @DECOMPOSITIONS;
423         $prop{'decomposition'} = _search(\@DECOMPOSITIONS, 0, $#DECOMPOSITIONS,
424                                                                 $code) // "";
425     }
426
427     # Can use num() to get the numeric values, if any.
428     if (! defined (my $value = num($char))) {
429         $prop{'decimal'} = $prop{'digit'} = $prop{'numeric'} = "";
430     }
431     else {
432         if ($char =~ /\d/) {
433             $prop{'decimal'} = $prop{'digit'} = $prop{'numeric'} = $value;
434         }
435         else {
436
437             # For non-decimal-digits, we have to read in the Numeric type
438             # to distinguish them.  It is not just a matter of integer vs.
439             # rational, as some whole number values are not considered digits,
440             # e.g., TAMIL NUMBER TEN.
441             $prop{'decimal'} = "";
442
443             @NUMERIC_TYPES =_read_table("To/Nt.pl") unless @NUMERIC_TYPES;
444             if ((_search(\@NUMERIC_TYPES, 0, $#NUMERIC_TYPES, $code) // "")
445                 eq 'Digit')
446             {
447                 $prop{'digit'} = $prop{'numeric'} = $value;
448             }
449             else {
450                 $prop{'digit'} = "";
451                 $prop{'numeric'} = $real_to_rational{$value} // $value;
452             }
453         }
454     }
455
456     $prop{'mirrored'} = ($char =~ /\p{Bidi_Mirrored}/) ? 'Y' : 'N';
457
458     %UNICODE_1_NAMES =_read_table("To/Na1.pl", "use_hash") unless %UNICODE_1_NAMES;
459     $prop{'unicode10'} = $UNICODE_1_NAMES{$code} // "";
460
461     UnicodeVersion() unless defined $v_unicode_version;
462     if ($v_unicode_version ge v6.0.0) {
463         $prop{'comment'} = "";
464     }
465     else {
466         %ISO_COMMENT = _read_table("To/Isc.pl", "use_hash") unless %ISO_COMMENT;
467         $prop{'comment'} = (defined $ISO_COMMENT{$code})
468                            ? $ISO_COMMENT{$code}
469                            : "";
470     }
471
472     %SIMPLE_UPPER = _read_table("To/Uc.pl", "use_hash") unless %SIMPLE_UPPER;
473     $prop{'upper'} = (defined $SIMPLE_UPPER{$code})
474                      ? sprintf("%04X", $SIMPLE_UPPER{$code})
475                      : "";
476
477     %SIMPLE_LOWER = _read_table("To/Lc.pl", "use_hash") unless %SIMPLE_LOWER;
478     $prop{'lower'} = (defined $SIMPLE_LOWER{$code})
479                      ? sprintf("%04X", $SIMPLE_LOWER{$code})
480                      : "";
481
482     %SIMPLE_TITLE = _read_table("To/Tc.pl", "use_hash") unless %SIMPLE_TITLE;
483     $prop{'title'} = (defined $SIMPLE_TITLE{$code})
484                      ? sprintf("%04X", $SIMPLE_TITLE{$code})
485                      : "";
486
487     $prop{block}  = charblock($code);
488     $prop{script} = charscript($code);
489     return \%prop;
490 }
491
492 sub _search { # Binary search in a [[lo,hi,prop],[...],...] table.
493     my ($table, $lo, $hi, $code) = @_;
494
495     return if $lo > $hi;
496
497     my $mid = int(($lo+$hi) / 2);
498
499     if ($table->[$mid]->[0] < $code) {
500         if ($table->[$mid]->[1] >= $code) {
501             return $table->[$mid]->[2];
502         } else {
503             _search($table, $mid + 1, $hi, $code);
504         }
505     } elsif ($table->[$mid]->[0] > $code) {
506         _search($table, $lo, $mid - 1, $code);
507     } else {
508         return $table->[$mid]->[2];
509     }
510 }
511
512 sub _read_table ($;$) {
513
514     # Returns the contents of the mktables generated table file located at $1
515     # in the form of either an array of arrays or a hash, depending on if the
516     # optional second parameter is true (for hash return) or not.  In the case
517     # of a hash return, each key is a code point, and its corresponding value
518     # is what the table gives as the code point's corresponding value.  In the
519     # case of an array return, each outer array denotes a range with [0] the
520     # start point of that range; [1] the end point; and [2] the value that
521     # every code point in the range has.  The hash return is useful for fast
522     # lookup when the table contains only single code point ranges.  The array
523     # return takes much less memory when there are large ranges.
524     #
525     # This function has the side effect of setting
526     # $utf8::SwashInfo{$property}{'format'} to be the mktables format of the
527     #                                       table; and
528     # $utf8::SwashInfo{$property}{'missing'} to be the value for all entries
529     #                                        not listed in the table.
530     # where $property is the Unicode property name, preceded by 'To' for map
531     # properties., e.g., 'ToSc'.
532     #
533     # Table entries look like one of:
534     # 0000      0040    Common  # [65]
535     # 00AA              Latin
536
537     my $table = shift;
538     my $return_hash = shift;
539     $return_hash = 0 unless defined $return_hash;
540     my @return;
541     my %return;
542     local $_;
543     my $list = do "unicore/$table";
544
545     # Look up if this property requires adjustments, which we do below if it
546     # does.
547     require "unicore/Heavy.pl";
548     my $property = $table =~ s/\.pl//r;
549     $property = $utf8::file_to_swash_name{$property};
550     my $to_adjust = defined $property
551                     && $utf8::SwashInfo{$property}{'format'} =~ / ^ a /x;
552
553     for (split /^/m, $list) {
554         my ($start, $end, $value) = / ^ (.+?) \t (.*?) \t (.+?)
555                                         \s* ( \# .* )?  # Optional comment
556                                         $ /x;
557         my $decimal_start = hex $start;
558         my $decimal_end = ($end eq "") ? $decimal_start : hex $end;
559         $value = hex $value if $to_adjust
560                                && $utf8::SwashInfo{$property}{'format'} eq 'ax';
561         if ($return_hash) {
562             foreach my $i ($decimal_start .. $decimal_end) {
563                 $return{$i} = ($to_adjust)
564                               ? $value + $i - $decimal_start
565                               : $value;
566             }
567         }
568         elsif (! $to_adjust
569                && @return
570                && $return[-1][1] == $decimal_start - 1
571                && $return[-1][2] eq $value)
572         {
573             # If this is merely extending the previous range, do just that.
574             $return[-1]->[1] = $decimal_end;
575         }
576         else {
577             push @return, [ $decimal_start, $decimal_end, $value ];
578         }
579     }
580     return ($return_hash) ? %return : @return;
581 }
582
583 sub charinrange {
584     my ($range, $arg) = @_;
585     my $code = _getcode($arg);
586     croak __PACKAGE__, "::charinrange: unknown code '$arg'"
587         unless defined $code;
588     _search($range, 0, $#$range, $code);
589 }
590
591 =head2 B<charblock()>
592
593     use Unicode::UCD 'charblock';
594
595     my $charblock = charblock(0x41);
596     my $charblock = charblock(1234);
597     my $charblock = charblock(0x263a);
598     my $charblock = charblock("U+263a");
599
600     my $range     = charblock('Armenian');
601
602 With a L</code point argument> charblock() returns the I<block> the code point
603 belongs to, e.g.  C<Basic Latin>.  The old-style block name is returned (see
604 L</Old-style versus new-style block names>).
605 If the code point is unassigned, this returns the block it would belong to if
606 it were assigned.  (If the Unicode version being used is so early as to not
607 have blocks, all code points are considered to be in C<No_Block>.)
608
609 See also L</Blocks versus Scripts>.
610
611 If supplied with an argument that can't be a code point, charblock() tries to
612 do the opposite and interpret the argument as an old-style block name.  On an
613 ASCII platform, the return value is a I<range set> with one range: an
614 anonymous list with a single element that consists of another anonymous list
615 whose first element is the first code point in the block, and whose second
616 (and final) element is the final code point in the block.  On an EBCDIC
617 platform, the first two Unicode blocks are not contiguous.  Their range sets
618 are lists containing I<start-of-range>, I<end-of-range> code point pairs. You
619 can test whether a code point is in a range set using the L</charinrange()>
620 function. If the argument is not a known block, C<undef> is returned.
621
622 =cut
623
624 my @BLOCKS;
625 my %BLOCKS;
626
627 sub _charblocks {
628
629     # Can't read from the mktables table because it loses the hyphens in the
630     # original.
631     unless (@BLOCKS) {
632         UnicodeVersion() unless defined $v_unicode_version;
633         if ($v_unicode_version lt v2.0.0) {
634             my $subrange = [ 0, 0x10FFFF, 'No_Block' ];
635             push @BLOCKS, $subrange;
636             push @{$BLOCKS{'No_Block'}}, $subrange;
637         }
638         elsif (openunicode(\$BLOCKSFH, "Blocks.txt")) {
639             local $_;
640             local $/ = "\n";
641             while (<$BLOCKSFH>) {
642                 if (/^([0-9A-F]+)\.\.([0-9A-F]+);\s+(.+)/) {
643                     my ($lo, $hi) = (hex($1), hex($2));
644                     my $subrange = [ $lo, $hi, $3 ];
645                     push @BLOCKS, $subrange;
646                     push @{$BLOCKS{$3}}, $subrange;
647                 }
648             }
649             close($BLOCKSFH);
650             if (! IS_ASCII_PLATFORM) {
651                 # The first two blocks, through 0xFF, are wrong on EBCDIC
652                 # platforms.
653
654                 my @new_blocks = _read_table("To/Blk.pl");
655
656                 # Get rid of the first two ranges in the Unicode version, and
657                 # replace them with the ones computed by mktables.
658                 shift @BLOCKS;
659                 shift @BLOCKS;
660                 delete $BLOCKS{'Basic Latin'};
661                 delete $BLOCKS{'Latin-1 Supplement'};
662
663                 # But there are multiple entries in the computed versions, and
664                 # we change their names to (which we know) to be the old-style
665                 # ones.
666                 for my $i (0.. @new_blocks - 1) {
667                     if ($new_blocks[$i][2] =~ s/Basic_Latin/Basic Latin/
668                         or $new_blocks[$i][2] =~
669                                     s/Latin_1_Supplement/Latin-1 Supplement/)
670                     {
671                         push @{$BLOCKS{$new_blocks[$i][2]}}, $new_blocks[$i];
672                     }
673                     else {
674                         splice @new_blocks, $i;
675                         last;
676                     }
677                 }
678                 unshift @BLOCKS, @new_blocks;
679             }
680         }
681     }
682 }
683
684 sub charblock {
685     my $arg = shift;
686
687     _charblocks() unless @BLOCKS;
688
689     my $code = _getcode($arg);
690
691     if (defined $code) {
692         my $result = _search(\@BLOCKS, 0, $#BLOCKS, $code);
693         return $result if defined $result;
694         return 'No_Block';
695     }
696     elsif (exists $BLOCKS{$arg}) {
697         return _dclone $BLOCKS{$arg};
698     }
699 }
700
701 =head2 B<charscript()>
702
703     use Unicode::UCD 'charscript';
704
705     my $charscript = charscript(0x41);
706     my $charscript = charscript(1234);
707     my $charscript = charscript("U+263a");
708
709     my $range      = charscript('Thai');
710
711 With a L</code point argument> charscript() returns the I<script> the
712 code point belongs to, e.g.  C<Latin>, C<Greek>, C<Han>.
713 If the code point is unassigned or the Unicode version being used is so early
714 that it doesn't have scripts, this function returns C<"Unknown">.
715
716 If supplied with an argument that can't be a code point, charscript() tries
717 to do the opposite and interpret the argument as a script name. The
718 return value is a I<range set>: an anonymous list of lists that contain
719 I<start-of-range>, I<end-of-range> code point pairs. You can test whether a
720 code point is in a range set using the L</charinrange()> function. If the
721 argument is not a known script, C<undef> is returned.
722
723 See also L</Blocks versus Scripts>.
724
725 =cut
726
727 my @SCRIPTS;
728 my %SCRIPTS;
729
730 sub _charscripts {
731     unless (@SCRIPTS) {
732         UnicodeVersion() unless defined $v_unicode_version;
733         if ($v_unicode_version lt v3.1.0) {
734             push @SCRIPTS, [ 0, 0x10FFFF, 'Unknown' ];
735         }
736         else {
737             @SCRIPTS =_read_table("To/Sc.pl");
738         }
739     }
740     foreach my $entry (@SCRIPTS) {
741         $entry->[2] =~ s/(_\w)/\L$1/g;  # Preserve old-style casing
742         push @{$SCRIPTS{$entry->[2]}}, $entry;
743     }
744 }
745
746 sub charscript {
747     my $arg = shift;
748
749     _charscripts() unless @SCRIPTS;
750
751     my $code = _getcode($arg);
752
753     if (defined $code) {
754         my $result = _search(\@SCRIPTS, 0, $#SCRIPTS, $code);
755         return $result if defined $result;
756         return $utf8::SwashInfo{'ToSc'}{'missing'};
757     } elsif (exists $SCRIPTS{$arg}) {
758         return _dclone $SCRIPTS{$arg};
759     }
760
761     return;
762 }
763
764 =head2 B<charblocks()>
765
766     use Unicode::UCD 'charblocks';
767
768     my $charblocks = charblocks();
769
770 charblocks() returns a reference to a hash with the known block names
771 as the keys, and the code point ranges (see L</charblock()>) as the values.
772
773 The names are in the old-style (see L</Old-style versus new-style block
774 names>).
775
776 L<prop_invmap("block")|/prop_invmap()> can be used to get this same data in a
777 different type of data structure.
778
779 See also L</Blocks versus Scripts>.
780
781 =cut
782
783 sub charblocks {
784     _charblocks() unless %BLOCKS;
785     return _dclone \%BLOCKS;
786 }
787
788 =head2 B<charscripts()>
789
790     use Unicode::UCD 'charscripts';
791
792     my $charscripts = charscripts();
793
794 charscripts() returns a reference to a hash with the known script
795 names as the keys, and the code point ranges (see L</charscript()>) as
796 the values.
797
798 L<prop_invmap("script")|/prop_invmap()> can be used to get this same data in a
799 different type of data structure.
800
801 See also L</Blocks versus Scripts>.
802
803 =cut
804
805 sub charscripts {
806     _charscripts() unless %SCRIPTS;
807     return _dclone \%SCRIPTS;
808 }
809
810 =head2 B<charinrange()>
811
812 In addition to using the C<\p{Blk=...}> and C<\P{Blk=...}> constructs, you
813 can also test whether a code point is in the I<range> as returned by
814 L</charblock()> and L</charscript()> or as the values of the hash returned
815 by L</charblocks()> and L</charscripts()> by using charinrange():
816
817     use Unicode::UCD qw(charscript charinrange);
818
819     $range = charscript('Hiragana');
820     print "looks like hiragana\n" if charinrange($range, $codepoint);
821
822 =cut
823
824 my %GENERAL_CATEGORIES =
825  (
826     'L'  =>         'Letter',
827     'LC' =>         'CasedLetter',
828     'Lu' =>         'UppercaseLetter',
829     'Ll' =>         'LowercaseLetter',
830     'Lt' =>         'TitlecaseLetter',
831     'Lm' =>         'ModifierLetter',
832     'Lo' =>         'OtherLetter',
833     'M'  =>         'Mark',
834     'Mn' =>         'NonspacingMark',
835     'Mc' =>         'SpacingMark',
836     'Me' =>         'EnclosingMark',
837     'N'  =>         'Number',
838     'Nd' =>         'DecimalNumber',
839     'Nl' =>         'LetterNumber',
840     'No' =>         'OtherNumber',
841     'P'  =>         'Punctuation',
842     'Pc' =>         'ConnectorPunctuation',
843     'Pd' =>         'DashPunctuation',
844     'Ps' =>         'OpenPunctuation',
845     'Pe' =>         'ClosePunctuation',
846     'Pi' =>         'InitialPunctuation',
847     'Pf' =>         'FinalPunctuation',
848     'Po' =>         'OtherPunctuation',
849     'S'  =>         'Symbol',
850     'Sm' =>         'MathSymbol',
851     'Sc' =>         'CurrencySymbol',
852     'Sk' =>         'ModifierSymbol',
853     'So' =>         'OtherSymbol',
854     'Z'  =>         'Separator',
855     'Zs' =>         'SpaceSeparator',
856     'Zl' =>         'LineSeparator',
857     'Zp' =>         'ParagraphSeparator',
858     'C'  =>         'Other',
859     'Cc' =>         'Control',
860     'Cf' =>         'Format',
861     'Cs' =>         'Surrogate',
862     'Co' =>         'PrivateUse',
863     'Cn' =>         'Unassigned',
864  );
865
866 sub general_categories {
867     return _dclone \%GENERAL_CATEGORIES;
868 }
869
870 =head2 B<general_categories()>
871
872     use Unicode::UCD 'general_categories';
873
874     my $categories = general_categories();
875
876 This returns a reference to a hash which has short
877 general category names (such as C<Lu>, C<Nd>, C<Zs>, C<S>) as keys and long
878 names (such as C<UppercaseLetter>, C<DecimalNumber>, C<SpaceSeparator>,
879 C<Symbol>) as values.  The hash is reversible in case you need to go
880 from the long names to the short names.  The general category is the
881 one returned from
882 L</charinfo()> under the C<category> key.
883
884 The L</prop_value_aliases()> function can be used to get all the synonyms of
885 the category name.
886
887 =cut
888
889 my %BIDI_TYPES =
890  (
891    'L'   => 'Left-to-Right',
892    'LRE' => 'Left-to-Right Embedding',
893    'LRO' => 'Left-to-Right Override',
894    'R'   => 'Right-to-Left',
895    'AL'  => 'Right-to-Left Arabic',
896    'RLE' => 'Right-to-Left Embedding',
897    'RLO' => 'Right-to-Left Override',
898    'PDF' => 'Pop Directional Format',
899    'EN'  => 'European Number',
900    'ES'  => 'European Number Separator',
901    'ET'  => 'European Number Terminator',
902    'AN'  => 'Arabic Number',
903    'CS'  => 'Common Number Separator',
904    'NSM' => 'Non-Spacing Mark',
905    'BN'  => 'Boundary Neutral',
906    'B'   => 'Paragraph Separator',
907    'S'   => 'Segment Separator',
908    'WS'  => 'Whitespace',
909    'ON'  => 'Other Neutrals',
910  ); 
911
912 =head2 B<bidi_types()>
913
914     use Unicode::UCD 'bidi_types';
915
916     my $categories = bidi_types();
917
918 This returns a reference to a hash which has the short
919 bidi (bidirectional) type names (such as C<L>, C<R>) as keys and long
920 names (such as C<Left-to-Right>, C<Right-to-Left>) as values.  The
921 hash is reversible in case you need to go from the long names to the
922 short names.  The bidi type is the one returned from
923 L</charinfo()>
924 under the C<bidi> key.  For the exact meaning of the various bidi classes
925 the Unicode TR9 is recommended reading:
926 L<http://www.unicode.org/reports/tr9/>
927 (as of Unicode 5.0.0)
928
929 The L</prop_value_aliases()> function can be used to get all the synonyms of
930 the bidi type name.
931
932 =cut
933
934 sub bidi_types {
935     return _dclone \%BIDI_TYPES;
936 }
937
938 =head2 B<compexcl()>
939
940     use Unicode::UCD 'compexcl';
941
942     my $compexcl = compexcl(0x09dc);
943
944 This routine returns C<undef> if the Unicode version being used is so early
945 that it doesn't have this property.  It is included for backwards
946 compatibility, but as of Perl 5.12 and more modern Unicode versions, for
947 most purposes it is probably more convenient to use one of the following
948 instead:
949
950     my $compexcl = chr(0x09dc) =~ /\p{Comp_Ex};
951     my $compexcl = chr(0x09dc) =~ /\p{Full_Composition_Exclusion};
952
953 or even
954
955     my $compexcl = chr(0x09dc) =~ /\p{CE};
956     my $compexcl = chr(0x09dc) =~ /\p{Composition_Exclusion};
957
958 The first two forms return B<true> if the L</code point argument> should not
959 be produced by composition normalization.  For the final two forms to return
960 B<true>, it is additionally required that this fact not otherwise be
961 determinable from the Unicode data base.
962
963 This routine behaves identically to the final two forms.  That is,
964 it does not return B<true> if the code point has a decomposition
965 consisting of another single code point, nor if its decomposition starts
966 with a code point whose combining class is non-zero.  Code points that meet
967 either of these conditions should also not be produced by composition
968 normalization, which is probably why you should use the
969 C<Full_Composition_Exclusion> property instead, as shown above.
970
971 The routine returns B<false> otherwise.
972
973 =cut
974
975 sub compexcl {
976     my $arg  = shift;
977     my $code = _getcode($arg);
978     croak __PACKAGE__, "::compexcl: unknown code '$arg'"
979         unless defined $code;
980
981     UnicodeVersion() unless defined $v_unicode_version;
982     return if $v_unicode_version lt v3.0.0;
983
984     no warnings "non_unicode";     # So works on non-Unicode code points
985     return chr($code) =~ /\p{Composition_Exclusion}/;
986 }
987
988 =head2 B<casefold()>
989
990     use Unicode::UCD 'casefold';
991
992     my $casefold = casefold(0xDF);
993     if (defined $casefold) {
994         my @full_fold_hex = split / /, $casefold->{'full'};
995         my $full_fold_string =
996                     join "", map {chr(hex($_))} @full_fold_hex;
997         my @turkic_fold_hex =
998                         split / /, ($casefold->{'turkic'} ne "")
999                                         ? $casefold->{'turkic'}
1000                                         : $casefold->{'full'};
1001         my $turkic_fold_string =
1002                         join "", map {chr(hex($_))} @turkic_fold_hex;
1003     }
1004     if (defined $casefold && $casefold->{'simple'} ne "") {
1005         my $simple_fold_hex = $casefold->{'simple'};
1006         my $simple_fold_string = chr(hex($simple_fold_hex));
1007     }
1008
1009 This returns the (almost) locale-independent case folding of the
1010 character specified by the L</code point argument>.  (Starting in Perl v5.16,
1011 the core function C<fc()> returns the C<full> mapping (described below)
1012 faster than this does, and for entire strings.)
1013
1014 If there is no case folding for the input code point, C<undef> is returned.
1015
1016 If there is a case folding for that code point, a reference to a hash
1017 with the following fields is returned:
1018
1019 =over
1020
1021 =item B<code>
1022
1023 the input native L</code point argument> expressed in hexadecimal, with
1024 leading zeros
1025 added if necessary to make it contain at least four hexdigits
1026
1027 =item B<full>
1028
1029 one or more codes (separated by spaces) that, taken in order, give the
1030 code points for the case folding for I<code>.
1031 Each has at least four hexdigits.
1032
1033 =item B<simple>
1034
1035 is empty, or is exactly one code with at least four hexdigits which can be used
1036 as an alternative case folding when the calling program cannot cope with the
1037 fold being a sequence of multiple code points.  If I<full> is just one code
1038 point, then I<simple> equals I<full>.  If there is no single code point folding
1039 defined for I<code>, then I<simple> is the empty string.  Otherwise, it is an
1040 inferior, but still better-than-nothing alternative folding to I<full>.
1041
1042 =item B<mapping>
1043
1044 is the same as I<simple> if I<simple> is not empty, and it is the same as I<full>
1045 otherwise.  It can be considered to be the simplest possible folding for
1046 I<code>.  It is defined primarily for backwards compatibility.
1047
1048 =item B<status>
1049
1050 is C<C> (for C<common>) if the best possible fold is a single code point
1051 (I<simple> equals I<full> equals I<mapping>).  It is C<S> if there are distinct
1052 folds, I<simple> and I<full> (I<mapping> equals I<simple>).  And it is C<F> if
1053 there is only a I<full> fold (I<mapping> equals I<full>; I<simple> is empty).
1054 Note that this
1055 describes the contents of I<mapping>.  It is defined primarily for backwards
1056 compatibility.
1057
1058 For Unicode versions between 3.1 and 3.1.1 inclusive, I<status> can also be
1059 C<I> which is the same as C<C> but is a special case for dotted uppercase I and
1060 dotless lowercase i:
1061
1062 =over
1063
1064 =item Z<>B<*> If you use this C<I> mapping
1065
1066 the result is case-insensitive,
1067 but dotless and dotted I's are not distinguished
1068
1069 =item Z<>B<*> If you exclude this C<I> mapping
1070
1071 the result is not fully case-insensitive, but
1072 dotless and dotted I's are distinguished
1073
1074 =back
1075
1076 =item B<turkic>
1077
1078 contains any special folding for Turkic languages.  For versions of Unicode
1079 starting with 3.2, this field is empty unless I<code> has a different folding
1080 in Turkic languages, in which case it is one or more codes (separated by
1081 spaces) that, taken in order, give the code points for the case folding for
1082 I<code> in those languages.
1083 Each code has at least four hexdigits.
1084 Note that this folding does not maintain canonical equivalence without
1085 additional processing.
1086
1087 For Unicode versions between 3.1 and 3.1.1 inclusive, this field is empty unless
1088 there is a
1089 special folding for Turkic languages, in which case I<status> is C<I>, and
1090 I<mapping>, I<full>, I<simple>, and I<turkic> are all equal.  
1091
1092 =back
1093
1094 Programs that want complete generality and the best folding results should use
1095 the folding contained in the I<full> field.  But note that the fold for some
1096 code points will be a sequence of multiple code points.
1097
1098 Programs that can't cope with the fold mapping being multiple code points can
1099 use the folding contained in the I<simple> field, with the loss of some
1100 generality.  In Unicode 5.1, about 7% of the defined foldings have no single
1101 code point folding.
1102
1103 The I<mapping> and I<status> fields are provided for backwards compatibility for
1104 existing programs.  They contain the same values as in previous versions of
1105 this function.
1106
1107 Locale is not completely independent.  The I<turkic> field contains results to
1108 use when the locale is a Turkic language.
1109
1110 For more information about case mappings see
1111 L<http://www.unicode.org/unicode/reports/tr21>
1112
1113 =cut
1114
1115 my %CASEFOLD;
1116
1117 sub _casefold {
1118     unless (%CASEFOLD) {   # Populate the hash
1119         my ($full_invlist_ref, $full_invmap_ref, undef, $default)
1120                                                 = prop_invmap('Case_Folding');
1121
1122         # Use the recipe given in the prop_invmap() pod to convert the
1123         # inversion map into the hash.
1124         for my $i (0 .. @$full_invlist_ref - 1 - 1) {
1125             next if $full_invmap_ref->[$i] == $default;
1126             my $adjust = -1;
1127             for my $j ($full_invlist_ref->[$i] .. $full_invlist_ref->[$i+1] -1) {
1128                 $adjust++;
1129                 if (! ref $full_invmap_ref->[$i]) {
1130
1131                     # This is a single character mapping
1132                     $CASEFOLD{$j}{'status'} = 'C';
1133                     $CASEFOLD{$j}{'simple'}
1134                         = $CASEFOLD{$j}{'full'}
1135                         = $CASEFOLD{$j}{'mapping'}
1136                         = sprintf("%04X", $full_invmap_ref->[$i] + $adjust);
1137                     $CASEFOLD{$j}{'code'} = sprintf("%04X", $j);
1138                     $CASEFOLD{$j}{'turkic'} = "";
1139                 }
1140                 else {  # prop_invmap ensures that $adjust is 0 for a ref
1141                     $CASEFOLD{$j}{'status'} = 'F';
1142                     $CASEFOLD{$j}{'full'}
1143                     = $CASEFOLD{$j}{'mapping'}
1144                     = join " ", map { sprintf "%04X", $_ }
1145                                                     @{$full_invmap_ref->[$i]};
1146                     $CASEFOLD{$j}{'simple'} = "";
1147                     $CASEFOLD{$j}{'code'} = sprintf("%04X", $j);
1148                     $CASEFOLD{$j}{'turkic'} = "";
1149                 }
1150             }
1151         }
1152
1153         # We have filled in the full mappings above, assuming there were no
1154         # simple ones for the ones with multi-character maps.  Now, we find
1155         # and fix the cases where that assumption was false.
1156         (my ($simple_invlist_ref, $simple_invmap_ref, undef), $default)
1157                                         = prop_invmap('Simple_Case_Folding');
1158         for my $i (0 .. @$simple_invlist_ref - 1 - 1) {
1159             next if $simple_invmap_ref->[$i] == $default;
1160             my $adjust = -1;
1161             for my $j ($simple_invlist_ref->[$i]
1162                        .. $simple_invlist_ref->[$i+1] -1)
1163             {
1164                 $adjust++;
1165                 next if $CASEFOLD{$j}{'status'} eq 'C';
1166                 $CASEFOLD{$j}{'status'} = 'S';
1167                 $CASEFOLD{$j}{'simple'}
1168                     = $CASEFOLD{$j}{'mapping'}
1169                     = sprintf("%04X", $simple_invmap_ref->[$i] + $adjust);
1170                 $CASEFOLD{$j}{'code'} = sprintf("%04X", $j);
1171                 $CASEFOLD{$j}{'turkic'} = "";
1172             }
1173         }
1174
1175         # We hard-code in the turkish rules
1176         UnicodeVersion() unless defined $v_unicode_version;
1177         if ($v_unicode_version ge v3.2.0) {
1178
1179             # These two code points should already have regular entries, so
1180             # just fill in the turkish fields
1181             $CASEFOLD{ord('I')}{'turkic'} = '0131';
1182             $CASEFOLD{0x130}{'turkic'} = sprintf "%04X", ord('i');
1183         }
1184         elsif ($v_unicode_version ge v3.1.0) {
1185
1186             # These two code points don't have entries otherwise.
1187             $CASEFOLD{0x130}{'code'} = '0130';
1188             $CASEFOLD{0x131}{'code'} = '0131';
1189             $CASEFOLD{0x130}{'status'} = $CASEFOLD{0x131}{'status'} = 'I';
1190             $CASEFOLD{0x130}{'turkic'}
1191                 = $CASEFOLD{0x130}{'mapping'}
1192                 = $CASEFOLD{0x130}{'full'}
1193                 = $CASEFOLD{0x130}{'simple'}
1194                 = $CASEFOLD{0x131}{'turkic'}
1195                 = $CASEFOLD{0x131}{'mapping'}
1196                 = $CASEFOLD{0x131}{'full'}
1197                 = $CASEFOLD{0x131}{'simple'}
1198                 = sprintf "%04X", ord('i');
1199         }
1200     }
1201 }
1202
1203 sub casefold {
1204     my $arg  = shift;
1205     my $code = _getcode($arg);
1206     croak __PACKAGE__, "::casefold: unknown code '$arg'"
1207         unless defined $code;
1208
1209     _casefold() unless %CASEFOLD;
1210
1211     return $CASEFOLD{$code};
1212 }
1213
1214 =head2 B<all_casefolds()>
1215
1216
1217     use Unicode::UCD 'all_casefolds';
1218
1219     my $all_folds_ref = all_casefolds();
1220     foreach my $char_with_casefold (sort { $a <=> $b }
1221                                     keys %$all_folds_ref)
1222     {
1223         printf "%04X:", $char_with_casefold;
1224         my $casefold = $all_folds_ref->{$char_with_casefold};
1225
1226         # Get folds for $char_with_casefold
1227
1228         my @full_fold_hex = split / /, $casefold->{'full'};
1229         my $full_fold_string =
1230                     join "", map {chr(hex($_))} @full_fold_hex;
1231         print " full=", join " ", @full_fold_hex;
1232         my @turkic_fold_hex =
1233                         split / /, ($casefold->{'turkic'} ne "")
1234                                         ? $casefold->{'turkic'}
1235                                         : $casefold->{'full'};
1236         my $turkic_fold_string =
1237                         join "", map {chr(hex($_))} @turkic_fold_hex;
1238         print "; turkic=", join " ", @turkic_fold_hex;
1239         if (defined $casefold && $casefold->{'simple'} ne "") {
1240             my $simple_fold_hex = $casefold->{'simple'};
1241             my $simple_fold_string = chr(hex($simple_fold_hex));
1242             print "; simple=$simple_fold_hex";
1243         }
1244         print "\n";
1245     }
1246
1247 This returns all the case foldings in the current version of Unicode in the
1248 form of a reference to a hash.  Each key to the hash is the decimal
1249 representation of a Unicode character that has a casefold to other than
1250 itself.  The casefold of a semi-colon is itself, so it isn't in the hash;
1251 likewise for a lowercase "a", but there is an entry for a capital "A".  The
1252 hash value for each key is another hash, identical to what is returned by
1253 L</casefold()> if called with that code point as its argument.  So the value
1254 C<< all_casefolds()->{ord("A")}' >> is equivalent to C<casefold(ord("A"))>;
1255
1256 =cut
1257
1258 sub all_casefolds () {
1259     _casefold() unless %CASEFOLD;
1260     return _dclone \%CASEFOLD;
1261 }
1262
1263 =head2 B<casespec()>
1264
1265     use Unicode::UCD 'casespec';
1266
1267     my $casespec = casespec(0xFB00);
1268
1269 This returns the potentially locale-dependent case mappings of the L</code point
1270 argument>.  The mappings may be longer than a single code point (which the basic
1271 Unicode case mappings as returned by L</charinfo()> never are).
1272
1273 If there are no case mappings for the L</code point argument>, or if all three
1274 possible mappings (I<lower>, I<title> and I<upper>) result in single code
1275 points and are locale independent and unconditional, C<undef> is returned
1276 (which means that the case mappings, if any, for the code point are those
1277 returned by L</charinfo()>).
1278
1279 Otherwise, a reference to a hash giving the mappings (or a reference to a hash
1280 of such hashes, explained below) is returned with the following keys and their
1281 meanings:
1282
1283 The keys in the bottom layer hash with the meanings of their values are:
1284
1285 =over
1286
1287 =item B<code>
1288
1289 the input native L</code point argument> expressed in hexadecimal, with
1290 leading zeros
1291 added if necessary to make it contain at least four hexdigits
1292
1293 =item B<lower>
1294
1295 one or more codes (separated by spaces) that, taken in order, give the
1296 code points for the lower case of I<code>.
1297 Each has at least four hexdigits.
1298
1299 =item B<title>
1300
1301 one or more codes (separated by spaces) that, taken in order, give the
1302 code points for the title case of I<code>.
1303 Each has at least four hexdigits.
1304
1305 =item B<upper>
1306
1307 one or more codes (separated by spaces) that, taken in order, give the
1308 code points for the upper case of I<code>.
1309 Each has at least four hexdigits.
1310
1311 =item B<condition>
1312
1313 the conditions for the mappings to be valid.
1314 If C<undef>, the mappings are always valid.
1315 When defined, this field is a list of conditions,
1316 all of which must be true for the mappings to be valid.
1317 The list consists of one or more
1318 I<locales> (see below)
1319 and/or I<contexts> (explained in the next paragraph),
1320 separated by spaces.
1321 (Other than as used to separate elements, spaces are to be ignored.)
1322 Case distinctions in the condition list are not significant.
1323 Conditions preceded by "NON_" represent the negation of the condition.
1324
1325 A I<context> is one of those defined in the Unicode standard.
1326 For Unicode 5.1, they are defined in Section 3.13 C<Default Case Operations>
1327 available at
1328 L<http://www.unicode.org/versions/Unicode5.1.0/>.
1329 These are for context-sensitive casing.
1330
1331 =back
1332
1333 The hash described above is returned for locale-independent casing, where
1334 at least one of the mappings has length longer than one.  If C<undef> is
1335 returned, the code point may have mappings, but if so, all are length one,
1336 and are returned by L</charinfo()>.
1337 Note that when this function does return a value, it will be for the complete
1338 set of mappings for a code point, even those whose length is one.
1339
1340 If there are additional casing rules that apply only in certain locales,
1341 an additional key for each will be defined in the returned hash.  Each such key
1342 will be its locale name, defined as a 2-letter ISO 3166 country code, possibly
1343 followed by a "_" and a 2-letter ISO language code (possibly followed by a "_"
1344 and a variant code).  You can find the lists of all possible locales, see
1345 L<Locale::Country> and L<Locale::Language>.
1346 (In Unicode 6.0, the only locales returned by this function
1347 are C<lt>, C<tr>, and C<az>.)
1348
1349 Each locale key is a reference to a hash that has the form above, and gives
1350 the casing rules for that particular locale, which take precedence over the
1351 locale-independent ones when in that locale.
1352
1353 If the only casing for a code point is locale-dependent, then the returned
1354 hash will not have any of the base keys, like C<code>, C<upper>, etc., but
1355 will contain only locale keys.
1356
1357 For more information about case mappings see
1358 L<http://www.unicode.org/unicode/reports/tr21/>
1359
1360 =cut
1361
1362 my %CASESPEC;
1363
1364 sub _casespec {
1365     unless (%CASESPEC) {
1366         UnicodeVersion() unless defined $v_unicode_version;
1367         if ($v_unicode_version lt v2.1.8) {
1368             %CASESPEC = {};
1369         }
1370         elsif (openunicode(\$CASESPECFH, "SpecialCasing.txt")) {
1371             local $_;
1372             local $/ = "\n";
1373             while (<$CASESPECFH>) {
1374                 if (/^([0-9A-F]+); ([0-9A-F]+(?: [0-9A-F]+)*)?; ([0-9A-F]+(?: [0-9A-F]+)*)?; ([0-9A-F]+(?: [0-9A-F]+)*)?; (\w+(?: \w+)*)?/) {
1375
1376                     my ($hexcode, $lower, $title, $upper, $condition) =
1377                         ($1, $2, $3, $4, $5);
1378                     if (! IS_ASCII_PLATFORM) { # Remap entry to native
1379                         foreach my $var_ref (\$hexcode,
1380                                              \$lower,
1381                                              \$title,
1382                                              \$upper)
1383                         {
1384                             next unless defined $$var_ref;
1385                             $$var_ref = join " ",
1386                                         map { sprintf("%04X",
1387                                               utf8::unicode_to_native(hex $_)) }
1388                                         split " ", $$var_ref;
1389                         }
1390                     }
1391
1392                     my $code = hex($hexcode);
1393
1394                     # In 2.1.8, there were duplicate entries; ignore all but
1395                     # the first one -- there were no conditions in the file
1396                     # anyway.
1397                     if (exists $CASESPEC{$code} && $v_unicode_version ne v2.1.8)
1398                     {
1399                         if (exists $CASESPEC{$code}->{code}) {
1400                             my ($oldlower,
1401                                 $oldtitle,
1402                                 $oldupper,
1403                                 $oldcondition) =
1404                                     @{$CASESPEC{$code}}{qw(lower
1405                                                            title
1406                                                            upper
1407                                                            condition)};
1408                             if (defined $oldcondition) {
1409                                 my ($oldlocale) =
1410                                 ($oldcondition =~ /^([a-z][a-z](?:_\S+)?)/);
1411                                 delete $CASESPEC{$code};
1412                                 $CASESPEC{$code}->{$oldlocale} =
1413                                 { code      => $hexcode,
1414                                   lower     => $oldlower,
1415                                   title     => $oldtitle,
1416                                   upper     => $oldupper,
1417                                   condition => $oldcondition };
1418                             }
1419                         }
1420                         my ($locale) =
1421                             ($condition =~ /^([a-z][a-z](?:_\S+)?)/);
1422                         $CASESPEC{$code}->{$locale} =
1423                         { code      => $hexcode,
1424                           lower     => $lower,
1425                           title     => $title,
1426                           upper     => $upper,
1427                           condition => $condition };
1428                     } else {
1429                         $CASESPEC{$code} =
1430                         { code      => $hexcode,
1431                           lower     => $lower,
1432                           title     => $title,
1433                           upper     => $upper,
1434                           condition => $condition };
1435                     }
1436                 }
1437             }
1438             close($CASESPECFH);
1439         }
1440     }
1441 }
1442
1443 sub casespec {
1444     my $arg  = shift;
1445     my $code = _getcode($arg);
1446     croak __PACKAGE__, "::casespec: unknown code '$arg'"
1447         unless defined $code;
1448
1449     _casespec() unless %CASESPEC;
1450
1451     return ref $CASESPEC{$code} ? _dclone $CASESPEC{$code} : $CASESPEC{$code};
1452 }
1453
1454 =head2 B<namedseq()>
1455
1456     use Unicode::UCD 'namedseq';
1457
1458     my $namedseq = namedseq("KATAKANA LETTER AINU P");
1459     my @namedseq = namedseq("KATAKANA LETTER AINU P");
1460     my %namedseq = namedseq();
1461
1462 If used with a single argument in a scalar context, returns the string
1463 consisting of the code points of the named sequence, or C<undef> if no
1464 named sequence by that name exists.  If used with a single argument in
1465 a list context, it returns the list of the ordinals of the code points.  If used
1466 with no
1467 arguments in a list context, returns a hash with the names of the
1468 named sequences as the keys and the named sequences as strings as
1469 the values.  Otherwise, it returns C<undef> or an empty list depending
1470 on the context.
1471
1472 This function only operates on officially approved (not provisional) named
1473 sequences.
1474
1475 Note that as of Perl 5.14, C<\N{KATAKANA LETTER AINU P}> will insert the named
1476 sequence into double-quoted strings, and C<charnames::string_vianame("KATAKANA
1477 LETTER AINU P")> will return the same string this function does, but will also
1478 operate on character names that aren't named sequences, without you having to
1479 know which are which.  See L<charnames>.
1480
1481 =cut
1482
1483 my %NAMEDSEQ;
1484
1485 sub _namedseq {
1486     unless (%NAMEDSEQ) {
1487         if (openunicode(\$NAMEDSEQFH, "Name.pl")) {
1488             local $_;
1489             local $/ = "\n";
1490             while (<$NAMEDSEQFH>) {
1491                 if (/^ [0-9A-F]+ \  /x) {
1492                     chomp;
1493                     my ($sequence, $name) = split /\t/;
1494                     my @s = map { chr(hex($_)) } split(' ', $sequence);
1495                     $NAMEDSEQ{$name} = join("", @s);
1496                 }
1497             }
1498             close($NAMEDSEQFH);
1499         }
1500     }
1501 }
1502
1503 sub namedseq {
1504
1505     # Use charnames::string_vianame() which now returns this information,
1506     # unless the caller wants the hash returned, in which case we read it in,
1507     # and thereafter use it instead of calling charnames, as it is faster.
1508
1509     my $wantarray = wantarray();
1510     if (defined $wantarray) {
1511         if ($wantarray) {
1512             if (@_ == 0) {
1513                 _namedseq() unless %NAMEDSEQ;
1514                 return %NAMEDSEQ;
1515             } elsif (@_ == 1) {
1516                 my $s;
1517                 if (%NAMEDSEQ) {
1518                     $s = $NAMEDSEQ{ $_[0] };
1519                 }
1520                 else {
1521                     $s = charnames::string_vianame($_[0]);
1522                 }
1523                 return defined $s ? map { ord($_) } split('', $s) : ();
1524             }
1525         } elsif (@_ == 1) {
1526             return $NAMEDSEQ{ $_[0] } if %NAMEDSEQ;
1527             return charnames::string_vianame($_[0]);
1528         }
1529     }
1530     return;
1531 }
1532
1533 my %NUMERIC;
1534
1535 sub _numeric {
1536     my @numbers = _read_table("To/Nv.pl");
1537     foreach my $entry (@numbers) {
1538         my ($start, $end, $value) = @$entry;
1539
1540         # If value contains a slash, convert to decimal, add a reverse hash
1541         # used by charinfo.
1542         if ((my @rational = split /\//, $value) == 2) {
1543             my $real = $rational[0] / $rational[1];
1544             $real_to_rational{$real} = $value;
1545             $value = $real;
1546
1547             # Should only be single element, but just in case...
1548             for my $i ($start .. $end) {
1549                 $NUMERIC{$i} = $value;
1550             }
1551         }
1552         else {
1553             # The values require adjusting, as is in 'a' format
1554             for my $i ($start .. $end) {
1555                 $NUMERIC{$i} = $value + $i - $start;
1556             }
1557         }
1558     }
1559
1560     # Decided unsafe to use these that aren't officially part of the Unicode
1561     # standard.
1562     #use Math::Trig;
1563     #my $pi = acos(-1.0);
1564     #$NUMERIC{0x03C0} = $pi;
1565
1566     # Euler's constant, not to be confused with Euler's number
1567     #$NUMERIC{0x2107} = 0.57721566490153286060651209008240243104215933593992;
1568
1569     # Euler's number
1570     #$NUMERIC{0x212F} = 2.7182818284590452353602874713526624977572;
1571
1572     return;
1573 }
1574
1575 =pod
1576
1577 =head2 B<num()>
1578
1579     use Unicode::UCD 'num';
1580
1581     my $val = num("123");
1582     my $one_quarter = num("\N{VULGAR FRACTION 1/4}");
1583
1584 C<num> returns the numeric value of the input Unicode string; or C<undef> if it
1585 doesn't think the entire string has a completely valid, safe numeric value.
1586
1587 If the string is just one character in length, the Unicode numeric value
1588 is returned if it has one, or C<undef> otherwise.  Note that this need
1589 not be a whole number.  C<num("\N{TIBETAN DIGIT HALF ZERO}")>, for
1590 example returns -0.5.
1591
1592 =cut
1593
1594 #A few characters to which Unicode doesn't officially
1595 #assign a numeric value are considered numeric by C<num>.
1596 #These are:
1597
1598 # EULER CONSTANT             0.5772...  (this is NOT Euler's number)
1599 # SCRIPT SMALL E             2.71828... (this IS Euler's number)
1600 # GREEK SMALL LETTER PI      3.14159...
1601
1602 =pod
1603
1604 If the string is more than one character, C<undef> is returned unless
1605 all its characters are decimal digits (that is, they would match C<\d+>),
1606 from the same script.  For example if you have an ASCII '0' and a Bengali
1607 '3', mixed together, they aren't considered a valid number, and C<undef>
1608 is returned.  A further restriction is that the digits all have to be of
1609 the same form.  A half-width digit mixed with a full-width one will
1610 return C<undef>.  The Arabic script has two sets of digits;  C<num> will
1611 return C<undef> unless all the digits in the string come from the same
1612 set.
1613
1614 C<num> errs on the side of safety, and there may be valid strings of
1615 decimal digits that it doesn't recognize.  Note that Unicode defines
1616 a number of "digit" characters that aren't "decimal digit" characters.
1617 "Decimal digits" have the property that they have a positional value, i.e.,
1618 there is a units position, a 10's position, a 100's, etc, AND they are
1619 arranged in Unicode in blocks of 10 contiguous code points.  The Chinese
1620 digits, for example, are not in such a contiguous block, and so Unicode
1621 doesn't view them as decimal digits, but merely digits, and so C<\d> will not
1622 match them.  A single-character string containing one of these digits will
1623 have its decimal value returned by C<num>, but any longer string containing
1624 only these digits will return C<undef>.
1625
1626 Strings of multiple sub- and superscripts are not recognized as numbers.  You
1627 can use either of the compatibility decompositions in Unicode::Normalize to
1628 change these into digits, and then call C<num> on the result.
1629
1630 =cut
1631
1632 # To handle sub, superscripts, this could if called in list context,
1633 # consider those, and return the <decomposition> type in the second
1634 # array element.
1635
1636 sub num {
1637     my $string = $_[0];
1638
1639     _numeric unless %NUMERIC;
1640
1641     my $length = length($string);
1642     return $NUMERIC{ord($string)} if $length == 1;
1643     return if $string =~ /\D/;
1644     my $first_ord = ord(substr($string, 0, 1));
1645     my $value = $NUMERIC{$first_ord};
1646
1647     # To be a valid decimal number, it should be in a block of 10 consecutive
1648     # characters, whose values are 0, 1, 2, ... 9.  Therefore this digit's
1649     # value is its offset in that block from the character that means zero.
1650     my $zero_ord = $first_ord - $value;
1651
1652     # Unicode 6.0 instituted the rule that only digits in a consecutive
1653     # block of 10 would be considered decimal digits.  If this is an earlier
1654     # release, we verify that this first character is a member of such a
1655     # block.  That is, that the block of characters surrounding this one
1656     # consists of all \d characters whose numeric values are the expected
1657     # ones.
1658     UnicodeVersion() unless defined $v_unicode_version;
1659     if ($v_unicode_version lt v6.0.0) {
1660         for my $i (0 .. 9) {
1661             my $ord = $zero_ord + $i;
1662             return unless chr($ord) =~ /\d/;
1663             my $numeric = $NUMERIC{$ord};
1664             return unless defined $numeric;
1665             return unless $numeric == $i;
1666         }
1667     }
1668
1669     for my $i (1 .. $length -1) {
1670
1671         # Here we know either by verifying, or by fact of the first character
1672         # being a \d in Unicode 6.0 or later, that any character between the
1673         # character that means 0, and 9 positions above it must be \d, and
1674         # must have its value correspond to its offset from the zero.  Any
1675         # characters outside these 10 do not form a legal number for this
1676         # function.
1677         my $ord = ord(substr($string, $i, 1));
1678         my $digit = $ord - $zero_ord;
1679         return unless $digit >= 0 && $digit <= 9;
1680         $value = $value * 10 + $digit;
1681     }
1682
1683     return $value;
1684 }
1685
1686 =pod
1687
1688 =head2 B<prop_aliases()>
1689
1690     use Unicode::UCD 'prop_aliases';
1691
1692     my ($short_name, $full_name, @other_names) = prop_aliases("space");
1693     my $same_full_name = prop_aliases("Space");     # Scalar context
1694     my ($same_short_name) = prop_aliases("Space");  # gets 0th element
1695     print "The full name is $full_name\n";
1696     print "The short name is $short_name\n";
1697     print "The other aliases are: ", join(", ", @other_names), "\n";
1698
1699     prints:
1700     The full name is White_Space
1701     The short name is WSpace
1702     The other aliases are: Space
1703
1704 Most Unicode properties have several synonymous names.  Typically, there is at
1705 least a short name, convenient to type, and a long name that more fully
1706 describes the property, and hence is more easily understood.
1707
1708 If you know one name for a Unicode property, you can use C<prop_aliases> to find
1709 either the long name (when called in scalar context), or a list of all of the
1710 names, somewhat ordered so that the short name is in the 0th element, the long
1711 name in the next element, and any other synonyms are in the remaining
1712 elements, in no particular order.
1713
1714 The long name is returned in a form nicely capitalized, suitable for printing.
1715
1716 The input parameter name is loosely matched, which means that white space,
1717 hyphens, and underscores are ignored (except for the trailing underscore in
1718 the old_form grandfathered-in C<"L_">, which is better written as C<"LC">, and
1719 both of which mean C<General_Category=Cased Letter>).
1720
1721 If the name is unknown, C<undef> is returned (or an empty list in list
1722 context).  Note that Perl typically recognizes property names in regular
1723 expressions with an optional C<"Is_>" (with or without the underscore)
1724 prefixed to them, such as C<\p{isgc=punct}>.  This function does not recognize
1725 those in the input, returning C<undef>.  Nor are they included in the output
1726 as possible synonyms.
1727
1728 C<prop_aliases> does know about the Perl extensions to Unicode properties,
1729 such as C<Any> and C<XPosixAlpha>, and the single form equivalents to Unicode
1730 properties such as C<XDigit>, C<Greek>, C<In_Greek>, and C<Is_Greek>.  The
1731 final example demonstrates that the C<"Is_"> prefix is recognized for these
1732 extensions; it is needed to resolve ambiguities.  For example,
1733 C<prop_aliases('lc')> returns the list C<(lc, Lowercase_Mapping)>, but
1734 C<prop_aliases('islc')> returns C<(Is_LC, Cased_Letter)>.  This is
1735 because C<islc> is a Perl extension which is short for
1736 C<General_Category=Cased Letter>.  The lists returned for the Perl extensions
1737 will not include the C<"Is_"> prefix (whether or not the input had it) unless
1738 needed to resolve ambiguities, as shown in the C<"islc"> example, where the
1739 returned list had one element containing C<"Is_">, and the other without.
1740
1741 It is also possible for the reverse to happen:  C<prop_aliases('isc')> returns
1742 the list C<(isc, ISO_Comment)>; whereas C<prop_aliases('c')> returns
1743 C<(C, Other)> (the latter being a Perl extension meaning
1744 C<General_Category=Other>.
1745 L<perluniprops/Properties accessible through Unicode::UCD> lists the available
1746 forms, including which ones are discouraged from use.
1747
1748 Those discouraged forms are accepted as input to C<prop_aliases>, but are not
1749 returned in the lists.  C<prop_aliases('isL&')> and C<prop_aliases('isL_')>,
1750 which are old synonyms for C<"Is_LC"> and should not be used in new code, are
1751 examples of this.  These both return C<(Is_LC, Cased_Letter)>.  Thus this
1752 function allows you to take a discouraged form, and find its acceptable
1753 alternatives.  The same goes with single-form Block property equivalences.
1754 Only the forms that begin with C<"In_"> are not discouraged; if you pass
1755 C<prop_aliases> a discouraged form, you will get back the equivalent ones that
1756 begin with C<"In_">.  It will otherwise look like a new-style block name (see.
1757 L</Old-style versus new-style block names>).
1758
1759 C<prop_aliases> does not know about any user-defined properties, and will
1760 return C<undef> if called with one of those.  Likewise for Perl internal
1761 properties, with the exception of "Perl_Decimal_Digit" which it does know
1762 about (and which is documented below in L</prop_invmap()>).
1763
1764 =cut
1765
1766 # It may be that there are use cases where the discouraged forms should be
1767 # returned.  If that comes up, an optional boolean second parameter to the
1768 # function could be created, for example.
1769
1770 # These are created by mktables for this routine and stored in unicore/UCD.pl
1771 # where their structures are described.
1772 our %string_property_loose_to_name;
1773 our %ambiguous_names;
1774 our %loose_perlprop_to_name;
1775 our %prop_aliases;
1776
1777 sub prop_aliases ($) {
1778     my $prop = $_[0];
1779     return unless defined $prop;
1780
1781     require "unicore/UCD.pl";
1782     require "unicore/Heavy.pl";
1783     require "utf8_heavy.pl";
1784
1785     # The property name may be loosely or strictly matched; we don't know yet.
1786     # But both types use lower-case.
1787     $prop = lc $prop;
1788
1789     # It is loosely matched if its lower case isn't known to be strict.
1790     my $list_ref;
1791     if (! exists $utf8::stricter_to_file_of{$prop}) {
1792         my $loose = utf8::_loose_name($prop);
1793
1794         # There is a hash that converts from any loose name to its standard
1795         # form, mapping all synonyms for a  name to one name that can be used
1796         # as a key into another hash.  The whole concept is for memory
1797         # savings, as the second hash doesn't have to have all the
1798         # combinations.  Actually, there are two hashes that do the
1799         # converstion.  One is used in utf8_heavy.pl (stored in Heavy.pl) for
1800         # looking up properties matchable in regexes.  This function needs to
1801         # access string properties, which aren't available in regexes, so a
1802         # second conversion hash is made for them (stored in UCD.pl).  Look in
1803         # the string one now, as the rest can have an optional 'is' prefix,
1804         # which these don't.
1805         if (exists $string_property_loose_to_name{$loose}) {
1806
1807             # Convert to its standard loose name.
1808             $prop = $string_property_loose_to_name{$loose};
1809         }
1810         else {
1811             my $retrying = 0;   # bool.  ? Has an initial 'is' been stripped
1812         RETRY:
1813             if (exists $utf8::loose_property_name_of{$loose}
1814                 && (! $retrying
1815                     || ! exists $ambiguous_names{$loose}))
1816             {
1817                 # Found an entry giving the standard form.  We don't get here
1818                 # (in the test above) when we've stripped off an
1819                 # 'is' and the result is an ambiguous name.  That is because
1820                 # these are official Unicode properties (though Perl can have
1821                 # an optional 'is' prefix meaning the official property), and
1822                 # all ambiguous cases involve a Perl single-form extension
1823                 # for the gc, script, or block properties, and the stripped
1824                 # 'is' means that they mean one of those, and not one of
1825                 # these
1826                 $prop = $utf8::loose_property_name_of{$loose};
1827             }
1828             elsif (exists $loose_perlprop_to_name{$loose}) {
1829
1830                 # This hash is specifically for this function to list Perl
1831                 # extensions that aren't in the earlier hashes.  If there is
1832                 # only one element, the short and long names are identical.
1833                 # Otherwise the form is already in the same form as
1834                 # %prop_aliases, which is handled at the end of the function.
1835                 $list_ref = $loose_perlprop_to_name{$loose};
1836                 if (@$list_ref == 1) {
1837                     my @list = ($list_ref->[0], $list_ref->[0]);
1838                     $list_ref = \@list;
1839                 }
1840             }
1841             elsif (! exists $utf8::loose_to_file_of{$loose}) {
1842
1843                 # loose_to_file_of is a complete list of loose names.  If not
1844                 # there, the input is unknown.
1845                 return;
1846             }
1847             elsif ($loose =~ / [:=] /x) {
1848
1849                 # Here we found the name but not its aliases, so it has to
1850                 # exist.  Exclude property-value combinations.  (This shows up
1851                 # for something like ccc=vr which matches loosely, but is a
1852                 # synonym for ccc=9 which matches only strictly.
1853                 return;
1854             }
1855             else {
1856
1857                 # Here it has to exist, and isn't a property-value
1858                 # combination.  This means it must be one of the Perl
1859                 # single-form extensions.  First see if it is for a
1860                 # property-value combination in one of the following
1861                 # properties.
1862                 my @list;
1863                 foreach my $property ("gc", "script") {
1864                     @list = prop_value_aliases($property, $loose);
1865                     last if @list;
1866                 }
1867                 if (@list) {
1868
1869                     # Here, it is one of those property-value combination
1870                     # single-form synonyms.  There are ambiguities with some
1871                     # of these.  Check against the list for these, and adjust
1872                     # if necessary.
1873                     for my $i (0 .. @list -1) {
1874                         if (exists $ambiguous_names
1875                                    {utf8::_loose_name(lc $list[$i])})
1876                         {
1877                             # The ambiguity is resolved by toggling whether or
1878                             # not it has an 'is' prefix
1879                             $list[$i] =~ s/^Is_// or $list[$i] =~ s/^/Is_/;
1880                         }
1881                     }
1882                     return @list;
1883                 }
1884
1885                 # Here, it wasn't one of the gc or script single-form
1886                 # extensions.  It could be a block property single-form
1887                 # extension.  An 'in' prefix definitely means that, and should
1888                 # be looked up without the prefix.  However, starting in
1889                 # Unicode 6.1, we have to special case 'indic...', as there
1890                 # is a property that begins with that name.   We shouldn't
1891                 # strip the 'in' from that.   I'm (khw) generalizing this to
1892                 # 'indic' instead of the single property, because I suspect
1893                 # that others of this class may come along in the future.
1894                 # However, this could backfire and a block created whose name
1895                 # begins with 'dic...', and we would want to strip the 'in'.
1896                 # At which point this would have to be tweaked.
1897                 my $began_with_in = $loose =~ s/^in(?!dic)//;
1898                 @list = prop_value_aliases("block", $loose);
1899                 if (@list) {
1900                     map { $_ =~ s/^/In_/ } @list;
1901                     return @list;
1902                 }
1903
1904                 # Here still haven't found it.  The last opportunity for it
1905                 # being valid is only if it began with 'is'.  We retry without
1906                 # the 'is', setting a flag to that effect so that we don't
1907                 # accept things that begin with 'isis...'
1908                 if (! $retrying && ! $began_with_in && $loose =~ s/^is//) {
1909                     $retrying = 1;
1910                     goto RETRY;
1911                 }
1912
1913                 # Here, didn't find it.  Since it was in %loose_to_file_of, we
1914                 # should have been able to find it.
1915                 carp __PACKAGE__, "::prop_aliases: Unexpectedly could not find '$prop'.  Send bug report to perlbug\@perl.org";
1916                 return;
1917             }
1918         }
1919     }
1920
1921     if (! $list_ref) {
1922         # Here, we have set $prop to a standard form name of the input.  Look
1923         # it up in the structure created by mktables for this purpose, which
1924         # contains both strict and loosely matched properties.  Avoid
1925         # autovivifying.
1926         $list_ref = $prop_aliases{$prop} if exists $prop_aliases{$prop};
1927         return unless $list_ref;
1928     }
1929
1930     # The full name is in element 1.
1931     return $list_ref->[1] unless wantarray;
1932
1933     return @{_dclone $list_ref};
1934 }
1935
1936 =pod
1937
1938 =head2 B<prop_value_aliases()>
1939
1940     use Unicode::UCD 'prop_value_aliases';
1941
1942     my ($short_name, $full_name, @other_names)
1943                                    = prop_value_aliases("Gc", "Punct");
1944     my $same_full_name = prop_value_aliases("Gc", "P");   # Scalar cntxt
1945     my ($same_short_name) = prop_value_aliases("Gc", "P"); # gets 0th
1946                                                            # element
1947     print "The full name is $full_name\n";
1948     print "The short name is $short_name\n";
1949     print "The other aliases are: ", join(", ", @other_names), "\n";
1950
1951     prints:
1952     The full name is Punctuation
1953     The short name is P
1954     The other aliases are: Punct
1955
1956 Some Unicode properties have a restricted set of legal values.  For example,
1957 all binary properties are restricted to just C<true> or C<false>; and there
1958 are only a few dozen possible General Categories.
1959
1960 For such properties, there are usually several synonyms for each possible
1961 value.  For example, in binary properties, I<truth> can be represented by any of
1962 the strings "Y", "Yes", "T", or "True"; and the General Category
1963 "Punctuation" by that string, or "Punct", or simply "P".
1964
1965 Like property names, there is typically at least a short name for each such
1966 property-value, and a long name.  If you know any name of the property-value,
1967 you can use C<prop_value_aliases>() to get the long name (when called in
1968 scalar context), or a list of all the names, with the short name in the 0th
1969 element, the long name in the next element, and any other synonyms in the
1970 remaining elements, in no particular order, except that any all-numeric
1971 synonyms will be last.
1972
1973 The long name is returned in a form nicely capitalized, suitable for printing.
1974
1975 Case, white space, hyphens, and underscores are ignored in the input parameters
1976 (except for the trailing underscore in the old-form grandfathered-in general
1977 category property value C<"L_">, which is better written as C<"LC">).
1978
1979 If either name is unknown, C<undef> is returned.  Note that Perl typically
1980 recognizes property names in regular expressions with an optional C<"Is_>"
1981 (with or without the underscore) prefixed to them, such as C<\p{isgc=punct}>.
1982 This function does not recognize those in the property parameter, returning
1983 C<undef>.
1984
1985 If called with a property that doesn't have synonyms for its values, it
1986 returns the input value, possibly normalized with capitalization and
1987 underscores.
1988
1989 For the block property, new-style block names are returned (see
1990 L</Old-style versus new-style block names>).
1991
1992 To find the synonyms for single-forms, such as C<\p{Any}>, use
1993 L</prop_aliases()> instead.
1994
1995 C<prop_value_aliases> does not know about any user-defined properties, and
1996 will return C<undef> if called with one of those.
1997
1998 =cut
1999
2000 # These are created by mktables for this routine and stored in unicore/UCD.pl
2001 # where their structures are described.
2002 our %loose_to_standard_value;
2003 our %prop_value_aliases;
2004
2005 sub prop_value_aliases ($$) {
2006     my ($prop, $value) = @_;
2007     return unless defined $prop && defined $value;
2008
2009     require "unicore/UCD.pl";
2010     require "utf8_heavy.pl";
2011
2012     # Find the property name synonym that's used as the key in other hashes,
2013     # which is element 0 in the returned list.
2014     ($prop) = prop_aliases($prop);
2015     return if ! $prop;
2016     $prop = utf8::_loose_name(lc $prop);
2017
2018     # Here is a legal property, but the hash below (created by mktables for
2019     # this purpose) only knows about the properties that have a very finite
2020     # number of potential values, that is not ones whose value could be
2021     # anything, like most (if not all) string properties.  These don't have
2022     # synonyms anyway.  Simply return the input.  For example, there is no
2023     # synonym for ('Uppercase_Mapping', A').
2024     return $value if ! exists $prop_value_aliases{$prop};
2025
2026     # The value name may be loosely or strictly matched; we don't know yet.
2027     # But both types use lower-case.
2028     $value = lc $value;
2029
2030     # If the name isn't found under loose matching, it certainly won't be
2031     # found under strict
2032     my $loose_value = utf8::_loose_name($value);
2033     return unless exists $loose_to_standard_value{"$prop=$loose_value"};
2034
2035     # Similarly if the combination under loose matching doesn't exist, it
2036     # won't exist under strict.
2037     my $standard_value = $loose_to_standard_value{"$prop=$loose_value"};
2038     return unless exists $prop_value_aliases{$prop}{$standard_value};
2039
2040     # Here we did find a combination under loose matching rules.  But it could
2041     # be that is a strict property match that shouldn't have matched.
2042     # %prop_value_aliases is set up so that the strict matches will appear as
2043     # if they were in loose form.  Thus, if the non-loose version is legal,
2044     # we're ok, can skip the further check.
2045     if (! exists $utf8::stricter_to_file_of{"$prop=$value"}
2046
2047         # We're also ok and skip the further check if value loosely matches.
2048         # mktables has verified that no strict name under loose rules maps to
2049         # an existing loose name.  This code relies on the very limited
2050         # circumstances that strict names can be here.  Strict name matching
2051         # happens under two conditions:
2052         # 1) when the name begins with an underscore.  But this function
2053         #    doesn't accept those, and %prop_value_aliases doesn't have
2054         #    them.
2055         # 2) When the values are numeric, in which case we need to look
2056         #    further, but their squeezed-out loose values will be in
2057         #    %stricter_to_file_of
2058         && exists $utf8::stricter_to_file_of{"$prop=$loose_value"})
2059     {
2060         # The only thing that's legal loosely under strict is that can have an
2061         # underscore between digit pairs XXX
2062         while ($value =~ s/(\d)_(\d)/$1$2/g) {}
2063         return unless exists $utf8::stricter_to_file_of{"$prop=$value"};
2064     }
2065
2066     # Here, we know that the combination exists.  Return it.
2067     my $list_ref = $prop_value_aliases{$prop}{$standard_value};
2068     if (@$list_ref > 1) {
2069         # The full name is in element 1.
2070         return $list_ref->[1] unless wantarray;
2071
2072         return @{_dclone $list_ref};
2073     }
2074
2075     return $list_ref->[0] unless wantarray;
2076
2077     # Only 1 element means that it repeats
2078     return ( $list_ref->[0], $list_ref->[0] );
2079 }
2080
2081 # All 1 bits is the largest possible UV.
2082 $Unicode::UCD::MAX_CP = ~0;
2083
2084 =pod
2085
2086 =head2 B<prop_invlist()>
2087
2088 C<prop_invlist> returns an inversion list (described below) that defines all the
2089 code points for the binary Unicode property (or "property=value" pair) given
2090 by the input parameter string:
2091
2092  use feature 'say';
2093  use Unicode::UCD 'prop_invlist';
2094  say join ", ", prop_invlist("Any");
2095
2096  prints:
2097  0, 1114112
2098
2099 If the input is unknown C<undef> is returned in scalar context; an empty-list
2100 in list context.  If the input is known, the number of elements in
2101 the list is returned if called in scalar context.
2102
2103 L<perluniprops|perluniprops/Properties accessible through \p{} and \P{}> gives
2104 the list of properties that this function accepts, as well as all the possible
2105 forms for them (including with the optional "Is_" prefixes).  (Except this
2106 function doesn't accept any Perl-internal properties, some of which are listed
2107 there.) This function uses the same loose or tighter matching rules for
2108 resolving the input property's name as is done for regular expressions.  These
2109 are also specified in L<perluniprops|perluniprops/Properties accessible
2110 through \p{} and \P{}>.  Examples of using the "property=value" form are:
2111
2112  say join ", ", prop_invlist("Script=Shavian");
2113
2114  prints:
2115  66640, 66688
2116
2117  say join ", ", prop_invlist("ASCII_Hex_Digit=No");
2118
2119  prints:
2120  0, 48, 58, 65, 71, 97, 103
2121
2122  say join ", ", prop_invlist("ASCII_Hex_Digit=Yes");
2123
2124  prints:
2125  48, 58, 65, 71, 97, 103
2126
2127 Inversion lists are a compact way of specifying Unicode property-value
2128 definitions.  The 0th item in the list is the lowest code point that has the
2129 property-value.  The next item (item [1]) is the lowest code point beyond that
2130 one that does NOT have the property-value.  And the next item beyond that
2131 ([2]) is the lowest code point beyond that one that does have the
2132 property-value, and so on.  Put another way, each element in the list gives
2133 the beginning of a range that has the property-value (for even numbered
2134 elements), or doesn't have the property-value (for odd numbered elements).
2135 The name for this data structure stems from the fact that each element in the
2136 list toggles (or inverts) whether the corresponding range is or isn't on the
2137 list.
2138
2139 In the final example above, the first ASCII Hex digit is code point 48, the
2140 character "0", and all code points from it through 57 (a "9") are ASCII hex
2141 digits.  Code points 58 through 64 aren't, but 65 (an "A") through 70 (an "F")
2142 are, as are 97 ("a") through 102 ("f").  103 starts a range of code points
2143 that aren't ASCII hex digits.  That range extends to infinity, which on your
2144 computer can be found in the variable C<$Unicode::UCD::MAX_CP>.  (This
2145 variable is as close to infinity as Perl can get on your platform, and may be
2146 too high for some operations to work; you may wish to use a smaller number for
2147 your purposes.)
2148
2149 Note that the inversion lists returned by this function can possibly include
2150 non-Unicode code points, that is anything above 0x10FFFF.  Unicode properties
2151 are not defined on such code points.  You might wish to change the output to
2152 not include these.  Simply add 0x110000 at the end of the non-empty returned
2153 list if it isn't already that value; and pop that value if it is; like:
2154
2155  my @list = prop_invlist("foo");
2156  if (@list) {
2157      if ($list[-1] == 0x110000) {
2158          pop @list;  # Defeat the turning on for above Unicode
2159      }
2160      else {
2161          push @list, 0x110000; # Turn off for above Unicode
2162      }
2163  }
2164
2165 It is a simple matter to expand out an inversion list to a full list of all
2166 code points that have the property-value:
2167
2168  my @invlist = prop_invlist($property_name);
2169  die "empty" unless @invlist;
2170  my @full_list;
2171  for (my $i = 0; $i < @invlist; $i += 2) {
2172     my $upper = ($i + 1) < @invlist
2173                 ? $invlist[$i+1] - 1      # In range
2174                 : $Unicode::UCD::MAX_CP;  # To infinity.  You may want
2175                                           # to stop much much earlier;
2176                                           # going this high may expose
2177                                           # perl deficiencies with very
2178                                           # large numbers.
2179     for my $j ($invlist[$i] .. $upper) {
2180         push @full_list, $j;
2181     }
2182  }
2183
2184 C<prop_invlist> does not know about any user-defined nor Perl internal-only
2185 properties, and will return C<undef> if called with one of those.
2186
2187 The L</search_invlist()> function is provided for finding a code point within
2188 an inversion list.
2189
2190 =cut
2191
2192 # User-defined properties could be handled with some changes to utf8_heavy.pl;
2193 # and implementing here of dealing with EXTRAS.  If done, consideration should
2194 # be given to the fact that the user subroutine could return different results
2195 # with each call; security issues need to be thought about.
2196
2197 # These are created by mktables for this routine and stored in unicore/UCD.pl
2198 # where their structures are described.
2199 our %loose_defaults;
2200 our $MAX_UNICODE_CODEPOINT;
2201
2202 sub prop_invlist ($;$) {
2203     my $prop = $_[0];
2204
2205     # Undocumented way to get at Perl internal properties
2206     my $internal_ok = defined $_[1] && $_[1] eq '_perl_core_internal_ok';
2207
2208     return if ! defined $prop;
2209
2210     require "utf8_heavy.pl";
2211
2212     # Warnings for these are only for regexes, so not applicable to us
2213     no warnings 'deprecated';
2214
2215     # Get the swash definition of the property-value.
2216     my $swash = utf8::SWASHNEW(__PACKAGE__, $prop, undef, 1, 0);
2217
2218     # Fail if not found, or isn't a boolean property-value, or is a
2219     # user-defined property, or is internal-only.
2220     return if ! $swash
2221               || ref $swash eq ""
2222               || $swash->{'BITS'} != 1
2223               || $swash->{'USER_DEFINED'}
2224               || (! $internal_ok && $prop =~ /^\s*_/);
2225
2226     if ($swash->{'EXTRAS'}) {
2227         carp __PACKAGE__, "::prop_invlist: swash returned for $prop unexpectedly has EXTRAS magic";
2228         return;
2229     }
2230     if ($swash->{'SPECIALS'}) {
2231         carp __PACKAGE__, "::prop_invlist: swash returned for $prop unexpectedly has SPECIALS magic";
2232         return;
2233     }
2234
2235     my @invlist;
2236
2237     if ($swash->{'LIST'} =~ /^V/) {
2238
2239         # A 'V' as the first character marks the input as already an inversion
2240         # list, in which case, all we need to do is put the remaining lines
2241         # into our array.
2242         @invlist = split "\n", $swash->{'LIST'} =~ s/ \s* (?: \# .* )? $ //xmgr;
2243         shift @invlist;
2244     }
2245     else {
2246         # The input lines look like:
2247         # 0041\t005A   # [26]
2248         # 005F
2249
2250         # Split into lines, stripped of trailing comments
2251         foreach my $range (split "\n",
2252                               $swash->{'LIST'} =~ s/ \s* (?: \# .* )? $ //xmgr)
2253         {
2254             # And find the beginning and end of the range on the line
2255             my ($hex_begin, $hex_end) = split "\t", $range;
2256             my $begin = hex $hex_begin;
2257
2258             # If the new range merely extends the old, we remove the marker
2259             # created the last time through the loop for the old's end, which
2260             # causes the new one's end to be used instead.
2261             if (@invlist && $begin == $invlist[-1]) {
2262                 pop @invlist;
2263             }
2264             else {
2265                 # Add the beginning of the range
2266                 push @invlist, $begin;
2267             }
2268
2269             if (defined $hex_end) { # The next item starts with the code point 1
2270                                     # beyond the end of the range.
2271                 no warnings 'portable';
2272                 my $end = hex $hex_end;
2273                 last if $end == $Unicode::UCD::MAX_CP;
2274                 push @invlist, $end + 1;
2275             }
2276             else {  # No end of range, is a single code point.
2277                 push @invlist, $begin + 1;
2278             }
2279         }
2280     }
2281
2282     # Could need to be inverted: add or subtract a 0 at the beginning of the
2283     # list.
2284     if ($swash->{'INVERT_IT'}) {
2285         if (@invlist && $invlist[0] == 0) {
2286             shift @invlist;
2287         }
2288         else {
2289             unshift @invlist, 0;
2290         }
2291     }
2292
2293     return @invlist;
2294 }
2295
2296 =pod
2297
2298 =head2 B<prop_invmap()>
2299
2300  use Unicode::UCD 'prop_invmap';
2301  my ($list_ref, $map_ref, $format, $default)
2302                                       = prop_invmap("General Category");
2303
2304 C<prop_invmap> is used to get the complete mapping definition for a property,
2305 in the form of an inversion map.  An inversion map consists of two parallel
2306 arrays.  One is an ordered list of code points that mark range beginnings, and
2307 the other gives the value (or mapping) that all code points in the
2308 corresponding range have.
2309
2310 C<prop_invmap> is called with the name of the desired property.  The name is
2311 loosely matched, meaning that differences in case, white-space, hyphens, and
2312 underscores are not meaningful (except for the trailing underscore in the
2313 old-form grandfathered-in property C<"L_">, which is better written as C<"LC">,
2314 or even better, C<"Gc=LC">).
2315
2316 Many Unicode properties have more than one name (or alias).  C<prop_invmap>
2317 understands all of these, including Perl extensions to them.  Ambiguities are
2318 resolved as described above for L</prop_aliases()>.  The Perl internal
2319 property "Perl_Decimal_Digit, described below, is also accepted.  An empty
2320 list is returned if the property name is unknown.
2321 See L<perluniprops/Properties accessible through Unicode::UCD> for the
2322 properties acceptable as inputs to this function.
2323
2324 It is a fatal error to call this function except in list context.
2325
2326 In addition to the two arrays that form the inversion map, C<prop_invmap>
2327 returns two other values; one is a scalar that gives some details as to the
2328 format of the entries of the map array; the other is a default value, useful
2329 in maps whose format name begins with the letter C<"a">, as described
2330 L<below in its subsection|/a>; and for specialized purposes, such as
2331 converting to another data structure, described at the end of this main
2332 section.
2333
2334 This means that C<prop_invmap> returns a 4 element list.  For example,
2335
2336  my ($blocks_ranges_ref, $blocks_maps_ref, $format, $default)
2337                                                  = prop_invmap("Block");
2338
2339 In this call, the two arrays will be populated as shown below (for Unicode
2340 6.0):
2341
2342  Index  @blocks_ranges  @blocks_maps
2343    0        0x0000      Basic Latin
2344    1        0x0080      Latin-1 Supplement
2345    2        0x0100      Latin Extended-A
2346    3        0x0180      Latin Extended-B
2347    4        0x0250      IPA Extensions
2348    5        0x02B0      Spacing Modifier Letters
2349    6        0x0300      Combining Diacritical Marks
2350    7        0x0370      Greek and Coptic
2351    8        0x0400      Cyrillic
2352   ...
2353  233        0x2B820     No_Block
2354  234        0x2F800     CJK Compatibility Ideographs Supplement
2355  235        0x2FA20     No_Block
2356  236        0xE0000     Tags
2357  237        0xE0080     No_Block
2358  238        0xE0100     Variation Selectors Supplement
2359  239        0xE01F0     No_Block
2360  240        0xF0000     Supplementary Private Use Area-A
2361  241        0x100000    Supplementary Private Use Area-B
2362  242        0x110000    No_Block
2363
2364 The first line (with Index [0]) means that the value for code point 0 is "Basic
2365 Latin".  The entry "0x0080" in the @blocks_ranges column in the second line
2366 means that the value from the first line, "Basic Latin", extends to all code
2367 points in the range from 0 up to but not including 0x0080, that is, through
2368 127.  In other words, the code points from 0 to 127 are all in the "Basic
2369 Latin" block.  Similarly, all code points in the range from 0x0080 up to (but
2370 not including) 0x0100 are in the block named "Latin-1 Supplement", etc.
2371 (Notice that the return is the old-style block names; see L</Old-style versus
2372 new-style block names>).
2373
2374 The final line (with Index [242]) means that the value for all code points above
2375 the legal Unicode maximum code point have the value "No_Block", which is the
2376 term Unicode uses for a non-existing block.
2377
2378 The arrays completely specify the mappings for all possible code points.
2379 The final element in an inversion map returned by this function will always be
2380 for the range that consists of all the code points that aren't legal Unicode,
2381 but that are expressible on the platform.  (That is, it starts with code point
2382 0x110000, the first code point above the legal Unicode maximum, and extends to
2383 infinity.) The value for that range will be the same that any typical
2384 unassigned code point has for the specified property.  (Certain unassigned
2385 code points are not "typical"; for example the non-character code points, or
2386 those in blocks that are to be written right-to-left.  The above-Unicode
2387 range's value is not based on these atypical code points.)  It could be argued
2388 that, instead of treating these as unassigned Unicode code points, the value
2389 for this range should be C<undef>.  If you wish, you can change the returned
2390 arrays accordingly.
2391
2392 The maps for almost all properties are simple scalars that should be
2393 interpreted as-is.
2394 These values are those given in the Unicode-supplied data files, which may be
2395 inconsistent as to capitalization and as to which synonym for a property-value
2396 is given.  The results may be normalized by using the L</prop_value_aliases()>
2397 function.
2398
2399 There are exceptions to the simple scalar maps.  Some properties have some
2400 elements in their map list that are themselves lists of scalars; and some
2401 special strings are returned that are not to be interpreted as-is.  Element
2402 [2] (placed into C<$format> in the example above) of the returned four element
2403 list tells you if the map has any of these special elements or not, as follows:
2404
2405 =over
2406
2407 =item B<C<s>>
2408
2409 means all the elements of the map array are simple scalars, with no special
2410 elements.  Almost all properties are like this, like the C<block> example
2411 above.
2412
2413 =item B<C<sl>>
2414
2415 means that some of the map array elements have the form given by C<"s">, and
2416 the rest are lists of scalars.  For example, here is a portion of the output
2417 of calling C<prop_invmap>() with the "Script Extensions" property:
2418
2419  @scripts_ranges  @scripts_maps
2420       ...
2421       0x0953      Devanagari
2422       0x0964      [ Bengali, Devanagari, Gurumukhi, Oriya ]
2423       0x0966      Devanagari
2424       0x0970      Common
2425
2426 Here, the code points 0x964 and 0x965 are both used in Bengali,
2427 Devanagari, Gurmukhi, and Oriya, but no other scripts.
2428
2429 The Name_Alias property is also of this form.  But each scalar consists of two
2430 components:  1) the name, and 2) the type of alias this is.  They are
2431 separated by a colon and a space.  In Unicode 6.1, there are several alias types:
2432
2433 =over
2434
2435 =item C<correction>
2436
2437 indicates that the name is a corrected form for the
2438 original name (which remains valid) for the same code point.
2439
2440 =item C<control>
2441
2442 adds a new name for a control character.
2443
2444 =item C<alternate>
2445
2446 is an alternate name for a character
2447
2448 =item C<figment>
2449
2450 is a name for a character that has been documented but was never in any
2451 actual standard.
2452
2453 =item C<abbreviation>
2454
2455 is a common abbreviation for a character
2456
2457 =back
2458
2459 The lists are ordered (roughly) so the most preferred names come before less
2460 preferred ones.
2461
2462 For example,
2463
2464  @aliases_ranges        @alias_maps
2465     ...
2466     0x009E        [ 'PRIVACY MESSAGE: control', 'PM: abbreviation' ]
2467     0x009F        [ 'APPLICATION PROGRAM COMMAND: control',
2468                     'APC: abbreviation'
2469                   ]
2470     0x00A0        'NBSP: abbreviation'
2471     0x00A1        ""
2472     0x00AD        'SHY: abbreviation'
2473     0x00AE        ""
2474     0x01A2        'LATIN CAPITAL LETTER GHA: correction'
2475     0x01A3        'LATIN SMALL LETTER GHA: correction'
2476     0x01A4        ""
2477     ...
2478
2479 A map to the empty string means that there is no alias defined for the code
2480 point.
2481
2482 =item B<C<a>>
2483
2484 is like C<"s"> in that all the map array elements are scalars, but here they are
2485 restricted to all being integers, and some have to be adjusted (hence the name
2486 C<"a">) to get the correct result.  For example, in:
2487
2488  my ($uppers_ranges_ref, $uppers_maps_ref, $format, $default)
2489                           = prop_invmap("Simple_Uppercase_Mapping");
2490
2491 the returned arrays look like this:
2492
2493  @$uppers_ranges_ref    @$uppers_maps_ref   Note
2494        0                      0
2495       97                     65          'a' maps to 'A', b => B ...
2496      123                      0
2497      181                    924          MICRO SIGN => Greek Cap MU
2498      182                      0
2499      ...
2500
2501 and C<$default> is 0.
2502
2503 Let's start with the second line.  It says that the uppercase of code point 97
2504 is 65; or C<uc("a")> == "A".  But the line is for the entire range of code
2505 points 97 through 122.  To get the mapping for any code point in this range,
2506 you take the offset it has from the beginning code point of the range, and add
2507 that to the mapping for that first code point.  So, the mapping for 122 ("z")
2508 is derived by taking the offset of 122 from 97 (=25) and adding that to 65,
2509 yielding 90 ("z").  Likewise for everything in between.
2510
2511 Requiring this simple adjustment allows the returned arrays to be
2512 significantly smaller than otherwise, up to a factor of 10, speeding up
2513 searching through them.
2514
2515 Ranges that map to C<$default>, C<"0">, behave somewhat differently.  For
2516 these, each code point maps to itself.  So, in the first line in the example,
2517 S<C<ord(uc(chr(0)))>> is 0, S<C<ord(uc(chr(1)))>> is 1, ..
2518 S<C<ord(uc(chr(96)))>> is 96.
2519
2520 =item B<C<al>>
2521
2522 means that some of the map array elements have the form given by C<"a">, and
2523 the rest are ordered lists of code points.
2524 For example, in:
2525
2526  my ($uppers_ranges_ref, $uppers_maps_ref, $format, $default)
2527                                  = prop_invmap("Uppercase_Mapping");
2528
2529 the returned arrays look like this:
2530
2531  @$uppers_ranges_ref    @$uppers_maps_ref
2532        0                      0
2533       97                     65
2534      123                      0
2535      181                    924
2536      182                      0
2537      ...
2538     0x0149              [ 0x02BC 0x004E ]
2539     0x014A                    0
2540     0x014B                  330
2541      ...
2542
2543 This is the full Uppercase_Mapping property (as opposed to the
2544 Simple_Uppercase_Mapping given in the example for format C<"a">).  The only
2545 difference between the two in the ranges shown is that the code point at
2546 0x0149 (LATIN SMALL LETTER N PRECEDED BY APOSTROPHE) maps to a string of two
2547 characters, 0x02BC (MODIFIER LETTER APOSTROPHE) followed by 0x004E (LATIN
2548 CAPITAL LETTER N).
2549
2550 No adjustments are needed to entries that are references to arrays; each such
2551 entry will have exactly one element in its range, so the offset is always 0.
2552
2553 The fourth (index [3]) element (C<$default>) in the list returned for this
2554 format is 0.
2555
2556 =item B<C<ae>>
2557
2558 This is like C<"a">, but some elements are the empty string, and should not be
2559 adjusted.
2560 The one internal Perl property accessible by C<prop_invmap> is of this type:
2561 "Perl_Decimal_Digit" returns an inversion map which gives the numeric values
2562 that are represented by the Unicode decimal digit characters.  Characters that
2563 don't represent decimal digits map to the empty string, like so:
2564
2565  @digits    @values
2566  0x0000       ""
2567  0x0030        0
2568  0x003A:      ""
2569  0x0660:       0
2570  0x066A:      ""
2571  0x06F0:       0
2572  0x06FA:      ""
2573  0x07C0:       0
2574  0x07CA:      ""
2575  0x0966:       0
2576  ...
2577
2578 This means that the code points from 0 to 0x2F do not represent decimal digits;
2579 the code point 0x30 (DIGIT ZERO) represents 0;  code point 0x31, (DIGIT ONE),
2580 represents 0+1-0 = 1; ... code point 0x39, (DIGIT NINE), represents 0+9-0 = 9;
2581 ... code points 0x3A through 0x65F do not represent decimal digits; 0x660
2582 (ARABIC-INDIC DIGIT ZERO), represents 0; ... 0x07C1 (NKO DIGIT ONE),
2583 represents 0+1-0 = 1 ...
2584
2585 The fourth (index [3]) element (C<$default>) in the list returned for this
2586 format is the empty string.
2587
2588 =item B<C<ale>>
2589
2590 is a combination of the C<"al"> type and the C<"ae"> type.  Some of
2591 the map array elements have the forms given by C<"al">, and
2592 the rest are the empty string.  The property C<NFKC_Casefold> has this form.
2593 An example slice is:
2594
2595  @$ranges_ref  @$maps_ref         Note
2596     ...
2597    0x00AA       97                FEMININE ORDINAL INDICATOR => 'a'
2598    0x00AB        0
2599    0x00AD                         SOFT HYPHEN => ""
2600    0x00AE        0
2601    0x00AF     [ 0x0020, 0x0304 ]  MACRON => SPACE . COMBINING MACRON
2602    0x00B0        0
2603    ...
2604
2605 The fourth (index [3]) element (C<$default>) in the list returned for this
2606 format is 0.
2607
2608 =item B<C<ar>>
2609
2610 means that all the elements of the map array are either rational numbers or
2611 the string C<"NaN">, meaning "Not a Number".  A rational number is either an
2612 integer, or two integers separated by a solidus (C<"/">).  The second integer
2613 represents the denominator of the division implied by the solidus, and is
2614 actually always positive, so it is guaranteed not to be 0 and to not be
2615 signed.  When the element is a plain integer (without the
2616 solidus), it may need to be adjusted to get the correct value by adding the
2617 offset, just as other C<"a"> properties.  No adjustment is needed for
2618 fractions, as the range is guaranteed to have just a single element, and so
2619 the offset is always 0.
2620
2621 If you want to convert the returned map to entirely scalar numbers, you
2622 can use something like this:
2623
2624  my ($invlist_ref, $invmap_ref, $format) = prop_invmap($property);
2625  if ($format && $format eq "ar") {
2626      map { $_ = eval $_ if $_ ne 'NaN' } @$map_ref;
2627  }
2628
2629 Here's some entries from the output of the property "Nv", which has format
2630 C<"ar">.
2631
2632  @numerics_ranges  @numerics_maps       Note
2633         0x00           "NaN"
2634         0x30             0           DIGIT 0 .. DIGIT 9
2635         0x3A           "NaN"
2636         0xB2             2           SUPERSCRIPTs 2 and 3
2637         0xB4           "NaN"
2638         0xB9             1           SUPERSCRIPT 1
2639         0xBA           "NaN"
2640         0xBC            1/4          VULGAR FRACTION 1/4
2641         0xBD            1/2          VULGAR FRACTION 1/2
2642         0xBE            3/4          VULGAR FRACTION 3/4
2643         0xBF           "NaN"
2644         0x660            0           ARABIC-INDIC DIGIT ZERO .. NINE
2645         0x66A          "NaN"
2646
2647 The fourth (index [3]) element (C<$default>) in the list returned for this
2648 format is C<"NaN">.
2649
2650 =item B<C<n>>
2651
2652 means the Name property.  All the elements of the map array are simple
2653 scalars, but some of them contain special strings that require more work to
2654 get the actual name.
2655
2656 Entries such as:
2657
2658  CJK UNIFIED IDEOGRAPH-<code point>
2659
2660 mean that the name for the code point is "CJK UNIFIED IDEOGRAPH-"
2661 with the code point (expressed in hexadecimal) appended to it, like "CJK
2662 UNIFIED IDEOGRAPH-3403" (similarly for S<C<CJK COMPATIBILITY IDEOGRAPH-E<lt>code
2663 pointE<gt>>>).
2664
2665 Also, entries like
2666
2667  <hangul syllable>
2668
2669 means that the name is algorithmically calculated.  This is easily done by
2670 the function L<charnames/charnames::viacode(code)>.
2671
2672 Note that for control characters (C<Gc=cc>), Unicode's data files have the
2673 string "C<E<lt>controlE<gt>>", but the real name of each of these characters is the empty
2674 string.  This function returns that real name, the empty string.  (There are
2675 names for these characters, but they are considered aliases, not the Name
2676 property name, and are contained in the C<Name_Alias> property.)
2677
2678 =item B<C<ad>>
2679
2680 means the Decomposition_Mapping property.  This property is like C<"al">
2681 properties, except that one of the scalar elements is of the form:
2682
2683  <hangul syllable>
2684
2685 This signifies that this entry should be replaced by the decompositions for
2686 all the code points whose decomposition is algorithmically calculated.  (All
2687 of them are currently in one range and no others outside the range are likely
2688 to ever be added to Unicode; the C<"n"> format
2689 has this same entry.)  These can be generated via the function
2690 L<Unicode::Normalize::NFD()|Unicode::Normalize>.
2691
2692 Note that the mapping is the one that is specified in the Unicode data files,
2693 and to get the final decomposition, it may need to be applied recursively.
2694
2695 The fourth (index [3]) element (C<$default>) in the list returned for this
2696 format is 0.
2697
2698 =back
2699
2700 Note that a format begins with the letter "a" if and only the property it is
2701 for requires adjustments by adding the offsets in multi-element ranges.  For
2702 all these properties, an entry should be adjusted only if the map is a scalar
2703 which is an integer.  That is, it must match the regular expression:
2704
2705     / ^ -? \d+ $ /xa
2706
2707 Further, the first element in a range never needs adjustment, as the
2708 adjustment would be just adding 0.
2709
2710 A binary search such as that provided by L</search_invlist()>, can be used to
2711 quickly find a code point in the inversion list, and hence its corresponding
2712 mapping.
2713
2714 The final, fourth element (index [3], assigned to C<$default> in the "block"
2715 example) in the four element list returned by this function is used with the
2716 C<"a"> format types; it may also be useful for applications
2717 that wish to convert the returned inversion map data structure into some
2718 other, such as a hash.  It gives the mapping that most code points map to
2719 under the property.  If you establish the convention that any code point not
2720 explicitly listed in your data structure maps to this value, you can
2721 potentially make your data structure much smaller.  As you construct your data
2722 structure from the one returned by this function, simply ignore those ranges
2723 that map to this value.  For example, to
2724 convert to the data structure searchable by L</charinrange()>, you can follow
2725 this recipe for properties that don't require adjustments:
2726
2727  my ($list_ref, $map_ref, $format, $default) = prop_invmap($property);
2728  my @range_list;
2729
2730  # Look at each element in the list, but the -2 is needed because we
2731  # look at $i+1 in the loop, and the final element is guaranteed to map
2732  # to $default by prop_invmap(), so we would skip it anyway.
2733  for my $i (0 .. @$list_ref - 2) {
2734     next if $map_ref->[$i] eq $default;
2735     push @range_list, [ $list_ref->[$i],
2736                         $list_ref->[$i+1],
2737                         $map_ref->[$i]
2738                       ];
2739  }
2740
2741  print charinrange(\@range_list, $code_point), "\n";
2742
2743 With this, C<charinrange()> will return C<undef> if its input code point maps
2744 to C<$default>.  You can avoid this by omitting the C<next> statement, and adding
2745 a line after the loop to handle the final element of the inversion map.
2746
2747 Similarly, this recipe can be used for properties that do require adjustments:
2748
2749  for my $i (0 .. @$list_ref - 2) {
2750     next if $map_ref->[$i] eq $default;
2751
2752     # prop_invmap() guarantees that if the mapping is to an array, the
2753     # range has just one element, so no need to worry about adjustments.
2754     if (ref $map_ref->[$i]) {
2755         push @range_list,
2756                    [ $list_ref->[$i], $list_ref->[$i], $map_ref->[$i] ];
2757     }
2758     else {  # Otherwise each element is actually mapped to a separate
2759             # value, so the range has to be split into single code point
2760             # ranges.
2761
2762         my $adjustment = 0;
2763
2764         # For each code point that gets mapped to something...
2765         for my $j ($list_ref->[$i] .. $list_ref->[$i+1] -1 ) {
2766
2767             # ... add a range consisting of just it mapping to the
2768             # original plus the adjustment, which is incremented for the
2769             # next time through the loop, as the offset increases by 1
2770             # for each element in the range
2771             push @range_list,
2772                              [ $j, $j, $map_ref->[$i] + $adjustment++ ];
2773         }
2774     }
2775  }
2776
2777 Note that the inversion maps returned for the C<Case_Folding> and
2778 C<Simple_Case_Folding> properties do not include the Turkic-locale mappings.
2779 Use L</casefold()> for these.
2780
2781 C<prop_invmap> does not know about any user-defined properties, and will
2782 return C<undef> if called with one of those.
2783
2784 =cut
2785
2786 # User-defined properties could be handled with some changes to utf8_heavy.pl;
2787 # if done, consideration should be given to the fact that the user subroutine
2788 # could return different results with each call, which could lead to some
2789 # security issues.
2790
2791 # One could store things in memory so they don't have to be recalculated, but
2792 # it is unlikely this will be called often, and some properties would take up
2793 # significant memory.
2794
2795 # These are created by mktables for this routine and stored in unicore/UCD.pl
2796 # where their structures are described.
2797 our @algorithmic_named_code_points;
2798 our $HANGUL_BEGIN;
2799 our $HANGUL_COUNT;
2800
2801 sub prop_invmap ($) {
2802
2803     croak __PACKAGE__, "::prop_invmap: must be called in list context" unless wantarray;
2804
2805     my $prop = $_[0];
2806     return unless defined $prop;
2807
2808     # Fail internal properties
2809     return if $prop =~ /^_/;
2810
2811     # The values returned by this function.
2812     my (@invlist, @invmap, $format, $missing);
2813
2814     # The swash has two components we look at, the base list, and a hash,
2815     # named 'SPECIALS', containing any additional members whose mappings don't
2816     # fit into the base list scheme of things.  These generally 'override'
2817     # any value in the base list for the same code point.
2818     my $overrides;
2819
2820     require "utf8_heavy.pl";
2821     require "unicore/UCD.pl";
2822
2823 RETRY:
2824
2825     # If there are multiple entries for a single code point
2826     my $has_multiples = 0;
2827
2828     # Try to get the map swash for the property.  They have 'To' prepended to
2829     # the property name, and 32 means we will accept 32 bit return values.
2830     # The 0 means we aren't calling this from tr///.
2831     my $swash = utf8::SWASHNEW(__PACKAGE__, "To$prop", undef, 32, 0);
2832
2833     # If didn't find it, could be because needs a proxy.  And if was the
2834     # 'Block' or 'Name' property, use a proxy even if did find it.  Finding it
2835     # in these cases would be the result of the installation changing mktables
2836     # to output the Block or Name tables.  The Block table gives block names
2837     # in the new-style, and this routine is supposed to return old-style block
2838     # names.  The Name table is valid, but we need to execute the special code
2839     # below to add in the algorithmic-defined name entries.
2840     # And NFKCCF needs conversion, so handle that here too.
2841     if (ref $swash eq ""
2842         || $swash->{'TYPE'} =~ / ^ To (?: Blk | Na | NFKCCF ) $ /x)
2843     {
2844
2845         # Get the short name of the input property, in standard form
2846         my ($second_try) = prop_aliases($prop);
2847         return unless $second_try;
2848         $second_try = utf8::_loose_name(lc $second_try);
2849
2850         if ($second_try eq "in") {
2851
2852             # This property is identical to age for inversion map purposes
2853             $prop = "age";
2854             goto RETRY;
2855         }
2856         elsif ($second_try =~ / ^ s ( cf | fc | [ltu] c ) $ /x) {
2857
2858             # These properties use just the LIST part of the full mapping,
2859             # which includes the simple maps that are otherwise overridden by
2860             # the SPECIALS.  So all we need do is to not look at the SPECIALS;
2861             # set $overrides to indicate that
2862             $overrides = -1;
2863
2864             # The full name is the simple name stripped of its initial 's'
2865             $prop = $1;
2866
2867             # .. except for this case
2868             $prop = 'cf' if $prop eq 'fc';
2869
2870             goto RETRY;
2871         }
2872         elsif ($second_try eq "blk") {
2873
2874             # We use the old block names.  Just create a fake swash from its
2875             # data.
2876             _charblocks();
2877             my %blocks;
2878             $blocks{'LIST'} = "";
2879             $blocks{'TYPE'} = "ToBlk";
2880             $utf8::SwashInfo{ToBlk}{'missing'} = "No_Block";
2881             $utf8::SwashInfo{ToBlk}{'format'} = "s";
2882
2883             foreach my $block (@BLOCKS) {
2884                 $blocks{'LIST'} .= sprintf "%x\t%x\t%s\n",
2885                                            $block->[0],
2886                                            $block->[1],
2887                                            $block->[2];
2888             }
2889             $swash = \%blocks;
2890         }
2891         elsif ($second_try eq "na") {
2892
2893             # Use the combo file that has all the Name-type properties in it,
2894             # extracting just the ones that are for the actual 'Name'
2895             # property.  And create a fake swash from it.
2896             my %names;
2897             $names{'LIST'} = "";
2898             my $original = do "unicore/Name.pl";
2899             my $algorithm_names = \@algorithmic_named_code_points;
2900
2901             # We need to remove the names from it that are aliases.  For that
2902             # we need to also read in that table.  Create a hash with the keys
2903             # being the code points, and the values being a list of the
2904             # aliases for the code point key.
2905             my ($aliases_code_points, $aliases_maps, undef, undef) =
2906                                                 &prop_invmap('Name_Alias');
2907             my %aliases;
2908             for (my $i = 0; $i < @$aliases_code_points; $i++) {
2909                 my $code_point = $aliases_code_points->[$i];
2910                 $aliases{$code_point} = $aliases_maps->[$i];
2911
2912                 # If not already a list, make it into one, so that later we
2913                 # can treat things uniformly
2914                 if (! ref $aliases{$code_point}) {
2915                     $aliases{$code_point} = [ $aliases{$code_point} ];
2916                 }
2917
2918                 # Remove the alias type from the entry, retaining just the
2919                 # name.
2920                 map { s/:.*// } @{$aliases{$code_point}};
2921             }
2922
2923             my $i = 0;
2924             foreach my $line (split "\n", $original) {
2925                 my ($hex_code_point, $name) = split "\t", $line;
2926
2927                 # Weeds out all comments, blank lines, and named sequences
2928                 next if $hex_code_point =~ /[^[:xdigit:]]/a;
2929
2930                 my $code_point = hex $hex_code_point;
2931
2932                 # The name of all controls is the default: the empty string.
2933                 # The set of controls is immutable
2934                 next if chr($code_point) =~ /[[:cntrl:]]/u;
2935
2936                 # If this is a name_alias, it isn't a name
2937                 next if grep { $_ eq $name } @{$aliases{$code_point}};
2938
2939                 # If we are beyond where one of the special lines needs to
2940                 # be inserted ...
2941                 while ($i < @$algorithm_names
2942                     && $code_point > $algorithm_names->[$i]->{'low'})
2943                 {
2944
2945                     # ... then insert it, ahead of what we were about to
2946                     # output
2947                     $names{'LIST'} .= sprintf "%x\t%x\t%s\n",
2948                                             $algorithm_names->[$i]->{'low'},
2949                                             $algorithm_names->[$i]->{'high'},
2950                                             $algorithm_names->[$i]->{'name'};
2951
2952                     # Done with this range.
2953                     $i++;
2954
2955                     # We loop until all special lines that precede the next
2956                     # regular one are output.
2957                 }
2958
2959                 # Here, is a normal name.
2960                 $names{'LIST'} .= sprintf "%x\t\t%s\n", $code_point, $name;
2961             } # End of loop through all the names
2962
2963             $names{'TYPE'} = "ToNa";
2964             $utf8::SwashInfo{ToNa}{'missing'} = "";
2965             $utf8::SwashInfo{ToNa}{'format'} = "n";
2966             $swash = \%names;
2967         }
2968         elsif ($second_try =~ / ^ ( d [mt] ) $ /x) {
2969
2970             # The file is a combination of dt and dm properties.  Create a
2971             # fake swash from the portion that we want.
2972             my $original = do "unicore/Decomposition.pl";
2973             my %decomps;
2974
2975             if ($second_try eq 'dt') {
2976                 $decomps{'TYPE'} = "ToDt";
2977                 $utf8::SwashInfo{'ToDt'}{'missing'} = "None";
2978                 $utf8::SwashInfo{'ToDt'}{'format'} = "s";
2979             }   # 'dm' is handled below, with 'nfkccf'
2980
2981             $decomps{'LIST'} = "";
2982
2983             # This property has one special range not in the file: for the
2984             # hangul syllables.  But not in Unicode version 1.
2985             UnicodeVersion() unless defined $v_unicode_version;
2986             my $done_hangul = ($v_unicode_version lt v2.0.0)
2987                               ? 1
2988                               : 0;    # Have we done the hangul range ?
2989             foreach my $line (split "\n", $original) {
2990                 my ($hex_lower, $hex_upper, $type_and_map) = split "\t", $line;
2991                 my $code_point = hex $hex_lower;
2992                 my $value;
2993                 my $redo = 0;
2994
2995                 # The type, enclosed in <...>, precedes the mapping separated
2996                 # by blanks
2997                 if ($type_and_map =~ / ^ < ( .* ) > \s+ (.*) $ /x) {
2998                     $value = ($second_try eq 'dt') ? $1 : $2
2999                 }
3000                 else {  # If there is no type specified, it's canonical
3001                     $value = ($second_try eq 'dt')
3002                              ? "Canonical" :
3003                              $type_and_map;
3004                 }
3005
3006                 # Insert the hangul range at the appropriate spot.
3007                 if (! $done_hangul && $code_point > $HANGUL_BEGIN) {
3008                     $done_hangul = 1;
3009                     $decomps{'LIST'} .=
3010                                 sprintf "%x\t%x\t%s\n",
3011                                         $HANGUL_BEGIN,
3012                                         $HANGUL_BEGIN + $HANGUL_COUNT - 1,
3013                                         ($second_try eq 'dt')
3014                                         ? "Canonical"
3015                                         : "<hangul syllable>";
3016                 }
3017
3018                 if ($value =~ / / && $hex_upper ne "" && $hex_upper ne $hex_lower) {
3019                     $line = sprintf("%04X\t%s\t%s", hex($hex_lower) + 1, $hex_upper, $value);
3020                     $hex_upper = "";
3021                     $redo = 1;
3022                 }
3023
3024                 # And append this to our constructed LIST.
3025                 $decomps{'LIST'} .= "$hex_lower\t$hex_upper\t$value\n";
3026
3027                 redo if $redo;
3028             }
3029             $swash = \%decomps;
3030         }
3031         elsif ($second_try ne 'nfkccf') { # Don't know this property. Fail.
3032             return;
3033         }
3034
3035         if ($second_try eq 'nfkccf' || $second_try eq 'dm') {
3036
3037             # The 'nfkccf' property is stored in the old format for backwards
3038             # compatibility for any applications that has read its file
3039             # directly before prop_invmap() existed.
3040             # And the code above has extracted the 'dm' property from its file
3041             # yielding the same format.  So here we convert them to adjusted
3042             # format for compatibility with the other properties similar to
3043             # them.
3044             my %revised_swash;
3045
3046             # We construct a new converted list.
3047             my $list = "";
3048
3049             my @ranges = split "\n", $swash->{'LIST'};
3050             for (my $i = 0; $i < @ranges; $i++) {
3051                 my ($hex_begin, $hex_end, $map) = split "\t", $ranges[$i];
3052
3053                 # The dm property has maps that are space separated sequences
3054                 # of code points, as well as the special entry "<hangul
3055                 # syllable>, which also contains a blank.
3056                 my @map = split " ", $map;
3057                 if (@map > 1) {
3058
3059                     # If it's just the special entry, append as-is.
3060                     if ($map eq '<hangul syllable>') {
3061                         $list .= "$ranges[$i]\n";
3062                     }
3063                     else {
3064
3065                         # These should all be single-element ranges.
3066                         croak __PACKAGE__, "::prop_invmap: Not expecting a mapping with multiple code points in a multi-element range, $ranges[$i]" if $hex_end ne "" && $hex_end ne $hex_begin;
3067
3068                         # Convert them to decimal, as that's what's expected.
3069                         $list .= "$hex_begin\t\t"
3070                             . join(" ", map { hex } @map)
3071                             . "\n";
3072                     }
3073                     next;
3074                 }
3075
3076                 # Here, the mapping doesn't have a blank, is for a single code
3077                 # point.
3078                 my $begin = hex $hex_begin;
3079                 my $end = (defined $hex_end && $hex_end ne "")
3080                         ? hex $hex_end
3081                         : $begin;
3082
3083                 # Again, the output is to be in decimal.
3084                 my $decimal_map = hex $map;
3085
3086                 # We know that multi-element ranges with the same mapping
3087                 # should not be adjusted, as after the adjustment
3088                 # multi-element ranges are for consecutive increasing code
3089                 # points.  Further, the final element in the list won't be
3090                 # adjusted, as there is nothing after it to include in the
3091                 # adjustment
3092                 if ($begin != $end || $i == @ranges -1) {
3093
3094                     # So just convert these to single-element ranges
3095                     foreach my $code_point ($begin .. $end) {
3096                         $list .= sprintf("%04X\t\t%d\n",
3097                                         $code_point, $decimal_map);
3098                     }
3099                 }
3100                 else {
3101
3102                     # Here, we have a candidate for adjusting.  What we do is
3103                     # look through the subsequent adjacent elements in the
3104                     # input.  If the map to the next one differs by 1 from the
3105                     # one before, then we combine into a larger range with the
3106                     # initial map.  Loop doing this until we find one that
3107                     # can't be combined.
3108
3109                     my $offset = 0;     # How far away are we from the initial
3110                                         # map
3111                     my $squished = 0;   # ? Did we squish at least two
3112                                         # elements together into one range
3113                     for ( ; $i < @ranges; $i++) {
3114                         my ($next_hex_begin, $next_hex_end, $next_map)
3115                                                 = split "\t", $ranges[$i+1];
3116
3117                         # In the case of 'dm', the map may be a sequence of
3118                         # multiple code points, which are never combined with
3119                         # another range
3120                         last if $next_map =~ / /;
3121
3122                         $offset++;
3123                         my $next_decimal_map = hex $next_map;
3124
3125                         # If the next map is not next in sequence, it
3126                         # shouldn't be combined.
3127                         last if $next_decimal_map != $decimal_map + $offset;
3128
3129                         my $next_begin = hex $next_hex_begin;
3130
3131                         # Likewise, if the next element isn't adjacent to the
3132                         # previous one, it shouldn't be combined.
3133                         last if $next_begin != $begin + $offset;
3134
3135                         my $next_end = (defined $next_hex_end
3136                                         && $next_hex_end ne "")
3137                                             ? hex $next_hex_end
3138                                             : $next_begin;
3139
3140                         # And finally, if the next element is a multi-element
3141                         # range, it shouldn't be combined.
3142                         last if $next_end != $next_begin;
3143
3144                         # Here, we will combine.  Loop to see if we should
3145                         # combine the next element too.
3146                         $squished = 1;
3147                     }
3148
3149                     if ($squished) {
3150
3151                         # Here, 'i' is the element number of the last element to
3152                         # be combined, and the range is single-element, or we
3153                         # wouldn't be combining.  Get it's code point.
3154                         my ($hex_end, undef, undef) = split "\t", $ranges[$i];
3155                         $list .= "$hex_begin\t$hex_end\t$decimal_map\n";
3156                     } else {
3157
3158                         # Here, no combining done.  Just append the initial
3159                         # (and current) values.
3160                         $list .= "$hex_begin\t\t$decimal_map\n";
3161                     }
3162                 }
3163             } # End of loop constructing the converted list
3164
3165             # Finish up the data structure for our converted swash
3166             my $type = ($second_try eq 'nfkccf') ? 'ToNFKCCF' : 'ToDm';
3167             $revised_swash{'LIST'} = $list;
3168             $revised_swash{'TYPE'} = $type;
3169             $revised_swash{'SPECIALS'} = $swash->{'SPECIALS'};
3170             $swash = \%revised_swash;
3171
3172             $utf8::SwashInfo{$type}{'missing'} = 0;
3173             $utf8::SwashInfo{$type}{'format'} = 'a';
3174         }
3175     }
3176
3177     if ($swash->{'EXTRAS'}) {
3178         carp __PACKAGE__, "::prop_invmap: swash returned for $prop unexpectedly has EXTRAS magic";
3179         return;
3180     }
3181
3182     # Here, have a valid swash return.  Examine it.
3183     my $returned_prop = $swash->{'TYPE'};
3184
3185     # All properties but binary ones should have 'missing' and 'format'
3186     # entries
3187     $missing = $utf8::SwashInfo{$returned_prop}{'missing'};
3188     $missing = 'N' unless defined $missing;
3189
3190     $format = $utf8::SwashInfo{$returned_prop}{'format'};
3191     $format = 'b' unless defined $format;
3192
3193     my $requires_adjustment = $format =~ /^a/;
3194
3195     if ($swash->{'LIST'} =~ /^V/) {
3196         @invlist = split "\n", $swash->{'LIST'} =~ s/ \s* (?: \# .* )? $ //xmgr;
3197         shift @invlist;
3198         foreach my $i (0 .. @invlist - 1) {
3199             $invmap[$i] = ($i % 2 == 0) ? 'Y' : 'N'
3200         }
3201
3202         # The map includes lines for all code points; add one for the range
3203         # from 0 to the first Y.
3204         if ($invlist[0] != 0) {
3205             unshift @invlist, 0;
3206             unshift @invmap, 'N';
3207         }
3208     }
3209     else {
3210         # The LIST input lines look like:
3211         # ...
3212         # 0374\t\tCommon
3213         # 0375\t0377\tGreek   # [3]
3214         # 037A\t037D\tGreek   # [4]
3215         # 037E\t\tCommon
3216         # 0384\t\tGreek
3217         # ...
3218         #
3219         # Convert them to like
3220         # 0374 => Common
3221         # 0375 => Greek
3222         # 0378 => $missing
3223         # 037A => Greek
3224         # 037E => Common
3225         # 037F => $missing
3226         # 0384 => Greek
3227         #
3228         # For binary properties, the final non-comment column is absent, and
3229         # assumed to be 'Y'.
3230
3231         foreach my $range (split "\n", $swash->{'LIST'}) {
3232             $range =~ s/ \s* (?: \# .* )? $ //xg; # rmv trailing space, comments
3233
3234             # Find the beginning and end of the range on the line
3235             my ($hex_begin, $hex_end, $map) = split "\t", $range;
3236             my $begin = hex $hex_begin;
3237             no warnings 'portable';
3238             my $end = (defined $hex_end && $hex_end ne "")
3239                     ? hex $hex_end
3240                     : $begin;
3241
3242             # Each time through the loop (after the first):
3243             # $invlist[-2] contains the beginning of the previous range processed
3244             # $invlist[-1] contains the end+1 of the previous range processed
3245             # $invmap[-2] contains the value of the previous range processed
3246             # $invmap[-1] contains the default value for missing ranges
3247             #                                                       ($missing)
3248             #
3249             # Thus, things are set up for the typical case of a new
3250             # non-adjacent range of non-missings to be added.  But, if the new
3251             # range is adjacent, it needs to replace the [-1] element; and if
3252             # the new range is a multiple value of the previous one, it needs
3253             # to be added to the [-2] map element.
3254
3255             # The first time through, everything will be empty.  If the
3256             # property doesn't have a range that begins at 0, add one that
3257             # maps to $missing
3258             if (! @invlist) {
3259                 if ($begin != 0) {
3260                     push @invlist, 0;
3261                     push @invmap, $missing;
3262                 }
3263             }
3264             elsif (@invlist > 1 && $invlist[-2] == $begin) {
3265
3266                 # Here we handle the case where the input has multiple entries
3267                 # for each code point.  mktables should have made sure that
3268                 # each such range contains only one code point.  At this
3269                 # point, $invlist[-1] is the $missing that was added at the
3270                 # end of the last loop iteration, and [-2] is the last real
3271                 # input code point, and that code point is the same as the one
3272                 # we are adding now, making the new one a multiple entry.  Add
3273                 # it to the existing entry, either by pushing it to the
3274                 # existing list of multiple entries, or converting the single
3275                 # current entry into a list with both on it.  This is all we
3276                 # need do for this iteration.
3277
3278                 if ($end != $begin) {
3279                     croak __PACKAGE__, ":prop_invmap: Multiple maps per code point in '$prop' require single-element ranges: begin=$begin, end=$end, map=$map";
3280                 }
3281                 if (! ref $invmap[-2]) {
3282                     $invmap[-2] = [ $invmap[-2], $map ];
3283                 }
3284                 else {
3285                     push @{$invmap[-2]}, $map;
3286                 }
3287                 $has_multiples = 1;
3288                 next;
3289             }
3290             elsif ($invlist[-1] == $begin) {
3291
3292                 # If the input isn't in the most compact form, so that there
3293                 # are two adjacent ranges that map to the same thing, they
3294                 # should be combined (EXCEPT where the arrays require
3295                 # adjustments, in which case everything is already set up
3296                 # correctly).  This happens in our constructed dt mapping, as
3297                 # Element [-2] is the map for the latest range so far
3298                 # processed.  Just set the beginning point of the map to
3299                 # $missing (in invlist[-1]) to 1 beyond where this range ends.
3300                 # For example, in
3301                 # 12\t13\tXYZ
3302                 # 14\t17\tXYZ
3303                 # we have set it up so that it looks like
3304                 # 12 => XYZ
3305                 # 14 => $missing
3306                 #
3307                 # We now see that it should be
3308                 # 12 => XYZ
3309                 # 18 => $missing
3310                 if (! $requires_adjustment && @invlist > 1 && ( (defined $map)
3311                                     ? $invmap[-2] eq $map
3312                                     : $invmap[-2] eq 'Y'))
3313                 {
3314                     $invlist[-1] = $end + 1;
3315                     next;
3316                 }
3317
3318                 # Here, the range started in the previous iteration that maps
3319                 # to $missing starts at the same code point as this range.
3320                 # That means there is no gap to fill that that range was
3321                 # intended for, so we just pop it off the parallel arrays.
3322                 pop @invlist;
3323                 pop @invmap;
3324             }
3325
3326             # Add the range beginning, and the range's map.
3327             push @invlist, $begin;
3328             if ($returned_prop eq 'ToDm') {
3329
3330                 # The decomposition maps are either a line like <hangul
3331                 # syllable> which are to be taken as is; or a sequence of code
3332                 # points in hex and separated by blanks.  Convert them to
3333                 # decimal, and if there is more than one, use an anonymous
3334                 # array as the map.
3335                 if ($map =~ /^ < /x) {
3336                     push @invmap, $map;
3337                 }
3338                 else {
3339                     my @map = split " ", $map;
3340                     if (@map == 1) {
3341                         push @invmap, $map[0];
3342                     }
3343                     else {
3344                         push @invmap, \@map;
3345                     }
3346                 }
3347             }
3348             else {
3349
3350                 # Otherwise, convert hex formatted list entries to decimal;
3351                 # add a 'Y' map for the missing value in binary properties, or
3352                 # otherwise, use the input map unchanged.
3353                 $map = ($format eq 'x' || $format eq 'ax')
3354                     ? hex $map
3355                     : $format eq 'b'
3356                     ? 'Y'
3357                     : $map;
3358                 push @invmap, $map;
3359             }
3360
3361             # We just started a range.  It ends with $end.  The gap between it
3362             # and the next element in the list must be filled with a range
3363             # that maps to the default value.  If there is no gap, the next
3364             # iteration will pop this, unless there is no next iteration, and
3365             # we have filled all of the Unicode code space, so check for that
3366             # and skip.
3367             if ($end < $Unicode::UCD::MAX_CP) {
3368                 push @invlist, $end + 1;
3369                 push @invmap, $missing;
3370             }
3371         }
3372     }
3373
3374     # If the property is empty, make all code points use the value for missing
3375     # ones.
3376     if (! @invlist) {
3377         push @invlist, 0;
3378         push @invmap, $missing;
3379     }
3380
3381     # The final element is always for just the above-Unicode code points.  If
3382     # not already there, add it.  It merely splits the current final range
3383     # that extends to infinity into two elements, each with the same map.
3384     # (This is to conform with the API that says the final element is for
3385     # $MAX_UNICODE_CODEPOINT + 1 .. INFINITY.)
3386     if ($invlist[-1] != $MAX_UNICODE_CODEPOINT + 1) {
3387         push @invmap, $invmap[-1];
3388         push @invlist, $MAX_UNICODE_CODEPOINT + 1;
3389     }
3390
3391     # The second component of the map are those values that require
3392     # non-standard specification, stored in SPECIALS.  These override any
3393     # duplicate code points in LIST.  If we are using a proxy, we may have
3394     # already set $overrides based on the proxy.
3395     $overrides = $swash->{'SPECIALS'} unless defined $overrides;
3396     if ($overrides) {
3397
3398         # A negative $overrides implies that the SPECIALS should be ignored,
3399         # and a simple 'a' list is the value.
3400         if ($overrides < 0) {
3401             $format = 'a';
3402         }
3403         else {
3404
3405             # Currently, all overrides are for properties that normally map to
3406             # single code points, but now some will map to lists of code
3407             # points (but there is an exception case handled below).
3408             $format = 'al';
3409
3410             # Look through the overrides.
3411             foreach my $cp_maybe_utf8 (keys %$overrides) {
3412                 my $cp;
3413                 my @map;
3414
3415                 # If the overrides came from SPECIALS, the code point keys are
3416                 # packed UTF-8.
3417                 if ($overrides == $swash->{'SPECIALS'}) {
3418                     $cp = unpack("C0U", $cp_maybe_utf8);
3419                     @map = unpack "U0U*", $swash->{'SPECIALS'}{$cp_maybe_utf8};
3420
3421                     # The empty string will show up unpacked as an empty
3422                     # array.
3423                     $format = 'ale' if @map == 0;
3424                 }
3425                 else {
3426
3427                     # But if we generated the overrides, we didn't bother to
3428                     # pack them, and we, so far, do this only for properties
3429                     # that are 'a' ones.
3430                     $cp = $cp_maybe_utf8;
3431                     @map = hex $overrides->{$cp};
3432                     $format = 'a';
3433                 }
3434
3435                 # Find the range that the override applies to.
3436                 my $i = search_invlist(\@invlist, $cp);
3437                 if ($cp < $invlist[$i] || $cp >= $invlist[$i + 1]) {
3438                     croak __PACKAGE__, "::prop_invmap: wrong_range, cp=$cp; i=$i, current=$invlist[$i]; next=$invlist[$i + 1]"
3439                 }
3440
3441                 # And what that range currently maps to
3442                 my $cur_map = $invmap[$i];
3443
3444                 # If there is a gap between the next range and the code point
3445                 # we are overriding, we have to add elements to both arrays to
3446                 # fill that gap, using the map that applies to it, which is
3447                 # $cur_map, since it is part of the current range.
3448                 if ($invlist[$i + 1] > $cp + 1) {
3449                     #use feature 'say';
3450                     #say "Before splice:";
3451                     #say 'i-2=[', $i-2, ']', sprintf("%04X maps to %s", $invlist[$i-2], $invmap[$i-2]) if $i >= 2;
3452                     #say 'i-1=[', $i-1, ']', sprintf("%04X maps to %s", $invlist[$i-1], $invmap[$i-1]) if $i >= 1;
3453                     #say 'i  =[', $i, ']', sprintf("%04X maps to %s", $invlist[$i], $invmap[$i]);
3454                     #say 'i+1=[', $i+1, ']', sprintf("%04X maps to %s", $invlist[$i+1], $invmap[$i+1]) if $i < @invlist + 1;
3455                     #say 'i+2=[', $i+2, ']', sprintf("%04X maps to %s", $invlist[$i+2], $invmap[$i+2]) if $i < @invlist + 2;
3456
3457                     splice @invlist, $i + 1, 0, $cp + 1;
3458                     splice @invmap, $i + 1, 0, $cur_map;
3459
3460                     #say "After splice:";
3461                     #say 'i-2=[', $i-2, ']', sprintf("%04X maps to %s", $invlist[$i-2], $invmap[$i-2]) if $i >= 2;
3462                     #say 'i-1=[', $i-1, ']', sprintf("%04X maps to %s", $invlist[$i-1], $invmap[$i-1]) if $i >= 1;
3463                     #say 'i  =[', $i, ']', sprintf("%04X maps to %s", $invlist[$i], $invmap[$i]);
3464                     #say 'i+1=[', $i+1, ']', sprintf("%04X maps to %s", $invlist[$i+1], $invmap[$i+1]) if $i < @invlist + 1;
3465                     #say 'i+2=[', $i+2, ']', sprintf("%04X maps to %s", $invlist[$i+2], $invmap[$i+2]) if $i < @invlist + 2;
3466                 }
3467
3468                 # If the remaining portion of the range is multiple code
3469                 # points (ending with the one we are replacing, guaranteed by
3470                 # the earlier splice).  We must split it into two
3471                 if ($invlist[$i] < $cp) {
3472                     $i++;   # Compensate for the new element
3473
3474                     #use feature 'say';
3475                     #say "Before splice:";
3476                     #say 'i-2=[', $i-2, ']', sprintf("%04X maps to %s", $invlist[$i-2], $invmap[$i-2]) if $i >= 2;
3477                     #say 'i-1=[', $i-1, ']', sprintf("%04X maps to %s", $invlist[$i-1], $invmap[$i-1]) if $i >= 1;
3478                     #say 'i  =[', $i, ']', sprintf("%04X maps to %s", $invlist[$i], $invmap[$i]);
3479                     #say 'i+1=[', $i+1, ']', sprintf("%04X maps to %s", $invlist[$i+1], $invmap[$i+1]) if $i < @invlist + 1;
3480                     #say 'i+2=[', $i+2, ']', sprintf("%04X maps to %s", $invlist[$i+2], $invmap[$i+2]) if $i < @invlist + 2;
3481
3482                     splice @invlist, $i, 0, $cp;
3483                     splice @invmap, $i, 0, 'dummy';
3484
3485                     #say "After splice:";
3486                     #say 'i-2=[', $i-2, ']', sprintf("%04X maps to %s", $invlist[$i-2], $invmap[$i-2]) if $i >= 2;
3487                     #say 'i-1=[', $i-1, ']', sprintf("%04X maps to %s", $invlist[$i-1], $invmap[$i-1]) if $i >= 1;
3488                     #say 'i  =[', $i, ']', sprintf("%04X maps to %s", $invlist[$i], $invmap[$i]);
3489                     #say 'i+1=[', $i+1, ']', sprintf("%04X maps to %s", $invlist[$i+1], $invmap[$i+1]) if $i < @invlist + 1;
3490                     #say 'i+2=[', $i+2, ']', sprintf("%04X maps to %s", $invlist[$i+2], $invmap[$i+2]) if $i < @invlist + 2;
3491                 }
3492
3493                 # Here, the range we are overriding contains a single code
3494                 # point.  The result could be the empty string, a single
3495                 # value, or a list.  If the last case, we use an anonymous
3496                 # array.
3497                 $invmap[$i] = (scalar @map == 0)
3498                                ? ""
3499                                : (scalar @map > 1)
3500                                   ? \@map
3501                                   : $map[0];
3502             }
3503         }
3504     }
3505     elsif ($format eq 'x') {
3506
3507         # All hex-valued properties are really to code points, and have been
3508         # converted to decimal.
3509         $format = 's';
3510     }
3511     elsif ($returned_prop eq 'ToDm') {
3512         $format = 'ad';
3513     }
3514     elsif ($format eq 'sw') { # blank-separated elements to form a list.
3515         map { $_ = [ split " ", $_  ] if $_ =~ / / } @invmap;
3516         $format = 'sl';
3517     }
3518     elsif ($returned_prop eq 'ToNameAlias') {
3519
3520         # This property currently doesn't have any lists, but theoretically
3521         # could
3522         $format = 'sl';
3523     }
3524     elsif ($returned_prop eq 'ToPerlDecimalDigit') {
3525         $format = 'ae';
3526     }
3527     elsif ($returned_prop eq 'ToNv') {
3528
3529         # The one property that has this format is stored as a delta, so needs
3530         # to indicate that need to add code point to it.
3531         $format = 'ar';
3532     }
3533     elsif ($format ne 'n' && $format ne 'a') {
3534
3535         # All others are simple scalars
3536         $format = 's';
3537     }
3538     if ($has_multiples &&  $format !~ /l/) {
3539         croak __PACKAGE__, "::prop_invmap: Wrong format '$format' for prop_invmap('$prop'); should indicate has lists";
3540     }
3541
3542     return (\@invlist, \@invmap, $format, $missing);
3543 }
3544
3545 sub search_invlist {
3546
3547 =pod
3548
3549 =head2 B<search_invlist()>
3550
3551  use Unicode::UCD qw(prop_invmap prop_invlist);
3552  use Unicode::UCD 'search_invlist';
3553
3554  my @invlist = prop_invlist($property_name);
3555  print $code_point, ((search_invlist(\@invlist, $code_point) // -1) % 2)
3556                      ? " isn't"
3557                      : " is",
3558      " in $property_name\n";
3559
3560  my ($blocks_ranges_ref, $blocks_map_ref) = prop_invmap("Block");
3561  my $index = search_invlist($blocks_ranges_ref, $code_point);
3562  print "$code_point is in block ", $blocks_map_ref->[$index], "\n";
3563
3564 C<search_invlist> is used to search an inversion list returned by
3565 C<prop_invlist> or C<prop_invmap> for a particular L</code point argument>.
3566 C<undef> is returned if the code point is not found in the inversion list
3567 (this happens only when it is not a legal L<code point argument>, or is less
3568 than the list's first element).  A warning is raised in the first instance.
3569
3570 Otherwise, it returns the index into the list of the range that contains the
3571 code point.; that is, find C<i> such that
3572
3573     list[i]<= code_point < list[i+1].
3574
3575 As explained in L</prop_invlist()>, whether a code point is in the list or not
3576 depends on if the index is even (in) or odd (not in).  And as explained in
3577 L</prop_invmap()>, the index is used with the returned parallel array to find
3578 the mapping.
3579
3580 =cut
3581
3582
3583     my $list_ref = shift;
3584     my $input_code_point = shift;
3585     my $code_point = _getcode($input_code_point);
3586
3587     if (! defined $code_point) {
3588         carp __PACKAGE__, "::search_invlist: unknown code '$input_code_point'";
3589         return;
3590     }
3591
3592     my $max_element = @$list_ref - 1;
3593
3594     # Return undef if list is empty or requested item is before the first element.
3595     return if $max_element < 0;
3596     return if $code_point < $list_ref->[0];
3597
3598     # Short cut something at the far-end of the table.  This also allows us to
3599     # refer to element [$i+1] without fear of being out-of-bounds in the loop
3600     # below.
3601     return $max_element if $code_point >= $list_ref->[$max_element];
3602
3603     use integer;        # want integer division
3604
3605     my $i = $max_element / 2;
3606
3607     my $lower = 0;
3608     my $upper = $max_element;
3609     while (1) {
3610
3611         if ($code_point >= $list_ref->[$i]) {
3612
3613             # Here we have met the lower constraint.  We can quit if we
3614             # also meet the upper one.
3615             last if $code_point < $list_ref->[$i+1];
3616
3617             $lower = $i;        # Still too low.
3618
3619         }
3620         else {
3621
3622             # Here, $code_point < $list_ref[$i], so look lower down.
3623             $upper = $i;
3624         }
3625
3626         # Split search domain in half to try again.
3627         my $temp = ($upper + $lower) / 2;
3628
3629         # No point in continuing unless $i changes for next time
3630         # in the loop.
3631         return $i if $temp == $i;
3632         $i = $temp;
3633     } # End of while loop
3634
3635     # Here we have found the offset
3636     return $i;
3637 }
3638
3639 =head2 Unicode::UCD::UnicodeVersion
3640
3641 This returns the version of the Unicode Character Database, in other words, the
3642 version of the Unicode standard the database implements.  The version is a
3643 string of numbers delimited by dots (C<'.'>).
3644
3645 =cut
3646
3647 my $UNICODEVERSION;
3648
3649 sub UnicodeVersion {
3650     unless (defined $UNICODEVERSION) {
3651         openunicode(\$VERSIONFH, "version");
3652         local $/ = "\n";
3653         chomp($UNICODEVERSION = <$VERSIONFH>);
3654         close($VERSIONFH);
3655         croak __PACKAGE__, "::VERSION: strange version '$UNICODEVERSION'"
3656             unless $UNICODEVERSION =~ /^\d+(?:\.\d+)+$/;
3657     }
3658     $v_unicode_version = pack "C*", split /\./, $UNICODEVERSION;
3659     return $UNICODEVERSION;
3660 }
3661
3662 =head2 B<Blocks versus Scripts>
3663
3664 The difference between a block and a script is that scripts are closer
3665 to the linguistic notion of a set of code points required to present
3666 languages, while block is more of an artifact of the Unicode code point
3667 numbering and separation into blocks of consecutive code points (so far the
3668 size of a block is some multiple of 16, like 128 or 256).
3669
3670 For example the Latin B<script> is spread over several B<blocks>, such
3671 as C<Basic Latin>, C<Latin 1 Supplement>, C<Latin Extended-A>, and
3672 C<Latin Extended-B>.  On the other hand, the Latin script does not
3673 contain all the characters of the C<Basic Latin> block (also known as
3674 ASCII): it includes only the letters, and not, for example, the digits
3675 or the punctuation.
3676
3677 For blocks see L<http://www.unicode.org/Public/UNIDATA/Blocks.txt>
3678
3679 For scripts see UTR #24: L<http://www.unicode.org/unicode/reports/tr24/>
3680
3681 =head2 B<Matching Scripts and Blocks>
3682
3683 Scripts are matched with the regular-expression construct
3684 C<\p{...}> (e.g. C<\p{Tibetan}> matches characters of the Tibetan script),
3685 while C<\p{Blk=...}> is used for blocks (e.g. C<\p{Blk=Tibetan}> matches
3686 any of the 256 code points in the Tibetan block).
3687
3688 =head2 Old-style versus new-style block names
3689
3690 Unicode publishes the names of blocks in two different styles, though the two
3691 are equivalent under Unicode's loose matching rules.
3692
3693 The original style uses blanks and hyphens in the block names (except for
3694 C<No_Block>), like so:
3695
3696  Miscellaneous Mathematical Symbols-B
3697
3698 The newer style replaces these with underscores, like this:
3699
3700  Miscellaneous_Mathematical_Symbols_B
3701
3702 This newer style is consistent with the values of other Unicode properties.
3703 To preserve backward compatibility, all the functions in Unicode::UCD that
3704 return block names (except one) return the old-style ones.  That one function,
3705 L</prop_value_aliases()> can be used to convert from old-style to new-style:
3706
3707  my $new_style = prop_values_aliases("block", $old_style);
3708
3709 Perl also has single-form extensions that refer to blocks, C<In_Cyrillic>,
3710 meaning C<Block=Cyrillic>.  These have always been written in the new style.
3711
3712 To convert from new-style to old-style, follow this recipe:
3713
3714  $old_style = charblock((prop_invlist("block=$new_style"))[0]);
3715
3716 (which finds the range of code points in the block using C<prop_invlist>,
3717 gets the lower end of the range (0th element) and then looks up the old name
3718 for its block using C<charblock>).
3719
3720 Note that starting in Unicode 6.1, many of the block names have shorter
3721 synonyms.  These are always given in the new style.
3722
3723 =head1 AUTHOR
3724
3725 Jarkko Hietaniemi.  Now maintained by perl5 porters.
3726
3727 =cut
3728
3729 1;