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