X-Git-Url: https://pere.pagekite.me/gitweb/homepage.git/blobdiff_plain/e704e201f6efe413ac6549a46ee4a2f6d2e51a2d..ae5db6d19f3d85fdd5e7bd4c12be28fa3f15fc43:/linux/glibc/check-locale
diff --git a/linux/glibc/check-locale b/linux/glibc/check-locale
new file mode 100755
index 0000000000..9d5baf6340
--- /dev/null
+++ b/linux/glibc/check-locale
@@ -0,0 +1,236 @@
+#!/usr/bin/perl
+#
+# Author: Petter Reinholdtsen
+# Date: 2004-06-01
+#
+# License: GPL v2 or later at your choice
+#
+# Test the content of GNU libc locales, detect some common errors.
+#
+# The latest version is available from
+# .
+
+use warnings;
+use strict;
+
+use vars qw($locale $warncount $errcount);
+
+sub uxx_to_utf8 {
+ my $line = shift;
+ $line =~ s//pack('U',hex($1))/ge;
+ return $line;
+}
+
+sub error {
+ my $msg = shift;
+ $errcount++;
+ print "error: $locale: $msg\n";
+}
+
+sub warning {
+ my $msg = shift;
+ $warncount++;
+ print "warning: $locale: $msg\n";
+}
+
+sub check_lc_identification {
+ my @lines = @_;
+ for my $line (@lines) {
+ if ($line =~ m/^category\s+(\S+)$/) {
+ warning "LC_IDENTIFICATION: missing quotes around category standard ref: $1"
+ if ($1 !~ m/\".+\"/);
+ }
+ if ($line =~ m/^email\s+(\S+)\s*$/) {
+ my $email = $1;
+ warning "LC_IDENTIFICATION: obsolete email: $email"
+ if ($email =~ m/"?bug-glibc\@gnu.org"?/);
+ }
+ }
+}
+sub check_lc_paper {
+ my @lines = @_;
+ my $height = undef;
+ my $width = undef;
+ for (@lines) {
+ $height = $1 if (m/^height\s*(\d+)\s*$/);
+ $width = $1 if (m/^width\s*(\d+)\s*$/);
+ return if (m/^copy\s+/); # Nothing to check
+ }
+
+ if (!defined $width || defined $height) {
+# warning "LC_PAPER: Missing height or width.";
+ return;
+ }
+
+ if (210 == $width && 297 == $height) { # ISO A4
+ } elsif (216 == $width && 279 == $height) { # US Letter
+ } else {
+ warning "LC_PAPER: unknown paper size.";
+ }
+}
+
+sub check_lc_measurement {
+ my @lines = @_;
+ for my $line (@lines) {
+ if ($line =~ m/^\s*(measurement)\s+(\S+)\s*$/) {
+ my $value = $2;
+ if (defined $value && $value !~ m/^\d+$/) {
+ warning "LC_MEASUREMENT: measurements should be number 1 or 2.";
+ } elsif ($value < 1 && 2 < $value) {
+ warning "LC_MEASUREMENT: measurements should be 1 or 2.";
+ }
+ }
+ }
+}
+
+sub check_lc_numeric {
+ my @lines = @_;
+ for my $line (@lines) {
+ next if ($line eq "LC_NUMERIC" || $line eq "END LC_NUMERIC");
+ next if ($line =~ m/^$/);
+ if ($line =~ m/^\s*(grouping)\s+(\S+)\s*$/) {
+ my $value = $2;
+ if ($value =~ m/^-?\d+$/) {
+ # Only digits (or - digits)
+ if ( $value < 1 && $value != -1) {
+ warning "LC_NUMERIC: grouping should positive or -1: $value";
+ }
+ } else {
+ if (defined $value && $value !~ m/\d+;\d+/) {
+ warning "LC_NUMERIC: grouping should use ; as separator: $value";
+ }
+ }
+ } elsif ($line =~ m/^\s*(decimal_point)\s+(\S+)\s*$/) {
+ } elsif ($line =~ m/^\s*(thousands_sep)\s+(\S+)\s*$/) {
+ my $sep = $2;
+# print "P: '$sep'\n";
+ warning "LC_NUMERIC: Unusual thousands_sep '$sep' [".
+ uxx_to_utf8($sep)."]"
+ unless (grep { $_ eq $sep; } ('""',
+ '""',
+ '""',
+ '""',
+ '""',
+ '""'));
+ } elsif ($line =~ m/^\s*(copy)\s+(\S+)\s*$/) {
+ } else {
+ warning "LC_NUMERIC: Unknown keyword '$line'";
+ }
+ }
+}
+
+sub check_lc_messages {
+ my @lines = @_;
+ for (@lines) {
+ if (m/^\s*(yesexpr|noexpr)\s+(.+)$/) {
+ my $type = $1;
+ my $regex = uxx_to_utf8($2);
+ unless ($regex =~ m/^"\^/) {
+ error "LC_MESSAGES: $type missing '^' prefix: $regex";
+ }
+ unless ($regex =~ m/\[.+\]|\(.+\)/) {
+ error "LC_MESSAGES: $type missing '[.+]|(.+)' content: $regex";
+ }
+ if ($regex =~ m/\.\*"$/) {
+ warning "LC_MESSAGES: $type have '.*' postfix: $regex";
+ }
+ if ($regex =~ m/[0-9]/) {
+ warning "LC_MESSAGES: $type have numbers in regex: $regex";
+ }
+ if ($type eq "yesexpr" && ($regex !~ m/y/ ||
+ $regex !~ m/Y/)) {
+ warning "LC_MESSAGES: $type missing 'yY' in content: $regex";
+ }
+ if ($type eq "noexpr" && ($regex !~ m/n/ ||
+ $regex !~ m/N/)) {
+ warning "LC_MESSAGES: $type missing 'nN' in content: $regex";
+ }
+ }
+ }
+}
+
+sub check_order {
+ my @blocks = @_;
+ my @order= qw(LC_IDENTIFICATION
+ LC_CTYPE
+ LC_COLLATE
+ LC_MONETARY
+ LC_NUMERIC
+ LC_TIME
+ LC_MESSAGES
+ LC_PAPER
+ LC_NAME
+ LC_ADDRESS
+ LC_TELEPHONE
+ LC_MEASUREMENT);
+ my $pos = 0;
+ for my $section (@blocks) {
+ if ($section eq $order[$pos]) {
+ $pos++;
+ } else {
+ $pos = 0;
+ $pos++ while ($order[$pos] ne $section);
+ warning "$section: not following section $order[$pos-1]";
+ }
+ }
+}
+
+sub check_charset {
+ my @blocks = @_;
+ for my $section (@blocks) {
+ if ($section =~ m/^%\s*[Cc]arset:\s*$/) {
+ return;
+ }
+ }
+ warning "Missing '% Charset: ' info";
+}
+
+my $section;
+my %sections;
+my @blocks = ();
+for my $filename (@ARGV) {
+ open (FILE, "<$filename") || die "Unable to read $filename";
+ $locale = $filename;
+ my $buf = undef;
+ my @lines;
+ %sections = ();
+ while () {
+ chomp;
+ s/%.*$//; # Remove comments
+ s/\#.*$//;
+ if (m%^(.+)/$%) {
+ $buf .= $1;
+ next;
+ }
+ if (! defined $buf) {
+ $buf = $_;
+ } else {
+ $buf .= $_;
+ }
+ if (!$section && m/^(LC_.*)\s*$/) {
+ $section = $1;
+ @lines = ();
+ #print "Found section $section\n";
+ }
+ push(@lines, $buf);
+ if (m/^END (LC_.+)\s*$/) {
+ if (exists $sections{$section}) {
+ warning "duplicate section $section";
+ }
+ push(@blocks, $section);
+ $sections{$section} = [@lines];
+ $section = "";
+ #print "Stored section $section\n";
+ }
+ undef $buf;
+ }
+ close(FILE);
+
+# check_order(@blocks);
+ check_charset(@blocks);
+ check_lc_identification(@{$sections{'LC_IDENTIFICATION'}});
+ check_lc_messages(@{$sections{'LC_MESSAGES'}});
+ check_lc_numeric(@{$sections{'LC_NUMERIC'}});
+ check_lc_paper(@{$sections{'LC_PAPER'}});
+ check_lc_measurement(@{$sections{'LC_MEASUREMENT'}});
+}