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 : #include "sal/config.h"
21 :
22 : #include <cstddef>
23 : #include <cstring>
24 :
25 : #include "helper.hxx"
26 : #include "boost/scoped_ptr.hpp"
27 : #include <stdio.h>
28 : #include <stdlib.h>
29 : #include "common.hxx"
30 : #include "export.hxx"
31 : #include "tokens.h"
32 : #include <iostream>
33 : #include <rtl/strbuf.hxx>
34 :
35 : void yyerror( const char * );
36 : void YYWarning( const char * );
37 :
38 : namespace {
39 :
40 : MergeDataFile * pMergeDataFile = 0; //TODO
41 :
42 : namespace global {
43 :
44 13 : OString inputPathname;
45 13 : boost::scoped_ptr< Export > exporter;
46 :
47 : }
48 :
49 : }
50 :
51 : extern "C" {
52 :
53 13 : FILE * init(int argc, char ** argv) {
54 :
55 13 : common::HandledArgs aArgs;
56 13 : if ( !common::handleArguments(argc, argv, aArgs) )
57 : {
58 0 : common::writeUsage("transex3","*.src/*.hrc");
59 0 : std::exit(EXIT_FAILURE);
60 : }
61 13 : global::inputPathname = aArgs.m_sInputFile;
62 :
63 13 : FILE * pFile = std::fopen(global::inputPathname.getStr(), "r");
64 13 : if (pFile == 0) {
65 : std::fprintf(
66 : stderr, "Error: Cannot open file \"%s\"\n",
67 0 : global::inputPathname.getStr());
68 0 : std::exit(EXIT_FAILURE);
69 : }
70 :
71 13 : if (aArgs.m_bMergeMode) {
72 : global::exporter.reset(
73 13 : new Export(aArgs.m_sMergeSrc, aArgs.m_sOutputFile, aArgs.m_sLanguage));
74 : } else {
75 0 : global::exporter.reset(new Export(aArgs.m_sOutputFile));
76 : }
77 :
78 13 : global::exporter->Init();
79 :
80 13 : return pFile;
81 : }
82 :
83 262 : int Parse( int nTyp, const char *pTokenText ){
84 262 : global::exporter->Execute( nTyp , pTokenText );
85 262 : return 1;
86 : }
87 13 : void Close(){
88 13 : global::exporter->pParseQueue->Close();
89 13 : global::exporter.reset();
90 : // avoid nontrivial Export dtor being executed during exit
91 13 : }
92 :
93 32478 : int WorkOnTokenSet( int nTyp, char *pTokenText )
94 : {
95 :
96 32478 : global::exporter->pParseQueue->Push( QueueEntry( nTyp , OString(pTokenText) ) );
97 32478 : return 1;
98 : }
99 :
100 : } // extern
101 :
102 : extern "C" {
103 :
104 0 : int SetError()
105 : {
106 : // set error at global instance of class Export
107 0 : global::exporter->SetError();
108 0 : return 1;
109 : }
110 : }
111 :
112 : extern "C" {
113 :
114 13 : int GetError()
115 : {
116 : // get error at global instance of class Export
117 13 : if (global::exporter->GetError())
118 0 : return 1;
119 13 : return sal_False;
120 : }
121 : }
122 :
123 : //
124 : // class ResData
125 : //
126 :
127 1059 : sal_Bool ResData::SetId( const OString& rId, sal_uInt16 nLevel )
128 : {
129 1059 : if ( nLevel > nIdLevel )
130 : {
131 670 : nIdLevel = nLevel;
132 670 : sId = rId;
133 :
134 670 : if ( bChild && bChildWithText )
135 : {
136 0 : OString sError(RTL_CONSTASCII_STRINGPARAM("ResId after child definition"));
137 0 : yyerror(sError.getStr());
138 0 : SetError();
139 : }
140 :
141 670 : if ( sId.getLength() > 255 )
142 : {
143 0 : YYWarning( "LocalId > 255 chars, truncating..." );
144 0 : sId = sId.copy(0, 255).trim();
145 : }
146 :
147 670 : return sal_True;
148 : }
149 :
150 389 : return sal_False;
151 : }
152 :
153 : //
154 : // class Export
155 : //
156 :
157 : namespace
158 : {
159 :
160 1262 : static sal_Int32 lcl_countOccurrences(const OString& text, char c)
161 : {
162 1262 : sal_Int32 n = 0;
163 3786 : for (sal_Int32 i = 0;; ++i) {
164 3786 : i = text.indexOf(c, i);
165 3786 : if (i == -1) {
166 1262 : break;
167 : }
168 2524 : ++n;
169 2524 : }
170 1262 : return n;
171 : }
172 :
173 : }
174 :
175 0 : Export::Export(const OString &rOutput)
176 : :
177 : bDefine( sal_False ),
178 : bNextMustBeDefineEOL( sal_False ),
179 : nLevel( 0 ),
180 : nList( LIST_NON ),
181 : nListIndex( 0 ),
182 : nListLevel( 0 ),
183 : bSkipFile( false ),
184 : bMergeMode( false ),
185 : bError( sal_False ),
186 : bReadOver( sal_False ),
187 : bDontWriteOutput( sal_False ),
188 : sFilename( global::inputPathname ),
189 : sLanguages( OString() ),
190 0 : pParseQueue( new ParserQueue( *this ) )
191 : {
192 0 : aOutput.mPo = new PoOfstream( rOutput, PoOfstream::APP );
193 0 : if (!aOutput.mPo->isOpen()) {
194 0 : fprintf(stderr, "ERROR : Can't open file %s\n", rOutput.getStr());
195 0 : exit ( -1 );
196 : }
197 0 : }
198 :
199 13 : Export::Export(
200 : const OString &rMergeSource, const OString &rOutput,
201 : const OString &rLanguage )
202 : :
203 : bDefine( sal_False ),
204 : bNextMustBeDefineEOL( sal_False ),
205 : nLevel( 0 ),
206 : nList( LIST_NON ),
207 : nListIndex( 0 ),
208 : nListLevel( 0 ),
209 : bSkipFile( false ),
210 : bMergeMode( sal_True ),
211 : sMergeSrc( rMergeSource ),
212 : bError( sal_False ),
213 : bReadOver( sal_False ),
214 : bDontWriteOutput( sal_False ),
215 : sFilename( global::inputPathname ),
216 : sLanguages( rLanguage ),
217 13 : pParseQueue( new ParserQueue( *this ) )
218 : {
219 13 : aOutput.mSimple = new std::ofstream();
220 13 : aOutput.mSimple->open(rOutput.getStr(), std::ios_base::out | std::ios_base::trunc);
221 13 : }
222 :
223 13 : void Export::Init()
224 : {
225 : // resets the internal status, used before parseing another file
226 13 : bDefine = sal_False;
227 13 : bNextMustBeDefineEOL = sal_False;
228 13 : nLevel = 0;
229 13 : nList = LIST_NON;
230 13 : m_sListLang = OString();
231 13 : nListIndex = 0;
232 13 : for ( size_t i = 0, n = aResStack.size(); i < n; ++i )
233 0 : delete aResStack[ i ];
234 13 : aResStack.clear();
235 13 : }
236 :
237 26 : Export::~Export()
238 : {
239 13 : if( pParseQueue )
240 13 : delete pParseQueue;
241 13 : if ( bMergeMode )
242 : {
243 13 : aOutput.mSimple->close();
244 13 : delete aOutput.mSimple;
245 : }
246 : else
247 : {
248 0 : aOutput.mPo->close();
249 0 : delete aOutput.mPo;
250 : }
251 13 : for ( size_t i = 0, n = aResStack.size(); i < n; ++i )
252 0 : delete aResStack[ i ];
253 13 : aResStack.clear();
254 :
255 13 : if ( bMergeMode ) {
256 13 : if ( !pMergeDataFile )
257 0 : pMergeDataFile = new MergeDataFile(sMergeSrc, global::inputPathname, false);
258 :
259 13 : delete pMergeDataFile;
260 : }
261 13 : }
262 :
263 32764 : int Export::Execute( int nToken, const char * pToken )
264 : {
265 :
266 32764 : OString sToken( pToken );
267 65528 : OString sOrig( sToken );
268 32764 : sal_Bool bWriteToMerged = bMergeMode;
269 :
270 32764 : if ( nToken == CONDITION )
271 : {
272 157 : OString sTestToken(pToken);
273 314 : sTestToken = sTestToken.replaceAll("\t", OString()).
274 157 : replaceAll(" ", OString());
275 157 : if (( !bReadOver ) && ( sTestToken.indexOf("#ifndef__RSC_PARSER") == 0 ))
276 0 : bReadOver = sal_True;
277 157 : else if (( bReadOver ) && ( sTestToken.indexOf("#endif") == 0 ))
278 0 : bReadOver = sal_False;
279 : }
280 89478 : if ((( nToken < FILTER_LEVEL ) || ( bReadOver )) &&
281 28360 : (!(( bNextMustBeDefineEOL ) && ( sOrig == "\n" )))) {
282 : // this tokens are not mandatory for parsing, so ignore them ...
283 28356 : if ( bMergeMode )
284 28356 : WriteToMerged( sOrig , false ); // ... or write them directly to dest.
285 28356 : return 0;
286 : }
287 :
288 4408 : ResData *pResData = NULL;
289 4408 : if ( nLevel ) {
290 : // res. exists at cur. level
291 3791 : pResData = ( (nLevel-1) < aResStack.size() ) ? aResStack[ nLevel-1 ] : NULL;
292 : }
293 617 : else if (( nToken != RESOURCE ) &&
294 585 : ( nToken != RESOURCEEXPR ) &&
295 585 : ( nToken != SMALRESOURCE ) &&
296 585 : ( nToken != LEVELUP ) &&
297 513 : ( nToken != NORMDEFINE ) &&
298 253 : ( nToken != RSCDEFINE ) &&
299 187 : ( nToken != CONDITION ) &&
300 : ( nToken != PRAGMA ))
301 : {
302 : // no res. exists at cur. level so return
303 187 : if ( bMergeMode )
304 187 : WriteToMerged( sOrig , false );
305 187 : return 0;
306 : }
307 : // #define NO_LOCALIZE_EXPORT
308 4221 : if( bSkipFile ){
309 0 : if ( bMergeMode ) {
310 0 : WriteToMerged( sOrig , false );
311 : }
312 0 : return 1;
313 : }
314 :
315 :
316 4221 : if ( bDefine ) {
317 2576 : if (( nToken != EMPTYLINE ) && ( nToken != LEVELDOWN ) && ( nToken != LEVELUP )) {
318 : // cur. res. defined in macro
319 1945 : if ( bNextMustBeDefineEOL ) {
320 2 : if ( nToken != RSCDEFINELEND ) {
321 : // end of macro found, so destroy res.
322 2 : bDefine = sal_False;
323 2 : Execute( LEVELDOWN, "" );
324 2 : bNextMustBeDefineEOL = sal_False;
325 : }
326 : else {
327 : // next line also in macro definition
328 0 : bNextMustBeDefineEOL = sal_False;
329 0 : if ( bMergeMode )
330 0 : WriteToMerged( sOrig , false );
331 0 : return 1;
332 : }
333 : }
334 : }
335 : }
336 :
337 4221 : sal_Bool bExecuteDown = sal_False;
338 4221 : if ( nToken != LEVELDOWN ) {
339 3389 : sal_uInt16 nOpen = 0;
340 3389 : sal_uInt16 nClose = 0;
341 3389 : sal_Bool bReadOver1 = sal_False;
342 3389 : sal_uInt16 i = 0;
343 107581 : for ( i = 0; i < sToken.getLength(); i++ ) {
344 104192 : if ( sToken[i] == '"' )
345 878 : bReadOver1 = !bReadOver1;
346 104192 : if ( !bReadOver1 && ( sToken[i] == '{' ))
347 572 : nOpen++;
348 : }
349 :
350 3389 : bReadOver1 = sal_False;
351 107581 : for ( i = 0; i < sToken.getLength(); i++ ) {
352 104192 : if ( sToken[i] == '"' )
353 878 : bReadOver1 = !bReadOver1;
354 104192 : if ( !bReadOver1 && ( sToken[i] == '}' ))
355 3 : nClose++;
356 : }
357 :
358 3389 : if ( nOpen < nClose )
359 0 : bExecuteDown = sal_True;
360 : }
361 4221 : switch ( nToken ) {
362 :
363 : case NORMDEFINE:
364 72 : sToken = sToken.replace('\r', ' ').replace('\t', ' ');
365 : for (;;) {
366 501 : sal_Int32 n = 0;
367 501 : sToken = sToken.replaceFirst(" ", " ", &n);
368 501 : if (n == -1) {
369 72 : break;
370 : }
371 429 : }
372 72 : if( sToken.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("#define NO_LOCALIZE_EXPORT")) ){
373 0 : bSkipFile = true;
374 0 : return 0;
375 : }
376 72 : if ( bMergeMode )
377 72 : WriteToMerged( sOrig , false );
378 :
379 72 : return 0;
380 :
381 :
382 : case RSCDEFINE:
383 265 : bDefine = sal_True; // res. defined in macro
384 :
385 : case RESOURCE:
386 : case RESOURCEEXPR: {
387 394 : bDontWriteOutput = sal_False;
388 394 : if ( nToken != RSCDEFINE )
389 129 : bNextMustBeDefineEOL = sal_False;
390 : // this is the beginning of a new res.
391 394 : nLevel++;
392 394 : if ( nLevel > 1 ) {
393 102 : aResStack[ nLevel - 2 ]->bChild = sal_True;
394 : }
395 :
396 : // create new instance for this res. and fill mandatory fields
397 :
398 394 : pResData = new ResData( FullId() , sFilename );
399 394 : aResStack.push_back( pResData );
400 788 : sToken = sToken.replaceAll("\n", OString()).
401 : replaceAll("\r", OString()).
402 394 : replaceAll("{", OString()).replace('\t', ' ');
403 394 : sToken = sToken.trim();
404 394 : OString sTLower = sToken.getToken(0, ' ').toAsciiLowerCase();
405 394 : pResData->sResTyp = sTLower;
406 788 : OString sId( sToken.copy( pResData->sResTyp.getLength() + 1 ));
407 788 : OString sCondition;
408 394 : if ( sId.indexOf( '#' ) != -1 )
409 : {
410 : // between ResTyp, Id and paranthes is a precomp. condition
411 22 : sCondition = "#";
412 22 : sal_Int32 n = 0;
413 22 : sId = sId.getToken(0, '#', n);
414 22 : sCondition += sId.getToken(0, '#', n);
415 : }
416 394 : sId = sId.getToken(0, '/');
417 394 : CleanValue( sId );
418 394 : sId = sId.replaceAll("\t", OString());
419 394 : pResData->SetId( sId, ID_LEVEL_IDENTIFIER );
420 394 : if (!sCondition.isEmpty())
421 : {
422 22 : Execute( CONDITION, ""); // execute the precomp. condition
423 394 : }
424 : }
425 394 : break;
426 : case SMALRESOURCE: {
427 377 : bDontWriteOutput = sal_False;
428 : // this is the beginning of a new res.
429 377 : bNextMustBeDefineEOL = sal_False;
430 377 : nLevel++;
431 377 : if ( nLevel > 1 ) {
432 377 : aResStack[ nLevel - 2 ]->bChild = sal_True;
433 : }
434 :
435 : // create new instance for this res. and fill mandatory fields
436 :
437 377 : pResData = new ResData( FullId() , sFilename );
438 377 : aResStack.push_back( pResData );
439 754 : sToken = sToken.replaceAll("\n", OString()).
440 : replaceAll("\r", OString()).
441 : replaceAll("{", OString()).
442 : replaceAll("\t", OString()).
443 : replaceAll(" ", OString()).
444 377 : replaceAll("\\", OString()).toAsciiLowerCase();
445 377 : pResData->sResTyp = sToken;
446 : }
447 377 : break;
448 : case LEVELUP: {
449 : // push
450 59 : if ( nList )
451 0 : nListLevel++;
452 59 : if ( nList )
453 0 : break;
454 :
455 59 : bDontWriteOutput = sal_False;
456 59 : OString sLowerTyp;
457 59 : if ( pResData )
458 59 : sLowerTyp = "unknown";
459 59 : nLevel++;
460 59 : if ( nLevel > 1 ) {
461 59 : aResStack[ nLevel - 2 ]->bChild = sal_True;
462 : }
463 :
464 59 : ResData *pNewData = new ResData( FullId() , sFilename );
465 59 : pNewData->sResTyp = sLowerTyp;
466 59 : aResStack.push_back( pNewData );
467 : }
468 59 : break;
469 : case LEVELDOWN: {
470 : // pop
471 832 : if ( !nList ) {
472 830 : bDontWriteOutput = sal_False;
473 830 : if ( nLevel ) {
474 830 : if ( bDefine && (nLevel == 1 )) {
475 1 : bDefine = sal_False;
476 1 : bNextMustBeDefineEOL = sal_False;
477 : }
478 830 : WriteData( pResData );
479 830 : ResStack::iterator it = aResStack.begin();
480 830 : ::std::advance( it, nLevel-1 );
481 830 : delete *it;
482 830 : aResStack.erase( it );
483 830 : nLevel--;
484 : }
485 : }
486 : else {
487 2 : if ( bDefine )
488 2 : bNextMustBeDefineEOL = sal_True;
489 2 : if ( !nListLevel ) {
490 2 : nList = LIST_NON;
491 : }
492 : else
493 0 : nListLevel--;
494 : }
495 : }
496 832 : break;
497 : case ASSIGNMENT:
498 : {
499 1089 : bDontWriteOutput = sal_False;
500 : // interpret different types of assignement
501 1089 : sal_Int32 n = 0;
502 : OString sKey = sToken.getToken(0, '=', n).
503 : replaceAll(" ", OString()).
504 1089 : replaceAll("\t", OString());
505 2178 : OString sValue = sToken.getToken(0, '=', n);
506 1089 : CleanValue( sValue );
507 1089 : sKey = sKey.toAsciiUpperCase();
508 1089 : if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("IDENTIFIER")))
509 : {
510 : OString sId(
511 : sValue.replaceAll("\t", OString()).
512 357 : replaceAll(" ", OString()));
513 357 : pResData->SetId(sId, ID_LEVEL_IDENTIFIER);
514 : }
515 732 : else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("HELPID")))
516 : {
517 323 : pResData->sHelpId = sValue;
518 : }
519 409 : else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("STRINGLIST")))
520 : {
521 0 : pResData->bList = sal_True;
522 0 : nList = LIST_STRING;
523 0 : m_sListLang = SOURCE_LANGUAGE;
524 0 : nListIndex = 0;
525 0 : nListLevel = 0;
526 : }
527 409 : else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("FILTERLIST")))
528 : {
529 0 : pResData->bList = sal_True;
530 0 : nList = LIST_FILTER;
531 0 : m_sListLang = SOURCE_LANGUAGE;
532 0 : nListIndex = 0;
533 0 : nListLevel = 0;
534 : }
535 409 : else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("UIENTRIES")))
536 : {
537 0 : pResData->bList = sal_True;
538 0 : nList = LIST_UIENTRIES;
539 0 : m_sListLang = SOURCE_LANGUAGE;
540 0 : nListIndex = 0;
541 0 : nListLevel = 0;
542 : }
543 2178 : if (sToken.indexOf( '{' ) != -1
544 1089 : && (lcl_countOccurrences(sToken, '{')
545 0 : > lcl_countOccurrences(sToken, '}')))
546 : {
547 0 : Parse( LEVELUP, "" );
548 1089 : }
549 : }
550 1089 : break;
551 : case UIENTRIES:
552 : case LISTASSIGNMENT:
553 : {
554 4 : bDontWriteOutput = sal_False;
555 : OString sTmpToken(
556 4 : sToken.replaceAll(" ", OString()).toAsciiLowerCase());
557 4 : sal_Int32 nPos = sTmpToken.indexOf("[en-us]=");
558 4 : if (nPos != -1) {
559 : OString sKey(
560 : sTmpToken.copy(0 , nPos).replaceAll(" ", OString()).
561 2 : replaceAll("\t", OString()));
562 4 : OString sValue = sToken.getToken(1, '=');
563 2 : CleanValue( sValue );
564 2 : sKey = sKey.toAsciiUpperCase();
565 2 : if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("STRINGLIST")))
566 : {
567 2 : pResData->bList = sal_True;
568 2 : nList = LIST_STRING;
569 2 : m_sListLang = SOURCE_LANGUAGE;
570 2 : nListIndex = 0;
571 2 : nListLevel = 0;
572 : }
573 0 : else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("FILTERLIST")))
574 : {
575 0 : pResData->bList = sal_True;
576 0 : nList = LIST_FILTER;
577 0 : m_sListLang = SOURCE_LANGUAGE;
578 0 : nListIndex = 0;
579 0 : nListLevel = 0;
580 : }
581 0 : else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("PAIREDLIST")))
582 : {
583 0 : pResData->bList = sal_True;
584 0 : nList = LIST_PAIRED;
585 0 : m_sListLang = SOURCE_LANGUAGE;
586 0 : nListIndex = 0;
587 0 : nListLevel = 0;
588 : }
589 0 : else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("ITEMLIST")))
590 : {
591 0 : pResData->bList = sal_True;
592 0 : nList = LIST_ITEM;
593 0 : m_sListLang = SOURCE_LANGUAGE;
594 0 : nListIndex = 0;
595 0 : nListLevel = 0;
596 : }
597 0 : else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("UIENTRIES")))
598 : {
599 0 : pResData->bList = sal_True;
600 0 : nList = LIST_UIENTRIES;
601 0 : m_sListLang = SOURCE_LANGUAGE;
602 0 : nListIndex = 0;
603 0 : nListLevel = 0;
604 2 : }
605 4 : }
606 : }
607 4 : break;
608 : case TEXT:
609 : case _LISTTEXT:
610 : case LISTTEXT: {
611 : // this is an entry for a String- or FilterList
612 23 : if ( nList ) {
613 17 : SetChildWithText();
614 17 : sal_Int32 n = 0;
615 17 : OString sEntry(sToken.getToken(1, '"', n));
616 17 : if ( lcl_countOccurrences(sToken, '"') > 2 )
617 0 : sEntry += "\"";
618 17 : if ( sEntry == "\\\"" )
619 0 : sEntry = "\"";
620 17 : InsertListEntry( sEntry, sOrig );
621 : }
622 : }
623 23 : break;
624 : case LONGTEXTLINE:
625 : case TEXTLINE:
626 415 : bDontWriteOutput = sal_False;
627 415 : if ( nLevel )
628 : {
629 415 : CutComment( sToken );
630 :
631 : // this is a text line!!!
632 415 : OString t(sToken.getToken(0, '='));
633 : OString sKey(
634 : t.getToken(0, '[').replaceAll(" ", OString()).
635 830 : replaceAll("\t", OString()));
636 830 : OString sText( GetText( sToken, nToken ));
637 830 : OString sLang;
638 415 : if ( sToken.getToken(0, '=').indexOf('[') != -1 )
639 : {
640 628 : sLang = sToken.getToken(0, '=').getToken(1, '[').
641 314 : getToken(0, ']');
642 314 : CleanValue( sLang );
643 : }
644 830 : OString sLangIndex = sLang;
645 830 : OString sOrigKey = sKey;
646 415 : if ( !sText.isEmpty() && !sLang.isEmpty() )
647 : {
648 309 : sKey = sKey.toAsciiUpperCase();
649 618 : if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("TEXT")) ||
650 0 : sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("MESSAGE")) ||
651 0 : sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("CUSTOMUNITTEXT")) ||
652 309 : sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("SLOTNAME")) ||
653 0 : sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("UINAME")))
654 : {
655 309 : SetChildWithText();
656 309 : if ( sLangIndex.equalsIgnoreAsciiCase("en-US") )
657 308 : pResData->SetId( sText, ID_LEVEL_TEXT );
658 :
659 309 : pResData->bText = sal_True;
660 309 : pResData->sTextTyp = sOrigKey;
661 309 : if ( !bMergeMode )
662 : {
663 0 : if (!pResData->sText[ sLangIndex ].isEmpty())
664 : {
665 0 : OStringBuffer sError(RTL_CONSTASCII_STRINGPARAM("Language "));
666 0 : sError.append(sLangIndex);
667 0 : sError.append(RTL_CONSTASCII_STRINGPARAM("defined twice"));
668 0 : yyerror(sError.getStr());
669 : }
670 0 : pResData->sText[ sLangIndex ] = sText;
671 : }
672 : }
673 0 : else if ( sKey == "HELPTEXT" ) {
674 0 : SetChildWithText();
675 0 : pResData->bHelpText = sal_True;
676 0 : if ( !bMergeMode )
677 : {
678 0 : if (!pResData->sHelpText[ sLangIndex ].isEmpty())
679 : {
680 0 : OStringBuffer sError(RTL_CONSTASCII_STRINGPARAM("Language "));
681 0 : sError.append(sLangIndex);
682 0 : sError.append(" defined twice");
683 0 : YYWarning(sError.getStr());
684 : }
685 0 : pResData->sHelpText[ sLangIndex ] = sText;
686 : }
687 : }
688 0 : else if ( sKey == "QUICKHELPTEXT" ) {
689 0 : SetChildWithText();
690 0 : pResData->bQuickHelpText = sal_True;
691 0 : if ( !bMergeMode )
692 : {
693 0 : if (!pResData->sQuickHelpText[ sLangIndex ].isEmpty())
694 : {
695 0 : OStringBuffer sError(RTL_CONSTASCII_STRINGPARAM("Language "));
696 0 : sError.append(sLangIndex);
697 0 : sError.append(RTL_CONSTASCII_STRINGPARAM(" defined twice"));
698 0 : YYWarning(sError.getStr());
699 : }
700 0 : pResData->sQuickHelpText[ sLangIndex ] = sText;
701 : }
702 : }
703 0 : else if ( sKey == "TITLE" ) {
704 0 : SetChildWithText();
705 0 : pResData->bTitle = sal_True;
706 0 : if ( !bMergeMode )
707 : {
708 0 : if ( !pResData->sTitle[ sLangIndex ].isEmpty())
709 : {
710 0 : OStringBuffer sError(RTL_CONSTASCII_STRINGPARAM("Language "));
711 0 : sError.append(sLangIndex);
712 0 : sError.append(RTL_CONSTASCII_STRINGPARAM(" defined twice"));
713 0 : YYWarning(sError.getStr());
714 : }
715 0 : pResData->sTitle[ sLangIndex ] = sText;
716 : }
717 : }
718 0 : else if ( sKey == "ACCESSPATH" ) {
719 0 : pResData->SetId( sText, ID_LEVEL_ACCESSPATH );
720 : }
721 0 : else if ( sKey == "FIELDNAME" ) {
722 0 : pResData->SetId( sText, ID_LEVEL_FIELDNAME );
723 : }
724 415 : }
725 : }
726 415 : break;
727 : case NEWTEXTINRES: {
728 0 : bDontWriteOutput = sal_True;
729 : }
730 0 : break;
731 : case APPFONTMAPPING:
732 : {
733 205 : bDontWriteOutput = sal_False;
734 : }
735 205 : break;
736 : case RSCDEFINELEND:
737 219 : bDontWriteOutput = sal_False;
738 219 : break;
739 : case CONDITION: {
740 157 : bDontWriteOutput = sal_False;
741 157 : if ( nLevel ) {
742 91 : WriteData( pResData, sal_True );
743 : }
744 : }
745 157 : break;
746 : case EMPTYLINE : {
747 361 : bDontWriteOutput = sal_False;
748 361 : if ( bDefine ) {
749 257 : bNextMustBeDefineEOL = sal_False;
750 257 : bDefine = sal_False;
751 776 : while ( nLevel )
752 262 : Parse( LEVELDOWN, "" );
753 : }
754 : }
755 361 : break;
756 : case PRAGMA : {
757 0 : bDontWriteOutput = sal_False;
758 0 : fprintf(stderr, "ERROR: archaic PRAGMA %s\n", sToken.getStr());
759 0 : exit(-1);
760 : }
761 : break;
762 : case TEXTREFID : {
763 12 : bDontWriteOutput = sal_True;
764 : }
765 : }
766 4149 : if ( bWriteToMerged ) {
767 : // the current token must be written to dest. without merging
768 :
769 4149 : if( bDefine && sOrig.getLength() > 2 ){
770 84698 : for( sal_uInt16 n = 0 ; n < sOrig.getLength() ; n++ ){
771 82536 : if( sOrig[n] == '\n' && sOrig[n-1] != '\\'){
772 0 : sOrig = sOrig.replaceAt(n++, 0, "\\");
773 : }
774 : }
775 : }
776 4149 : WriteToMerged( sOrig , false);
777 : }
778 :
779 4149 : if ( bExecuteDown ) {
780 0 : Parse( LEVELDOWN, "" );
781 : }
782 :
783 36913 : return 1;
784 : }
785 :
786 415 : void Export::CutComment( OString &rText )
787 : {
788 415 : if (rText.indexOf("//") != -1) {
789 0 : OString sWork(rText.replaceAll("\\\"", "XX"));
790 0 : bool bInner = false;
791 0 : for (sal_Int32 i = 0; i < sWork.getLength() - 1; ++i) {
792 0 : if (sWork[i] == '"') {
793 0 : bInner = !bInner;
794 0 : } else if (sWork[i] == '/' && !bInner && sWork[i + 1] == '/' ) {
795 0 : rText = rText.copy(0, i);
796 0 : break;
797 : }
798 0 : }
799 : }
800 415 : }
801 :
802 921 : sal_Bool Export::WriteData( ResData *pResData, sal_Bool bCreateNew )
803 : {
804 921 : if ( bMergeMode ) {
805 921 : MergeRest( pResData );
806 921 : return sal_True;
807 : }
808 :
809 : // mandatory to export: en-US
810 :
811 0 : if (( !pResData->sText[ SOURCE_LANGUAGE ].isEmpty())
812 0 : ||
813 0 : ( !pResData->sHelpText[ SOURCE_LANGUAGE ].isEmpty())
814 0 : ||
815 0 : ( !pResData->sQuickHelpText[ SOURCE_LANGUAGE ].isEmpty())
816 0 : ||
817 0 : ( !pResData->sTitle[ SOURCE_LANGUAGE ].isEmpty()))
818 :
819 : {
820 0 : OString sGID = pResData->sGId;
821 0 : OString sLID;
822 0 : if (sGID.isEmpty())
823 0 : sGID = pResData->sId;
824 : else
825 0 : sLID = pResData->sId;
826 :
827 0 : OString sXText;
828 0 : OString sXHText;
829 0 : OString sXQHText;
830 0 : OString sXTitle;
831 :
832 0 : sXText = pResData->sText[ SOURCE_LANGUAGE ];
833 0 : if (!pResData->sText[ X_COMMENT ].isEmpty())
834 0 : sXHText = pResData->sText[ X_COMMENT ];
835 : else
836 0 : sXHText = pResData->sHelpText[ SOURCE_LANGUAGE ];
837 0 : sXQHText = pResData->sQuickHelpText[ SOURCE_LANGUAGE ];
838 0 : sXTitle = pResData->sTitle[ SOURCE_LANGUAGE ];
839 :
840 0 : if( !sXText.isEmpty() )
841 : {
842 0 : ConvertExportContent(sXText);
843 0 : ConvertExportContent(sXHText);
844 : common::writePoEntry(
845 : "Transex3", *aOutput.mPo, global::inputPathname,
846 0 : pResData->sResTyp, sGID, sLID, sXHText, sXText);
847 : }
848 0 : if( !sXQHText.isEmpty() )
849 : {
850 0 : ConvertExportContent(sXQHText);
851 : common::writePoEntry(
852 : "Transex3", *aOutput.mPo, global::inputPathname, pResData->sResTyp,
853 0 : sGID, sLID, OString(), sXQHText, PoEntry::TQUICKHELPTEXT );
854 : }
855 0 : if( !sXTitle.isEmpty() )
856 : {
857 0 : ConvertExportContent(sXTitle);
858 : common::writePoEntry(
859 : "Transex3", *aOutput.mPo, global::inputPathname, pResData->sResTyp,
860 0 : sGID, sLID, OString(), sXTitle, PoEntry::TTITLE );
861 : }
862 :
863 0 : if ( bCreateNew ) {
864 0 : pResData->sText[ SOURCE_LANGUAGE ] = "";
865 0 : pResData->sHelpText[ SOURCE_LANGUAGE ] = "";
866 0 : pResData->sQuickHelpText[ SOURCE_LANGUAGE ]= "";
867 0 : pResData->sTitle[ SOURCE_LANGUAGE ] = "";
868 0 : }
869 : }
870 0 : if ( pResData->pStringList ) {
871 0 : OString sList( "stringlist" );
872 0 : WriteExportList( pResData, pResData->pStringList, sList, bCreateNew );
873 0 : if ( bCreateNew )
874 0 : pResData->pStringList = 0;
875 : }
876 0 : if ( pResData->pFilterList ) {
877 0 : OString sList( "filterlist" );
878 0 : WriteExportList( pResData, pResData->pFilterList, sList, bCreateNew );
879 0 : if ( bCreateNew )
880 0 : pResData->pFilterList = 0;
881 : }
882 0 : if ( pResData->pItemList ) {
883 0 : OString sList( "itemlist" );
884 0 : WriteExportList( pResData, pResData->pItemList, sList, bCreateNew );
885 0 : if ( bCreateNew )
886 0 : pResData->pItemList = 0;
887 : }
888 0 : if ( pResData->pPairedList ) {
889 0 : OString sList( "pairedlist" );
890 0 : WriteExportList( pResData, pResData->pPairedList, sList, bCreateNew );
891 0 : if ( bCreateNew )
892 0 : pResData->pPairedList = 0;
893 : }
894 0 : if ( pResData->pUIEntries ) {
895 0 : OString sList( "uientries" );
896 0 : WriteExportList( pResData, pResData->pUIEntries, sList, bCreateNew );
897 0 : if ( bCreateNew )
898 0 : pResData->pUIEntries = 0;
899 : }
900 0 : return sal_True;
901 : }
902 :
903 0 : OString Export::GetPairedListID(const OString& rText)
904 : {
905 : // < "STRING" ; IDENTIFIER ; > ;
906 0 : return rText.getToken(1, ';').toAsciiUpperCase().replace('\t', ' ').trim();
907 : }
908 :
909 0 : OString Export::GetPairedListString(const OString& rText)
910 : {
911 : // < "STRING" ; IDENTIFIER ; > ;
912 0 : OString sString(rText.getToken(0, ';').replace('\t', ' '));
913 0 : sString = sString.trim();
914 0 : OString s1(sString.copy(sString.indexOf('"') + 1));
915 0 : sString = s1.copy(0, s1.lastIndexOf('"'));
916 0 : return sString.trim();
917 : }
918 :
919 0 : OString Export::StripList(const OString & rText)
920 : {
921 0 : OString s1 = rText.copy( rText.indexOf('\"') + 1);
922 0 : return s1.copy( 0 , s1.lastIndexOf('\"'));
923 : }
924 :
925 0 : sal_Bool Export::WriteExportList(ResData *pResData, ExportList *pExportList,
926 : const OString &rTyp, sal_Bool bCreateNew)
927 : {
928 0 : OString sGID(pResData->sGId);
929 0 : if (sGID.isEmpty())
930 0 : sGID = pResData->sId;
931 : else {
932 0 : sGID += ".";
933 0 : sGID += pResData->sId;
934 0 : while (!sGID.isEmpty() && sGID[sGID.getLength() - 1] == '.') {
935 0 : sGID = sGID.copy(0, sGID.getLength() - 1);
936 : }
937 : }
938 :
939 0 : for ( size_t i = 0; pExportList != NULL && i < pExportList->size(); i++ )
940 : {
941 0 : ExportListEntry *pEntry = (*pExportList)[ i ];
942 :
943 0 : OString sLID;
944 0 : OString sText((*pEntry)[ SOURCE_LANGUAGE ] );
945 :
946 : // Strip PairList Line String
947 0 : if (rTyp.equalsIgnoreAsciiCase("pairedlist"))
948 : {
949 0 : sLID = GetPairedListID( sText );
950 0 : sText = GetPairedListString( sText );
951 : }
952 : else
953 : {
954 0 : sLID = OString::valueOf(static_cast<sal_Int64>(i + 1));
955 0 : sText = StripList( sText );
956 0 : if( sText == "\\\"" )
957 0 : sText = "\"";
958 : }
959 0 : ConvertExportContent(sText);
960 : common::writePoEntry(
961 : "Transex3", *aOutput.mPo, global::inputPathname,
962 0 : rTyp, sGID, sLID, OString(), sText);
963 :
964 0 : if ( bCreateNew )
965 0 : delete [] pEntry;
966 0 : }
967 0 : if ( bCreateNew )
968 0 : delete pExportList;
969 :
970 0 : return sal_True;
971 : }
972 :
973 830 : OString Export::FullId()
974 : {
975 830 : OStringBuffer sFull;
976 830 : if ( nLevel > 1 )
977 : {
978 538 : sFull.append(aResStack[ 0 ]->sId);
979 932 : for ( size_t i = 1; i < nLevel - 1; ++i )
980 : {
981 394 : OString sToAdd = aResStack[ i ]->sId;
982 394 : if (!sToAdd.isEmpty())
983 102 : sFull.append('.').append(sToAdd);
984 394 : }
985 : }
986 830 : if (sFull.getLength() > 255)
987 : {
988 0 : OString sError(RTL_CONSTASCII_STRINGPARAM("GroupId > 255 chars"));
989 0 : printf("GroupID = %s\n", sFull.getStr());
990 0 : yyerror(sError.getStr());
991 : }
992 :
993 830 : return sFull.makeStringAndClear();
994 : }
995 :
996 17 : void Export::InsertListEntry(const OString &rText, const OString &rLine)
997 : {
998 17 : ResData *pResData = ( nLevel-1 < aResStack.size() ) ? aResStack[ nLevel-1 ] : NULL;
999 :
1000 17 : ExportList *pList = NULL;
1001 17 : if ( nList == LIST_STRING ) {
1002 17 : pList = pResData->pStringList;
1003 17 : if ( !pList ) {
1004 2 : pResData->pStringList = new ExportList();
1005 2 : pList = pResData->pStringList;
1006 2 : nListIndex = 0;
1007 : }
1008 : }
1009 0 : else if ( nList == LIST_FILTER ) {
1010 0 : pList = pResData->pFilterList;
1011 0 : if ( !pList ) {
1012 0 : pResData->pFilterList = new ExportList();
1013 0 : pList = pResData->pFilterList;
1014 0 : nListIndex = 0;
1015 : }
1016 : }
1017 0 : else if ( nList == LIST_ITEM ) {
1018 0 : pList = pResData->pItemList;
1019 0 : if ( !pList ) {
1020 0 : pResData->pItemList = new ExportList();
1021 0 : pList = pResData->pItemList;
1022 0 : nListIndex = 0;
1023 : }
1024 : }
1025 0 : else if ( nList == LIST_PAIRED ) {
1026 0 : pList = pResData->pPairedList;
1027 0 : if ( !pList ) {
1028 0 : pResData->pPairedList = new ExportList();
1029 0 : pList = pResData->pPairedList;
1030 0 : nListIndex = 0;
1031 : }
1032 : }
1033 0 : else if ( nList == LIST_UIENTRIES ) {
1034 0 : pList = pResData->pUIEntries;
1035 0 : if ( !pList ) {
1036 0 : pResData->pUIEntries = new ExportList();
1037 0 : pList = pResData->pUIEntries;
1038 0 : nListIndex = 0;
1039 : }
1040 : }
1041 : else
1042 17 : return;
1043 :
1044 17 : if ( nListIndex + 1 > pList->size())
1045 : {
1046 17 : ExportListEntry *pNew = new ExportListEntry();
1047 17 : (*pNew)[LIST_REFID] = OString::number(REFID_NONE);
1048 17 : pList->push_back(pNew);
1049 : }
1050 17 : ExportListEntry *pCurEntry = (*pList)[ nListIndex ];
1051 :
1052 : // For paired list use the line to set proper lid
1053 17 : if( nList == LIST_PAIRED ){
1054 0 : (*pCurEntry)[ m_sListLang ] = rLine;
1055 : }else
1056 17 : (*pCurEntry)[ m_sListLang ] = rText;
1057 :
1058 17 : if ( m_sListLang.equalsIgnoreAsciiCase("en-US") ) {
1059 17 : (*pCurEntry)[ SOURCE_LANGUAGE ] = rLine;
1060 :
1061 17 : pList->NewSourceLanguageListEntry();
1062 : }
1063 :
1064 17 : nListIndex++;
1065 : }
1066 :
1067 2214 : void Export::CleanValue( OString &rValue )
1068 : {
1069 5807 : while ( !rValue.isEmpty()) {
1070 3567 : if (( rValue[0] == ' ' ) || ( rValue[0] == '\t' ))
1071 1379 : rValue = rValue.copy( 1 );
1072 : else
1073 2188 : break;
1074 : }
1075 :
1076 2214 : if ( !rValue.isEmpty()) {
1077 18613 : for ( sal_Int32 i = rValue.getLength() - 1; i > 0; i-- ) {
1078 48378 : if (( rValue[i] == ' ' ) || ( rValue[i] == '\t' ) ||
1079 14492 : ( rValue[i] == '\n' ) || ( rValue[i] == ';' ) ||
1080 28224 : ( rValue[i] == '{' ) || ( rValue[i] == '\\' ) ||
1081 2173 : ( rValue[i] == '\r' ))
1082 16425 : rValue = rValue.copy(0, i);
1083 : else
1084 2173 : break;
1085 : }
1086 : }
1087 2214 : }
1088 :
1089 : #define TXT_STATE_TEXT 0x001
1090 : #define TXT_STATE_MACRO 0x002
1091 :
1092 415 : OString Export::GetText(const OString &rSource, int nToken)
1093 : {
1094 415 : OString sReturn;
1095 415 : switch ( nToken )
1096 : {
1097 : case TEXTLINE:
1098 : case LONGTEXTLINE:
1099 : {
1100 415 : OString sTmp(rSource.copy(rSource.indexOf('=')));
1101 415 : CleanValue( sTmp );
1102 830 : sTmp = sTmp.replaceAll("\n", OString()).
1103 : replaceAll("\r", OString()).
1104 : replaceAll("\\\\\"", "-=<[BSlashBSlashHKom]>=-\"").
1105 : replaceAll("\\\"", "-=<[Hochkomma]>=-").
1106 : replaceAll("\\", "-=<[0x7F]>=-").
1107 415 : replaceAll("\\0x7F", "-=<[0x7F]>=-");
1108 :
1109 415 : sal_uInt16 nState = TXT_STATE_TEXT;
1110 1245 : for (sal_Int32 i = 1; i <= lcl_countOccurrences(sTmp, '"'); ++i)
1111 : {
1112 830 : OString sToken(sTmp.getToken(i, '"'));
1113 830 : if (!sToken.isEmpty()) {
1114 410 : if ( nState == TXT_STATE_TEXT ) {
1115 410 : sReturn += sToken;
1116 410 : nState = TXT_STATE_MACRO;
1117 : }
1118 : else {
1119 0 : sToken = sToken.replace('\t', ' ');
1120 : for (;;) {
1121 0 : sal_Int32 n = 0;
1122 0 : sToken = sToken.replaceFirst(" ", " ", &n);
1123 0 : if (n == -1) {
1124 0 : break;
1125 : }
1126 0 : }
1127 0 : sToken = sToken.trim();
1128 0 : if (!sToken.isEmpty()) {
1129 0 : sReturn += "\\\" ";
1130 0 : sReturn += sToken;
1131 0 : sReturn += " \\\"";
1132 : }
1133 0 : nState = TXT_STATE_TEXT;
1134 : }
1135 : }
1136 830 : }
1137 :
1138 830 : sReturn = sReturn.replaceAll("-=<[0x7F]>=-", "").
1139 : replaceAll("-=<[Hochkomma]>=-", "\"").
1140 : replaceAll("-=<[BSlashBSlashHKom]>=-", "\\\\").
1141 : replaceAll("\\\\", "-=<[BSlashBSlash]>=-").
1142 830 : replaceAll("-=<[BSlashBSlash]>=-", "\\");
1143 : }
1144 415 : break;
1145 : }
1146 415 : return sReturn;
1147 : }
1148 :
1149 32764 : void Export::WriteToMerged(const OString &rText , bool bSDFContent)
1150 : {
1151 32764 : OString sText(rText);
1152 : for (;;) {
1153 32764 : sal_Int32 n = 0;
1154 32764 : sText = sText.replaceFirst(" \n", "\n", &n);
1155 32764 : if (n == -1) {
1156 32764 : break;
1157 : }
1158 0 : }
1159 42631 : if (pParseQueue->bNextIsM && bSDFContent && sText.getLength() > 2) {
1160 0 : for (sal_Int32 n = 0; n < sText.getLength(); ++n) {
1161 0 : if (sText[n] == '\n' && sText[n - 1] != '\\') {
1162 0 : sText = sText.replaceAt(n++, 0, "\\");
1163 : }
1164 : }
1165 32764 : } else if (pParseQueue->bLastWasM && sText.getLength() > 2) {
1166 75231 : for (sal_Int32 n = 0; n < sText.getLength(); ++n) {
1167 72736 : if (sText[n] == '\n' && sText[n - 1] != '\\') {
1168 0 : sText = sText.replaceAt(n++, 0, "\\");
1169 : }
1170 72736 : if (sText[n] == '\n') {
1171 604 : pParseQueue->bMflag = true;
1172 : }
1173 : }
1174 30269 : } else if (pParseQueue->bCurrentIsM && bSDFContent && sText.getLength() > 2)
1175 : {
1176 0 : for (sal_Int32 n = 0; n < sText.getLength(); ++n) {
1177 0 : if (sText[n] == '\n' && sText[n - 1] != '\\') {
1178 0 : sText = sText.replaceAt(n++, 0, "\\");
1179 0 : pParseQueue->bMflag = true;
1180 : }
1181 : }
1182 30269 : } else if (pParseQueue->bMflag) {
1183 7983 : for (sal_Int32 n = 1; n < sText.getLength(); ++n) {
1184 6002 : if (sText[n] == '\n' && sText[n - 1] != '\\') {
1185 0 : sText = sText.replaceAt(n++, 0, "\\");
1186 : }
1187 : }
1188 201957 : } for (sal_Int32 i = 0; i < sText.getLength(); ++i) {
1189 169193 : if (sText[i] == '\n') {
1190 5334 : *aOutput.mSimple << '\n';
1191 : } else {
1192 163859 : char cChar = sText[i];
1193 163859 : *aOutput.mSimple << cChar;
1194 : }
1195 32764 : }
1196 32764 : }
1197 :
1198 0 : void Export::ConvertMergeContent( OString &rText )
1199 : {
1200 0 : rText = rText.replaceAll("\\\'","\'"); // Temporary: until PO files contain escaped single quotes
1201 : // (Maybe next PO update solve this)
1202 0 : rText =
1203 : helper::escapeAll(
1204 : rText.replaceAll("","\\0x7F"),
1205 0 : "\n""\t""\\""\"","\\n""\\t""\\\\""\\\"");
1206 :
1207 0 : rText = "\"" + rText + "\"";
1208 0 : }
1209 :
1210 0 : void Export::ConvertExportContent( OString& rText )
1211 : {
1212 0 : rText = helper::unEscapeAll(rText,"\\n""\\t""\\\\""\\\"","\n""\t""\\""\"");
1213 0 : }
1214 :
1215 2 : bool Export::GetAllMergeEntrysOfList(ResData *pResData, std::vector<MergeEntrys*>& o_vMergeEntrys, ExportList*& o_pList )
1216 : {
1217 2 : o_vMergeEntrys.clear();
1218 2 : o_pList = 0;
1219 :
1220 2 : if (!pResData->sGId.isEmpty())
1221 0 : pResData->sGId = pResData->sGId + OString('.');
1222 2 : pResData->sGId = pResData->sGId + pResData->sId;
1223 :
1224 : // Find out the type of List
1225 2 : MergeEntrys* pEntrysOfFirstItem = 0;
1226 2 : sal_uInt16 nType = LIST_STRING;
1227 2 : bool bPairedList = false;
1228 20 : while( !pEntrysOfFirstItem && nType <= LIST_UIENTRIES )
1229 : {
1230 16 : switch ( nType )
1231 : {
1232 2 : case LIST_STRING : pResData->sResTyp = "stringlist"; o_pList = pResData->pStringList; bPairedList = false; break;
1233 2 : case LIST_FILTER : pResData->sResTyp = "filterlist"; o_pList = pResData->pFilterList; bPairedList = false; break;
1234 2 : case LIST_UIENTRIES : pResData->sResTyp = "uientries"; o_pList = pResData->pUIEntries;bPairedList = false; break;
1235 2 : case LIST_ITEM : pResData->sResTyp = "itemlist"; o_pList = pResData->pItemList; bPairedList = false; break;
1236 2 : case LIST_PAIRED : pResData->sResTyp = "pairedlist"; o_pList = pResData->pPairedList; bPairedList = true; break;
1237 : }
1238 :
1239 : // Set matching pairedlist identifier
1240 16 : if( bPairedList && pResData->pPairedList )
1241 : {
1242 0 : ExportListEntry* pListE = ( ExportListEntry* ) (*pResData->pPairedList)[ 0 ];
1243 0 : pResData->sId = GetPairedListID ( (*pListE)[ SOURCE_LANGUAGE ] );
1244 : }
1245 : else
1246 16 : pResData->sId = "1";
1247 :
1248 16 : pEntrysOfFirstItem = pMergeDataFile->GetMergeEntrys( pResData );
1249 16 : ++nType;
1250 : }
1251 :
1252 2 : if( !pEntrysOfFirstItem )
1253 : {
1254 2 : o_pList = 0;
1255 2 : return false;
1256 : }
1257 : else
1258 0 : nList = nType-1;
1259 :
1260 0 : sal_uInt16 nMaxIndex = 0;
1261 0 : if ( o_pList )
1262 : {
1263 0 : nMaxIndex = o_pList->GetSourceLanguageListEntryCount();
1264 : }
1265 : /**
1266 : * Check whether count of listentries match with count
1267 : * of translated items. If not than write origin items
1268 : * to the list to avoid mixed translations
1269 : * (exclude pairedlist)
1270 : */
1271 0 : if( !bPairedList )
1272 : {
1273 : MergeEntrys* pEntrys;
1274 : // MergeData contains longer list
1275 0 : pResData->sId = OString::number(nMaxIndex+1);
1276 0 : pEntrys = pMergeDataFile->GetMergeEntrys( pResData );
1277 0 : if ( pEntrys )
1278 0 : return false;
1279 : // MergeData contains shorter list
1280 0 : pResData->sId = OString::number(nMaxIndex);
1281 0 : pEntrys = pMergeDataFile->GetMergeEntrys( pResData );
1282 0 : if ( !pEntrys )
1283 0 : return false;
1284 0 : pResData->sId = "1";
1285 : }
1286 :
1287 0 : o_vMergeEntrys.push_back(pEntrysOfFirstItem);
1288 :
1289 0 : for( sal_uInt16 nLIndex = 2; nLIndex <= nMaxIndex; ++nLIndex )
1290 : {
1291 : // Set matching pairedlist identifier
1292 0 : if ( bPairedList )
1293 : {
1294 0 : ExportListEntry* pListE = ( ExportListEntry* )(*pResData->pPairedList)[ ( nLIndex ) -1 ];
1295 0 : if( pListE )
1296 : {
1297 0 : pResData->sId = GetPairedListID ( (*pListE)[ SOURCE_LANGUAGE ] );
1298 : }
1299 : }
1300 : else
1301 0 : pResData->sId = OString::number(nLIndex);
1302 :
1303 0 : MergeEntrys* pEntrys = pMergeDataFile->GetMergeEntrys( pResData );
1304 0 : if( pEntrys )
1305 : {
1306 0 : o_vMergeEntrys.push_back(pEntrys);
1307 : }
1308 : }
1309 0 : return true;
1310 : }
1311 :
1312 0 : void Export::ResData2Output( MergeEntrys *pEntry, sal_uInt16 nType, const OString& rTextType )
1313 : {
1314 0 : sal_Bool bAddSemicolon = sal_False;
1315 0 : sal_Bool bFirst = sal_True;
1316 0 : OString sCur;
1317 :
1318 0 : for( unsigned int n = 0; n < aLanguages.size(); n++ ){
1319 0 : sCur = aLanguages[ n ];
1320 :
1321 0 : OString sText;
1322 0 : sal_Bool bText = pEntry->GetText( sText, nType, sCur , sal_True );
1323 0 : if ( bText && !sText.isEmpty() ) {
1324 0 : OString sOutput;
1325 0 : if ( bNextMustBeDefineEOL) {
1326 0 : if ( bFirst )
1327 0 : sOutput += "\t\\\n";
1328 : else
1329 0 : sOutput += ";\t\\\n";
1330 : }
1331 0 : bFirst=sal_False;
1332 0 : sOutput += "\t";
1333 :
1334 0 : sOutput += rTextType;
1335 :
1336 0 : if ( !sCur.equalsIgnoreAsciiCase("en-US") ) {
1337 0 : sOutput += "[ ";
1338 0 : sOutput += sCur;
1339 0 : sOutput += " ] ";
1340 : }
1341 0 : sOutput += "= ";
1342 0 : ConvertMergeContent( sText );
1343 0 : sOutput += sText;
1344 :
1345 0 : if ( bDefine )
1346 0 : sOutput += ";\\\n";
1347 0 : else if ( !bNextMustBeDefineEOL )
1348 0 : sOutput += ";\n";
1349 : else
1350 0 : bAddSemicolon = sal_True;
1351 0 : for ( sal_uInt16 j = 1; j < nLevel; j++ )
1352 0 : sOutput += "\t";
1353 0 : WriteToMerged( sOutput , true );
1354 : }
1355 0 : }
1356 :
1357 :
1358 0 : if ( bAddSemicolon ) {
1359 0 : OString sOutput( ";" );
1360 0 : WriteToMerged( sOutput , false );
1361 0 : }
1362 0 : }
1363 :
1364 921 : void Export::MergeRest( ResData *pResData, sal_uInt16 nMode )
1365 : {
1366 921 : if ( !pMergeDataFile ){
1367 13 : pMergeDataFile = new MergeDataFile( sMergeSrc, global::inputPathname, false );
1368 13 : aLanguages = pMergeDataFile->GetLanguages();
1369 :
1370 : }
1371 921 : switch ( nMode ) {
1372 : case MERGE_MODE_NORMAL : {
1373 921 : MergeEntrys *pEntry = 0;
1374 921 : if( pResData->bText || pResData->bQuickHelpText || pResData->bTitle )
1375 308 : pEntry = pMergeDataFile->GetMergeEntrys( pResData );
1376 :
1377 921 : if ( pEntry ) {
1378 0 : if ( pResData->bText )
1379 0 : ResData2Output( pEntry, STRING_TYP_TEXT, pResData->sTextTyp );
1380 :
1381 0 : if ( pResData->bQuickHelpText )
1382 0 : ResData2Output( pEntry, STRING_TYP_QUICKHELPTEXT, OString("QuickHelpText") );
1383 :
1384 0 : if ( pResData->bTitle )
1385 0 : ResData2Output( pEntry, STRING_TYP_TITLE, OString("Title") );
1386 : }
1387 :
1388 : // Merge Lists
1389 :
1390 921 : if ( pResData->bList ) {
1391 2 : OString sOldId = pResData->sId;
1392 4 : OString sOldGId = pResData->sGId;
1393 4 : OString sOldTyp = pResData->sResTyp;
1394 2 : sal_uInt16 nOldListTyp = nList;
1395 :
1396 4 : OString sSpace;
1397 2 : for ( sal_uInt16 i = 1; i < nLevel-1; i++ )
1398 0 : sSpace += "\t";
1399 :
1400 4 : std::vector<MergeEntrys*> vMergeEntryVector;
1401 2 : ExportList* pList = 0;
1402 2 : bool bTranslateList = GetAllMergeEntrysOfList(pResData, vMergeEntryVector, pList);
1403 :
1404 2 : if( pList )
1405 : {
1406 0 : OString sCur;
1407 0 : for( unsigned int n = 0; n < aLanguages.size(); n++ )
1408 : {
1409 0 : sCur = aLanguages[ n ];
1410 :
1411 0 : sal_uInt16 nLIndex = 0;
1412 0 : sal_uInt16 nMaxIndex = pList->GetSourceLanguageListEntryCount();
1413 0 : while( nLIndex < nMaxIndex )
1414 : {
1415 0 : if ( nLIndex == 0 )
1416 : {
1417 0 : OStringBuffer sHead;
1418 0 : if ( bNextMustBeDefineEOL )
1419 0 : sHead.append("\\\n\t");
1420 0 : sHead.append(sSpace);
1421 0 : switch ( nList )
1422 : {
1423 : case LIST_STRING:
1424 0 : sHead.append("StringList ");
1425 0 : break;
1426 : case LIST_FILTER:
1427 0 : sHead.append("FilterList ");
1428 0 : break;
1429 : case LIST_ITEM:
1430 0 : sHead.append("ItemList ");
1431 0 : break;
1432 : case LIST_PAIRED:
1433 0 : sHead.append("PairedList ");
1434 0 : break;
1435 : case LIST_UIENTRIES:
1436 0 : sHead.append("UIEntries ");
1437 0 : break;
1438 : }
1439 0 : sHead.append("[ ");
1440 0 : sHead.append(sCur);
1441 0 : sHead.append(" ] ");
1442 0 : if ( bDefine || bNextMustBeDefineEOL )
1443 : {
1444 0 : sHead.append("= \\\n");
1445 0 : sHead.append(sSpace);
1446 0 : sHead.append("\t{\\\n\t");
1447 : }
1448 : else
1449 : {
1450 0 : sHead.append("= \n");
1451 0 : sHead.append(sSpace);
1452 0 : sHead.append("\t{\n\t");
1453 : }
1454 0 : WriteToMerged(sHead.makeStringAndClear() , true);
1455 : }
1456 0 : OString sLine;
1457 0 : if ( pList && (*pList)[ nLIndex ] )
1458 0 : sLine = ( *(*pList)[ nLIndex ])[ SOURCE_LANGUAGE ];
1459 :
1460 0 : if ( sLine.indexOf( '>' ) != -1 ) {
1461 0 : if (( nList != LIST_UIENTRIES ) &&
1462 0 : (( sLine.indexOf( '{' ) == -1 ) ||
1463 0 : ( sLine.indexOf( '{' ) >= sLine.indexOf( '"' ))) &&
1464 0 : (( sLine.indexOf( '<' ) == -1 ) ||
1465 0 : ( sLine.indexOf( '<' ) >= sLine.indexOf( '"' ))))
1466 : {
1467 0 : sLine = sLine.replaceFirst("\"", "< \"" );
1468 : }
1469 : }
1470 :
1471 0 : if( bTranslateList && nLIndex < vMergeEntryVector.size() )
1472 : {
1473 0 : OString sText;
1474 : sal_Bool bText;
1475 0 : bText = vMergeEntryVector[nLIndex]->GetText( sText, STRING_TYP_TEXT, sCur, sal_True );
1476 0 : if ( bText && !sText.isEmpty() )
1477 : {
1478 0 : ConvertMergeContent( sText );
1479 0 : OString sPre = sLine.copy( 0 , sLine.indexOf('"') );
1480 0 : OString sPost = sLine.copy( sLine.lastIndexOf('"') + 1 );
1481 0 : sLine = sPre + sText + sPost;
1482 0 : }
1483 : }
1484 :
1485 0 : OString sText1( "\t" );
1486 0 : sText1 += sLine;
1487 0 : if ( bDefine || bNextMustBeDefineEOL )
1488 0 : sText1 += " ;\\\n";
1489 : else
1490 0 : sText1 += " ;\n";
1491 0 : sText1 += sSpace;
1492 0 : sText1 += "\t";
1493 0 : WriteToMerged( sText1 ,true );
1494 0 : ++nLIndex;
1495 0 : }
1496 0 : if ( nLIndex > 0 ) {
1497 0 : OString sFooter;
1498 0 : if (!sSpace.isEmpty()) {
1499 0 : sFooter = sSpace.copy(1);
1500 : }
1501 0 : if ( bNextMustBeDefineEOL )
1502 0 : sFooter += "};";
1503 0 : else if ( !bDefine )
1504 0 : sFooter += "};\n\t";
1505 : else
1506 0 : sFooter += "\n\n";
1507 0 : WriteToMerged( sFooter ,true );
1508 : }
1509 0 : }
1510 : }
1511 :
1512 2 : pResData->sId = sOldId;
1513 2 : pResData->sGId = sOldGId;
1514 2 : pResData->sResTyp = sOldTyp;
1515 4 : nList = nOldListTyp;
1516 : }
1517 : }
1518 921 : break;
1519 : case MERGE_MODE_LIST : {
1520 : }
1521 0 : break;
1522 : }
1523 921 : pParseQueue->bMflag = false;
1524 921 : }
1525 :
1526 326 : void Export::SetChildWithText()
1527 : {
1528 326 : if ( aResStack.size() > 1 ) {
1529 639 : for ( size_t i = 0; i < aResStack.size() - 1; i++ ) {
1530 406 : aResStack[ i ]->bChildWithText = sal_True;
1531 : }
1532 : }
1533 326 : }
1534 :
1535 32478 : void ParserQueue::Push( const QueueEntry& aEntry )
1536 : {
1537 32478 : sal_Int32 nLen = aEntry.sLine.getLength();
1538 :
1539 32478 : if( !bStart ){
1540 24656 : aQueueCur->push( aEntry );
1541 24656 : if( nLen > 1 && aEntry.sLine[nLen-1] == '\n' )
1542 11 : bStart = true;
1543 24645 : else if ( aEntry.nTyp != IGNOREDTOKENS ){
1544 21182 : if( nLen > 1 && ( aEntry.sLine[nLen-1] == '\\') ){
1545 : // Next is Macro
1546 389 : bCurrentIsM = true;
1547 : }else{
1548 : // Next is no Macro
1549 20793 : bCurrentIsM = false;
1550 : }
1551 : }
1552 : }
1553 : else{
1554 7822 : aQueueNext->push( aEntry );
1555 7822 : if( nLen > 1 && aEntry.sLine[nLen-1] != '\n' ){
1556 2958 : if( nLen > 1 && ( aEntry.sLine[nLen-1] == '\\') ){
1557 : // Next is Macro
1558 1301 : bNextIsM = true;
1559 : }
1560 : else{
1561 : // Next is no Macro
1562 1657 : bNextIsM = false;
1563 : }
1564 4864 : }else if( nLen > 2 && aEntry.sLine[nLen-1] == '\n' ){
1565 404 : if( aEntry.nTyp != IGNOREDTOKENS ){
1566 404 : if( nLen > 2 && ( aEntry.sLine[nLen-2] == '\\') ){
1567 : // Next is Macro
1568 385 : bNextIsM = true;
1569 : }
1570 : else{
1571 : // Next is no Macro
1572 19 : bNextIsM = false;
1573 : }
1574 : }
1575 : // Pop current
1576 404 : Pop( *aQueueCur );
1577 404 : bLastWasM = bCurrentIsM;
1578 : // next -> current
1579 404 : bCurrentIsM = bNextIsM;
1580 404 : aQref = aQueueCur;
1581 404 : aQueueCur = aQueueNext;
1582 404 : aQueueNext = aQref;
1583 :
1584 : }
1585 :
1586 : else{
1587 : // Pop current
1588 4460 : Pop( *aQueueCur );
1589 4460 : bLastWasM = bCurrentIsM;
1590 : // next -> current
1591 4460 : bCurrentIsM = bNextIsM;
1592 4460 : aQref = aQueueCur;
1593 4460 : aQueueCur = aQueueNext;
1594 4460 : aQueueNext = aQref;
1595 : }
1596 : }
1597 32478 : }
1598 :
1599 13 : void ParserQueue::Close(){
1600 : // Pop current
1601 13 : Pop( *aQueueCur );
1602 : // next -> current
1603 13 : bLastWasM = bCurrentIsM;
1604 13 : bCurrentIsM = bNextIsM;
1605 13 : aQref = aQueueCur;
1606 13 : aQueueCur = aQueueNext;
1607 13 : aQueueNext = aQref;
1608 13 : bNextIsM = false;
1609 13 : Pop( *aQueueNext );
1610 13 : };
1611 :
1612 4890 : void ParserQueue::Pop( std::queue<QueueEntry>& aQueue )
1613 : {
1614 42258 : while (!aQueue.empty())
1615 : {
1616 32478 : QueueEntry aEntry = aQueue.front();
1617 32478 : aQueue.pop();
1618 32478 : aExport.Execute(aEntry.nTyp, aEntry.sLine.getStr());
1619 32478 : }
1620 4890 : }
1621 :
1622 13 : ParserQueue::ParserQueue( Export& aExportObj )
1623 : :
1624 : bCurrentIsM( false ),
1625 : bNextIsM( false ) ,
1626 : bLastWasM( false ),
1627 : bMflag( false ) ,
1628 : aExport( aExportObj ) ,
1629 13 : bStart( false )
1630 : {
1631 13 : aQueueNext = new std::queue<QueueEntry>;
1632 13 : aQueueCur = new std::queue<QueueEntry>;
1633 13 : }
1634 :
1635 :
1636 13 : ParserQueue::~ParserQueue(){
1637 13 : if( aQueueNext ) delete aQueueNext;
1638 13 : if( aQueueCur ) delete aQueueCur;
1639 52 : }
1640 :
1641 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|