/usr/share/rpmlint/I18NCheck.py is in rpmlint 1.9-6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | # -*- coding: utf-8 -*-
#############################################################################
# File : I18NCheck.py
# Package : rpmlint
# Author : Frederic Lepied
# Created on : Mon Nov 22 20:02:56 1999
# Purpose : checks i18n bugs.
#############################################################################
import re
import rpm
from __isocodes__ import COUNTRIES, LANGUAGES
import AbstractCheck
from Filter import addDetails, printError, printWarning
# Associative array of invalid value => correct value
INCORRECT_LOCALES = {
'in': 'id',
'in_ID': 'id_ID',
'iw': 'he',
'iw_IL': 'he_IL',
'gr': 'el',
'gr_GR': 'el_GR',
'cz': 'cs',
'cz_CZ': 'cs_CZ',
'lug': 'lg', # 'lug' is valid, but we standardize on 2 letter codes
'en_UK': 'en_GB'}
package_regex = re.compile('-(' + '|'.join(LANGUAGES) + ')$')
locale_regex = re.compile('^(/usr/share/locale/([^/]+))/')
correct_subdir_regex = re.compile('^(([a-z][a-z]([a-z])?(_[A-Z][A-Z])?)([.@].*$)?)$')
lc_messages_regex = re.compile('/usr/share/locale/([^/]+)/LC_MESSAGES/.*(mo|po)$')
man_regex = re.compile('/usr(?:/share)?/man/([^/]+)/man[0-9n][^/]*/[^/]+$')
# list of exceptions
#
# note: ISO-8859-9E is non standard, ISO-8859-{6,8} are of limited use
# as locales (since all modern handling of bidi is based on utf-8 anyway),
# so they should be removed once UTF-8 is deployed)
EXCEPTION_DIRS = (
'C', 'POSIX', 'CP1251', 'CP1255', 'CP1256',
'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5',
'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-9E',
'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15',
'KOI8-R', 'KOI8-U', 'UTF-8', 'default')
def is_valid_lang(lang):
# TODO: @Foo and charset handling
lang = re.sub("[@.].*$", "", lang)
if lang in LANGUAGES:
return True
ix = lang.find("_")
if ix == -1:
return False
# TODO: don't accept all lang_COUNTRY combinations
country = lang[ix + 1:]
if country not in COUNTRIES:
return False
lang = lang[0:ix]
if lang not in LANGUAGES:
return False
return True
class I18NCheck(AbstractCheck.AbstractCheck):
def __init__(self):
AbstractCheck.AbstractCheck.__init__(self, 'I18NCheck')
def check_binary(self, pkg):
files = list(pkg.files().keys())
files.sort()
locales = [] # list of locales for this packages
webapp = False
i18n_tags = pkg[rpm.RPMTAG_HEADERI18NTABLE] or ()
for i in i18n_tags:
try:
correct = INCORRECT_LOCALES[i]
printError(pkg, 'incorrect-i18n-tag-' + correct, i)
except KeyError:
pass
# as some webapps have their files under /var/www/html, and
# others in /usr/share or /usr/lib, the only reliable way
# sofar to detect them is to look for an apache configuration file
for f in files:
if f.startswith('/etc/apache2/') or \
f.startswith('/etc/httpd/conf.d/'):
webapp = True
for f in files:
res = locale_regex.search(f)
if res:
locale = res.group(2)
# checks the same locale only once
if locale not in locales:
locales.append(locale)
res2 = correct_subdir_regex.search(locale)
if not res2:
if locale not in EXCEPTION_DIRS:
printError(pkg, 'incorrect-locale-subdir', f)
else:
locale_name = res2.group(2)
try:
correct = INCORRECT_LOCALES[locale_name]
printError(pkg, 'incorrect-locale-' + correct, f)
except KeyError:
pass
res = lc_messages_regex.search(f)
subdir = None
if res:
subdir = res.group(1)
if not is_valid_lang(subdir):
printError(pkg, 'invalid-lc-messages-dir', f)
else:
res = man_regex.search(f)
if res:
subdir = res.group(1)
if is_valid_lang(subdir):
subdir = None
else:
printError(pkg, 'invalid-locale-man-dir', f)
if f.endswith('.mo') or subdir:
if pkg.files()[f].lang == '' and not webapp:
printWarning(pkg, 'file-not-in-%lang', f)
main_dir, main_lang = ("", "")
for f in files:
lang = pkg.files()[f].lang
if main_lang and lang == "" and is_prefix(main_dir + '/', f):
printError(pkg, 'subfile-not-in-%lang', f)
if main_lang != lang:
main_dir, main_lang = f, lang
name = pkg.name
res = package_regex.search(name)
if res:
locales = 'locales-' + res.group(1)
if locales != name:
if locales not in (x[0] for x in pkg.requires()):
printError(pkg, 'no-dependency-on', locales)
def is_prefix(p, s):
return len(p) <= len(s) and p == s[:len(p)]
# Create an object to enable the auto registration of the test
check = I18NCheck()
addDetails(
# Need to add a function to list all the locales
'incorrect-i18n-tag-',
"""
""",
'incorrect-locale-subdir',
"""
""",
'incorrect-locale-',
"""
""",
'invalid-lc-messages-dir',
"""
""",
'invalid-locale-man-dir',
"""
""",
'file-not-in-lang',
"""
""",
'no-dependency-on',
"""
""",
'subfile-not-in-%lang',
""" If /foo/bar is not tagged %lang(XX) whereas /foo is, the package won't be
installable if XX is not in %_install_langs.""",
)
# I18NCheck.py ends here
# ex: ts=4 sw=4 et
|