The ../../../program/ links in the URE jar Class-Paths are a temporary kludge (and juh.jar had lacked adaption for Mac OS X). Change-Id: I2542d8a582866485dd61c05df3fc6b4b39a8403d
478 lines
16 KiB
C++
478 lines
16 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <list>
|
|
#include <vector>
|
|
#include <rtl/string.hxx>
|
|
#include <rtl/ustring.hxx>
|
|
#include <osl/file.hxx>
|
|
#include "po.hxx"
|
|
|
|
// Translated style names must be unique
|
|
static void checkStyleNames(const OString& aLanguage)
|
|
{
|
|
std::map<OString,sal_uInt16> aLocalizedStyleNames;
|
|
std::map<OString,sal_uInt16> aLocalizedNumStyleNames;
|
|
std::list<PoEntry> repeatedEntries;
|
|
|
|
OString aPoPath = OString(getenv("SRC_ROOT")) +
|
|
"/translations/source/" +
|
|
aLanguage + "/sw/source/ui/utlui.po";
|
|
PoIfstream aPoInput;
|
|
aPoInput.open(aPoPath);
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPath << std::endl;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
aPoInput.readEntry(aPoEntry);
|
|
bool bRepeated = false;
|
|
if( aPoInput.eof() )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( !aPoEntry.isFuzzy() && aPoEntry.getSourceFile() == "poolfmt.src" &&
|
|
aPoEntry.getGroupId().startsWith("STR_POOLCOLL") )
|
|
{
|
|
OString aMsgStr = aPoEntry.getMsgStr();
|
|
if( aMsgStr.isEmpty() )
|
|
continue;
|
|
if( aLocalizedStyleNames.find(aMsgStr) == aLocalizedStyleNames.end() )
|
|
aLocalizedStyleNames[aMsgStr] = 1;
|
|
else {
|
|
aLocalizedStyleNames[aMsgStr]++;
|
|
bRepeated = true;
|
|
}
|
|
}
|
|
if( !aPoEntry.isFuzzy() && aPoEntry.getSourceFile() == "poolfmt.src" &&
|
|
aPoEntry.getGroupId().startsWith("STR_POOLNUMRULE") )
|
|
{
|
|
OString aMsgStr = aPoEntry.getMsgStr();
|
|
if( aMsgStr.isEmpty() )
|
|
continue;
|
|
if( aLocalizedNumStyleNames.find(aMsgStr) == aLocalizedNumStyleNames.end() )
|
|
aLocalizedNumStyleNames[aMsgStr] = 1;
|
|
else {
|
|
aLocalizedNumStyleNames[aMsgStr]++;
|
|
bRepeated = true;
|
|
}
|
|
}
|
|
if (bRepeated)
|
|
repeatedEntries.push_back(aPoEntry);
|
|
}
|
|
aPoInput.close();
|
|
|
|
for( std::map<OString,sal_uInt16>::iterator it=aLocalizedStyleNames.begin(); it!=aLocalizedStyleNames.end(); ++it)
|
|
{
|
|
if( it->second > 1 )
|
|
{
|
|
std::cout << "ERROR: Style name translations must be unique in:\n" <<
|
|
aPoPath << "\nLanguage: " << aLanguage << "\nDuplicated translation is: " << it->first <<
|
|
"\nSee STR_POOLCOLL_*\n\n";
|
|
}
|
|
}
|
|
for( std::map<OString,sal_uInt16>::iterator it=aLocalizedNumStyleNames.begin(); it!=aLocalizedNumStyleNames.end(); ++it)
|
|
{
|
|
if( it->second > 1 )
|
|
{
|
|
std::cout << "ERROR: Style name translations must be unique in:\n" <<
|
|
aPoPath << "\nLanguage: " << aLanguage << "\nDuplicated translation is: " << it->first <<
|
|
"\nSee STR_POOLNUMRULE_*\n\n";
|
|
}
|
|
}
|
|
aPoInput.open(aPoPath);
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPath << std::endl;
|
|
PoOfstream aPoOutput;
|
|
aPoOutput.open(aPoPath+".new");
|
|
PoHeader aTmp("sw/source/ui/utlui");
|
|
aPoOutput.writeHeader(aTmp);
|
|
bool bAnyError = false;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
bool bError = false;
|
|
aPoInput.readEntry(aPoEntry);
|
|
if( aPoInput.eof() )
|
|
break;
|
|
for ( std::list<PoEntry>::iterator it=repeatedEntries.begin(); it!=repeatedEntries.end(); ++it) {
|
|
if (it->getMsgId() == aPoEntry.getMsgId() && it->getGroupId() == aPoEntry.getGroupId()) {
|
|
bError = true;
|
|
break;
|
|
}
|
|
}
|
|
if (bError) {
|
|
bAnyError = true;
|
|
} else {
|
|
aPoOutput.writeEntry(aPoEntry);
|
|
}
|
|
}
|
|
aPoInput.close();
|
|
aPoOutput.close();
|
|
OUString aPoPathURL;
|
|
osl::FileBase::getFileURLFromSystemPath(OStringToOUString(aPoPath, RTL_TEXTENCODING_UTF8), aPoPathURL);
|
|
if( bAnyError )
|
|
osl::File::move(aPoPathURL + ".new", aPoPathURL);
|
|
else
|
|
osl::File::remove(aPoPathURL + ".new");
|
|
|
|
}
|
|
|
|
// Translated spreadsheet function names must be unique
|
|
static void checkFunctionNames(const OString& aLanguage)
|
|
{
|
|
std::map<OString,sal_uInt16> aLocalizedFunctionNames;
|
|
std::map<OString,sal_uInt16> aLocalizedCoreFunctionNames;
|
|
|
|
std::list<PoEntry> repeatedEntries;
|
|
|
|
OString aPoPaths[4];
|
|
OUString aPoPathURL;
|
|
|
|
aPoPaths[0] = OString(getenv("SRC_ROOT")) +
|
|
"/translations/source/" +
|
|
aLanguage +
|
|
"/formula/source/core/resource.po";
|
|
PoIfstream aPoInput;
|
|
aPoInput.open(aPoPaths[0]);
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPaths[0] << std::endl;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
aPoInput.readEntry(aPoEntry);
|
|
if( aPoInput.eof() )
|
|
break;
|
|
if( !aPoEntry.isFuzzy() && aPoEntry.getGroupId() == "RID_STRLIST_FUNCTION_NAMES" )
|
|
{
|
|
OString aMsgStr = aPoEntry.getMsgStr();
|
|
if( aMsgStr.isEmpty() )
|
|
continue;
|
|
if( aLocalizedCoreFunctionNames.find(aMsgStr) == aLocalizedCoreFunctionNames.end() )
|
|
aLocalizedCoreFunctionNames[aMsgStr] = 1;
|
|
if( aLocalizedFunctionNames.find(aMsgStr) == aLocalizedFunctionNames.end() ) {
|
|
aLocalizedFunctionNames[aMsgStr] = 1;
|
|
} else {
|
|
aLocalizedFunctionNames[aMsgStr]++;
|
|
repeatedEntries.push_back(aPoEntry);
|
|
}
|
|
}
|
|
}
|
|
aPoInput.close();
|
|
|
|
aPoPaths[1] = OString(getenv("SRC_ROOT")) +
|
|
"/translations/source/" +
|
|
aLanguage +
|
|
"/scaddins/source/analysis.po";
|
|
aPoInput.open(aPoPaths[1]);
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPaths[1] << std::endl;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
aPoInput.readEntry(aPoEntry);
|
|
if( aPoInput.eof() )
|
|
break;
|
|
if( !aPoEntry.isFuzzy() && aPoEntry.getGroupId() == "RID_ANALYSIS_FUNCTION_NAMES" )
|
|
{
|
|
OString aMsgStr = aPoEntry.getMsgStr();
|
|
if( aMsgStr.isEmpty() )
|
|
continue;
|
|
if( aLocalizedCoreFunctionNames.find(aMsgStr) != aLocalizedCoreFunctionNames.end() )
|
|
aMsgStr += "_ADD";
|
|
if( aLocalizedFunctionNames.find(aMsgStr) == aLocalizedFunctionNames.end() ) {
|
|
aLocalizedFunctionNames[aMsgStr] = 1;
|
|
} else {
|
|
aLocalizedFunctionNames[aMsgStr]++;
|
|
repeatedEntries.push_back(aPoEntry);
|
|
}
|
|
}
|
|
}
|
|
aPoInput.close();
|
|
|
|
|
|
aPoPaths[2] = OString(getenv("SRC_ROOT")) +
|
|
"/translations/source/" +
|
|
aLanguage +
|
|
"/scaddins/source/datefunc.po";
|
|
aPoInput.open(aPoPaths[2]);
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPaths[2] << std::endl;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
aPoInput.readEntry(aPoEntry);
|
|
if( aPoInput.eof() )
|
|
break;
|
|
if( !aPoEntry.isFuzzy() && aPoEntry.getGroupId() == "RID_DATE_FUNCTION_NAMES" )
|
|
{
|
|
OString aMsgStr = aPoEntry.getMsgStr();
|
|
if( aMsgStr.isEmpty() )
|
|
continue;
|
|
if( aLocalizedCoreFunctionNames.find(aMsgStr) != aLocalizedCoreFunctionNames.end() )
|
|
aMsgStr += "_ADD";
|
|
if( aLocalizedFunctionNames.find(aMsgStr) == aLocalizedFunctionNames.end() ) {
|
|
aLocalizedFunctionNames[aMsgStr] = 1;
|
|
} else {
|
|
aLocalizedFunctionNames[aMsgStr]++;
|
|
repeatedEntries.push_back(aPoEntry);
|
|
}
|
|
}
|
|
}
|
|
aPoInput.close();
|
|
|
|
aPoPaths[3] = OString(getenv("SRC_ROOT")) +
|
|
"/translations/source/" +
|
|
aLanguage +
|
|
"/scaddins/source/pricing.po";
|
|
aPoInput.open(aPoPaths[3]);
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPaths[3] << std::endl;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
aPoInput.readEntry(aPoEntry);
|
|
if( aPoInput.eof() )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( !aPoEntry.isFuzzy() && aPoEntry.getGroupId() == "RID_PRICING_FUNCTION_NAMES" )
|
|
{
|
|
OString aMsgStr = aPoEntry.getMsgStr();
|
|
if( aMsgStr.isEmpty() )
|
|
continue;
|
|
if( aLocalizedCoreFunctionNames.find(aMsgStr) != aLocalizedCoreFunctionNames.end() )
|
|
aMsgStr += "_ADD";
|
|
if( aLocalizedFunctionNames.find(aMsgStr) == aLocalizedFunctionNames.end() ) {
|
|
aLocalizedFunctionNames[aMsgStr] = 1;
|
|
} else {
|
|
aLocalizedFunctionNames[aMsgStr]++;
|
|
repeatedEntries.push_back(aPoEntry);
|
|
}
|
|
}
|
|
}
|
|
aPoInput.close();
|
|
for( std::map<OString,sal_uInt16>::iterator it=aLocalizedFunctionNames.begin(); it!=aLocalizedFunctionNames.end(); ++it)
|
|
{
|
|
if( it->second > 1 )
|
|
{
|
|
std::cout
|
|
<< ("ERROR: Spreadsheet function name translations must be"
|
|
" unique.\nLanguage: ")
|
|
<< aLanguage << "\nDuplicated translation is: " << it->first
|
|
<< "\n\n";
|
|
}
|
|
}
|
|
|
|
for (int i=0;i<4;i++)
|
|
{
|
|
aPoInput.open(aPoPaths[i]);
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPaths[i] << std::endl;
|
|
PoOfstream aPoOutput;
|
|
aPoOutput.open(aPoPaths[i]+".new");
|
|
|
|
switch (i)
|
|
{
|
|
case 0:
|
|
{
|
|
PoHeader hd(OString("formula/source/core/resource"));
|
|
aPoOutput.writeHeader(hd);
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
PoHeader hd(OString("scaddins/source/analysis"));
|
|
aPoOutput.writeHeader(hd);
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
PoHeader hd(OString("scaddins/source/datefunc"));
|
|
aPoOutput.writeHeader(hd);
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
PoHeader hd(OString("scaddins/source/pricing"));
|
|
aPoOutput.writeHeader(hd);
|
|
break;
|
|
}
|
|
}
|
|
bool bAnyError = false;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
bool bError = false;
|
|
aPoInput.readEntry(aPoEntry);
|
|
if( aPoInput.eof() )
|
|
break;
|
|
for ( std::list<PoEntry>::iterator it=repeatedEntries.begin(); it!=repeatedEntries.end(); ++it)
|
|
{
|
|
if (it->getMsgId() == aPoEntry.getMsgId() && it->getGroupId() == aPoEntry.getGroupId())
|
|
{
|
|
bError = true;
|
|
break;
|
|
}
|
|
}
|
|
if (bError)
|
|
{
|
|
bAnyError = true;
|
|
}
|
|
else
|
|
{
|
|
aPoOutput.writeEntry(aPoEntry);
|
|
}
|
|
}
|
|
aPoInput.close();
|
|
aPoOutput.close();
|
|
osl::FileBase::getFileURLFromSystemPath(OStringToOUString(aPoPaths[i], RTL_TEXTENCODING_UTF8), aPoPathURL);
|
|
if( bAnyError )
|
|
osl::File::move(aPoPathURL + ".new", aPoPathURL);
|
|
else
|
|
osl::File::remove(aPoPathURL + ".new");
|
|
}
|
|
}
|
|
|
|
// In instsetoo_native/inc_openoffice/windows/msi_languages.po
|
|
// where an en-US string ends with '|', translation must end
|
|
// with '|', too.
|
|
static void checkVerticalBar(const OString& aLanguage)
|
|
{
|
|
OString aPoPath = OString(getenv("SRC_ROOT")) +
|
|
"/translations/source/" +
|
|
aLanguage +
|
|
"/instsetoo_native/inc_openoffice/windows/msi_languages.po";
|
|
PoIfstream aPoInput;
|
|
aPoInput.open(aPoPath);
|
|
PoOfstream aPoOutput;
|
|
aPoOutput.open(aPoPath+".new");
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPath << std::endl;
|
|
PoHeader aTmp("instsetoo_native/inc_openoffice/windows/msi_languages");
|
|
aPoOutput.writeHeader(aTmp);
|
|
bool bError = false;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
aPoInput.readEntry(aPoEntry);
|
|
if( aPoInput.eof() )
|
|
break;
|
|
if( !aPoEntry.isFuzzy() && aPoEntry.getMsgId().endsWith("|") &&
|
|
!aPoEntry.getMsgStr().isEmpty() && !aPoEntry.getMsgStr().endsWith("|") )
|
|
{
|
|
std::cout
|
|
<< ("ERROR: Missing '|' character at the end of translated"
|
|
" string.\nIt causes runtime error in installer.\nFile: ")
|
|
<< aPoPath << std::endl
|
|
<< "Language: " << aLanguage << std::endl
|
|
<< "English: " << aPoEntry.getMsgId() << std::endl
|
|
<< "Localized: " << aPoEntry.getMsgStr() << std::endl
|
|
<< std::endl;
|
|
bError = true;
|
|
}
|
|
else
|
|
aPoOutput.writeEntry(aPoEntry);
|
|
}
|
|
aPoInput.close();
|
|
aPoOutput.close();
|
|
OUString aPoPathURL;
|
|
osl::FileBase::getFileURLFromSystemPath(OStringToOUString(aPoPath, RTL_TEXTENCODING_UTF8), aPoPathURL);
|
|
if( bError )
|
|
osl::File::move(aPoPathURL + ".new", aPoPathURL);
|
|
else
|
|
osl::File::remove(aPoPathURL + ".new");
|
|
}
|
|
|
|
// In starmath/source.po Math symbol names (from symbol.src)
|
|
// must not contain spaces
|
|
static void checkMathSymbolNames(const OString& aLanguage)
|
|
{
|
|
OString aPoPath = OString(getenv("SRC_ROOT")) +
|
|
"/translations/source/" +
|
|
aLanguage +
|
|
"/starmath/source.po";
|
|
PoIfstream aPoInput;
|
|
aPoInput.open(aPoPath);
|
|
PoOfstream aPoOutput;
|
|
aPoOutput.open(aPoPath+".new");
|
|
if( !aPoInput.isOpen() )
|
|
std::cerr << "Warning: Cannot open " << aPoPath << std::endl;
|
|
PoHeader aTmp("starmath/source");
|
|
aPoOutput.writeHeader(aTmp);
|
|
bool bError = false;
|
|
|
|
for(;;)
|
|
{
|
|
PoEntry aPoEntry;
|
|
aPoInput.readEntry(aPoEntry);
|
|
if( aPoInput.eof() )
|
|
break;
|
|
if( !aPoEntry.isFuzzy() && aPoEntry.getGroupId() == "RID_UI_SYMBOL_NAMES" &&
|
|
!aPoEntry.getMsgStr().isEmpty() && (aPoEntry.getMsgStr().indexOf(" ") != -1) )
|
|
{
|
|
std::cout
|
|
<< "ERROR: Math symbol names must not contain spaces.\nFile: "
|
|
<< aPoPath << std::endl
|
|
<< "Language: " << aLanguage << std::endl
|
|
<< "English: " << aPoEntry.getMsgId() << std::endl
|
|
<< "Localized: " << aPoEntry.getMsgStr() << std::endl
|
|
<< std::endl;
|
|
bError = true;
|
|
}
|
|
else
|
|
aPoOutput.writeEntry(aPoEntry);
|
|
}
|
|
aPoInput.close();
|
|
aPoOutput.close();
|
|
OUString aPoPathURL;
|
|
osl::FileBase::getFileURLFromSystemPath(OStringToOUString(aPoPath, RTL_TEXTENCODING_UTF8), aPoPathURL);
|
|
if( bError )
|
|
osl::File::move(aPoPathURL + ".new", aPoPathURL);
|
|
else
|
|
osl::File::remove(aPoPathURL + ".new");
|
|
}
|
|
|
|
int main()
|
|
{
|
|
OString aLanguages(getenv("ALL_LANGS"));
|
|
if( aLanguages.isEmpty() )
|
|
{
|
|
std::cerr << "Usage: bin/run pocheck\n";
|
|
return 1;
|
|
}
|
|
for(sal_Int32 i = 1;;++i) // skip en-US
|
|
{
|
|
OString aLanguage = aLanguages.getToken(i,' ');
|
|
if( aLanguage.isEmpty() )
|
|
break;
|
|
if( aLanguage == "qtz" )
|
|
continue;
|
|
checkStyleNames(aLanguage);
|
|
checkFunctionNames(aLanguage);
|
|
checkVerticalBar(aLanguage);
|
|
checkMathSymbolNames(aLanguage);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|