use ExtUtils::MakeMaker;
-my @tables = qw(iso8859 EBCDIC Symbols);
+
+my %tables = (iso8859 => ['ascii.enc', 'cp1250.enc'],
+ EBCDIC => ['cp1047.enc','cp37.enc','posix-bc.enc'],
+ Symbols => ['symbol.enc','dingbats.enc'],
+ );
+
+opendir(ENC,'Encode');
+while (defined(my $file = readdir(ENC)))
+ {
+ if ($file =~ /iso8859.*\.enc/)
+ {
+ push(@{$tables{iso8859}},$file);
+ }
+ }
+closedir(ENC);
+
WriteMakefile(
NAME => "Encode",
sub post_initialize
{
my ($self) = @_;
- push(@{$self->{'O_FILES'}},map("$_\$(OBJ_EXT)",@tables));
- $self->{'clean'}{'FILES'} .= join(' ',map("$_.*",@tables));
+ push(@{$self->{'O_FILES'}},map("$_\$(OBJ_EXT)",keys %tables));
+ my @files;
+ foreach my $table (keys %tables)
+ {
+ foreach my $ext (qw($(OBJ_EXT) .c .h .def))
+ {
+ push (@files,$table.$ext);
+ }
+ }
+ $self->{'clean'}{'FILES'} .= join(' ',@files);
return '';
}
-sub clean
-{
- my ($self) = @_;
- return $self->SUPER::clean . qq[
- \$(RM_F) ].join(' ',map("$_.*",@tables))."\n"
-}
-
sub postamble
{
- return '
-
-Encode$(OBJ_EXT) : iso8859$(OBJ_EXT) EBCDIC$(OBJ_EXT) Symbols$(OBJ_EXT)
-
-iso8859.c : compile Makefile
- $(PERL) compile $@ Encode/ascii.enc Encode/iso8859*.enc Encode/cp1250.enc
-
-EBCDIC.c : compile Makefile Encode/cp1047.enc Encode/cp37.enc Encode/posix-bc.enc
- $(PERL) compile $@ Encode/cp1047.enc Encode/cp37.enc Encode/posix-bc.enc
-
-Symbols.c : compile Makefile Encode/symbol.enc Encode/dingbats.enc
- $(PERL) compile $@ Encode/symbol.enc Encode/dingbats.enc
-
-'
+ my $self = shift;
+ my $dir = $self->catdir($self->curdir,'Encode');
+ my $str = "# Encode$(OBJ_EXT) depends on .h and .def files not .c files - but all written by compile\n";
+ $str .= 'Encode$(OBJ_EXT) :';
+ my @rules;
+ foreach my $table (keys %tables)
+ {
+ $str .= " $table.c";
+ }
+ $str .= "\n\n";
+ foreach my $table (keys %tables)
+ {
+ $str .= "$table.c : compile \$(MAKEFILE)";
+ foreach my $file (@{$tables{$table}})
+ {
+ $str .= ' '.$self->catfile($dir,$file);
+ }
+ $str .= "\n\t\$(PERL) compile \$\@";
+ foreach my $file (@{$tables{$table}})
+ {
+ $str .= ' '.$self->catfile($dir,$file);
+ }
+ $str .= "\n\n";
+ }
+ return $str;
}
sub encode_U
{
+ # UTF-8 encocde long hand - only covers part of perl's range
my $uv = shift;
if ($uv < 0x80)
{
sub encode_S
{
+ # encode single byte
my ($ch,$page) = @_;
return chr($ch);
}
sub encode_D
{
+ # encode double byte MS byte first
my ($ch,$page) = @_;
return chr($page).chr($ch);
}
sub encode_M
{
+ # encode Multi-byte - single for 0..255 otherwise double
my ($ch,$page) = @_;
return &encode_D if $page;
return &encode_S;
}
+# Win32 does not expand globs on command line
eval "\@ARGV = map(glob(\$_),\@ARGV)" if ($^O eq 'MSWin32');
my $cname = shift(@ARGV);
chmod(0666,$hname) if -f $cname && !-w $hname;
open(H,">$hname") || die "Cannot open $hname:$!";
+foreach my $fh (\*C,\*D,\*H)
+{
+ print $fh <<"END";
+/*
+ !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
+ This file was autogenerated by:
+ $^X $0 $cname @ARGV
+*/
+END
+}
+
if ($cname =~ /(\w+)\.xs$/)
{
print C "#include <EXTERN.h>\n";
my ($name) = $enc =~ /^.*?([\w-]+)(\.enc)$/;
if (open(E,$enc))
{
- compile(\*E,$name,\*C);
+ compile_enc(\*E,lc($name),\*C);
}
else
{
my $sym = "${enc}_encoding";
$sym =~ s/\W+/_/g;
print C "encode_t $sym = \n";
- print C " {",join(',',"\"$enc\"",@{$encoding{$enc}}),"};\n";
+ print C " {",join(',',"\"$enc\"",@{$encoding{$enc}}),"};\n\n";
}
foreach my $enc (sort cmp_name keys %encoding)
close(D);
close(H);
-
-
-sub compile
+sub compile_enc
{
my ($fh,$name,$ch) = @_;
my $e2u = {};
chomp($type);
return if $type eq 'E';
my ($def,$sym,$pages) = split(/\s+/,scalar(<$fh>));
- warn "t=$type s=$sym d=$def p=$pages $name\n";
+ warn "$type encoded $name\n";
my $rep = '';
{
my $v = hex($def);
}
}
-
sub outstring
{
my ($fh,$name,$s) = @_;
}
}
$strings{$s} = $sym = $name;
- printf $fh "static const U8 %s[%d] =\n",$name,length($s);
+ printf $fh "\nstatic const U8 %s[%d] =\n",$name,length($s);
# Do in chunks of 16 chars to constrain line length
# Assumes ANSI C adjacent string litteral concatenation
while (length($s))
print $fh '"',join('',map(sprintf('\x%02x',ord($_)),split(//,$c))),'"';
print $fh "\n" if length($s);
}
- printf $fh ";\n\n";
+ printf $fh ";\n";
}
return $sym;
}
-sub output
+sub process
{
- my ($fh,$name,$a) = @_;
+ my ($name,$a) = @_;
$name =~ s/\W+/_/g;
$a->{Cname} = $name;
my @keys = grep(ref($a->{$_}),sort keys %$a);
- print $fh "\nextern encpage_t $name\[\];\n";
- # print $fh "\nstatic encpage_t *$name;\n";
- # Sub-tables
- my %str;
my $l;
my @ent;
foreach my $b (@keys)
$l = $b;
push(@ent,$b);
}
- unless (exists $t->{Cname})
+ if (exists $t->{Cname})
{
- output($fh,sprintf("%s_%02x",$name,ord($s)),$t);
+ $t->{'Forward'} = 1 if $t != $a;
+ }
+ else
+ {
+ process(sprintf("%s_%02x",$name,ord($s)),$t);
}
}
if (ord($keys[-1]) < 255)
$a->{$t} = [$t,chr(255),undef,$a,0,0];
push(@ent,$t);
}
+ $a->{'Entries'} = \@ent;
+}
+
+sub outtable
+{
+ my ($fh,$a) = @_;
+ my $name = $a->{'Cname'};
# String tables
- foreach my $b (@ent)
+ foreach my $b (@{$a->{'Entries'}})
{
next unless $a->{$b}[5];
my $s = ord($a->{$b}[0]);
my $e = ord($a->{$b}[1]);
outstring($fh,sprintf("%s__%02x_%02x",$name,$s,$e),$a->{$b}[2]);
}
-
- print $fh "\n";
- print $fh "encpage_t $name\[",scalar(@ent),"] = {\n";
- foreach my $b (@ent)
+ if ($a->{'Forward'})
+ {
+ print $fh "\nstatic encpage_t $name\[",scalar(@{$a->{'Entries'}}),"];\n";
+ }
+ $a->{'Done'} = 1;
+ foreach my $b (@{$a->{'Entries'}})
+ {
+ my ($s,$e,$out,$t,$end,$l) = @{$a->{$b}};
+ outtable($fh,$t) unless $t->{'Done'};
+ }
+ print $fh "\nstatic encpage_t $name\[",scalar(@{$a->{'Entries'}}),"] = {\n";
+ foreach my $b (@{$a->{'Entries'}})
{
my ($s,$e,$out,$t,$end,$l) = @{$a->{$b}};
my $sc = ord($s);
print $fh ",",$t->{Cname};
printf $fh ",0x%02x,0x%02x,$l,$end},\n",$sc,$ec;
}
- print $fh "};\n\n";
+ print $fh "};\n";
+}
+
+sub output
+{
+ my ($fh,$name,$a) = @_;
+ process($name,$a);
+ # Sub-tables
+ outtable($fh,$a);
}