xref: /aoo4110/main/rsc/source/prj/start.cxx (revision b1cdbd2c)
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