#!/usr/bin/perl -w use strict; my @inputdata; my $started = 0; while (<>) { chomp; last if $started and /^---End table---$/; push @inputdata, $_ if $started; $started = 1 if /^---Start table---$/; } die "It would seem no input was found\n" unless @inputdata; # 0 is ignored # 1 is assigned by strxfrm to end of pass # 2 is space or tabelator -- end of word in pass 0 and 1 # 255 (or max in pass) is a compound char notificator my @tables = ( [], [], [], [] ); my %compound = ( ); my @maxval = ( 3, 3, 3, 3 ); my @value = ( 3, 3, 3, 3 ); my $line; for $line (@inputdata) { my $only3 = 0; $value[1] = $value[2] = 3; if ($line =~ s/^\s+//) { $value[3]++; $only3 = 1; } while ($line ne '') { for (0 .. 3) { $maxval[$_] = $value[$_] if $maxval[$_] < $value[$_]; } if ($line =~ s/^\s+//) { $value[1]++ unless $only3; $value[2] = 3; next; } my $firstord; if ($line =~ s/^<([cC]h|CH)>//) { $firstord = ord $1; } else { $firstord = ord $line; $line = substr $line, 1; } for (0 .. 3) { if ($only3 and $_ < 3) { $tables[$_][$firstord] = 0; } else { $tables[$_][$firstord] = $value[$_]; } } $value[2]++ unless $only3; $value[3]++ if $only3; } $value[0]++ unless $only3; } my $pass; for $pass (0 .. 3) { $maxval[$pass]++; for (0 .. 255) { $tables[$pass][$_] = 0 unless defined $tables[$pass][$_]; } print map { sprintf "%c => %d\t", ( $_ < 32 ? ord('.') : $_ ), $tables[$pass][$_] } (0 .. 255); print "\nMax val: $maxval[$pass]\n"; } __END__ my $pass; for $pass (0 .. 3) { $tables[$pass][ord ' '] = 2; $tables[$pass][ord "\t"] = 2; my $min = 3; if ($pass == 3) { $min = 4; } my $i = 3; my $line; for $line (@inputdata) { my $line = $line; my $nearlynull = 0; $nearlynull = 1 if $line =~ s/^\s+//; next if $nearlynull and $pass != 3; my @items; if ($pass == 0) { $line =~ s/\s+//g; @items = ( $line ); } elsif ($pass == 1) { $i = $min; @items = split /\s+/, $line; } else { @items = grep { defined $_ and not /^\s*$/ } $line =~ /(<(?:[cC]h|CH)>|[\000-\377])/go; } for (@items) { while ($_ ne '') { if (s/^<([cC]h|CH)>//) { my $string = $+; $compound{$string}[$pass] = $i; $string =~ /^[\000-\377]/o; my $ch = $&; $compound{$ch}[$pass] = $tables[$pass][ord $ch]; } else { s/^[\000-\377]//o; my $ch = $&; $tables[$pass][ord $ch] = $i; } } $i++; } } $maxval[$pass] = $i; my $tag; for $tag (keys %compound) { if (defined $compound{$tag}[$pass]) { $tag =~ /^[\000-\377]/o; $tables[$pass][ord $&] = $tag; } } my $ord; if ($pass == 3) { for $ord (0 .. 31) { $tables[$pass][$ord] = $i unless defined $tables[$pass][$ord]; $tables[$pass][$ord + 128] = $i unless defined $tables[$pass][$ord + 128]; $i++; } for $ord (0 .. 255) { $tables[$pass][$ord] = $i++ unless defined $tables[$pass][$ord]; } } else { for $ord (0 .. 255) { $tables[$pass][$ord] = 0 unless defined $tables[$pass][$ord]; } } } my $type = "uchar"; print "#define uchar unsigned char\n"; print "$type * CZ_SORT_TABLE[] = {\n"; for $pass (0 .. 3) { print qq!\t"!; my $ord; for $ord (0 .. 255) { printf "\\%03o", $tables[$pass][$ord]; } print qq!",\n!; } print "};\n"; my $comp; for $comp (keys %compound) { print "$type CZ_SORT_VALUE_$comp\[\] = {\n"; for $pass (0 .. 3) { printf "\t($type)'\\%03o',", $compound{$comp}[$pass]; } print "\n\t};\n"; }