#!/usr/bin/perl # wmtranschk Ver 1.31 # Copyleft 2000-2001 # # This program is to help Webmin translators. # It searches missing duplicated and untranslated texts and files. # sub usage_and_exit { print <) { next unless /^\s*lang\s*=\s*(\w+)\s*,/; next if ($1 eq 'en'); push(@languages, $1); } } @languages or die "No language given\n"; # Discover all possible subdirectories, including '.'. opendir(MAINDIR, ".") or die "Cannot read directory `pwd`: $!"; while ($dirent = readdir(MAINDIR)) { next if $dirent eq '..'; next unless -d "$dirent/lang"; push(@available,$dirent); } closedir MAINDIR; @packages_to_check or @packages_to_check = sort @available; # main loop for each module foreach $package (@packages_to_check) { print "\nTesting directory '$package'\n" . '=' x 40 . "\n"; # Get English language reference data $nowarn = 1; # Don't care missing files $modinfo_hr = read_module_info($package); $confinfo_en_hr = read_config_info($package, ''); $lang_en_hr = read_lang($package, 'en'); $help_en_hr = read_help($package, ''); # Check translated data $nowarn = 0; # Complain about missing files foreach $language (@languages) { check_modinfo($package, $language); check_confinfo($package, $language); check_lang($package, $language); check_help($package, $language); } } ##################### Data reader routines #################### sub read_module_info { -e "$_[0]/module.info" and return readhash("$_[0]/module.info"); return undef; } sub read_config_info { my $ext = $_[1]; $ext and $ext = ".$ext"; -e "$_[0]/config.info$ext" and return readhash("$_[0]/config.info$ext"); $nowarn or print "$_[0]/config.info$ext: No such file\n"; return undef; } sub read_lang { -e "$_[0]/lang/$_[1]" and return readhash("$_[0]/lang/$_[1]"); $nowarn or print "$_[0]/lang/$_[1]: No such file\n"; return undef; } sub read_help { my $mod = shift; my $lang = shift; my(%hash, $dirent, $langre, $checksum); -d "$mod/help" or return undef; opendir(HELPDIR, "$mod/help") or die "Cannot read directory '$mod/help': $!"; $langre = $lang ? "$lang." : $lang; $langre =~ s|\.|\\\.|g; # escape dots while ($dirent = readdir(HELPDIR)) { next unless $dirent =~ m|^(\w+)\.${langre}html$|; open(HELP, "$mod/help/$dirent") or next; $hash{$1} = $checksum = 0; while () { $checksum += unpack("%32C*", $_); } close HELP; $hash{$1} = $checksum; } closedir HELPDIR; return \%hash; } sub readhash { my %hash; open(FILE, "$_[0]") or die "Cannot open file $_[0]: $!"; while () { chomp; next if /^#/; next if /^\s*$/; ($key, $value) = split(/=/, $_, 2); $key =~ s/\s+//g; $value =~ s/^\s+//g; $value =~ s/\s+$//g; if (defined $hash{$key}) { if ($hash{$key} eq $value) { print "$_[0]: Duplicated '$key'\n"; } else { print "$_[0]: Redefined '$key' (old='$hash{$key}', new='$value')\n"; } } $hash{lc($key)} = $value; } close FILE; return \%hash; } sub printhash { print "=====\n"; while (($key, $value) = each %{$_[0]}) { print " $key => $value\n"; } } ############## More or less sophisticated checker routines ############# # check_modinfo($package, $language); sub check_modinfo { my $module = shift; my $lang = lc(shift); $modinfo_hr or return; if (! ${$modinfo_hr}{"desc_$lang"}) { print "$module/module_info: Missing 'desc_$lang'\n"; } elsif (${$modinfo_hr}{"desc_$lang"} eq ${$modinfo_hr}{"desc"}) { print "$module/module_info: Untranslated 'desc_$lang'\n"; } return; } # check_confinfo($package, $language); sub check_confinfo { my $module = shift; my $lang = shift; my $lang_hr; $confinfo_en_hr or return; $lang_hr = read_config_info($module, $lang); $lang_hr or return; compare_hash($confinfo_en_hr, $lang_hr, "$module/config.info.$lang"); } # check_lang($package, $language); sub check_lang { my $module = shift; my $lang = shift; my $lang_hr; $lang_en_hr or return; $lang_hr = read_lang($module, $lang); $lang_hr or return; compare_hash($lang_en_hr, $lang_hr, "$module/lang/$lang"); } # check_help($package, $language); sub check_help { my $module = shift; my $lang = shift; my $lang_hr; $help_en_hr or return; $lang_hr = read_help($module, $lang); $lang_hr or return; compare_hash($help_en_hr, $lang_hr, "$module/help/", ".$lang.html"); } sub compare_hash { my ($eng_hr, $local_hr, $filename, $suffix) = @_; foreach (sort keys %$eng_hr) { if (! ${$local_hr}{$_}) { print "$filename: Missing '$_$suffix'\n"; } elsif (${$local_hr}{$_} eq ${$eng_hr}{$_}) { print "$filename: Untranslated '$_$suffix'\n"; } } foreach (sort keys %$local_hr) { if (! ${$eng_hr}{$_}) { print "$filename: Obsoleted '$_$suffix'\n"; } } }