This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add regen/mk_invlists.pl, charclass_invlists.h
[perl5.git] / regen / mk_invlists.pl
1 #!perl -w
2 use 5.015;
3 use strict;
4 use warnings;
5 use Unicode::UCD "prop_invlist";
6 require 'regen/regen_lib.pl';
7
8 # This program outputs charclass_invlists.h, which contains various inversion
9 # lists in the form of C arrays that are to be used as-is for inversion lists.
10 # Thus, the lists it contains are essentially pre-compiled, and need only a
11 # light-weight fast wrapper to make them usable at run-time.
12
13 # As such, this code knows about the internal structure of these lists, and
14 # any change made to that has to be done here as well.  A random number stored
15 # in the headers is used to minimize the possibility of things getting
16 # out-of-sync, or the wrong data structure being passed.  Currently that
17 # random number is:
18 my $VERSION_DATA_STRUCTURE_TYPE = 1064334010;
19
20 my $out_fh = open_new('charclass_invlists.h', '>',
21                       {style => '*', by => $0,
22                       from => "Unicode::UCD"});
23
24 print $out_fh "/* See the generating file for comments */\n\n";
25
26 sub output_invlist ($$) {
27     my $name = shift;
28     my $invlist = shift;     # Reference to inversion list array
29
30     # Output the inversion list $invlist using the name $name for it.
31     # It is output in the exact internal form for inversion lists.
32
33     my $zero_or_one;    # Is the last element of the header 0, or 1 ?
34
35     # If the first element is 0, it goes in the header, instead of the body
36     if ($invlist->[0] == 0) {
37         shift @$invlist;
38
39         $zero_or_one = 0;
40
41         # Add a dummy 0 at the end so that the length is constant.  inversion
42         # lists are always stored with enough room so that if they change from
43         # beginning with 0, they don't have to grow.
44         push @$invlist, 0;
45     }
46     else {
47         $zero_or_one = 1;
48     }
49
50     print $out_fh "\nUV ${name}_invlist[] = {\n";
51
52     print $out_fh "\t", scalar @$invlist, ",\t/* Number of elements */\n";
53     print $out_fh "\t0,\t/* Current iteration position */\n";
54     print $out_fh "\t$VERSION_DATA_STRUCTURE_TYPE, /* Version and data structure type */\n";
55     print $out_fh "\t", $zero_or_one,
56                   ",\t/* 0 if this is the first element of the list proper;",
57                   "\n\t\t   1 if the next element is the first */\n";
58
59     # The main body are the UVs passed in to this routine.  Do the final
60     # element separately
61     for my $i (0 .. @$invlist - 1 - 1) {
62         print $out_fh "\t$invlist->[$i],\n";
63     }
64
65     # The final element does not have a trailing comma, as C can't handle it.
66     print $out_fh "\t$invlist->[-1]\n";
67
68     print $out_fh "};\n";
69 }
70
71 output_invlist("Latin1", [ 0, 256 ]);
72 output_invlist("AboveLatin1", [ 256 ]);
73
74 for my $prop (qw(
75                 ASCII
76     )
77 ) {
78
79     my @invlist = prop_invlist($prop);
80     output_invlist($prop, \@invlist);
81 }
82
83 read_only_bottom_close_and_rename($out_fh)