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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_L10NTOOLS_INC_EXPORT_HXX
21 : #define INCLUDED_L10NTOOLS_INC_EXPORT_HXX
22 :
23 : #include "sal/config.h"
24 : #include "po.hxx"
25 :
26 : #include <cstddef>
27 : #include <fstream>
28 :
29 : #include <osl/file.hxx>
30 : #include <osl/file.h>
31 :
32 : #include <iterator>
33 : #include <set>
34 : #include <unordered_map>
35 : #include <vector>
36 : #include <queue>
37 : #include <string>
38 :
39 : #ifdef WNT
40 : #include <direct.h>
41 : #else
42 : #include <unistd.h>
43 : #endif
44 :
45 : #define NO_TRANSLATE_ISO "x-no-translate"
46 :
47 : class MergeEntrys;
48 :
49 : typedef std::unordered_map<OString, OString, OStringHash>
50 : OStringHashMap;
51 :
52 : typedef std::unordered_map<OString, bool, OStringHash>
53 : OStringBoolHashMap;
54 :
55 : #define SOURCE_LANGUAGE "en-US"
56 : #define X_COMMENT "x-comment"
57 :
58 :
59 : // class ResData
60 :
61 :
62 : #define ID_LEVEL_NULL 0x0000
63 : #define ID_LEVEL_TEXT 0x0002
64 : #define ID_LEVEL_IDENTIFIER 0x0005
65 :
66 : typedef std::vector< OString > ExportList;
67 :
68 : /// Purpose: holds mandatory data to export a single res (used with ResStack)
69 652 : class ResData
70 : {
71 : public:
72 : ResData( const OString &rGId );
73 : ResData( const OString &rGId , const OString &rFilename );
74 : bool SetId(const OString &rId, sal_uInt16 nLevel);
75 :
76 : sal_uInt16 nIdLevel;
77 : bool bChild;
78 : bool bChildWithText;
79 :
80 : bool bText;
81 : bool bQuickHelpText;
82 : bool bTitle;
83 :
84 : OString sResTyp;
85 : OString sId;
86 : OString sGId;
87 : OString sFilename;
88 :
89 : OStringHashMap sText;
90 :
91 : OStringHashMap sQuickHelpText;
92 :
93 : OStringHashMap sTitle;
94 :
95 : OString sTextTyp;
96 :
97 : ExportList m_aList;
98 : };
99 :
100 :
101 :
102 : // class Export
103 :
104 :
105 : #define LIST_NON 0x0000
106 : #define LIST_STRING 0x0001
107 : #define LIST_FILTER 0x0002
108 : #define LIST_ITEM 0x0004
109 : #define LIST_PAIRED 0x0005
110 : #define STRING_TYP_TEXT 0x0010
111 : #define STRING_TYP_QUICKHELPTEXT 0x0040
112 : #define STRING_TYP_TITLE 0x0080
113 :
114 :
115 : typedef ::std::vector< ResData* > ResStack;
116 : class ParserQueue;
117 :
118 : /// Purpose: syntax check and export of *.src, called from lexer
119 : class Export
120 : {
121 : private:
122 : union
123 : {
124 : std::ofstream* mSimple;
125 : PoOfstream* mPo;
126 :
127 : } aOutput;
128 :
129 : ResStack aResStack; ///< stack for parsing recursive
130 :
131 : bool bDefine; // cur. res. in a define?
132 : bool bNextMustBeDefineEOL; ///< define but no \ at lineend
133 : std::size_t nLevel; // res. recursiv? how deep?
134 : sal_uInt16 nList; ///< cur. res. is List
135 : std::size_t nListIndex;
136 : std::size_t nListLevel;
137 : bool bMergeMode;
138 : OString sMergeSrc;
139 : bool bError; // any errors while export?
140 : bool bReadOver;
141 : OString sFilename;
142 : OString sLanguages;
143 :
144 : std::vector<OString> aLanguages;
145 :
146 : ParserQueue* pParseQueue;
147 :
148 : bool WriteData( ResData *pResData, bool bCreateNew = false ); ///< called before dest. cur ResData
149 : bool WriteExportList( ResData *pResData, ExportList& rExportList, const sal_uInt16 nTyp );
150 :
151 : OString MergePairedList( OString const & sLine , OString const & sText );
152 :
153 : OString FullId(); ///< creates cur. GID
154 :
155 : static OString GetPairedListID(const OString & rText);
156 : static OString GetPairedListString(const OString& rText);
157 : static OString StripList(const OString& rText);
158 :
159 : void InsertListEntry(const OString &rLine);
160 : static void CleanValue( OString &rValue );
161 : static OString GetText(const OString &rSource, int nToken);
162 :
163 : void ResData2Output( MergeEntrys *pEntry, sal_uInt16 nType, const OString& rTextType );
164 : void MergeRest( ResData *pResData );
165 : static void ConvertMergeContent( OString &rText );
166 : static void ConvertExportContent( OString &rText );
167 :
168 : void WriteToMerged(const OString &rText , bool bSDFContent);
169 : void SetChildWithText();
170 :
171 : static void CutComment( OString &rText );
172 :
173 0 : void WriteUTF8ByteOrderMarkToOutput() { *aOutput.mSimple << '\xEF' << '\xBB' << '\xBF'; }
174 :
175 : public:
176 : Export( const OString &rOutput );
177 : Export(const OString &rMergeSource, const OString &rOutput, const OString &rLanguage, bool bUTF8BOM);
178 : ~Export();
179 :
180 : void Init();
181 : int Execute( int nToken, const char * pToken ); ///< called from lexer
182 :
183 0 : void SetError() { bError = true; }
184 8 : bool GetError() { return bError; }
185 22187 : ParserQueue* GetParseQueue() { return pParseQueue; }
186 : };
187 :
188 :
189 : // class MergeEntrys
190 :
191 :
192 : /// Purpose: holds information of data to merge
193 0 : class MergeEntrys
194 : {
195 : friend class MergeDataFile;
196 : private:
197 : OStringHashMap sText;
198 : OStringBoolHashMap bTextFirst;
199 : OStringHashMap sQuickHelpText;
200 : OStringBoolHashMap bQuickHelpTextFirst;
201 : OStringHashMap sTitle;
202 : OStringBoolHashMap bTitleFirst;
203 :
204 : public:
205 0 : MergeEntrys(){};
206 0 : void InsertEntry(const OString &rId, const OString &rText,
207 : const OString &rQuickHelpText, const OString &rTitle)
208 : {
209 :
210 0 : sText[ rId ] = rText;
211 0 : bTextFirst[ rId ] = true;
212 0 : sQuickHelpText[ rId ] = rQuickHelpText;
213 0 : bQuickHelpTextFirst[ rId ] = true;
214 0 : sTitle[ rId ] = rTitle;
215 0 : bTitleFirst[ rId ] = true;
216 0 : }
217 : bool GetText( OString &rReturn, sal_uInt16 nTyp, const OString &nLangIndex, bool bDel = false );
218 :
219 : /**
220 : Generate QTZ string with ResData
221 : For executable which works one language and without PO files.
222 : */
223 : static OString GetQTZText(const ResData& rResData, const OString& rOrigText);
224 :
225 : };
226 :
227 :
228 : // class MergeDataHashMap
229 :
230 :
231 : class MergeData;
232 :
233 : /** Container for MergeData
234 :
235 : This class is an HashMap with a hidden insertion
236 : order. The class can used just like a simple
237 : HashMap, but good to know that it's use is
238 : more effective if the accessing(find) order
239 : match with the insertion order.
240 :
241 : In the most case, this match is good.
242 : (e.g. reading PO files of different languages,
243 : executables merging)
244 : */
245 : class MergeDataHashMap
246 : {
247 : private:
248 : typedef std::unordered_map<OString, MergeData*, OStringHash> HashMap_t;
249 :
250 : public:
251 8 : MergeDataHashMap()
252 : : bFirstSearch(true)
253 8 : , aLastInsertion(m_aHashMap.end())
254 8 : , aLastFound(m_aHashMap.end())
255 24 : , aFirstInOrder(m_aHashMap.end())
256 : {
257 8 : }
258 :
259 8 : ~MergeDataHashMap()
260 8 : {
261 8 : }
262 :
263 : typedef HashMap_t::iterator iterator;
264 : typedef HashMap_t::const_iterator const_iterator;
265 :
266 : std::pair<iterator,bool> insert(const OString& rKey, MergeData* pMergeData);
267 : iterator find(const OString& rKey);
268 :
269 8 : iterator begin() {return m_aHashMap.begin();}
270 230 : iterator end() {return m_aHashMap.end();}
271 :
272 0 : const_iterator begin() const {return m_aHashMap.begin();}
273 0 : const_iterator end() const {return m_aHashMap.end();}
274 :
275 : private:
276 : bool bFirstSearch;
277 : HashMap_t m_aHashMap;
278 : iterator aLastInsertion;
279 : iterator aLastFound;
280 : iterator aFirstInOrder;
281 : };
282 :
283 :
284 : // class MergeData
285 :
286 :
287 : /// Purpose: holds information of data to merge (one resource)
288 : class MergeData
289 : {
290 : friend class MergeDataHashMap;
291 :
292 : public:
293 : OString sTyp;
294 : OString sGID;
295 : OString sLID;
296 : OString sFilename;
297 : MergeEntrys* pMergeEntrys;
298 : private:
299 : MergeDataHashMap::iterator m_aNextData;
300 : public:
301 : MergeData( const OString &rTyp, const OString &rGID, const OString &rLID , const OString &rFilename );
302 : ~MergeData();
303 0 : MergeEntrys* GetMergeEntries() { return pMergeEntrys;}
304 :
305 : bool operator==( ResData *pData );
306 : };
307 :
308 :
309 : // class MergeDataFile
310 :
311 :
312 : /// Purpose: holds information of data to merge, read from PO file
313 : class MergeDataFile
314 : {
315 : private:
316 : MergeDataHashMap aMap;
317 : std::set<OString> aLanguageSet;
318 :
319 : MergeData *GetMergeData( ResData *pResData , bool bCaseSensitve = false );
320 : void InsertEntry(const OString &rTYP, const OString &rGID,
321 : const OString &rLID, const OString &nLang,
322 : const OString &rTEXT, const OString &rQHTEXT,
323 : const OString &rTITLE, const OString &sFilename,
324 : bool bFirstLang, bool bCaseSensitive);
325 : public:
326 : explicit MergeDataFile(
327 : const OString &rFileName, const OString& rFile,
328 : bool bCaseSensitive, bool bWithQtz = true );
329 : ~MergeDataFile();
330 :
331 :
332 : std::vector<OString> GetLanguages() const;
333 0 : const MergeDataHashMap& getMap() const { return aMap; }
334 :
335 : MergeEntrys *GetMergeEntrys( ResData *pResData );
336 : MergeEntrys *GetMergeEntrysCaseSensitive( ResData *pResData );
337 :
338 : static OString CreateKey(const OString& rTYP, const OString& rGID,
339 : const OString& rLID, const OString& rFilename , bool bCaseSensitive = false);
340 : };
341 :
342 :
343 110895 : class QueueEntry
344 : {
345 : public:
346 22179 : QueueEntry(int nTypVal, const OString &rLineVal)
347 22179 : : nTyp(nTypVal), sLine(rLineVal)
348 : {
349 22179 : }
350 : int nTyp;
351 : OString sLine;
352 : };
353 :
354 : class ParserQueue
355 : {
356 : public:
357 :
358 : ParserQueue( Export& aExportObj );
359 : ~ParserQueue();
360 :
361 : inline void Push( const QueueEntry& aEntry );
362 : bool bCurrentIsM; // public ?
363 : bool bNextIsM; // public ?
364 : bool bLastWasM; // public ?
365 : bool bMflag; // public ?
366 :
367 : void Close();
368 : private:
369 : std::queue<QueueEntry>* aQueueNext;
370 : std::queue<QueueEntry>* aQueueCur;
371 :
372 : Export& aExport;
373 : bool bStart;
374 :
375 : inline void Pop( std::queue<QueueEntry>& aQueue );
376 :
377 : };
378 : #endif // INCLUDED_L10NTOOLS_INC_EXPORT_HXX
379 :
380 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|