annotate contrib/check-internal-format-escaping.py @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 #!/usr/bin/env python3
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 #
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 # Check gcc.pot file for stylistic issues as described in
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 # https://gcc.gnu.org/onlinedocs/gccint/Guidelines-for-Diagnostics.html,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 # especially in gcc-internal-format messages.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 #
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 # This file is part of GCC.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 #
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 # GCC is free software; you can redistribute it and/or modify it under
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 # the terms of the GNU General Public License as published by the Free
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 # Software Foundation; either version 3, or (at your option) any later
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 # version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 #
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 # GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 # for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 # You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 # along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 # <http://www.gnu.org/licenses/>.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 import argparse
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 import re
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 from collections import Counter
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 from typing import Dict, Match
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 import polib
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 seen_warnings = Counter()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 def location(msg: polib.POEntry):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 if msg.occurrences:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 occ = msg.occurrences[0]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 return f'{occ[0]}:{occ[1]}'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 return '<unknown location>'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 def warn(msg: polib.POEntry,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 diagnostic_id: str, diagnostic: str, include_msgid=True):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 To suppress a warning for a particular message,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 add a line "#, gcclint:ignore:{diagnostic_id}" to the message.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 if f'gcclint:ignore:{diagnostic_id}' in msg.flags:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 return
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 seen_warnings[diagnostic] += 1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 if include_msgid:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 print(f'{location(msg)}: {diagnostic} in {repr(msg.msgid)}')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 else:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 print(f'{location(msg)}: {diagnostic}')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 def lint_gcc_internal_format(msg: polib.POEntry):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 Checks a single message that has the gcc-internal-format. These
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 messages use a variety of placeholders like %qs, %<quotes%> and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 %q#E.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 msgid: str = msg.msgid
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 def outside_quotes(m: Match[str]):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 before = msgid[:m.start(0)]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 return before.count("%<") == before.count("%>")
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 def lint_matching_placeholders():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 Warns when literal values in placeholders are not exactly equal
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 in the translation. This can happen when doing copy-and-paste
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 translations of similar messages.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 To avoid these mismatches in the first place,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 structurally equal messages are found by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 lint_diagnostics_differing_only_in_placeholders.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 This check only applies when checking a finished translation
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 such as de.po, not gcc.pot.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 if not msg.translated():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 return
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 in_msgid = re.findall('%<[^%]+%>', msgid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 in_msgstr = re.findall('%<[^%]+%>', msg.msgstr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 if set(in_msgid) != set(in_msgstr):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 'placeholder-mismatch',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 f'placeholder mismatch: msgid has {in_msgid}, '
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 f'msgstr has {in_msgstr}',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 include_msgid=False)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 def lint_option_outside_quotes():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 for match in re.finditer(r'\S+', msgid):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 part = match.group()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 if not outside_quotes(match):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 continue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 if part.startswith('-'):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 if len(part) >= 2 and part[1].isalpha():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 if part == '-INF':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 continue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 'option-outside-quotes',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 'command line option outside %<quotes%>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 if part.startswith('__builtin_'):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 'builtin-outside-quotes',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 'builtin function outside %<quotes%>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 def lint_plain_apostrophe():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 for match in re.finditer("[^%]'", msgid):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 if outside_quotes(match):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 warn(msg, 'apostrophe', 'apostrophe without leading %')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 def lint_space_before_quote():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 A space before %< is often the result of string literals that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 are joined by the C compiler and neither literal has a space
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 to separate the words.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 for match in re.finditer("(.?[a-zA-Z0-9])%<", msgid):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 if match.group(1) != '%s':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 'no-space-before-quote',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 '%< directly following a letter or digit')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 def lint_underscore_outside_quotes():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 An underscore outside of quotes is used in several contexts,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 and many of them violate the GCC Guidelines for Diagnostics:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 * names of GCC-internal compiler functions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 * names of GCC-internal data structures
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 * static_cast and the like (which are legitimate)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 for match in re.finditer("_", msgid):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 if outside_quotes(match):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 'underscore-outside-quotes',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 'underscore outside of %<quotes%>')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 return
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 def lint_may_not():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 The term "may not" may either mean "it could be the case"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 or "should not". These two different meanings are sometimes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 hard to tell apart.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 if re.search(r'\bmay not\b', msgid):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 'ambiguous-may-not',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 'the term "may not" is ambiguous')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 def lint_unbalanced_quotes():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 if msgid.count("%<") != msgid.count("%>"):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 'unbalanced-quotes',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 'unbalanced %< and %> quotes')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 if msg.translated():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 if msg.msgstr.count("%<") != msg.msgstr.count("%>"):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 'unbalanced-quotes',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 'unbalanced %< and %> quotes')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 def lint_single_space_after_sentence():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 After a sentence there should be two spaces.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 if re.search(r'[.] [A-Z]', msgid):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 'single-space-after-sentence',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 'single space after sentence')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 def lint_non_canonical_quotes():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 Catches %<%s%>, which can be written in the shorter form %qs.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 match = re.search("%<%s%>|'%s'|\"%s\"|`%s'", msgid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 if match:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 'non-canonical-quotes',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 f'placeholder {match.group()} should be written as %qs')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 lint_option_outside_quotes()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 lint_plain_apostrophe()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 lint_space_before_quote()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 lint_underscore_outside_quotes()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 lint_may_not()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 lint_unbalanced_quotes()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 lint_matching_placeholders()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 lint_single_space_after_sentence()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 lint_non_canonical_quotes()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 def lint_diagnostics_differing_only_in_placeholders(po: polib.POFile):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 Detects messages that are structurally the same, except that they
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 use different plain strings inside %<quotes%>. These messages can
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 be merged in order to prevent copy-and-paste mistakes by the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 translators.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 See bug 90119.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 """
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 seen: Dict[str, polib.POEntry] = {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 for msg in po:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 msg: polib.POEntry
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 msgid = msg.msgid
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 normalized = re.sub('%<[^%]+%>', '%qs', msgid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 if normalized not in seen:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 seen[normalized] = msg
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 seen[msgid] = msg
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 continue
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 prev = seen[normalized]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 warn(msg,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 'same-pattern',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 f'same pattern for {repr(msgid)} and '
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 f'{repr(prev.msgid)} in {location(prev)}',
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 include_msgid=False)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 def lint_file(po: polib.POFile):
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 for msg in po:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 msg: polib.POEntry
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 if not msg.obsolete and not msg.fuzzy:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 if 'gcc-internal-format' in msg.flags:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 lint_gcc_internal_format(msg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 lint_diagnostics_differing_only_in_placeholders(po)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 def main():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 parser = argparse.ArgumentParser(description='')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 parser.add_argument('file', help='pot file')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 args = parser.parse_args()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 po = polib.pofile(args.file)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 lint_file(po)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 print()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 print('summary:')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 for entry in seen_warnings.most_common():
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 if entry[1] > 1:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 print(f'{entry[1]}\t{entry[0]}')
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 if __name__ == '__main__':
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 main()