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