Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : */
9 :
10 : #include <iostream>
11 : #include <fstream>
12 : #include <string>
13 : #include <vector>
14 : #include <map>
15 :
16 : #include <osl/file.hxx>
17 : #include <rtl/string.hxx>
18 :
19 : #include "po.hxx"
20 :
21 : using namespace std;
22 :
23 0 : bool isInSameFile( const OString& rFirstLine, const OString& rSecondLine)
24 : {
25 : const OString rFirstSource =
26 0 : rFirstLine.getToken(PoEntry::SOURCEFILE,'\t');
27 : const OString rSecondSource =
28 0 : rSecondLine.getToken(PoEntry::SOURCEFILE,'\t');
29 : return
30 : rFirstSource.copy(0,rFirstSource.lastIndexOf("\\")) ==
31 0 : rSecondSource.copy(0,rSecondSource.lastIndexOf("\\"));
32 : }
33 :
34 :
35 : //Get path of po file
36 0 : OString GetPath(const OString& rPath, const OString& rLine)
37 : {
38 0 : OString sSourceFile = rLine.getToken(PoEntry::SOURCEFILE,'\t');
39 : OString sSourcePath = rPath + "/" +
40 0 : rLine.getToken(PoEntry::PROJECT,'\t') + "/" +
41 : sSourceFile.copy(0,sSourceFile.lastIndexOf("\\")).
42 0 : replaceAll("\\","/");
43 0 : return sSourcePath;
44 : }
45 :
46 0 : OString DelLocalId(const OString& rLine)
47 : {
48 0 : unsigned nTabIndex = 0;
49 0 : for(unsigned nComponent=0; nComponent<PoEntry::LOCALID; ++nComponent)
50 : {
51 0 : nTabIndex = rLine.indexOf('\t',nTabIndex);
52 0 : ++nTabIndex;
53 : }
54 : return rLine.replaceAt(nTabIndex,
55 0 : rLine.indexOf('\t',nTabIndex)-nTabIndex,
56 0 : "");
57 : }
58 :
59 : //Renew po files of the actual language
60 0 : void HandleLanguage(const OString& LangEntryName, const OString& rOldPath,
61 : const OString& rNewPath, const OString& rpo2loPath,
62 : const OString& rSDFPath)
63 : {
64 : //Generate and open sdf
65 0 : cout << "Process start with language: " << LangEntryName.getStr() << endl;
66 0 : OUString aTempUrl;
67 0 : if (osl::FileBase::createTempFile(0, 0, &aTempUrl)
68 : != osl::FileBase::E_None)
69 : {
70 0 : cerr << "osl::FileBase::createTempFile() failed\n";
71 : return;
72 : }
73 0 : OUString aTempPath;
74 0 : if (osl::FileBase::getSystemPathFromFileURL(aTempUrl, aTempPath)
75 : != osl::FileBase::E_None)
76 : {
77 : cerr
78 0 : << "osl::FileBase::getSystemPathFromFileURL(" << aTempUrl
79 0 : << ") failed\n";
80 : return;
81 : }
82 : const OString SDFFileName =
83 0 : OUStringToOString(aTempPath, RTL_TEXTENCODING_UTF8);
84 : const OString cmd = OString(rpo2loPath +
85 0 : " -i " + rOldPath + "/" + LangEntryName +
86 0 : " -o " + SDFFileName +
87 0 : " -l " + LangEntryName +
88 0 : " -t " + rSDFPath);
89 0 : if (system(cmd.getStr()) != 0)
90 : {
91 0 : std::cerr << "Error: Failed to execute " << cmd.getStr() << '\n';
92 0 : throw false;
93 : }
94 0 : cout << "Language sdf is ready!" << endl;
95 :
96 : //Store info for po entries
97 0 : ifstream aSDFInput(SDFFileName.getStr());
98 0 : map<sal_Int32,pair<OString,OString> > aPoInfos;
99 0 : string s;
100 0 : getline(aSDFInput,s);
101 0 : while(!aSDFInput.eof())
102 : {
103 : //Get strings belong to one po entry and store
104 0 : const OString sActUnTrans = OString(s.data(),s.length());
105 0 : if( sActUnTrans.getToken(PoEntry::LANGUAGEID,'\t')=="ast" ) throw;
106 0 : getline(aSDFInput,s);
107 0 : const OString sActTrans = OString(s.data(),s.length());
108 :
109 0 : if(!(aPoInfos.insert( pair<sal_Int32,pair<OString,OString> >(
110 0 : sActTrans.getToken(PoEntry::WIDTH,'\t').toInt32(),
111 0 : pair<OString,OString>(sActUnTrans,sActTrans))).second))
112 : {
113 0 : cerr << "Error: faild to insert into map!" << '\n';
114 0 : throw;
115 : }
116 0 : getline(aSDFInput,s);
117 0 : }
118 :
119 : //Close and remove sdf file
120 0 : aSDFInput.close();
121 0 : if (osl::File::remove(aTempUrl) != osl::FileBase::E_None)
122 : {
123 0 : cerr << "Warning: failure removing temporary " << aTempUrl << '\n';
124 : }
125 :
126 : //Construct and write out po entries
127 0 : PoOfstream aNewPo;
128 0 : for( map<sal_Int32,pair<OString,OString> >::iterator
129 0 : pActInfo=aPoInfos.begin(); pActInfo!=aPoInfos.end(); ++pActInfo )
130 : {
131 : //Make new po file and add header
132 0 : if ( pActInfo==aPoInfos.begin() ||
133 0 : !isInSameFile(((--pActInfo)++)->second.first,pActInfo->second.first) )
134 : {
135 0 : if( pActInfo!=aPoInfos.begin() )
136 0 : aNewPo.close();
137 :
138 : const OString sNewPoFileName =
139 0 : GetPath(rNewPath + "/" +LangEntryName,pActInfo->second.first) +
140 0 : ".po";
141 0 : const OString cmd2 = OString("mkdir -p " + sNewPoFileName.copy(0,sNewPoFileName.lastIndexOf("/")));
142 0 : if (system(cmd2.getStr()) != 0)
143 : {
144 0 : std::cerr << "Error: Failed to execute " << cmd2.getStr() << '\n';
145 0 : throw false;
146 : }
147 :
148 0 : aNewPo.open(sNewPoFileName);
149 0 : if (!aNewPo.isOpen())
150 : {
151 : cerr
152 0 : << "Cannot open new po file: "
153 0 : << sNewPoFileName.getStr() << endl;
154 : return;
155 : }
156 : const OString sOldPoFileName =
157 0 : GetPath(rOldPath + "/" +LangEntryName,pActInfo->second.first) +
158 0 : ".po";
159 0 : ifstream aOldPo(sOldPoFileName.getStr());
160 0 : if (!aOldPo.is_open())
161 : {
162 : cerr
163 0 : << "Cannot open old po file: "
164 0 : << sOldPoFileName.getStr() << endl;
165 : return;
166 : }
167 :
168 0 : PoHeader aTmp(aOldPo);
169 0 : aNewPo.writeHeader(aTmp);
170 0 : aOldPo.close();
171 : }
172 :
173 : //Write out po entries
174 : const PoEntry::TYPE vInitializer[] =
175 0 : { PoEntry::TTEXT, PoEntry::TQUICKHELPTEXT, PoEntry::TTITLE };
176 : const vector<PoEntry::TYPE> vTypes( vInitializer,
177 0 : vInitializer + sizeof(vInitializer) / sizeof(vInitializer[0]) );
178 0 : unsigned short nDummyBit = 0;
179 0 : for( unsigned short nIndex=0; nIndex<vTypes.size(); ++nIndex )
180 : {
181 0 : if (!pActInfo->second.first.getToken(vTypes[nIndex],'\t').isEmpty())
182 : {
183 : /**Because of xrmex there are duplicated id's,
184 : only use this if xrmex have already fixed*/
185 : const OString sSource =
186 0 : pActInfo->second.first.getToken(PoEntry::SOURCEFILE,'\t');
187 : const OString sEnding =
188 0 : sSource.copy(sSource.getLength()-4, 4);
189 0 : if (pActInfo->second.first.getToken(PoEntry::GROUPID,'\t')==
190 0 : pActInfo->second.first.getToken(PoEntry::LOCALID,'\t') &&
191 0 : ( sEnding == ".xrm" || sEnding == ".xml" ))
192 : {
193 0 : pActInfo->second.first = DelLocalId(pActInfo->second.first);
194 : }
195 : try
196 : {
197 0 : PoEntry aPE(pActInfo->second.first, vTypes[nIndex]);
198 : const OString sActStr =
199 0 : pActInfo->second.second.getToken(vTypes[nIndex],'\t');
200 0 : aPE.setMsgStr(sActStr);
201 0 : aPE.setFuzzy( sActStr.isEmpty() ? false :
202 0 : static_cast<bool>(pActInfo->second.second.getToken(PoEntry::DUMMY,'\t').
203 0 : copy(nDummyBit++,1).toBoolean()));
204 0 : aNewPo.writeEntry(aPE);
205 : }
206 0 : catch( PoEntry::Exception& )
207 : {
208 : cerr
209 0 : << "Invalid sdf line "
210 0 : << pActInfo->second.first.replaceAll("\t","\\t").getStr() << '\n';
211 0 : }
212 : }
213 : }
214 0 : }
215 0 : aNewPo.close();
216 0 : aPoInfos.clear();
217 : }
218 :
219 :
220 0 : int main(int argc, char* argv[])
221 : {
222 : //Usage
223 0 : if (argc < 4)
224 : {
225 0 : cout << "Use: renewpot oldpots newpots po2lo en-US.sdf" << endl;
226 0 : return 1;
227 : }
228 :
229 : //Call processing function with all language directories
230 0 : OUString pathUrl;
231 0 : if( osl::Directory::getFileURLFromSystemPath(
232 0 : OStringToOUString( argv[ 1 ], RTL_TEXTENCODING_UTF8 ), pathUrl ) == osl::Directory::E_None )
233 : {
234 0 : osl::Directory dir( pathUrl );
235 0 : if( dir.reset() == osl::Directory::E_None )
236 : {
237 0 : for(;;)
238 : {
239 0 : osl::DirectoryItem item;
240 0 : if( dir.getNextItem( item ) != osl::Directory::E_None )
241 : break;
242 0 : osl::FileStatus status( osl_FileStatus_Mask_FileName );
243 0 : if( item.getFileStatus( status ) == osl::File::E_None && status.getFileName().indexOf('.')==-1 )
244 : HandleLanguage( OUStringToOString(status.getFileName(), RTL_TEXTENCODING_UTF8),
245 : OString(argv[1]),
246 : OString(argv[2]),OString(argv[3]),
247 0 : OString(argv[4]));
248 0 : }
249 0 : }
250 0 : }
251 0 : }
252 :
253 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|