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