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 <stdlib.h>
28 #include <stdio.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #if defined (WNT) && defined (tcpp)
32 #define _spawnvp spawnvp
33 #define _P_WAIT P_WAIT
34 #endif
35
36 #ifdef UNX
37 #include <unistd.h>
38 #include <sys/wait.h>
39 #else // UNX
40
41 #include <io.h>
42 #include <process.h>
43 #if defined ( OS2 ) && !defined ( GCC )
44 #include <direct.h>
45 #endif
46 #if !defined ( CSET ) && !defined ( OS2 )
47 #include <dos.h>
48 #endif
49
50 #endif // UNX
51 #include <rsctools.hxx>
52 #include <rscerror.h>
53 #include <sal/main.h>
54 #include <tools/fsys.hxx>
55
56 /*************** C O D E ************************************************/
57 /****************************************************************/
58 /* */
59 /* Function : fuer Ansi kompatibilitaet */
60 /* */
61 /****************************************************************/
62 #ifdef UNX
63 #define P_WAIT 0
spawnvp(int,const char * cmdname,char * const * argv)64 int spawnvp( int, const char * cmdname, char *const* argv ){
65 int rc(0);
66
67 switch( fork() ){
68 case -1:
69 return( -1 );
70 case 0:
71 if( execvp( cmdname, argv ) == -1 )
72 // an error occurs
73 return( -1 );
74 break;
75 default:
76 if( -1 == wait( &rc ) )
77 return( -1 );
78 }
79 return( WEXITSTATUS( rc ) );
80 }
81 #endif
82
83 /*************************************************************************
84 |* CallPrePro()
85 |*
86 |* Beschreibung
87 *************************************************************************/
CallPrePro(const ByteString & rPrePro,const ByteString & rInput,const ByteString & rOutput,RscPtrPtr * pCmdLine,sal_Bool bResponse)88 static sal_Bool CallPrePro( const ByteString& rPrePro,
89 const ByteString& rInput,
90 const ByteString& rOutput,
91 RscPtrPtr * pCmdLine,
92 sal_Bool bResponse )
93 {
94 RscPtrPtr aNewCmdL; // Kommandozeile
95 RscPtrPtr aRespCmdL; // Kommandozeile
96 RscPtrPtr * pCmdL = &aNewCmdL;
97 int i, nExit;
98 FILE* fRspFile = NULL;
99 ByteString aRspFileName;
100
101 if( bResponse )
102 {
103 aRspFileName = ::GetTmpFileName();
104 fRspFile = fopen( aRspFileName.GetBuffer(), "w" );
105 }
106
107 if( !fRspFile )
108 aNewCmdL.Append( rsc_strdup( rPrePro.GetBuffer() ) );
109
110 bool bVerbose = false;
111 for( i = 1; i < int(pCmdLine->GetCount() -1); i++ )
112 {
113 if ( 0 == rsc_stricmp( (char *)pCmdLine->GetEntry( i ), "-verbose" ) )
114 {
115 bVerbose = true;
116 continue;
117 }
118 if ( !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-u", 2 )
119 || !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-i", 2 )
120 || !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-d", 2 )
121 )
122 {
123 aNewCmdL.Append( rsc_strdup( (char *)pCmdLine->GetEntry( i ) ) );
124 }
125 }
126
127 aNewCmdL.Append( rsc_strdup( rInput.GetBuffer() ) );
128 aNewCmdL.Append( rsc_strdup( rOutput.GetBuffer() ) );
129 aNewCmdL.Append( (void *)0 );
130
131 if ( bVerbose )
132 {
133 printf( "Preprocessor commandline: " );
134 for( i = 0; i < (int)(pCmdL->GetCount() -1); i++ )
135 {
136 printf( " " );
137 printf( "%s", (const char *)pCmdL->GetEntry( i ) );
138 }
139 printf( "\n" );
140 }
141
142 if( fRspFile )
143 {
144 aRespCmdL.Append( rsc_strdup( rPrePro.GetBuffer() ) );
145 ByteString aTmpStr( '@' );
146 aTmpStr += aRspFileName;
147 aRespCmdL.Append( rsc_strdup( aTmpStr.GetBuffer() ) );
148 aRespCmdL.Append( (void *)0 );
149
150 pCmdL = &aRespCmdL;
151 for( i = 0; i < (int)(aNewCmdL.GetCount() -1); i++ )
152 {
153 #ifdef OS2
154 fprintf( fRspFile, "%s\n", (const char *)aNewCmdL.GetEntry( i ) );
155 #else
156 fprintf( fRspFile, "%s ", (const char *)aNewCmdL.GetEntry( i ) );
157 #endif
158 }
159 fclose( fRspFile );
160
161 if ( bVerbose )
162 {
163 printf( "Preprocessor startline: " );
164 for( i = 0; i < (int)(pCmdL->GetCount() -1); i++ )
165 {
166 printf( " " );
167 printf( "%s", (const char *)pCmdL->GetEntry( i ) );
168 }
169 printf( "\n" );
170 }
171 }
172
173 #if ((defined OS2 || defined WNT) && (defined TCPP || defined tcpp)) || defined UNX || defined OS2
174 nExit = spawnvp( P_WAIT, rPrePro.GetBuffer(), (char* const*)pCmdL->GetBlock() );
175 #elif defined CSET
176 nExit = spawnvp( P_WAIT, (char*)rPrePro.GetBuffer(), (const char**)pCmdL->GetBlock() );
177 #elif defined WTC
178 nExit = spawnvp( P_WAIT, (char*)rPrePro.GetBuffer(), (const char* const*)pCmdL->GetBlock() );
179 #elif defined MTW
180 nExit = spawnvp( P_WAIT, (char*)rPrePro.GetBuffer(), (char**)pCmdL->GetBlock() );
181 #else
182 nExit = spawnvp( P_WAIT, (char*)rPrePro.GetBuffer(), (const char**)pCmdL->GetBlock() );
183 #endif
184
185 if ( fRspFile )
186 #if OSL_DEBUG_LEVEL > 5
187 fprintf( stderr, "leaving response file %s\n", aRspFileName.GetBuffer() );
188 #else
189 unlink( aRspFileName.GetBuffer() );
190 #endif
191 if ( nExit )
192 return sal_False;
193
194 return sal_True;
195 }
196
197
198 /*************************************************************************
199 |* CallRsc2
200 |*
201 |* Beschreibung
202 *************************************************************************/
CallRsc2(ByteString aRsc2Name,RscStrList * pInputList,ByteString aSrsName,RscPtrPtr * pCmdLine)203 static sal_Bool CallRsc2( ByteString aRsc2Name,
204 RscStrList * pInputList,
205 ByteString aSrsName,
206 RscPtrPtr * pCmdLine )
207 {
208 int i, nExit;
209 ByteString* pString;
210 ByteString aRspFileName; // Response-Datei
211 FILE * fRspFile; // Response-Datei
212
213 aRspFileName = ::GetTmpFileName();
214 fRspFile = fopen( aRspFileName.GetBuffer(), "w" );
215
216 RscVerbosity eVerbosity = RscVerbosityNormal;
217 if( fRspFile )
218 {
219 for( i = 1; i < (int)(pCmdLine->GetCount() -1); i++ )
220 {
221 if ( !rsc_stricmp( (char *)pCmdLine->GetEntry( i ), "-verbose" ) )
222 {
223 eVerbosity = RscVerbosityVerbose;
224 continue;
225 }
226 if ( !rsc_stricmp( (char *)pCmdLine->GetEntry( i ), "-quiet" ) )
227 {
228 eVerbosity = RscVerbositySilent;
229 continue;
230 }
231 if( !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-fp=", 4 )
232 || !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-fo=", 4 )
233 || !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-pp=", 4 )
234 || !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-rsc2=", 6 )
235 || !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-presponse", 9 )
236 || !rsc_strnicmp( (char *)pCmdLine->GetEntry( i ), "-rc", 3 )
237 || !rsc_stricmp( (char *)pCmdLine->GetEntry( i ), "-+" )
238 || !rsc_stricmp( (char *)pCmdLine->GetEntry( i ), "-br" )
239 || !rsc_stricmp( (char *)pCmdLine->GetEntry( i ), "-bz" )
240 || !rsc_stricmp( (char *)pCmdLine->GetEntry( i ), "-r" )
241 // Am I the only one that thinks the following line inludes all the tests before?
242 || ( '-' != *(char *)pCmdLine->GetEntry( i ) ) )
243 {
244 }
245 else
246 #ifdef OS2
247 fprintf( fRspFile, "%s\n",
248 #else
249 fprintf( fRspFile, "%s ",
250 #endif
251 (const char *)pCmdLine->GetEntry( i ) );
252 };
253
254 #ifdef OS2
255 fprintf( fRspFile, "%s\n", aSrsName.GetBuffer() );
256 #else
257 fprintf( fRspFile, aSrsName.GetBuffer() );
258 #endif
259
260 pString = pInputList->First();
261 while( pString )
262 {
263 #ifdef OS2
264 fprintf( fRspFile, "%s\n", pString->GetBuffer() );
265 #else
266 fprintf( fRspFile, " %s", pString->GetBuffer() );
267 #endif
268 pString = pInputList->Next();
269 };
270
271 fclose( fRspFile );
272 };
273
274 RscPtrPtr aNewCmdL; // Kommandozeile
275 aNewCmdL.Append( rsc_strdup( aRsc2Name.GetBuffer() ) );
276 ByteString aTmpStr( '@' );
277 aTmpStr += aRspFileName;
278 aNewCmdL.Append( rsc_strdup( aTmpStr.GetBuffer() ) );
279 aNewCmdL.Append( (void *)0 );
280
281 if ( eVerbosity >= RscVerbosityVerbose )
282 {
283 printf( "Rsc2 commandline: " );
284 printf( "%s", (const char *)aNewCmdL.GetEntry( 0 ) );
285 printf( " " );
286 printf( "%s", (const char *)aNewCmdL.GetEntry( 1 ) );
287 printf( "\n" );
288 }
289
290 #if ((defined OS2 || defined WNT) && (defined TCPP || defined tcpp)) || defined UNX || defined OS2
291 nExit = spawnvp( P_WAIT, aRsc2Name.GetBuffer(), (char* const*)aNewCmdL.GetBlock() );
292 #elif defined CSET
293 nExit = spawnvp( P_WAIT, (char*)aRsc2Name.GetBuffer(), (char **)(const char**)aNewCmdL.GetBlock() );
294 #elif defined WTC
295 nExit = spawnvp( P_WAIT, (char*)aRsc2Name.GetBuffer(), (const char* const*)aNewCmdL.GetBlock() );
296 #elif defined MTW
297 nExit = spawnvp( P_WAIT, (char*)aRsc2Name.GetBuffer(), (char**)aNewCmdL.GetBlock() );
298 #else
299 nExit = spawnvp( P_WAIT, (char*)aRsc2Name.GetBuffer(), (const char**)aNewCmdL.GetBlock() );
300 #endif
301
302 if( fRspFile )
303 #if OSL_DEBUG_LEVEL > 5
304 fprintf( stderr, "leaving response file %s\n", aRspFileName.GetBuffer() );
305 #else
306 unlink( aRspFileName.GetBuffer() );
307 #endif
308 if( nExit )
309 return( sal_False );
310 return( sal_True );
311 }
312
313 /*************************************************************************
314 |*
315 |* main()
316 |*
317 |* Beschreibung
318 |* Ersterstellung MM 05.09.91
319 |* Letzte Aenderung MM 05.09.91
320 |*
321 *************************************************************************/
SAL_IMPLEMENT_MAIN_WITH_ARGS(argc,argv)322 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
323 {
324 sal_Bool bPrePro = sal_True;
325 sal_Bool bResFile = sal_True;
326 sal_Bool bHelp = sal_False;
327 sal_Bool bError = sal_False;
328 sal_Bool bResponse = sal_False;
329 ByteString aSolarbin(getenv("SOLARBINDIR"));
330 ByteString aDelim("/");
331 ByteString aPrePro; //( aSolarbin + aDelim + ByteString("rscpp"));
332 ByteString aRsc2Name; //( aSolarbin + aDelim + ByteString("rsc2"));
333 ByteString aSrsName;
334 ByteString aResName;
335 RscStrList aInputList;
336 RscStrList aTmpList;
337 char * pStr;
338 char ** ppStr;
339 RscPtrPtr aCmdLine; // Kommandozeile
340 sal_uInt32 i;
341 ByteString* pString;
342
343 aPrePro = aSolarbin;
344 aPrePro += aDelim;
345 aPrePro += ByteString("rscpp");
346
347 aRsc2Name = aSolarbin;
348 aRsc2Name += aDelim;
349 aRsc2Name += ByteString("rsc2");
350
351 pStr = ::ResponseFile( &aCmdLine, argv, argc );
352 if( pStr )
353 {
354 printf( "Cannot open response file <%s>\n", pStr );
355 return( 1 );
356 };
357
358 ppStr = (char **)aCmdLine.GetBlock();
359 ppStr++;
360 i = 1;
361 sal_Bool bSetSrs = sal_False;
362 while( ppStr && i < (aCmdLine.GetCount() -1) )
363 {
364 if( '-' == **ppStr )
365 {
366 if( !rsc_stricmp( (*ppStr) + 1, "p" )
367 || !rsc_stricmp( (*ppStr) + 1, "l" ) )
368 { // kein Preprozessor
369 bPrePro = sal_False;
370 }
371 else if( !rsc_stricmp( (*ppStr) + 1, "r" )
372 || !rsc_stricmp( (*ppStr) + 1, "s" ) )
373 { // erzeugt kein .res-file
374 bResFile = sal_False;
375 }
376 else if( !rsc_stricmp( (*ppStr) + 1, "h" ) )
377 { // Hilfe anzeigen
378 bHelp = sal_True;
379 }
380 else if( !rsc_strnicmp( (*ppStr) + 1, "presponse", 9 ) )
381 { // anderer Name fuer den Preprozessor
382 bResponse = sal_True;
383 }
384 else if( !rsc_strnicmp( (*ppStr) + 1, "pp=", 3 ) )
385 { // anderer Name fuer den Preprozessor
386 aPrePro = (*ppStr) + 4;
387 }
388 else if( !rsc_strnicmp( (*ppStr) + 1, "rsc2=", 5 ) )
389 { // Accept alternate name for the rsc2 compiler
390 aRsc2Name = (*ppStr) + 6;
391 }
392 else if( !rsc_strnicmp( (*ppStr) + 1, "fo=", 3 ) )
393 { // anderer Name fuer .res-file
394 aResName = (*ppStr) + 4;
395 }
396 else if( !rsc_strnicmp( (*ppStr) + 1, "fp=", 3 ) )
397 { // anderer Name fuer .srs-file
398 bSetSrs = sal_True;
399 aSrsName = (*ppStr);
400 }
401 }
402 else
403 {
404 // Eingabedatei
405 aInputList.Insert( new ByteString( *ppStr ), CONTAINER_APPEND );
406 }
407 ppStr++;
408 i++;
409 }
410
411 if( aInputList.Count() )
412 {
413 /* build the output file names */
414 if( ! aResName.Len() )
415 aResName = OutputFile( *aInputList.First(), "res" );
416 if( ! bSetSrs )
417 {
418 aSrsName = "-fp=";
419 aSrsName += OutputFile( *aInputList.First(), "srs" );
420 }
421 };
422
423 if( bHelp )
424 {
425 bPrePro = sal_False;
426 bResFile = sal_False;
427 };
428 if( bPrePro && aInputList.Count() )
429 {
430 ByteString aTmpName;
431
432 pString = aInputList.First();
433 while( pString )
434 {
435 aTmpName = ::GetTmpFileName();
436 if( !CallPrePro( aPrePro, *pString, aTmpName, &aCmdLine, bResponse ) )
437 {
438 printf( "Error starting preprocessor\n" );
439 bError = sal_True;
440 break;
441 }
442 aTmpList.Insert( new ByteString( aTmpName ), CONTAINER_APPEND );
443 pString = aInputList.Next();
444 };
445 };
446
447 if( !bError )
448 {
449 if( !CallRsc2( aRsc2Name, bPrePro ? &aTmpList : &aInputList,
450 aSrsName, &aCmdLine ) )
451 {
452 if( !bHelp )
453 {
454 printf( "Error starting rsc2 compiler\n" );
455 bError = sal_True;
456 }
457 };
458 };
459
460 pString = aTmpList.First();
461 while( pString )
462 {
463 #if OSL_DEBUG_LEVEL > 5
464 fprintf( stderr, "leaving temp file %s\n", pString->GetBuffer() );
465 #else
466 unlink( pString->GetBuffer() );
467 #endif
468 pString = aTmpList.Next();
469 };
470
471 return( bError );
472 }
473
RscExit(sal_uInt32 nExit)474 void RscExit( sal_uInt32 nExit )
475 {
476 if( nExit )
477 printf( "Program exit is %d\n", (int)nExit );
478 exit( nExit );
479 }
480