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