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