commit:     b54f286110c85c5808594b0ced0cb8a5f08994b5
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug  9 19:37:41 2025 +0000
Commit:     Kerin Millar <kfm <AT> plushkava <DOT> net>
CommitDate: Sat Aug  9 19:37:41 2025 +0000
URL:        https://gitweb.gentoo.org/proj/locale-gen.git/commit/?id=b54f2861

Disambiguate a mismatching codeset/charmap as a class of error

Consider the following two locale definitions, both of which are
erroneous.

# Invalid because the codeset part mismatches the charmap
zh_CN.GB18030  UTF-8

# Invalid because the charmap does not exist
zh_CN  GB2319

Presently, locale-gen(8) will raise the same diagnostic for both cases,
complaining of an "invalid/mismatching charmap". Render the
parse_config() subroutine able to distinguish between both cases so that
the diagnostics can be improved.

Mismatching codeset/charmap at /etc/locale.gen[2]: "zh_CN.GB18030  UTF-8"
Invalid charmap at /etc/locale.gen[5]: "zh_CN  GB2319"

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 locale-gen | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/locale-gen b/locale-gen
index cb54ed5..fb1a9bf 100755
--- a/locale-gen
+++ b/locale-gen
@@ -328,13 +328,15 @@ sub parse_config ($fh, $path, $locale_by, $charmap_by) {
 
                # Extract the specified locale and character map. Upon success,
                # a canonicalised representation of the locale is also returned.
-               my ($locale, $charmap, $canonical) = parse_entry(@fields);
+               my ($locale, $codeset, $charmap, $canonical) = 
parse_entry(@fields);
 
                # Validate both locale and character map before accepting.
                if (! $locale_by->{$locale}) {
                        $thrower->('Invalid locale', $line);
+               } elsif (defined $codeset && $codeset ne $charmap) {
+                       $thrower->('Mismatching codeset/charmap', $line);
                } elsif (! $charmap_by->{$charmap}) {
-                       $thrower->('Invalid/mismatching charmap', $line);
+                       $thrower->('Invalid charmap', $line);
                } else {
                        push @locales, [ $locale, $charmap, $canonical ];
                }
@@ -345,21 +347,19 @@ sub parse_config ($fh, $path, $locale_by, $charmap_by) {
 
 sub parse_entry ($locale, $charmap) {
        my $canonical;
+       my $codeset;
        if (2 == (my @fields = split /@/, $locale, 3)) {
                # de_DE@euro ISO-8859-15 => de_DE.ISO-8859-15@euro
                $canonical = sprintf '%s.%s@%s', $fields[0], $charmap, 
$fields[1];
        } elsif (2 == (@fields = split /\./, $locale, 3)) {
                # en_US.UTF-8 UTF-8 => en_US.UTF-8
-               $locale = $fields[0];
-               $canonical = "$locale.$charmap";
-               if ($fields[1] ne $charmap) {
-                       $charmap = '';
-               }
+               ($locale, $codeset) = @fields;
+               $canonical = "$locale.$codeset";
        } elsif (1 == @fields) {
                # en_US ISO-8859-1 => en_US.ISO-8859-1
                $canonical = "$locale.$charmap";
        }
-       return $locale, $charmap, $canonical;
+       return $locale, $codeset, $charmap, $canonical;
 }
 
 sub check_archive_dir ($prefix, $locale_dir) {

Reply via email to