1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
13 #include <rtl/string.hxx>
14 #include <rtl/ustring.hxx>
15 #include <osl/file.hxx>
18 // Translated style names must be unique
19 static void checkStyleNames(const OString
& aLanguage
)
21 std::map
<OString
,sal_uInt16
> aLocalizedStyleNames
;
22 std::map
<OString
,sal_uInt16
> aLocalizedNumStyleNames
;
23 std::vector
<PoEntry
> repeatedEntries
;
25 OString aPoPath
= getenv("SRC_ROOT") +
26 OStringLiteral("/translations/source/") +
27 aLanguage
+ "/sw/messages.po";
29 aPoInput
.open(aPoPath
);
30 if( !aPoInput
.isOpen() )
32 std::cerr
<< "Warning: Cannot open " << aPoPath
<< std::endl
;
39 aPoInput
.readEntry(aPoEntry
);
40 bool bRepeated
= false;
46 if( !aPoEntry
.isFuzzy() && aPoEntry
.getMsgCtxt().startsWith("STR_POOLCOLL") )
48 const OString
& aMsgStr
= aPoEntry
.getMsgStr();
49 if( aMsgStr
.isEmpty() )
51 if( aLocalizedStyleNames
.find(aMsgStr
) == aLocalizedStyleNames
.end() )
52 aLocalizedStyleNames
[aMsgStr
] = 1;
54 aLocalizedStyleNames
[aMsgStr
]++;
58 if( !aPoEntry
.isFuzzy() && aPoEntry
.getMsgCtxt().startsWith("STR_POOLNUMRULE") )
60 const OString
& aMsgStr
= aPoEntry
.getMsgStr();
61 if( aMsgStr
.isEmpty() )
63 if( aLocalizedNumStyleNames
.find(aMsgStr
) == aLocalizedNumStyleNames
.end() )
64 aLocalizedNumStyleNames
[aMsgStr
] = 1;
66 aLocalizedNumStyleNames
[aMsgStr
]++;
71 repeatedEntries
.push_back(aPoEntry
);
75 for (auto const& localizedStyleName
: aLocalizedStyleNames
)
77 if( localizedStyleName
.second
> 1 )
79 std::cout
<< "ERROR: Style name translations must be unique in:\n" <<
80 aPoPath
<< "\nLanguage: " << aLanguage
<< "\nDuplicated translation is: " << localizedStyleName
.first
<<
81 "\nSee STR_POOLCOLL_*\n\n";
84 for (auto const& localizedNumStyleName
: aLocalizedNumStyleNames
)
86 if( localizedNumStyleName
.second
> 1 )
88 std::cout
<< "ERROR: Style name translations must be unique in:\n" <<
89 aPoPath
<< "\nLanguage: " << aLanguage
<< "\nDuplicated translation is: " << localizedNumStyleName
.first
<<
90 "\nSee STR_POOLNUMRULE_*\n\n";
94 aPoInput
.open(aPoPath
, sPoHdrMsg
);
95 if( !aPoInput
.isOpen() )
97 std::cerr
<< "Warning: Cannot open " << aPoPath
<< std::endl
;
100 PoOfstream aPoOutput
;
101 aPoOutput
.open(aPoPath
+".new");
102 PoHeader
aTmp("sw/inc", sPoHdrMsg
);
103 aPoOutput
.writeHeader(aTmp
);
104 bool bAnyError
= false;
110 aPoInput
.readEntry(aPoEntry
);
113 for (auto const& repeatedEntry
: repeatedEntries
)
115 if (repeatedEntry
.getMsgId() == aPoEntry
.getMsgId() && repeatedEntry
.getMsgCtxt() == aPoEntry
.getMsgCtxt()) {
123 aPoOutput
.writeEntry(aPoEntry
);
129 osl::FileBase::getFileURLFromSystemPath(OStringToOUString(aPoPath
, RTL_TEXTENCODING_UTF8
), aPoPathURL
);
131 osl::File::move(aPoPathURL
+ ".new", aPoPathURL
);
133 osl::File::remove(aPoPathURL
+ ".new");
136 // Translated spreadsheet function names must be unique
137 static void checkFunctionNames(const OString
& aLanguage
)
139 std::map
<OString
,sal_uInt16
> aLocalizedFunctionNames
;
140 std::map
<OString
,sal_uInt16
> aLocalizedCoreFunctionNames
;
142 std::vector
<PoEntry
> repeatedEntries
;
147 aPoPaths
[0] = getenv("SRC_ROOT") +
148 OStringLiteral("/translations/source/") +
150 "/formula/messages.po";
153 aPoInput
.open(aPoPaths
[0], sPoHdrMsg
);
154 if( !aPoInput
.isOpen() )
156 std::cerr
<< "Warning: Cannot open " << aPoPaths
[0] << std::endl
;
163 aPoInput
.readEntry(aPoEntry
);
166 if( !aPoEntry
.isFuzzy() && aPoEntry
.getMsgCtxt() == "RID_STRLIST_FUNCTION_NAMES" )
168 const OString
& aMsgStr
= aPoEntry
.getMsgStr();
169 if( aMsgStr
.isEmpty() )
171 if( aLocalizedCoreFunctionNames
.find(aMsgStr
) == aLocalizedCoreFunctionNames
.end() )
172 aLocalizedCoreFunctionNames
[aMsgStr
] = 1;
173 if( aLocalizedFunctionNames
.find(aMsgStr
) == aLocalizedFunctionNames
.end() ) {
174 aLocalizedFunctionNames
[aMsgStr
] = 1;
176 aLocalizedFunctionNames
[aMsgStr
]++;
177 repeatedEntries
.push_back(aPoEntry
);
183 aPoPaths
[1] = getenv("SRC_ROOT") +
184 OStringLiteral("/translations/source/") +
186 "/scaddins/messages.po";
187 aPoInput
.open(aPoPaths
[1]);
188 if( !aPoInput
.isOpen() )
190 std::cerr
<< "Warning: Cannot open " << aPoPaths
[1] << std::endl
;
197 aPoInput
.readEntry(aPoEntry
);
200 if( !aPoEntry
.isFuzzy() && aPoEntry
.getMsgCtxt().startsWith("ANALYSIS_FUNCNAME") )
202 OString aMsgStr
= aPoEntry
.getMsgStr();
203 if( aMsgStr
.isEmpty() )
205 if( aLocalizedCoreFunctionNames
.find(aMsgStr
) != aLocalizedCoreFunctionNames
.end() )
207 if( aLocalizedFunctionNames
.find(aMsgStr
) == aLocalizedFunctionNames
.end() ) {
208 aLocalizedFunctionNames
[aMsgStr
] = 1;
210 aLocalizedFunctionNames
[aMsgStr
]++;
211 repeatedEntries
.push_back(aPoEntry
);
217 for (auto const& localizedFunctionName
: aLocalizedFunctionNames
)
219 if( localizedFunctionName
.second
> 1 )
222 << ("ERROR: Spreadsheet function name translations must be"
223 " unique.\nLanguage: ")
224 << aLanguage
<< "\nDuplicated translation is: " << localizedFunctionName
.first
229 for (int i
=0;i
<2;i
++)
231 aPoInput
.open(aPoPaths
[i
]);
232 if( !aPoInput
.isOpen() )
233 std::cerr
<< "Warning: Cannot open " << aPoPaths
[i
] << std::endl
;
234 PoOfstream aPoOutput
;
235 aPoOutput
.open(aPoPaths
[i
]+".new");
241 PoHeader
hd("formula/inc", sPoHdrMsg
);
242 aPoOutput
.writeHeader(hd
);
247 PoHeader
hd("scaddins/inc", sPoHdrMsg
);
248 aPoOutput
.writeHeader(hd
);
252 bool bAnyError
= false;
258 aPoInput
.readEntry(aPoEntry
);
261 for (auto const& repeatedEntry
: repeatedEntries
)
263 if (repeatedEntry
.getMsgId() == aPoEntry
.getMsgId() && repeatedEntry
.getMsgCtxt() == aPoEntry
.getMsgCtxt())
275 aPoOutput
.writeEntry(aPoEntry
);
280 osl::FileBase::getFileURLFromSystemPath(OStringToOUString(aPoPaths
[i
], RTL_TEXTENCODING_UTF8
), aPoPathURL
);
282 osl::File::move(aPoPathURL
+ ".new", aPoPathURL
);
284 osl::File::remove(aPoPathURL
+ ".new");
288 // In instsetoo_native/inc_openoffice/windows/msi_languages.po
289 // where an en-US string ends with '|', translation must end
291 static void checkVerticalBar(const OString
& aLanguage
)
293 OString aPoPath
= getenv("SRC_ROOT") +
294 OStringLiteral("/translations/source/") +
296 "/instsetoo_native/inc_openoffice/windows/msi_languages.po";
298 aPoInput
.open(aPoPath
);
299 if( !aPoInput
.isOpen() )
301 std::cerr
<< "Warning: Cannot open " << aPoPath
<< std::endl
;
304 PoOfstream aPoOutput
;
305 aPoOutput
.open(aPoPath
+".new");
306 PoHeader
aTmp("instsetoo_native/inc_openoffice/windows/msi_languages");
307 aPoOutput
.writeHeader(aTmp
);
313 aPoInput
.readEntry(aPoEntry
);
316 if( !aPoEntry
.isFuzzy() && aPoEntry
.getMsgId().endsWith("|") &&
317 !aPoEntry
.getMsgStr().isEmpty() && !aPoEntry
.getMsgStr().endsWith("|") )
320 << ("ERROR: Missing '|' character at the end of translated"
321 " string.\nIt causes runtime error in installer.\nFile: ")
322 << aPoPath
<< std::endl
323 << "Language: " << aLanguage
<< std::endl
324 << "English: " << aPoEntry
.getMsgId() << std::endl
325 << "Localized: " << aPoEntry
.getMsgStr() << std::endl
330 aPoOutput
.writeEntry(aPoEntry
);
335 osl::FileBase::getFileURLFromSystemPath(OStringToOUString(aPoPath
, RTL_TEXTENCODING_UTF8
), aPoPathURL
);
337 osl::File::move(aPoPathURL
+ ".new", aPoPathURL
);
339 osl::File::remove(aPoPathURL
+ ".new");
342 // In starmath/source.po Math symbol names (from symbol.src)
343 // must not contain spaces
344 static void checkMathSymbolNames(const OString
& aLanguage
)
346 OString aPoPath
= getenv("SRC_ROOT") +
347 OStringLiteral("/translations/source/") +
349 "/starmath/messages.po";
351 aPoInput
.open(aPoPath
);
352 if( !aPoInput
.isOpen() )
354 std::cerr
<< "Warning: Cannot open " << aPoPath
<< std::endl
;
357 PoOfstream aPoOutput
;
358 aPoOutput
.open(aPoPath
+".new");
359 PoHeader
aTmp("starmath/inc");
360 aPoOutput
.writeHeader(aTmp
);
366 aPoInput
.readEntry(aPoEntry
);
369 if( !aPoEntry
.isFuzzy() && aPoEntry
.getGroupId() == "RID_UI_SYMBOL_NAMES" &&
370 !aPoEntry
.getMsgStr().isEmpty() && (aPoEntry
.getMsgStr().indexOf(" ") != -1) )
373 << "ERROR: Math symbol names must not contain spaces.\nFile: "
374 << aPoPath
<< std::endl
375 << "Language: " << aLanguage
<< std::endl
376 << "English: " << aPoEntry
.getMsgId() << std::endl
377 << "Localized: " << aPoEntry
.getMsgStr() << std::endl
382 aPoOutput
.writeEntry(aPoEntry
);
387 osl::FileBase::getFileURLFromSystemPath(OStringToOUString(aPoPath
, RTL_TEXTENCODING_UTF8
), aPoPathURL
);
389 osl::File::move(aPoPathURL
+ ".new", aPoPathURL
);
391 osl::File::remove(aPoPathURL
+ ".new");
398 OString
aLanguages(getenv("ALL_LANGS"));
399 if( aLanguages
.isEmpty() )
401 std::cerr
<< "Usage: LD_LIBRARY_PATH=instdir/program make cmd cmd=workdir/LinkTarget/Executable/pocheck\n";
404 for(sal_Int32 i
= 1;;++i
) // skip en-US
406 OString aLanguage
= aLanguages
.getToken(i
,' ');
407 if( aLanguage
.isEmpty() )
409 if( aLanguage
== "qtz" )
411 checkStyleNames(aLanguage
);
412 checkFunctionNames(aLanguage
);
413 checkVerticalBar(aLanguage
);
414 checkMathSymbolNames(aLanguage
);
418 catch (std::exception
& e
)
420 std::cerr
<< "pocheck: exception " << e
.what() << std::endl
;
425 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */