codekingpro/portable-devtools
114k
1#!/usr/bin/env python32"""3 Convert the X11 locale.alias file into a mapping dictionary suitable4 for locale.py.5 6 Written by Marc-Andre Lemburg <mal@genix.com>, 2004-12-10.7 8"""9import locale10import sys11 12_locale = locale13 14# Location of the X11 alias file.15LOCALE_ALIAS = '/usr/share/X11/locale/locale.alias'16# Location of the glibc SUPPORTED locales file.17SUPPORTED = '/usr/share/i18n/SUPPORTED'18 19def parse(filename):20 21 with open(filename, encoding='latin1') as f:22 lines = list(f)23 # Remove mojibake in /usr/share/X11/locale/locale.alias.24 # b'\xef\xbf\xbd' == '\ufffd'.encode('utf-8')25 lines = [line for line in lines if '\xef\xbf\xbd' not in line]26 data = {}27 for line in lines:28 line = line.strip()29 if not line:30 continue31 if line[:1] == '#':32 continue33 locale, alias = line.split()34 # Fix non-standard locale names, e.g. ks_IN@devanagari.UTF-835 if '@' in alias:36 alias_lang, _, alias_mod = alias.partition('@')37 if '.' in alias_mod:38 alias_mod, _, alias_enc = alias_mod.partition('.')39 alias = alias_lang + '.' + alias_enc + '@' + alias_mod40 # Strip ':'41 if locale[-1] == ':':42 locale = locale[:-1]43 # Lower-case locale44 locale = locale.lower()45 # Ignore one letter locale mappings (except for 'c')46 if len(locale) == 1 and locale != 'c':47 continue48 # Normalize encoding, if given49 if '.' in locale:50 lang, encoding = locale.split('.')[:2]51 encoding = encoding.replace('-', '')52 encoding = encoding.replace('_', '')53 locale = lang + '.' + encoding54 data[locale] = alias55 return data56 57def parse_glibc_supported(filename):58 59 with open(filename, encoding='latin1') as f:60 lines = list(f)61 data = {}62 for line in lines:63 line = line.strip()64 if not line:65 continue66 if line[:1] == '#':67 continue68 line = line.replace('/', ' ').strip()69 line = line.rstrip('\\').rstrip()70 words = line.split()71 if len(words) != 2:72 continue73 alias, alias_encoding = words74 # Lower-case locale75 locale = alias.lower()76 # Normalize encoding, if given77 if '.' in locale:78 lang, encoding = locale.split('.')[:2]79 encoding = encoding.replace('-', '')80 encoding = encoding.replace('_', '')81 locale = lang + '.' + encoding82 # Add an encoding to alias83 alias, _, modifier = alias.partition('@')84 alias = _locale._replace_encoding(alias, alias_encoding)85 if modifier and not (modifier == 'euro' and alias_encoding == 'ISO-8859-15'):86 alias += '@' + modifier87 data[locale] = alias88 return data89 90def pprint(data):91 items = sorted(data.items())92 for k, v in items:93 print(f" {k!a:<40}{v!a},")94 95def print_differences(data, olddata):96 items = sorted(olddata.items())97 for k, v in items:98 if k not in data:99 print(f'# removed {k!a}')100 elif olddata[k] != data[k]:101 print(f'# updated {k!a} -> {olddata[k]!a} to {data[k]!a}')102 # Additions are not mentioned103 104def optimize(data):105 locale_alias = locale.locale_alias106 locale.locale_alias = data.copy()107 for k, v in data.items():108 del locale.locale_alias[k]109 if locale.normalize(k) != v:110 locale.locale_alias[k] = v111 newdata = locale.locale_alias112 errors = check(data)113 locale.locale_alias = locale_alias114 if errors:115 sys.exit(1)116 return newdata117 118def check(data):119 # Check that all alias definitions from the X11 file120 # are actually mapped to the correct alias locales.121 errors = 0122 for k, v in data.items():123 if locale.normalize(k) != v:124 print(f'ERROR: {k!a} -> {locale.normalize(k)!a} != {v!a}',125 file=sys.stderr)126 errors += 1127 return errors128 129if __name__ == '__main__':130 import argparse131 parser = argparse.ArgumentParser()132 parser.add_argument('--locale-alias', default=LOCALE_ALIAS,133 help='location of the X11 alias file '134 f'(default: {LOCALE_ALIAS})')135 parser.add_argument('--glibc-supported', default=SUPPORTED,136 help='location of the glibc SUPPORTED locales file '137 f'(default: {SUPPORTED})')138 args = parser.parse_args()139 140 data = locale.locale_alias.copy()141 data.update(parse_glibc_supported(args.glibc_supported))142 data.update(parse(args.locale_alias))143 # Hardcode 'c.utf8' -> 'C.UTF-8' because 'en_US.UTF-8' does not exist144 # on all platforms.145 data['c.utf8'] = 'C.UTF-8'146 while True:147 # Repeat optimization while the size is decreased.148 n = len(data)149 data = optimize(data)150 if len(data) == n:151 break152 print_differences(data, locale.locale_alias)153 print()154 print('locale_alias = {')155 pprint(data)156 print('}')157 