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 : /****************************************************************/
21 : /* Include File */
22 : /****************************************************************/
23 :
24 : #include <stdlib.h>
25 : #include <stdio.h>
26 : #include <fcntl.h>
27 :
28 : #ifdef UNX
29 : #include <unistd.h>
30 : #include <sys/wait.h>
31 : #include <sys/stat.h>
32 : #else
33 : #include <io.h>
34 : #include <process.h>
35 : #include <direct.h>
36 : #endif
37 :
38 : #include <string.h>
39 : #include <ctype.h>
40 : #include <errno.h>
41 :
42 : #include <tools/fsys.hxx>
43 : #include <tools/stream.hxx>
44 : #include <rscerror.h>
45 : #include <rsctop.hxx>
46 : #include <rscdb.hxx>
47 : #include <rscpar.hxx>
48 : #include <rscrsc.hxx>
49 : #include <rschash.hxx>
50 :
51 : #include <osl/file.h>
52 : #include <osl/file.hxx>
53 : #include <osl/process.h>
54 : #include <rtl/strbuf.hxx>
55 : #include <rtl/tencinfo.h>
56 : #include <rtl/textenc.h>
57 : #include <comphelper/string.hxx>
58 :
59 : #include <vector>
60 : #include <algorithm>
61 :
62 :
63 : using ::rtl::OUString;
64 : using ::rtl::OString;
65 : using ::rtl::OStringBuffer;
66 : using ::rtl::OStringToOUString;
67 : using comphelper::string::getToken;
68 : using comphelper::string::getTokenCount;
69 :
70 : /*************** F o r w a r d s *****************************************/
71 : /*************** G l o b a l e V a r i a b l e n **********************/
72 : rtl::OString* pStdParType = NULL;
73 : rtl::OString* pStdPar1 = NULL;
74 : rtl::OString* pStdPar2 = NULL;
75 : rtl::OString* pWinParType = NULL;
76 : rtl::OString* pWinPar1 = NULL;
77 : rtl::OString* pWinPar2 = NULL;
78 : sal_uInt32 nRefDeep = 10;
79 : AtomContainer* pHS = NULL;
80 :
81 :
82 : /*************** R s c C m d L i n e ************************************/
83 : /*************************************************************************
84 : |*
85 : |* RscCmdLine::Init()
86 : |*
87 : |* Beschreibung Kommandozeile interpretierten
88 : |*
89 : *************************************************************************/
90 691 : void RscCmdLine::Init()
91 : {
92 691 : nCommands = 0;
93 691 : nByteOrder = RSC_BIGENDIAN;
94 :
95 691 : DirEntry aEntry;
96 691 : aPath = rtl::OUStringToOString(aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US); //Immer im Aktuellen Pfad suchen
97 691 : m_aOutputFiles.clear();
98 691 : m_aOutputFiles.push_back( OutputFile() );
99 691 : }
100 :
101 : /*************************************************************************
102 : |*
103 : |* RscCmdLine::RscCmdLine()
104 : |*
105 : |* Beschreibung Kommandozeile interpretierten
106 : |*
107 : *************************************************************************/
108 691 : RscCmdLine::RscCmdLine( int argc, char ** argv, RscError * pEH )
109 : {
110 : char * pStr;
111 : char ** ppStr;
112 691 : RscPtrPtr aCmdLine; // Kommandozeile
113 : sal_uInt32 i;
114 691 : sal_Bool bOutputSrsIsSet = sal_False;
115 :
116 691 : Init(); // Defaults setzen
117 :
118 691 : pStr = ::ResponseFile( &aCmdLine, argv, argc );
119 691 : if( pStr )
120 0 : pEH->FatalError( ERR_OPENFILE, RscId(), pStr );
121 :
122 : /* check the inputted switches */
123 691 : ppStr = (char **)aCmdLine.GetBlock();
124 691 : ppStr++;
125 691 : i = 1;
126 23022 : while( ppStr && i < (aCmdLine.GetCount() -1) )
127 : {
128 : #if OSL_DEBUG_LEVEL > 1
129 : fprintf( stderr, "CmdLineArg: \"%s\"\n", *ppStr );
130 : #endif
131 21640 : if( '-' == **ppStr )
132 : {
133 41896 : if( !rsc_stricmp( (*ppStr) + 1, "h" )
134 20948 : || !strcmp( (*ppStr) + 1, "?" ) )
135 : { // Hilfe
136 0 : nCommands |= HELP_FLAG;
137 : }
138 20948 : else if( !rsc_stricmp( (*ppStr) + 1, "syntax" ) )
139 : { // Hilfe
140 0 : nCommands |= PRINTSYNTAX_FLAG;
141 : }
142 20948 : else if( !rsc_strnicmp( (*ppStr) + 1, "RefDeep", 7 ) )
143 : {
144 : // maximale Aufloesungtiefe fuer Referenzen
145 0 : nRefDeep = rtl::OString((*ppStr) + 1 + RTL_CONSTASCII_LENGTH("RefDeep")).toInt32();
146 : }
147 20948 : else if( !rsc_stricmp( (*ppStr) + 1, "p" ) )
148 : { // kein Preprozessor
149 61 : nCommands |= NOPREPRO_FLAG;
150 : }
151 20887 : else if( !rsc_stricmp( (*ppStr) + 1, "s" ) )
152 : { // nicht linken
153 630 : nCommands |= NOLINK_FLAG;
154 : }
155 20257 : else if( !rsc_stricmp( (*ppStr) + 1, "l" ) )
156 : { // Linken, keine Syntax und kein Prepro
157 0 : nCommands |= NOPREPRO_FLAG;
158 0 : nCommands |= NOSYNTAX_FLAG;
159 : }
160 20257 : else if( !rsc_stricmp( (*ppStr) + 1, "r" ) )
161 : { // erzeugt kein .res-file
162 0 : nCommands |= NORESFILE_FLAG;
163 : }
164 20257 : else if( !rsc_strnicmp( (*ppStr) + 1, "sub", 3 ) )
165 : {
166 : const char* pEqual;
167 122 : for( pEqual = (*ppStr)+4; *pEqual && *pEqual != '='; ++pEqual )
168 : ;
169 122 : if( *pEqual )
170 : {
171 122 : const rtl::OString aSPath( pEqual + 1 );
172 122 : DirEntry aSDir(rtl::OStringToOUString(aSPath, RTL_TEXTENCODING_ASCII_US));
173 :
174 : m_aReplacements.push_back( std::pair< OString, OString >( OString( (*ppStr)+4, pEqual - *ppStr - 4 ),
175 122 : rtl::OUStringToOString(aSDir.GetFull(), RTL_TEXTENCODING_ASCII_US) ) );
176 : }
177 : }
178 20135 : else if( !rsc_stricmp( (*ppStr) + 1, "PreLoad" ) )
179 : { // Alle Resourcen mit Preload
180 0 : nCommands |= PRELOAD_FLAG;
181 : }
182 20135 : else if( !rsc_stricmp( (*ppStr) + 1, "LITTLEENDIAN" ) )
183 : { // Byte Ordnung beim Schreiben
184 0 : nByteOrder = RSC_LITTLEENDIAN;
185 : }
186 20135 : else if( !rsc_stricmp( (*ppStr) + 1, "BIGENDIAN" ) )
187 : { // Byte Ordnung beim Schreiben
188 0 : nByteOrder = RSC_BIGENDIAN;
189 : }
190 20135 : else if( !rsc_stricmp( (*ppStr) + 1, "SMART" ) )
191 : { // Byte Ordnung beim Schreiben
192 0 : nCommands |= SMART_FLAG;
193 : }
194 20135 : else if( !rsc_strnicmp( (*ppStr) + 1, "d", 1 ) )
195 : { // Symbole definieren
196 9450 : nCommands |= DEFINE_FLAG;
197 : }
198 10685 : else if( !rsc_strnicmp( (*ppStr) + 1, "i", 1 ) )
199 : { // Include-Pfade definieren
200 9323 : nCommands |= INCLUDE_FLAG;
201 9323 : rtl::OStringBuffer aBuffer(aPath);
202 9323 : if (aBuffer.getLength())
203 9323 : aBuffer.append(rtl::OUStringToOString(DirEntry::GetSearchDelimiter(), RTL_TEXTENCODING_ASCII_US));
204 9323 : aBuffer.append((*ppStr) + 2);
205 9323 : aPath = aBuffer.makeStringAndClear();
206 : }
207 1362 : else if( !rsc_strnicmp( (*ppStr) + 1, "fs=", 3 ) )
208 : { // anderer Name fuer .rc-file
209 61 : if( m_aOutputFiles.back().aOutputRc.getLength() )
210 0 : m_aOutputFiles.push_back( OutputFile() );
211 61 : m_aOutputFiles.back().aOutputRc = (*ppStr) + 4;
212 : }
213 1301 : else if( !rsc_strnicmp( (*ppStr) + 1, "lip=", 4 ) )
214 : { // additional language specific include for system dependent files
215 488 : const rtl::OString aSysSearchDir( (*ppStr)+5 );
216 :
217 : // ignore empty -lip= arguments that we get lots of these days
218 488 : if (!aSysSearchDir.isEmpty())
219 : {
220 488 : DirEntry aSysDir(rtl::OStringToOUString(aSysSearchDir, RTL_TEXTENCODING_ASCII_US));
221 488 : m_aOutputFiles.back().aSysSearchDirs.push_back(
222 976 : rtl::OUStringToOString(aSysDir.GetFull(), RTL_TEXTENCODING_ASCII_US) );
223 488 : rtl::OString aLangSearchPath = m_aOutputFiles.back().aLangSearchPath;
224 488 : if( !aLangSearchPath.isEmpty() )
225 : {
226 : aLangSearchPath = aLangSearchPath +
227 427 : rtl::OUStringToOString(DirEntry::GetSearchDelimiter(), RTL_TEXTENCODING_ASCII_US);
228 : }
229 488 : aLangSearchPath = aLangSearchPath + aSysSearchDir;
230 :
231 488 : m_aOutputFiles.back().aLangSearchPath = aLangSearchPath;
232 488 : }
233 : }
234 813 : else if( !rsc_strnicmp( (*ppStr) + 1, "fp=", 3 ) )
235 : { // anderer Name fuer .srs-file
236 691 : aOutputSrs = (*ppStr) + 4;
237 691 : bOutputSrsIsSet = sal_True;
238 : }
239 122 : else if( !rsc_strnicmp( (*ppStr) + 1, "fl=", 3 ) )
240 : { // Name fuer listing-file
241 0 : aOutputLst = (*ppStr) + 4;
242 : }
243 122 : else if( !rsc_strnicmp( (*ppStr) + 1, "fh=", 3 ) )
244 : { // Name fuer .hxx-file
245 0 : aOutputHxx = (*ppStr) + 4;
246 : }
247 122 : else if( !rsc_strnicmp( (*ppStr) + 1, "fc=", 3 ) )
248 : { // Name fuer .cxx-file
249 0 : aOutputCxx = (*ppStr) + 4;
250 : }
251 122 : else if( !rsc_strnicmp( (*ppStr) + 1, "fr=", 3 ) )
252 : { // Name fuer .cxx-file der Resource Konstruktoren
253 0 : aOutputRcCtor = (*ppStr) + 4;
254 : }
255 122 : else if( !rsc_strnicmp( (*ppStr) + 1, "fx=", 3 ) )
256 : { // Name fuer .src-file
257 0 : aOutputSrc = (*ppStr) + 4;
258 : }
259 122 : else if( !rsc_strnicmp( (*ppStr) + 1, "ft=", 3 ) )
260 : { // touch file
261 0 : aTouchFile = (*ppStr) + 4;
262 : }
263 122 : else if( !rsc_strnicmp( (*ppStr) + 1, "oil=", 4 ) )
264 : {
265 61 : aILDir = (*ppStr) + 5;
266 : }
267 61 : else if( !rsc_stricmp( (*ppStr) + 1, "NoSysResTest" ) )
268 : { // Bitmap, Pointers, Icons nicht ueberpruefen
269 0 : nCommands |= NOSYSRESTEST_FLAG;
270 : }
271 61 : else if( !rsc_stricmp( (*ppStr) + 1, "SrsDefault" ) )
272 : { // Bitmap, Pointers, Icons nicht ueberpruefen
273 0 : nCommands |= SRSDEFAULT_FLAG;
274 : }
275 61 : else if( !rsc_strnicmp( (*ppStr) + 1, "CHARSET_", 8 ) )
276 : {
277 : // ignore (was an option once)
278 : }
279 61 : else if( !rsc_stricmp( (*ppStr) + 1, "lg" ) )
280 : {
281 0 : m_aOutputFiles.back().aLangName = rtl::OString();
282 : }
283 61 : else if( !rsc_strnicmp( (*ppStr) + 1, "lg", 2 ) )
284 : {
285 61 : if( !m_aOutputFiles.back().aLangName.isEmpty() )
286 0 : m_aOutputFiles.push_back( OutputFile() );
287 61 : m_aOutputFiles.back().aLangName = rtl::OString((*ppStr)+3);
288 : }
289 : else
290 0 : pEH->FatalError( ERR_UNKNOWNSW, RscId(), *ppStr );
291 : }
292 : else
293 : {
294 : // Eingabedatei
295 692 : aInputList.push_back( new rtl::OString(*ppStr) );
296 : }
297 21640 : ppStr++;
298 21640 : i++;
299 : }
300 :
301 691 : if( nCommands & HELP_FLAG )
302 0 : pEH->FatalError( ERR_USAGE, RscId() );
303 : // was an inputted file specified
304 691 : else if( !aInputList.empty() )
305 : {
306 691 : ::std::list<OutputFile>::iterator it;
307 1382 : for( it = m_aOutputFiles.begin(); it != m_aOutputFiles.end(); ++it )
308 : {
309 691 : if( it->aOutputRc.isEmpty() )
310 630 : it->aOutputRc = ::OutputFile( *aInputList.front(), "rc" );
311 : }
312 691 : if( ! bOutputSrsIsSet )
313 0 : aOutputSrs = ::OutputFile( *aInputList.front(), "srs" );
314 : }
315 0 : else if( !(nCommands & PRINTSYNTAX_FLAG) )
316 0 : pEH->FatalError( ERR_NOINPUT, RscId() );
317 691 : }
318 :
319 : /*************************************************************************
320 : |*
321 : |* RscCmdLine::~RscCmdLine()
322 : |*
323 : |* Beschreibung dtor
324 : |*
325 : *************************************************************************/
326 1382 : RscCmdLine::~RscCmdLine()
327 : {
328 1383 : for ( size_t i = 0, n = aInputList.size(); i < n; ++i )
329 692 : delete aInputList[ i ];
330 691 : aInputList.clear();
331 691 : }
332 :
333 : /*************************************************************************
334 : |*
335 : |* RscCmdLine::substitutePaths()
336 : |*
337 : *************************************************************************/
338 :
339 1692 : OString RscCmdLine::substitutePaths( const OString& rIn )
340 : {
341 : // prepare return value
342 1692 : OStringBuffer aRet( 256 );
343 1692 : std::list< std::pair< OString, OString > >::const_iterator last_match = m_aReplacements.end();
344 :
345 : // search for longest replacement match
346 5076 : for( std::list< std::pair< OString, OString > >::const_iterator repl = m_aReplacements.begin(); repl != m_aReplacements.end(); ++repl )
347 : {
348 3384 : if( rIn.compareTo( repl->second, repl->second.getLength() ) == 0 ) // path matches
349 : {
350 2114 : if( last_match == m_aReplacements.end() || last_match->second.getLength() < repl->second.getLength() )
351 2114 : last_match = repl;
352 : }
353 : }
354 :
355 : // copy replacement found and rest of rIn
356 1692 : sal_Int32 nIndex = 0;
357 1692 : if( last_match != m_aReplacements.end() )
358 : {
359 1692 : aRet.append( "%" );
360 1692 : aRet.append( last_match->first );
361 1692 : aRet.append( "%" );
362 1692 : nIndex = last_match->second.getLength();
363 : }
364 1692 : aRet.append( rIn.copy( nIndex ) );
365 :
366 1692 : return aRet.makeStringAndClear();
367 : }
368 :
369 : /*************** R s c C o m p i l e r **********************************/
370 : /****************************************************************/
371 : /* */
372 : /* RscCompiler :: RscCompiler(int argc, char **argv) */
373 : /* */
374 : /* Parameters : argc - number of parameters on command line */
375 : /* argv - arry of pointers to input parameters */
376 : /* */
377 : /* Description : main calling routine. Calls functions to */
378 : /* check and assign the input parameters. It then builds the */
379 : /* command line to call the Glockenspiel preprocessor */
380 : /****************************************************************/
381 :
382 691 : RscCompiler::RscCompiler( RscCmdLine * pLine, RscTypCont * pTypCont )
383 : {
384 691 : fListing = NULL;
385 691 : fExitFile = NULL;
386 :
387 : //Kommandozeile setzen, TypContainer setzen
388 691 : pCL = pLine;
389 691 : pTC = pTypCont;
390 :
391 691 : if( !pCL->aOutputLst.isEmpty() )
392 : {
393 0 : if ( NULL == (fListing = fopen( pCL->aOutputLst.getStr(), "w" )) )
394 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), pCL->aOutputLst.getStr() );
395 0 : pTC->pEH->SetListFile( fListing );
396 : }
397 691 : }
398 :
399 : /*************************************************************************
400 : |*
401 : |* RscCompiler :: RscCompiler()
402 : |*
403 : *************************************************************************/
404 1382 : RscCompiler::~RscCompiler()
405 : {
406 691 : pTC->pEH->SetListFile( NULL );
407 :
408 691 : if( fListing )
409 0 : fclose( fListing );
410 :
411 691 : if( fExitFile )
412 0 : fclose( fExitFile );
413 691 : if( !aTmpOutputHxx.isEmpty() )
414 0 : unlink( aTmpOutputHxx.getStr() );
415 691 : if( !aTmpOutputCxx.isEmpty() )
416 0 : unlink( aTmpOutputCxx.getStr() );
417 691 : if( !aTmpOutputRcCtor.isEmpty() )
418 0 : unlink( aTmpOutputRcCtor.getStr() );
419 691 : if( !aTmpOutputSrc.isEmpty() )
420 0 : unlink( aTmpOutputSrc.getStr() );
421 691 : }
422 :
423 : /*************************************************************************
424 : |*
425 : |* RscCompiler::Start()
426 : |*
427 : |* Beschreibung Datei in Kommandozeile aendern
428 : |*
429 : *************************************************************************/
430 691 : ERRTYPE RscCompiler::Start()
431 : {
432 691 : ERRTYPE aError;
433 : RscFile* pFName;
434 :
435 691 : if( PRINTSYNTAX_FLAG & pCL->nCommands )
436 : {
437 0 : pTC->WriteSyntax( stdout );
438 0 : printf( "khg\n" );
439 0 : return ERR_OK;
440 : }
441 :
442 : // Kein Parameter, dann Hilfe
443 691 : if( pCL->aInputList.empty() )
444 0 : pTC->pEH->FatalError( ERR_NOINPUT, RscId() );
445 :
446 1383 : for( size_t i = 0, n = pCL->aInputList.size(); i < n; ++i )
447 692 : pTC->aFileTab.NewCodeFile( *pCL->aInputList[ i ] );
448 :
449 691 : if( !(pCL->nCommands & NOSYNTAX_FLAG) )
450 : {
451 691 : if( pCL->nCommands & NOPREPRO_FLAG )
452 : {
453 :
454 61 : pTC->pEH->SetListFile( NULL );
455 :
456 61 : sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
457 184 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && aError.IsOk() )
458 : {
459 62 : pFName = pTC->aFileTab.Get( aIndex );
460 62 : if( !pFName->bScanned && !pFName->IsIncFile() )
461 : {
462 62 : aError = IncludeParser( aIndex );
463 : // Currentzeiger richtig setzen
464 62 : aIndex = pTC->aFileTab.GetIndexOf( pFName );
465 : };
466 62 : aIndex = pTC->aFileTab.NextIndex( aIndex );
467 : };
468 :
469 61 : pTC->pEH->SetListFile( fListing );
470 : }
471 : };
472 :
473 691 : if ( pTC->pEH->GetVerbosity() >= RscVerbosityVerbose )
474 : {
475 0 : pTC->pEH->StdOut( "Files: " );
476 0 : sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
477 0 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
478 : {
479 0 : pFName = pTC->aFileTab.Get( aIndex );
480 0 : pTC->pEH->StdOut( pFName->aFileName.getStr() );
481 0 : pTC->pEH->StdOut( " " );
482 0 : aIndex = pTC->aFileTab.NextIndex( aIndex );
483 : };
484 0 : pTC->pEH->StdOut( "\n" );
485 : }
486 :
487 691 : if( aError.IsOk() )
488 691 : aError = Link();
489 :
490 691 : if( aError.IsOk() )
491 691 : EndCompile();
492 :
493 691 : if( aError.IsError() )
494 0 : pTC->pEH->Error( ERR_ERROR, NULL, RscId() );
495 :
496 691 : return( aError );
497 : }
498 : /*************************************************************************
499 : |*
500 : |* RscCmdLine::EndCompile()
501 : |*
502 : |* Beschreibung Datei in Kommandozeile aendern
503 : |*
504 : *************************************************************************/
505 691 : void RscCompiler::EndCompile()
506 : {
507 691 : if( !pCL->aOutputSrs.isEmpty() && (pCL->nCommands & NOLINK_FLAG) )
508 : {
509 630 : pTC->pEH->StdOut( "Writing file ", RscVerbosityVerbose );
510 630 : pTC->pEH->StdOut( pCL->aOutputSrs.getStr(), RscVerbosityVerbose );
511 630 : pTC->pEH->StdOut( ".\n", RscVerbosityVerbose );
512 :
513 : // kopiere von TMP auf richtigen Namen
514 630 : unlink( pCL->aOutputSrs.getStr() ); // Zieldatei loeschen
515 630 : if( !(pCL->nCommands & NOSYNTAX_FLAG) )
516 : {
517 : FILE * foutput;
518 : RscFile * pFN;
519 :
520 630 : if( NULL == (foutput = fopen( pCL->aOutputSrs.getStr(), "w" )) )
521 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), pCL->aOutputSrs.getStr() );
522 : else
523 : {
524 : // Schreibe Datei
525 630 : sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
526 1260 : while( aIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
527 : {
528 630 : pFN = pTC->aFileTab.Get( aIndex );
529 630 : if( !pFN->IsIncFile() )
530 : {
531 630 : pTC->WriteSrc( foutput, NOFILE_INDEX, sal_False );
532 630 : break; // ?T 281091MM nur eine Src-Datei
533 : }
534 : };
535 :
536 630 : fclose( foutput );
537 : };
538 : };
539 : }
540 :
541 691 : if ( !aTmpOutputHxx.isEmpty() )
542 : {
543 0 : pTC->pEH->StdOut( "Writing file ", RscVerbosityVerbose );
544 0 : pTC->pEH->StdOut( pCL->aOutputHxx.getStr(), RscVerbosityVerbose );
545 0 : pTC->pEH->StdOut( ".\n", RscVerbosityVerbose );
546 :
547 : // kopiere von TMP auf richtigen Namen
548 0 : unlink( pCL->aOutputHxx.getStr() ); // Zieldatei loeschen
549 0 : Append( pCL->aOutputHxx, aTmpOutputHxx );
550 0 : unlink( aTmpOutputHxx.getStr() );// TempDatei loeschen
551 0 : aTmpOutputHxx = rtl::OString();
552 : }
553 :
554 691 : if( !aTmpOutputCxx.isEmpty() )
555 : {
556 0 : pTC->pEH->StdOut( "Writing file ", RscVerbosityVerbose );
557 0 : pTC->pEH->StdOut( pCL->aOutputCxx.getStr(), RscVerbosityVerbose );
558 0 : pTC->pEH->StdOut( ".\n", RscVerbosityVerbose );
559 :
560 : // kopiere von TMP auf richtigen Namen
561 0 : unlink( pCL->aOutputCxx.getStr() ); // Zieldatei loeschen
562 0 : Append( pCL->aOutputCxx, aTmpOutputCxx );
563 0 : unlink( aTmpOutputCxx.getStr() );// TempDatei loeschen
564 0 : aTmpOutputCxx = rtl::OString();
565 : }
566 :
567 691 : if( !aTmpOutputRcCtor.isEmpty() )
568 : {
569 0 : pTC->pEH->StdOut( "Writing file ", RscVerbosityVerbose );
570 0 : pTC->pEH->StdOut( pCL->aOutputRcCtor.getStr(), RscVerbosityVerbose );
571 0 : pTC->pEH->StdOut( ".\n", RscVerbosityVerbose );
572 :
573 : // kopiere von TMP auf richtigen Namen
574 0 : unlink( pCL->aOutputRcCtor.getStr() ); // Zieldatei loeschen
575 0 : Append( pCL->aOutputRcCtor, aTmpOutputRcCtor );
576 0 : unlink( aTmpOutputRcCtor.getStr() );// TempDatei loeschen
577 0 : aTmpOutputRcCtor = rtl::OString();
578 : }
579 :
580 691 : if( !aTmpOutputSrc.isEmpty() )
581 : {
582 : // kopiere von TMP auf richtigen Namen
583 0 : unlink( pCL->aOutputSrc.getStr() ); // Zieldatei loeschen
584 0 : Append( pCL->aOutputSrc, aTmpOutputSrc );
585 0 : unlink( aTmpOutputSrc.getStr() );// TempDatei loeschen
586 0 : aTmpOutputSrc = rtl::OString();
587 : }
588 :
589 691 : if( !pCL->aTouchFile.isEmpty() )
590 : {
591 0 : FILE* fp = fopen( pCL->aTouchFile.getStr(), "w" );
592 0 : if( fp )
593 : {
594 0 : fprintf( fp, "Done\n" );
595 0 : fclose( fp );
596 : }
597 : else
598 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), pCL->aTouchFile.getStr() );
599 : }
600 691 : }
601 :
602 : /*************************************************************************
603 : |*
604 : |* RscCompiler::IncludeParser()
605 : |*
606 : *************************************************************************/
607 62 : ERRTYPE RscCompiler :: IncludeParser( sal_uLong lFileKey )
608 : {
609 : FILE * finput;
610 : RscFile * pFName;
611 62 : ERRTYPE aError;
612 :
613 62 : pFName = pTC->aFileTab.Get( lFileKey );
614 62 : if( !pFName )
615 0 : aError = ERR_ERROR;
616 62 : else if( !pFName->bScanned )
617 : {
618 62 : finput = fopen( pFName->aPathName.getStr(), "r" );
619 62 : if( !finput )
620 : {
621 0 : aError = ERR_OPENFILE;
622 : pTC->pEH->Error( aError, NULL, RscId(),
623 0 : pFName->aPathName.getStr() );
624 : }
625 : else
626 : {
627 : RscFile * pFNTmp;
628 : RscDepend * pDep;
629 62 : RscFileInst aFileInst( pTC, lFileKey, lFileKey, finput );
630 :
631 62 : pFName->bScanned = sal_True;
632 62 : ::IncludeParser( &aFileInst );
633 62 : fclose( finput );
634 :
635 : // Include-Pfad durchsuchen
636 124 : for ( size_t i = 0, n = pFName->aDepLst.size(); i < n; ++i )
637 : {
638 62 : pDep = pFName->aDepLst[ i ];
639 62 : pFNTmp = pTC->aFileTab.GetFile( pDep->GetFileKey() );
640 : }
641 :
642 124 : for ( size_t i = 0, n = pFName->aDepLst.size(); i < n; ++i )
643 : {
644 62 : pDep = pFName->aDepLst[ i ];
645 62 : pFNTmp = pTC->aFileTab.GetFile( pDep->GetFileKey() );
646 : // Kein Pfad und Include Datei
647 62 : if( pFNTmp && !pFNTmp->bLoaded )
648 : {
649 62 : rtl::OUString aUniFileName(rtl::OStringToOUString(pFNTmp->aFileName, RTL_TEXTENCODING_ASCII_US));
650 62 : DirEntry aFullName(aUniFileName);
651 62 : if ( aFullName.Find(rtl::OStringToOUString(pCL->aPath, RTL_TEXTENCODING_ASCII_US)) )
652 : {
653 : pFNTmp->aPathName = rtl::OUStringToOString(
654 62 : aFullName.GetFull(), RTL_TEXTENCODING_ASCII_US);
655 : }
656 : else
657 0 : aError = ERR_OPENFILE;
658 : }
659 62 : };
660 : };
661 : };
662 :
663 62 : return aError;
664 : }
665 :
666 : /*************************************************************************
667 : |*
668 : |* RscCompiler :: ParseOneFile()
669 : |*
670 : *************************************************************************/
671 2015 : ERRTYPE RscCompiler :: ParseOneFile( sal_uLong lFileKey,
672 : const RscCmdLine::OutputFile* pOutputFile,
673 : const WriteRcContext* pContext )
674 : {
675 2015 : FILE * finput = NULL;
676 2015 : ERRTYPE aError;
677 : RscFile * pFName;
678 :
679 2015 : pFName = pTC->aFileTab.Get( lFileKey );
680 2015 : if( !pFName )
681 0 : aError = ERR_ERROR;
682 2015 : else if( !pFName->bLoaded )
683 : {
684 : RscDepend * pDep;
685 :
686 : //Include-Dateien vorher lesen
687 692 : pFName->bLoaded = sal_True; //Endlos Rekursion vermeiden
688 :
689 1384 : for ( size_t i = 0; i < pFName->aDepLst.size() && aError.IsOk(); ++i )
690 : {
691 692 : pDep = pFName->aDepLst[ i ];
692 692 : aError = ParseOneFile( pDep->GetFileKey(), pOutputFile, pContext );
693 : }
694 :
695 692 : if( aError.IsError() )
696 0 : pFName->bLoaded = sal_False; //bei Fehler nicht geladenen
697 : else
698 : {
699 692 : rtl::OUString aTmpName(rtl::OStringToOUString(::GetTmpFileName(), RTL_TEXTENCODING_ASCII_US));
700 692 : DirEntry aTmpPath( aTmpName ), aSrsPath(rtl::OStringToOUString(pFName->aPathName, RTL_TEXTENCODING_ASCII_US));
701 :
702 692 : aTmpPath.ToAbs();
703 692 : aSrsPath.ToAbs();
704 :
705 692 : if( pContext && pOutputFile )
706 62 : PreprocessSrsFile( *pOutputFile, *pContext, aSrsPath, aTmpPath );
707 : else
708 630 : aSrsPath.CopyTo( aTmpPath, FSYS_ACTION_COPYFILE );
709 :
710 : rtl::OString aParseFile(rtl::OUStringToOString(aTmpPath.GetFull(),
711 692 : RTL_TEXTENCODING_ASCII_US));
712 692 : finput = fopen(aParseFile.getStr(), "r");
713 :
714 692 : if( !finput )
715 : {
716 0 : pTC->pEH->Error( ERR_OPENFILE, NULL, RscId(), pFName->aPathName.getStr() );
717 0 : aError = ERR_OPENFILE;
718 : }
719 : else
720 : {
721 692 : RscFileInst aFileInst( pTC, lFileKey, lFileKey, finput );
722 :
723 692 : pTC->pEH->StdOut( "reading file ", RscVerbosityVerbose );
724 692 : pTC->pEH->StdOut( aParseFile.getStr(), RscVerbosityVerbose );
725 692 : pTC->pEH->StdOut( " ", RscVerbosityVerbose );
726 :
727 692 : aError = ::parser( &aFileInst );
728 692 : if( aError.IsError() )
729 0 : pTC->Delete( lFileKey );//Resourceobjekte loeschen
730 692 : pTC->pEH->StdOut( "\n", RscVerbosityVerbose );
731 692 : fclose( finput );
732 : };
733 :
734 692 : aTmpPath.Kill();
735 : };
736 : };
737 :
738 2015 : return( aError );
739 : }
740 :
741 : /*************************************************************************
742 : |*
743 : |* RscCompiler :: Link()
744 : |*
745 : *************************************************************************/
746 :
747 : namespace
748 : {
749 : using namespace ::osl;
750 : class RscIoError { };
751 183 : static inline OUString lcl_getAbsoluteUrl(const OUString& i_sBaseUrl, const OString& i_sPath)
752 : {
753 183 : OUString sRelUrl, sAbsUrl;
754 183 : if(FileBase::getFileURLFromSystemPath(OStringToOUString(i_sPath, RTL_TEXTENCODING_MS_1252), sRelUrl) != FileBase::E_None)
755 0 : throw RscIoError();
756 183 : if(FileBase::getAbsoluteFileURL(i_sBaseUrl, sRelUrl, sAbsUrl) != FileBase::E_None)
757 0 : throw RscIoError();
758 183 : return sAbsUrl;
759 : };
760 183 : static inline OString lcl_getSystemPath(const OUString& i_sUrl)
761 : {
762 183 : OUString sSys;
763 183 : if(FileBase::getSystemPathFromFileURL(i_sUrl, sSys) != FileBase::E_None)
764 0 : throw RscIoError();
765 : OSL_TRACE("temporary file: %s", OUStringToOString(sSys, RTL_TEXTENCODING_UTF8).getStr());
766 183 : return OUStringToOString(sSys, RTL_TEXTENCODING_MS_1252);
767 : };
768 122 : static inline OString lcl_getTempFile(OUString& sTempDirUrl)
769 : {
770 : // get a temp file name for the rc file
771 122 : OUString sTempUrl;
772 122 : if(FileBase::createTempFile(&sTempDirUrl, NULL, &sTempUrl) != FileBase::E_None)
773 0 : throw RscIoError();
774 : OSL_TRACE("temporary url: %s", OUStringToOString(sTempUrl, RTL_TEXTENCODING_UTF8).getStr());
775 122 : return lcl_getSystemPath(sTempUrl);
776 : };
777 : }
778 :
779 691 : ERRTYPE RscCompiler::Link()
780 : {
781 : FILE * foutput;
782 691 : ERRTYPE aError;
783 : RscFile* pFName;
784 :
785 691 : if( !(pCL->nCommands & NOLINK_FLAG) )
786 : {
787 61 : ::std::list<RscCmdLine::OutputFile>::const_iterator it;
788 :
789 122 : for( it = pCL->m_aOutputFiles.begin(); it != pCL->m_aOutputFiles.end(); ++it )
790 : {
791 : // cleanup nodes
792 185 : for( sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
793 62 : aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && aError.IsOk();
794 62 : aIndex = pTC->aFileTab.NextIndex( aIndex ) )
795 : {
796 62 : pFName = pTC->aFileTab.Get( aIndex );
797 62 : if( !pFName->IsIncFile() )
798 : {
799 62 : pTC->Delete( aIndex );
800 62 : aIndex = pTC->aFileTab.GetIndexOf( pFName );
801 62 : pFName->bLoaded = sal_False;
802 : }
803 : }
804 :
805 :
806 : // get two temp file urls
807 61 : OString aRcTmp, aSysListTmp, aSysList;
808 : try
809 : {
810 61 : OUString sPwdUrl;
811 61 : osl_getProcessWorkingDir( &sPwdUrl.pData );
812 61 : OUString sRcUrl = lcl_getAbsoluteUrl(sPwdUrl, it->aOutputRc);
813 : // TempDir is either the directory where the rc file is located or pwd
814 61 : OUString sTempDirUrl = sRcUrl.copy(0,sRcUrl.lastIndexOf('/'));
815 : OSL_TRACE("rc directory URL: %s", OUStringToOString(sTempDirUrl, RTL_TEXTENCODING_UTF8).getStr());
816 :
817 61 : aRcTmp = lcl_getTempFile(sTempDirUrl);
818 : OSL_TRACE("temporary rc file: %s", aRcTmp.getStr());
819 :
820 61 : OUString sOilDirUrl;
821 61 : if(!pCL->aILDir.isEmpty())
822 61 : sOilDirUrl = lcl_getAbsoluteUrl(sPwdUrl, pCL->aILDir);
823 : else
824 0 : sOilDirUrl = sTempDirUrl;
825 : OSL_TRACE("ilst directory URL: %s", OUStringToOString(sOilDirUrl, RTL_TEXTENCODING_UTF8).getStr());
826 :
827 61 : aSysListTmp = lcl_getTempFile(sOilDirUrl);
828 : OSL_TRACE("temporary ilst file: %s", aSysListTmp.getStr());
829 :
830 61 : OUString sIlstUrl;
831 61 : sIlstUrl = sRcUrl.copy(sRcUrl.lastIndexOf('/')+1);
832 61 : sIlstUrl = sIlstUrl.copy(0,sIlstUrl.lastIndexOf('.'));
833 61 : sIlstUrl += OUString(RTL_CONSTASCII_USTRINGPARAM(".ilst"));
834 61 : sIlstUrl = lcl_getAbsoluteUrl(sOilDirUrl, OUStringToOString(sIlstUrl, RTL_TEXTENCODING_UTF8));
835 :
836 61 : aSysList = lcl_getSystemPath(sIlstUrl);
837 61 : OSL_TRACE("ilst file: %s", aSysList.getStr());
838 : }
839 0 : catch (RscIoError&)
840 : {
841 0 : OString sMsg("Error with paths:\n");
842 0 : sMsg += "temporary rc file: " + aRcTmp + "\n";
843 0 : sMsg += "temporary ilst file: " + aSysListTmp + "\n";
844 0 : sMsg += "ilst file: " + aSysList + "\n";
845 0 : pTC->pEH->FatalError(ERR_OPENFILE, RscId(), sMsg.getStr());
846 : }
847 61 : if ( NULL == (fExitFile = foutput = fopen( aRcTmp.getStr(), "wb" )) )
848 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aRcTmp.getStr() );
849 :
850 : // Schreibe Datei
851 61 : sal_Char cSearchDelim = rtl::OUStringToOString(DirEntry::GetSearchDelimiter(), RTL_TEXTENCODING_ASCII_US)[0];
852 61 : sal_Char cAccessDelim = rtl::OUStringToOString(DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US)[0];
853 61 : pTC->ChangeLanguage( it->aLangName );
854 61 : pTC->SetSourceCharSet( RTL_TEXTENCODING_UTF8 );
855 61 : pTC->ClearSysNames();
856 61 : rtl::OStringBuffer aSysSearchPath(it->aLangSearchPath);
857 61 : sal_Int32 nIndex = 0;
858 61 : rtl::OString aSearchPath = pTC->GetSearchPath();
859 61 : do
860 : {
861 61 : rtl::OString aToken = aSearchPath.getToken( 0, cSearchDelim, nIndex );
862 61 : if (aSysSearchPath.getLength())
863 61 : aSysSearchPath.append(cSearchDelim);
864 61 : aSysSearchPath.append(aToken);
865 61 : aSysSearchPath.append(cAccessDelim);
866 61 : aSysSearchPath.append(it->aLangName);
867 61 : aSysSearchPath.append(cSearchDelim);
868 61 : aSysSearchPath.append(aToken);
869 : }
870 : while ( nIndex >= 0 );
871 : OSL_TRACE( "setting search path for language %s: %s", it->aLangName.getStr(), aSysSearchPath.getStr() );
872 61 : pTC->SetSysSearchPath(aSysSearchPath.makeStringAndClear());
873 :
874 61 : WriteRcContext aContext;
875 :
876 61 : aContext.fOutput = foutput;
877 61 : aContext.aOutputRc = it->aOutputRc;
878 61 : aContext.aOutputSysList = aSysListTmp;
879 61 : aContext.pCmdLine = pCL;
880 :
881 : // create empty sys list
882 61 : if( !aContext.aOutputSysList.isEmpty() )
883 : {
884 61 : FILE* pSysListFile = fopen( aContext.aOutputSysList.getStr(), "wb" );
885 :
886 61 : if( !pSysListFile )
887 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aContext.aOutputSysList.getStr() );
888 : else
889 61 : fclose( pSysListFile );
890 : }
891 :
892 : // parse files for specific language
893 185 : for( sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
894 62 : aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && aError.IsOk();
895 62 : aIndex = pTC->aFileTab.NextIndex( aIndex ) )
896 : {
897 62 : pFName = pTC->aFileTab.Get( aIndex );
898 62 : if( !pFName->IsIncFile() )
899 : {
900 62 : aError = ParseOneFile( aIndex, &*it, &aContext );
901 62 : aIndex = pTC->aFileTab.GetIndexOf( pFName );
902 : }
903 : };
904 :
905 61 : aError = pTC->WriteRc( aContext );
906 :
907 61 : fclose( foutput );
908 61 : fExitFile = NULL;
909 61 : unlink( it->aOutputRc.getStr() );
910 61 : if( rename( aRcTmp.getStr(), it->aOutputRc.getStr() ) )
911 : {
912 0 : OStringBuffer aBuf;
913 0 : aBuf.append( aRcTmp );
914 0 : aBuf.append( " -> " );
915 0 : aBuf.append( it->aOutputRc );
916 0 : pTC->pEH->FatalError( ERR_RENAMEFILE, RscId(), aBuf.getStr() );
917 : }
918 : else
919 : {
920 : #ifdef UNX
921 61 : chmod( it->aOutputRc.getStr(), S_IRWXU | S_IRWXG | S_IROTH );
922 : #endif
923 : }
924 :
925 61 : unlink( aSysList.getStr() );
926 61 : if( rename( aSysListTmp.getStr(), aSysList.getStr() ) )
927 : {
928 0 : OStringBuffer aBuf;
929 0 : aBuf.append( aSysListTmp );
930 0 : aBuf.append( " -> " );
931 0 : aBuf.append( aSysList );
932 0 : pTC->pEH->FatalError( ERR_RENAMEFILE, RscId(), aBuf.getStr() );
933 : }
934 : else
935 : {
936 : #ifdef UNX
937 61 : chmod( aSysList.getStr(), S_IRWXU | S_IRWXG | S_IROTH );
938 : #endif
939 : }
940 61 : }
941 : }
942 : else
943 : {
944 : // parse files
945 3152 : for( sal_uIntPtr aIndex = pTC->aFileTab.FirstIndex();
946 1261 : aIndex != UNIQUEINDEX_ENTRY_NOTFOUND && aError.IsOk();
947 1261 : aIndex = pTC->aFileTab.NextIndex( aIndex ) )
948 : {
949 1261 : pFName = pTC->aFileTab.Get( aIndex );
950 1261 : if( !pFName->IsIncFile() )
951 : {
952 1261 : aError = ParseOneFile( aIndex, NULL, NULL );
953 1261 : aIndex = pTC->aFileTab.GetIndexOf( pFName );
954 : }
955 : };
956 : }
957 :
958 : // hxx-Datei schreiben
959 691 : if( !pCL->aOutputHxx.isEmpty() && aError.IsOk() )
960 : {
961 0 : aTmpOutputHxx = ::GetTmpFileName();
962 0 : if ( NULL == (fExitFile = foutput = fopen( aTmpOutputHxx.getStr(), "w" )) )
963 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aTmpOutputHxx.getStr() );
964 :
965 0 : pTC->pEH->StdOut( "Generating .hxx file\n" );
966 :
967 : // Schreibe Datei
968 0 : aError = pTC->WriteHxx( foutput, NOFILE_INDEX );
969 :
970 0 : fclose( foutput );
971 0 : fExitFile = NULL;
972 : }
973 :
974 : // cxx-Datei schreiben
975 691 : if( !pCL->aOutputCxx.isEmpty() && aError.IsOk() )
976 : {
977 0 : aTmpOutputCxx = ::GetTmpFileName();
978 0 : if ( NULL == (fExitFile = foutput = fopen( aTmpOutputCxx.getStr(), "w" )) )
979 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aTmpOutputCxx.getStr() );
980 :
981 0 : pTC->pEH->StdOut( "Generating .cxx file\n" );
982 :
983 0 : rtl::OString aHxx = pCL->aOutputHxx;
984 0 : if( aHxx.isEmpty() )
985 : {
986 0 : rtl::OUString aUniOutputCxx(rtl::OStringToOUString(pCL->aOutputCxx, RTL_TEXTENCODING_ASCII_US));
987 : aHxx = rtl::OStringBuffer(rtl::OUStringToOString(DirEntry(aUniOutputCxx).GetBase(),
988 0 : RTL_TEXTENCODING_ASCII_US)).append(".hxx").makeStringAndClear();
989 : }
990 :
991 : // Schreibe Datei
992 0 : aError = pTC->WriteCxx( foutput, NOFILE_INDEX, aHxx );
993 :
994 0 : fclose( foutput );
995 0 : fExitFile = NULL;
996 : }
997 :
998 : // RcCtor-Datei schreiben
999 691 : if( !pCL->aOutputRcCtor.isEmpty() && aError.IsOk() )
1000 : {
1001 0 : aTmpOutputRcCtor = ::GetTmpFileName();
1002 0 : if ( NULL == (fExitFile = foutput = fopen( aTmpOutputRcCtor.getStr(), "w" )) )
1003 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aTmpOutputRcCtor.getStr() );
1004 :
1005 0 : pTC->pEH->StdOut( "Generating .cxx resource constructor file\n" );
1006 :
1007 : // Schreibe Datei
1008 0 : pTC->WriteRcCtor( foutput );
1009 :
1010 0 : fclose( foutput );
1011 0 : fExitFile = NULL;
1012 : }
1013 :
1014 : // src-Datei schreiben
1015 691 : if( !pCL->aOutputSrc.isEmpty() && aError.IsOk() )
1016 : {
1017 0 : aTmpOutputSrc = ::GetTmpFileName();
1018 0 : if ( NULL == (fExitFile = foutput = fopen( aTmpOutputSrc.getStr(), "w" )) )
1019 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aTmpOutputSrc.getStr() );
1020 :
1021 : // Schreibe Datei
1022 0 : pTC->WriteSrc( foutput, NOFILE_INDEX );
1023 :
1024 0 : fclose( foutput );
1025 0 : fExitFile = NULL;
1026 : };
1027 :
1028 691 : return( aError );
1029 : }
1030 :
1031 : /********************************************************************/
1032 : /* */
1033 : /* Function : Append( ) */
1034 : /* */
1035 : /* Parameters : psw - pointer to a preprocessor switch */
1036 : /* */
1037 : /* Description : appends text files */
1038 : /********************************************************************/
1039 0 : void RscCompiler::Append( const rtl::OString& rOutputSrs,
1040 : const rtl::OString& rTmpFile )
1041 : {
1042 0 : if( !::Append( rOutputSrs, rTmpFile ) )
1043 : {
1044 0 : rtl::OStringBuffer aTemp(rOutputSrs);
1045 0 : aTemp.append(" or ").append(rTmpFile);
1046 0 : pTC->pEH->FatalError( ERR_OPENFILE, RscId(), aTemp.getStr() );
1047 : }
1048 0 : }
1049 :
1050 : /*************************************************************************
1051 : |*
1052 : |* GetImageFilePath()
1053 : |*
1054 : |*************************************************************************/
1055 :
1056 1692 : bool RscCompiler::GetImageFilePath( const RscCmdLine::OutputFile& rOutputFile,
1057 : const WriteRcContext& rContext,
1058 : const rtl::OString& rBaseFileName,
1059 : rtl::OString& rImagePath,
1060 : FILE* pSysListFile )
1061 : {
1062 1692 : ::std::list< rtl::OString > aFileNames;
1063 1692 : bool bFound = false;
1064 :
1065 1692 : aFileNames.push_back( rBaseFileName + rtl::OString(".png") );
1066 1692 : aFileNames.push_back( rBaseFileName + rtl::OString(".bmp") );
1067 :
1068 1692 : ::std::list< rtl::OString >::iterator aFileIter( aFileNames.begin() );
1069 :
1070 5079 : while( ( aFileIter != aFileNames.end() ) && !bFound )
1071 : {
1072 1695 : ::std::list< rtl::OString >::const_iterator aDirIter( rOutputFile.aSysSearchDirs.begin() );
1073 :
1074 12800 : while( ( aDirIter != rOutputFile.aSysSearchDirs.end() ) && !bFound )
1075 : {
1076 9410 : const DirEntry aPath( rtl::OStringToOUString(*aDirIter, RTL_TEXTENCODING_ASCII_US) );
1077 9410 : DirEntry aRelPath( aPath );
1078 9410 : DirEntry aAbsPath( aRelPath += DirEntry(rtl::OStringToOUString(*aFileIter, RTL_TEXTENCODING_ASCII_US)) );
1079 :
1080 9410 : aAbsPath.ToAbs();
1081 9410 : const FileStat aFS( aAbsPath.GetFull() );
1082 :
1083 : #if OSL_DEBUG_LEVEL > 1
1084 : fprintf( stderr, "Searching image: %s\n", rtl::OUStringToOString(aRelPath.GetFull(), RTL_TEXTENCODING_ASCII_US).getStr() );
1085 : #endif
1086 :
1087 9410 : if( aFS.IsKind( FSYS_KIND_FILE ) )
1088 : {
1089 1692 : std::list< std::pair< OString, OString > >::const_iterator aReplIter( rContext.pCmdLine->m_aReplacements.begin() );
1090 1692 : String aStr( aRelPath.GetFull() );
1091 1692 : OString aRelPathStr( aStr.GetBuffer(), aStr.Len(), RTL_TEXTENCODING_ASCII_US );
1092 :
1093 5076 : while( ( aReplIter != rContext.pCmdLine->m_aReplacements.end() ) && !bFound )
1094 : {
1095 1692 : rtl::OString aSearch(aReplIter->second.toAsciiLowerCase());
1096 1692 : rtl::OString aSearchIn(aRelPathStr.toAsciiLowerCase());
1097 1692 : if( aSearchIn.indexOf(aSearch) == 0 )
1098 : {
1099 1692 : sal_Int32 nCopyPos = aReplIter->second.getLength(), nLength = aRelPathStr.getLength();
1100 1692 : const sal_Char* pChars = aRelPathStr.getStr();
1101 :
1102 5076 : while( ( nCopyPos < nLength ) && ( pChars[ nCopyPos ] == '/' || pChars[ nCopyPos ] == '\\' || pChars[ nCopyPos ] == ':' ) )
1103 : {
1104 1692 : ++nCopyPos;
1105 : }
1106 :
1107 1692 : if( nCopyPos < nLength )
1108 1692 : rImagePath = aRelPathStr.copy( nCopyPos ).replace( '\\', '/' );
1109 :
1110 1692 : bFound = true;
1111 : }
1112 :
1113 1692 : ++aReplIter;
1114 1692 : }
1115 :
1116 1692 : if( bFound && pSysListFile )
1117 : {
1118 1692 : DirEntry aSysPath(rtl::OStringToOUString(*aDirIter, RTL_TEXTENCODING_ASCII_US));
1119 1692 : String aSysPathFull( ( aSysPath += DirEntry( rtl::OStringToOUString( *aFileIter, RTL_TEXTENCODING_ASCII_US ) ) ).GetFull() );
1120 1692 : OString aSysPathStr( aSysPathFull.GetBuffer(), aSysPathFull.Len(), RTL_TEXTENCODING_ASCII_US );
1121 :
1122 1692 : fprintf( pSysListFile, "%s\n", rContext.pCmdLine->substitutePaths( aSysPathStr ).getStr() );
1123 1692 : }
1124 :
1125 : #if OSL_DEBUG_LEVEL > 1
1126 : fprintf( stderr, "ImagePath to add: %s\n", rImagePath.getStr() );
1127 : #endif
1128 : }
1129 :
1130 9410 : ++aDirIter;
1131 9410 : }
1132 :
1133 1695 : ++aFileIter;
1134 : }
1135 :
1136 1692 : return bFound;
1137 : }
1138 :
1139 : // ------------------------------------------------------------------------------
1140 :
1141 62 : void RscCompiler::PreprocessSrsFile( const RscCmdLine::OutputFile& rOutputFile,
1142 : const WriteRcContext& rContext,
1143 : const DirEntry& rSrsInPath,
1144 : const DirEntry& rSrsOutPath )
1145 : {
1146 62 : SvFileStream aIStm( rSrsInPath.GetFull(), STREAM_READ );
1147 62 : SvFileStream aOStm( rSrsOutPath.GetFull(), STREAM_WRITE | STREAM_TRUNC );
1148 62 : ::std::vector< rtl::OString > aMissingImages;
1149 62 : FILE* pSysListFile = rContext.aOutputSysList.isEmpty() ? NULL : fopen( rContext.aOutputSysList.getStr(), "ab" );
1150 :
1151 62 : if( !aIStm.GetError() && !aOStm.GetError() )
1152 : {
1153 62 : rtl::OString aLine;
1154 62 : rtl::OString aFilePath;
1155 :
1156 188742 : while( aIStm.ReadLine( aLine ) )
1157 : {
1158 560032 : if( ( getTokenCount(aLine, '=') == 2 ) &&
1159 371414 : ( getToken(aLine, 0, '=').indexOf("File") != -1 ) )
1160 : {
1161 991 : rtl::OString aBaseFileName( getToken(getToken(aLine, 1, '"'), 0, '.') );
1162 :
1163 991 : if( GetImageFilePath( rOutputFile, rContext, aBaseFileName, aFilePath, pSysListFile ) )
1164 : {
1165 : aLine = rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("File = \"")).
1166 1982 : append(aFilePath).append(RTL_CONSTASCII_STRINGPARAM("\";")).
1167 991 : makeStringAndClear();
1168 : }
1169 : else
1170 0 : aMissingImages.push_back( aBaseFileName );
1171 :
1172 991 : aOStm.WriteLine(aLine);
1173 : }
1174 187627 : else if (aLine.indexOfL(RTL_CONSTASCII_STRINGPARAM("ImageList")) != -1)
1175 : {
1176 63 : ::std::vector< ::std::pair< rtl::OString, sal_Int32 > > aEntryVector;
1177 :
1178 63 : aOStm.WriteLine(aLine);
1179 :
1180 63 : if (aLine.indexOf(';') == -1)
1181 : {
1182 61 : const sal_uInt32 nImgListStartPos = aIStm.Tell();
1183 :
1184 184 : do
1185 : {
1186 184 : if( !aIStm.ReadLine(aLine) )
1187 0 : break;
1188 : }
1189 184 : while (aLine.indexOfL(RTL_CONSTASCII_STRINGPARAM("Prefix")) == -1);
1190 :
1191 61 : const rtl::OString aPrefix( getToken(aLine, 1, '"') );
1192 61 : aIStm.Seek( nImgListStartPos );
1193 :
1194 550 : do
1195 : {
1196 550 : if (!aIStm.ReadLine(aLine) )
1197 0 : break;
1198 : }
1199 550 : while (aLine.indexOfL(RTL_CONSTASCII_STRINGPARAM("IdList")) == -1);
1200 :
1201 : // scan all ids and collect images
1202 945 : while (aLine.indexOf('}') == -1)
1203 : {
1204 823 : if( !aIStm.ReadLine(aLine) )
1205 0 : break;
1206 :
1207 823 : aLine = comphelper::string::stripStart(aLine, ' ');
1208 823 : aLine = comphelper::string::stripStart(aLine, '\t');
1209 823 : aLine = comphelper::string::remove(aLine, ';');
1210 :
1211 823 : if (comphelper::string::isdigitAsciiString(aLine))
1212 : {
1213 701 : sal_Int32 nNumber = atoi(aLine.getStr());
1214 :
1215 701 : rtl::OStringBuffer aBuf(aPrefix);
1216 701 : if( nNumber < 10000 )
1217 339 : aBuf.append('0');
1218 701 : aBuf.append(aLine);
1219 701 : rtl::OString aBaseFileName = aBuf.makeStringAndClear();
1220 :
1221 701 : if( GetImageFilePath( rOutputFile, rContext, aBaseFileName, aFilePath, pSysListFile ) )
1222 701 : aEntryVector.push_back( ::std::pair< rtl::OString, sal_Int32 >( aFilePath, nNumber ) );
1223 : else
1224 0 : aMissingImages.push_back( aBaseFileName );
1225 : }
1226 : }
1227 :
1228 61 : const sal_uInt32 nImgListEndPos = aIStm.Tell();
1229 61 : aIStm.Seek( nImgListStartPos );
1230 672 : while( aIStm.Tell() < nImgListEndPos )
1231 : {
1232 550 : aIStm.ReadLine( aLine );
1233 :
1234 550 : if (aLine.indexOfL(RTL_CONSTASCII_STRINGPARAM("IdList")) != -1)
1235 : {
1236 945 : while (aLine.indexOf('}') == -1)
1237 823 : aIStm.ReadLine(aLine);
1238 : }
1239 : else
1240 489 : aOStm.WriteLine(aLine);
1241 : }
1242 :
1243 61 : aOStm.WriteLine(rtl::OString(RTL_CONSTASCII_STRINGPARAM("FileList = {")));
1244 :
1245 762 : for( sal_uInt32 i = 0; i < aEntryVector.size(); ++i )
1246 : {
1247 : rtl::OStringBuffer aEntryString(
1248 701 : RTL_CONSTASCII_STRINGPARAM("< \""));
1249 :
1250 701 : aEntryString.append(aEntryVector[i].first);
1251 701 : aEntryString.append(RTL_CONSTASCII_STRINGPARAM("\"; "));
1252 701 : aEntryString.append(static_cast<sal_Int32>(aEntryVector[ i ].second));
1253 701 : aEntryString.append(RTL_CONSTASCII_STRINGPARAM("; >;"));
1254 :
1255 701 : aOStm.WriteLine(aEntryString.makeStringAndClear());
1256 701 : }
1257 :
1258 61 : aOStm.WriteLine(rtl::OString(RTL_CONSTASCII_STRINGPARAM("};")));
1259 : }
1260 : else
1261 2 : aOStm.WriteLine(aLine);
1262 : }
1263 : else
1264 187564 : aOStm.WriteLine(aLine);
1265 62 : }
1266 : }
1267 :
1268 62 : if( aMissingImages.size() > 0 )
1269 : {
1270 0 : rtl::OStringBuffer aImagesStr;
1271 :
1272 0 : for( sal_uInt32 i = 0; i < aMissingImages.size(); ++i )
1273 : {
1274 0 : if( i )
1275 0 : aImagesStr.append(' ');
1276 :
1277 0 : aImagesStr.append(aMissingImages[i]);
1278 : }
1279 :
1280 0 : pTC->pEH->FatalError( ERR_NOIMAGE, RscId(), aImagesStr.getStr() );
1281 : }
1282 :
1283 62 : if( pSysListFile )
1284 62 : fclose( pSysListFile );
1285 62 : }
1286 :
1287 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|