xref: /aoo41x/main/tools/bootstrp/mkcreate.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_tools.hxx"
30 
31 // global includes
32 #include <stdio.h>
33 
34 // local includes
35 #include "bootstrp/mkcreate.hxx"
36 #include "bootstrp/inimgr.hxx"
37 #include "bootstrp/appdef.hxx"
38 #include <tools/geninfo.hxx>
39 #include <tools/iparser.hxx>
40 #include "bootstrp/prj.hxx"
41 
42 char const *NoBuildProject[] = {
43 	"solenv",
44 	"EndOf_NoBuildProject"
45 };
46 
47 char const *LimitedPath[] = {
48 	"jurt\\com\\sun\\star",
49 	"r_tools",
50 	"ridljar",
51 	"setup2",
52 	"connectivity",
53 	"EndOf_LimitedPath"
54 };
55 
56 //
57 // class SourceDirectory
58 //
59 
60 /*****************************************************************************/
61 SourceDirectory::SourceDirectory( const ByteString &rDirectoryName,
62 	sal_uInt16 nOperatingSystem, SourceDirectory *pParentDirectory )
63 /*****************************************************************************/
64 				: ByteString( rDirectoryName ),
65 				pParent( pParentDirectory ),
66 				pSubDirectories( NULL ),
67 				nOSType( nOperatingSystem ),
68 				nDepth( 0 ),
69 				pDependencies( NULL ),
70 				pCodedDependencies( NULL ),
71 				pCodedIdentifier( NULL )
72 {
73 	if ( pParent ) {
74 		if ( !pParent->pSubDirectories )
75 			pParent->pSubDirectories = new SourceDirectoryList();
76 		pParent->pSubDirectories->InsertSorted( this );
77 		nDepth = pParent->nDepth + 1;
78 	}
79 }
80 
81 /*****************************************************************************/
82 SourceDirectory::~SourceDirectory()
83 /*****************************************************************************/
84 {
85 	delete pSubDirectories;
86 }
87 
88 /*****************************************************************************/
89 CodedDependency *SourceDirectory::AddCodedDependency(
90 	const ByteString &rCodedIdentifier,	sal_uInt16 nOperatingSystems )
91 /*****************************************************************************/
92 {
93 	CodedDependency *pReturn = NULL;
94 
95 	if ( !pCodedDependencies ) {
96 		pCodedDependencies = new SByteStringList();
97 		pReturn = new CodedDependency( rCodedIdentifier, nOperatingSystems );
98 		pCodedDependencies->PutString(( ByteString * ) pReturn );
99 	}
100 	else {
101 		sal_uIntPtr nPos =
102 			pCodedDependencies->IsString( (ByteString *) (& rCodedIdentifier) );
103 		if ( nPos == NOT_THERE ) {
104 			pReturn =
105 				new CodedDependency( rCodedIdentifier, nOperatingSystems );
106 			pCodedDependencies->PutString(( ByteString * ) pReturn );
107 		}
108 		else {
109 			pReturn =
110 				( CodedDependency * ) pCodedDependencies->GetObject( nPos );
111 			pReturn->TryToMerge( rCodedIdentifier, nOperatingSystems );
112 		}
113 	}
114 	return pReturn;
115 }
116 
117 /*****************************************************************************/
118 CodedDependency *SourceDirectory::AddCodedIdentifier(
119 	const ByteString &rCodedIdentifier,	sal_uInt16 nOperatingSystems )
120 /*****************************************************************************/
121 {
122 	CodedDependency *pReturn = NULL;
123 
124 	if ( !pCodedIdentifier ) {
125 		pCodedIdentifier = new SByteStringList();
126 		pReturn = new CodedDependency( rCodedIdentifier, nOperatingSystems );
127 		pCodedIdentifier->PutString(( ByteString * ) pReturn );
128 	}
129 	else {
130 		sal_uIntPtr nPos =
131 			pCodedIdentifier->IsString( ( ByteString *) (& rCodedIdentifier) );
132 		if ( nPos == NOT_THERE ) {
133 			pReturn =
134 				new CodedDependency( rCodedIdentifier, nOperatingSystems );
135 			pCodedIdentifier->PutString(( ByteString * ) pReturn );
136 		}
137 		else {
138 			pReturn =
139 				( CodedDependency * ) pCodedIdentifier->GetObject( nPos );
140 			pReturn->TryToMerge( rCodedIdentifier, nOperatingSystems );
141 		}
142 	}
143 	if ( pParent && pParent->nDepth > 1 )
144 		pParent->AddCodedIdentifier( rCodedIdentifier, nOperatingSystems );
145 
146 	return pReturn;
147 }
148 
149 /*****************************************************************************/
150 ByteString SourceDirectory::GetFullPath()
151 /*****************************************************************************/
152 {
153 	ByteString sFullPath;
154 	if ( pParent ) {
155 		sFullPath = pParent->GetFullPath();
156 		sFullPath += ByteString( PATH_SEPARATOR );
157 	}
158 	sFullPath += *this;
159 
160 	return sFullPath;
161 }
162 
163 /*****************************************************************************/
164 SourceDirectory *SourceDirectory::GetRootDirectory()
165 /*****************************************************************************/
166 {
167 	if ( !pParent )
168 		return this;
169 
170 	return pParent->GetRootDirectory();
171 }
172 
173 /*****************************************************************************/
174 SourceDirectory *SourceDirectory::GetSubDirectory(
175 	const ByteString &rDirectoryPath, sal_uInt16 nOperatingSystem )
176 /*****************************************************************************/
177 {
178 	ByteString sSearch;
179 
180 	sal_Bool bSubs = sal_True;
181 	sal_uIntPtr nIndex = 0;
182 
183 	while ( bSubs && ByteString( LimitedPath[ nIndex ]) != "EndOf_LimitedPath" ) {
184 		SourceDirectory *pActDir = this;
185 		ByteString sLimitation( LimitedPath[ nIndex ]);
186 
187 		sal_Bool bBreak = sal_False;
188 		for ( sal_uIntPtr i = sLimitation.GetTokenCount( '\\' ); i > 0 && !bBreak; i-- ) {
189 			if (( !pActDir ) || ( *pActDir != sLimitation.GetToken(( sal_uInt16 )( i - 1 ), '\\' )))
190 				bBreak = sal_True;
191 			else
192 				pActDir = pActDir->pParent;
193 		}
194 		bSubs = bBreak;
195 		nIndex++;
196 	}
197 
198 	if ( !bSubs )
199 	{
200 		sSearch = rDirectoryPath;
201 	}
202 	else
203 		sSearch = rDirectoryPath.GetToken( 0, PATH_SEPARATOR );
204 
205 	SourceDirectory *pSubDirectory = NULL;
206 
207 	if ( pSubDirectories )
208 		pSubDirectory = pSubDirectories->Search( sSearch );
209 
210 	if ( !pSubDirectory )
211 		pSubDirectory = new SourceDirectory(
212 			sSearch, nOperatingSystem, this );
213 
214 	pSubDirectory->nOSType |= nOperatingSystem;
215 
216 	if ( sSearch.Len() == rDirectoryPath.Len())
217 		return pSubDirectory;
218 
219 	ByteString sPath = rDirectoryPath.Copy( sSearch.Len() + 1 );
220 
221 	return pSubDirectory->GetSubDirectory( sPath, nOperatingSystem );
222 }
223 
224 /*****************************************************************************/
225 SourceDirectory *SourceDirectory::GetDirectory(
226 	const ByteString &rDirectoryName, sal_uInt16 nOperatingSystem )
227 /*****************************************************************************/
228 {
229 	ByteString sDirectoryName( rDirectoryName );
230 #ifdef UNX
231 	sDirectoryName.SearchAndReplaceAll( "\\", "/" );
232 #endif
233 
234 	SourceDirectory *pRoot = GetRootDirectory();
235 
236 	if ( sDirectoryName.Search( *pRoot ) != 0 )
237 		return NULL;
238 
239 	if ( sDirectoryName.Len() == pRoot->Len())
240 		return pRoot;
241 
242 	if ( sDirectoryName.GetChar( pRoot->Len()) == PATH_SEPARATOR ) {
243 		ByteString sSub = sDirectoryName.Copy( pRoot->Len() + 1 );
244 		return pRoot->GetSubDirectory( sSub, nOperatingSystem );
245 	}
246 
247 	return NULL;
248 }
249 
250 /*****************************************************************************/
251 SourceDirectory *SourceDirectory::Insert( const ByteString &rDirectoryName,
252 		sal_uInt16 nOperatingSystem )
253 /*****************************************************************************/
254 {
255 	SourceDirectory *pSubDirectory = NULL;
256 	if ( pSubDirectories )
257 		pSubDirectory = pSubDirectories->Search( rDirectoryName );
258 
259 	if ( !pSubDirectory )
260 		pSubDirectory = new SourceDirectory(
261 			rDirectoryName, nOperatingSystem, this );
262 
263 	return pSubDirectory;
264 }
265 
266 /*****************************************************************************/
267 Dependency *SourceDirectory::ResolvesDependency(
268 	CodedDependency *pCodedDependency )
269 /*****************************************************************************/
270 {
271 	if ( !pCodedIdentifier )
272 		return NULL;
273 
274 	sal_uIntPtr nPos = pCodedIdentifier->IsString( pCodedDependency );
275 	if ( nPos != NOT_THERE ) {
276 		CodedDependency *pIdentifier =
277 			( CodedDependency * ) pCodedIdentifier->GetObject( nPos );
278 		sal_uInt16 nResult =
279 			pIdentifier->GetOperatingSystem() &
280 			pCodedDependency->GetOperatingSystem();
281 		Dependency *pReturn = new Dependency( *this, nResult );
282 		nResult ^= pCodedDependency->GetOperatingSystem();
283 		pCodedDependency->SetOperatingSystem( nResult );
284 		return pReturn;
285 	}
286 	return NULL;
287 }
288 
289 
290 /*****************************************************************************/
291 void SourceDirectory::ResolveDependencies()
292 /*****************************************************************************/
293 {
294 	if ( !pSubDirectories )
295 		return;
296 
297 	for ( sal_uIntPtr i = 0; i < pSubDirectories->Count(); i++ ) {
298 		SourceDirectory *pActDirectory =
299 			( SourceDirectory * ) pSubDirectories->GetObject( i );
300 		if ( pActDirectory->pSubDirectories )
301 			pActDirectory->ResolveDependencies();
302 
303 		if ( pActDirectory->pCodedDependencies ) {
304 			while ( pActDirectory->pCodedDependencies->Count())
305 			{
306 				CodedDependency *pCodedDependency = ( CodedDependency * )
307 					pActDirectory->pCodedDependencies->GetObject(( sal_uIntPtr ) 0 );
308 
309 				for (
310 					sal_uIntPtr k = 0;
311 					( k < pSubDirectories->Count()) &&
312 						( pCodedDependency->GetOperatingSystem() != OS_NONE );
313 					k++
314 				) {
315 					Dependency *pDependency =
316                         ((SourceDirectory *) pSubDirectories->GetObject( k ))->
317 						ResolvesDependency( pCodedDependency );
318 					if ( pDependency )
319 					{
320 						if ( !pActDirectory->pDependencies )
321 							pActDirectory->pDependencies = new SByteStringList();
322 						pActDirectory->pDependencies->PutString( pDependency );
323 					}
324 				}
325 				if ( pCodedDependency->GetOperatingSystem()) {
326 					if ( !pCodedDependencies )
327 						pCodedDependencies = new SByteStringList();
328 					pCodedDependencies->PutString( pCodedDependency );
329 				}
330 				else
331 					delete pCodedDependency;
332 				pActDirectory->pCodedDependencies->Remove(( sal_uIntPtr ) 0 );
333 			}
334 		}
335 	}
336 }
337 
338 /*****************************************************************************/
339 ByteString SourceDirectory::GetTarget()
340 /*****************************************************************************/
341 {
342 	ByteString sReturn;
343 
344 	if ( !pDependencies )
345 		return sReturn;
346 
347 	sal_uIntPtr k = 0;
348 	while ( k < pDependencies->Count()) {
349 		if ( *this == *pDependencies->GetObject( k ))
350 			delete pDependencies->Remove( k );
351 		else
352 			k++;
353 	}
354 
355 	if ( !pDependencies->Count()) {
356 		delete pDependencies;
357 		pDependencies = NULL;
358 		return sReturn;
359 	}
360 
361 	sal_Bool bDependsOnPlatform = sal_False;
362 	for ( sal_uIntPtr i = 0; i < pDependencies->Count(); i++ )
363 		if ((( Dependency * ) pDependencies->GetObject( i ))->
364 			GetOperatingSystem() != OS_ALL )
365 			bDependsOnPlatform = sal_True;
366 
367 	ByteString sTarget( *this );
368 	sTarget.SearchAndReplaceAll( "\\", "$/" );
369 	if ( !bDependsOnPlatform ) {
370 		sReturn = sTarget;
371 		sReturn += " :";
372 		for ( sal_uIntPtr i = 0; i < pDependencies->Count(); i++ ) {
373 			ByteString sDependency( *pDependencies->GetObject( i ));
374 			sDependency.SearchAndReplaceAll( "\\", "$/" );
375 			sReturn += " ";
376 			sReturn += sDependency;
377 		}
378 	}
379 	else {
380 		ByteString sUNX( ".IF \"$(GUI)\" == \"UNX\"\n" );
381 		sUNX += sTarget;
382 		sUNX += " :";
383 		sal_Bool bUNX = sal_False;
384 
385 		ByteString sWNT( ".IF \"$(GUI)\" == \"WNT\"\n" );
386 		sWNT += sTarget;
387 		sWNT += " :";
388 		sal_Bool bWNT = sal_False;
389 
390 		ByteString sOS2( ".IF \"$(GUI)\" == \"OS2\"\n" );
391 		sOS2 += sTarget;
392 		sOS2 += " :";
393 		sal_Bool bOS2 = sal_False;
394 
395 		for ( sal_uIntPtr i = 0; i < pDependencies->Count(); i++ ) {
396 			Dependency *pDependency =
397 				( Dependency * ) pDependencies->GetObject( i );
398 			ByteString sDependency( *pDependency );
399 			sDependency.SearchAndReplaceAll( "\\", "$/" );
400 
401 			if ( pDependency->GetOperatingSystem() & OS_UNX ) {
402 				sUNX += " ";
403 				sUNX += sDependency;
404 				bUNX = sal_True;
405 			}
406 			if ( pDependency->GetOperatingSystem() & OS_WIN32 ) {
407 				sWNT += " ";
408 				sWNT += sDependency;
409 				bWNT = sal_True;
410 			}
411 			if ( pDependency->GetOperatingSystem() & OS_OS2 ) {
412 				sOS2 += " ";
413 				sOS2 += sDependency;
414 				bOS2 = sal_True;
415 			}
416 		}
417 
418 		if ( bUNX ) {
419 			sReturn += sUNX;
420 			sReturn += "\n.ENDIF\n";
421 		}
422 		if ( bWNT ) {
423 			sReturn += sWNT;
424 			sReturn += "\n.ENDIF\n";
425 		}
426 		if ( bOS2 ) {
427 			sReturn += sOS2;
428 			sReturn += "\n.ENDIF\n";
429 		}
430 	}
431 	sReturn.EraseTrailingChars( '\n' );
432 	return sReturn;
433 }
434 
435 /*****************************************************************************/
436 ByteString SourceDirectory::GetSubDirsTarget()
437 /*****************************************************************************/
438 {
439 	ByteString sReturn;
440 
441 	if ( pSubDirectories ) {
442 		sal_Bool bDependsOnPlatform = sal_False;
443 		for ( sal_uIntPtr i = 0; i < pSubDirectories->Count(); i++ )
444 			if ((( SourceDirectory * ) pSubDirectories->GetObject( i ))->
445 				GetOperatingSystems() != OS_ALL )
446 				bDependsOnPlatform = sal_True;
447 
448 		if ( !bDependsOnPlatform ) {
449 			sReturn = "RC_SUBDIRS = ";
450 
451 			for ( sal_uIntPtr i = 0; i < pSubDirectories->Count(); i++ ) {
452 				ByteString sSubDirectory( *pSubDirectories->GetObject( i ));
453 				sSubDirectory.SearchAndReplaceAll( "\\", "$/" );
454 				sReturn += " \\\n\t";
455 				sReturn += sSubDirectory;
456 			}
457 			sReturn += "\n";
458 		}
459 		else {
460 			ByteString sUNX( ".IF \"$(GUI)\" == \"UNX\"\n" );
461 			sUNX += "RC_SUBDIRS = ";
462 			sal_Bool bUNX = sal_False;
463 
464 			ByteString sWNT( ".IF \"$(GUI)\" == \"WNT\"\n" );
465 			sWNT += "RC_SUBDIRS = ";
466 			sal_Bool bWNT = sal_False;
467 
468 			ByteString sOS2( ".IF \"$(GUI)\" == \"OS2\"\n" );
469 			sOS2 += "RC_SUBDIRS = ";
470 			sal_Bool bOS2 = sal_False;
471 
472 			for ( sal_uIntPtr i = 0; i < pSubDirectories->Count(); i++ ) {
473 				SourceDirectory *pDirectory =
474 					( SourceDirectory * ) pSubDirectories->GetObject( i );
475 				ByteString sDirectory( *pDirectory );
476 				sDirectory.SearchAndReplaceAll( "\\", "$/" );
477 
478 				if ( pDirectory->GetOperatingSystems() & OS_UNX ) {
479 					sUNX += " \\\n\t";
480 					sUNX += sDirectory;
481 					bUNX = sal_True;
482 				}
483 				if ( pDirectory->GetOperatingSystems() & OS_WIN32 ) {
484 					sWNT += " \\\n\t";
485 					sWNT += sDirectory;
486 					bWNT = sal_True;
487 				}
488 				if ( pDirectory->GetOperatingSystems() & OS_OS2 ) {
489 					sOS2 += " \\\n\t";
490 					sOS2 += sDirectory;
491 					bOS2 = sal_True;
492 				}
493 			}
494 			if ( bUNX ) {
495 				sReturn += sUNX;
496 				sReturn += "\n.ENDIF\n";
497 			}
498 			if ( bWNT ) {
499 				sReturn += sWNT;
500 				sReturn += "\n.ENDIF\n";
501 			}
502 			if ( bOS2 ) {
503 				sReturn += sOS2;
504 				sReturn += "\n.ENDIF\n";
505 			}
506 		}
507 	}
508 	return sReturn;
509 }
510 
511 /*****************************************************************************/
512 sal_uInt16 SourceDirectory::GetOSType( const ByteString &sDependExt )
513 /*****************************************************************************/
514 {
515 	sal_uInt16 nOSType = 0;
516 	if ( sDependExt == "" )
517 		nOSType |= OS_ALL;
518 	else if ( sDependExt == "N" || sDependExt == "W" )
519 		nOSType |= OS_WIN32;
520 	else if ( sDependExt == "U" )
521 		nOSType |= OS_UNX;
522 	else if ( sDependExt == "P" )
523 		nOSType |= OS_OS2;
524 	return nOSType;
525 }
526 
527 /*****************************************************************************/
528 SourceDirectory *SourceDirectory::CreateRootDirectory(
529 	const ByteString &rRoot, const ByteString &rVersion, sal_Bool bAll )
530 /*****************************************************************************/
531 {
532 	IniManager aIniManager;
533 	aIniManager.Update();
534 
535 	ByteString sDefLst( GetDefStandList());
536 	ByteString sStandLst( aIniManager.ToLocal( sDefLst ));
537 	String s = String( sStandLst, gsl_getSystemTextEncoding());
538 	InformationParser aParser;
539 //	fprintf( stderr,
540 //		"Reading database %s ...\n", sStandLst.GetBuffer());
541 	GenericInformationList *pVerList = aParser.Execute(
542 		s );
543 
544 /*
545 	ByteString sPath( rVersion );
546 #ifndef UNX
547 	sPath += ByteString( "/settings/solarlist" );
548 #else
549 	sPath += ByteString( "/settings/unxsolarlist" );
550 #endif
551 	ByteString sSolarList( _SOLARLIST );
552 
553 	GenericInformation *pInfo = pVerList->GetInfo( sPath, sal_True );
554 	if ( pInfo ) {
555 		ByteString aIniRoot( GetIniRoot() );
556 		DirEntry aIniEntry( String( aIniRoot, RTL_TEXTENCODING_ASCII_US ));
557 		aIniEntry += DirEntry( String( pInfo->GetValue(), RTL_TEXTENCODING_ASCII_US )).GetBase( PATH_SEPARATOR );
558 		sSolarList = ByteString( aIniEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
559 	}
560 
561 	sSolarList = aIniManager.ToLocal( sSolarList );
562 	fprintf( stderr,
563 		"Reading directory information %s ...\n", sSolarList.GetBuffer());
564 */
565 
566 	ByteString sVersion( rVersion );
567 	Star aStar( pVerList, sVersion, sal_True, rRoot.GetBuffer());
568 //	fprintf( stderr,
569 //		"Creating virtual directory tree ...\n" );
570 
571 
572 	SourceDirectory *pSourceRoot = new SourceDirectory( rRoot, OS_ALL );
573 
574 	for ( sal_uIntPtr i = 0; i < aStar.Count(); i++ ) {
575 		Prj *pPrj = aStar.GetObject( i );
576 
577 		sal_Bool bBuildable = sal_True;
578 		sal_uIntPtr nIndex = 0;
579 
580 		while ( bBuildable && ByteString( NoBuildProject[ nIndex ]) != "EndOf_NoBuildProject" ) {
581 			bBuildable = ( ByteString( NoBuildProject[ nIndex ]) !=  pPrj->GetProjectName());
582 			nIndex ++;
583 		}
584 
585 		if ( bBuildable ) {
586 			SourceDirectory *pProject = pSourceRoot->Insert( pPrj->GetProjectName(), OS_ALL );
587 
588 			SByteStringList *pPrjDependencies = pPrj->GetDependencies( sal_False );
589 			if ( pPrjDependencies )
590 				for ( sal_uIntPtr x = 0; x < pPrjDependencies->Count(); x++ )
591 					pProject->AddCodedDependency( *pPrjDependencies->GetObject( x ), OS_ALL );
592 
593 			pProject->AddCodedIdentifier( pPrj->GetProjectName(), OS_ALL );
594 
595 			for ( sal_uIntPtr j = 0; j < pPrj->Count(); j++ ) {
596 				CommandData *pData = pPrj->GetObject( j );
597 				if ( bAll || ( pData->GetCommandType() == COMMAND_NMAKE )) {
598 					ByteString sDirPath( rRoot );
599 					sDirPath += ByteString( PATH_SEPARATOR );
600 					sDirPath += pData->GetPath();
601 					SourceDirectory *pDirectory =
602 						pSourceRoot->InsertFull( sDirPath, pData->GetOSType());
603 					SByteStringList *pDependencies = pData->GetDependencies();
604 					if ( pDependencies ) {
605 						for ( sal_uIntPtr k = 0; k < pDependencies->Count(); k++ ) {
606 							ByteString sDependency(*pDependencies->GetObject( k ));
607 							ByteString sDependExt(sDependency.GetToken( 1, '.' ));
608 							sDependExt.ToUpperAscii();
609 							pDirectory->AddCodedDependency(
610 								sDependency.GetToken( 0, '.' ), GetOSType( sDependExt ));
611 						}
612 					}
613 					ByteString sIdentifier = pData->GetLogFile();
614 					ByteString sIdExt = sIdentifier.GetToken( 1, '.' );
615 					sIdExt.ToUpperAscii();
616 					pDirectory->AddCodedIdentifier( sIdentifier.GetToken( 0, '.' ), GetOSType( sIdExt ));
617 				}
618 			}
619 		}
620 	}
621 	delete pVerList;
622 	return pSourceRoot;
623 }
624 
625 /*****************************************************************************/
626 sal_Bool SourceDirectory::RemoveDirectoryTreeAndAllDependencies()
627 /*****************************************************************************/
628 {
629 	if ( !pParent )
630 		return sal_False;
631 
632 	SourceDirectoryList *pParentContent = pParent->pSubDirectories;
633 	sal_uIntPtr i = 0;
634 	while ( i < pParentContent->Count()) {
635 		SourceDirectory *pCandidate =
636 			( SourceDirectory * )pParentContent->GetObject( i );
637 		if ( pCandidate == this ) {
638 			pParentContent->Remove( i );
639 		}
640 		else {
641 			if ( pCandidate->pDependencies ) {
642 				sal_uIntPtr nPos = pCandidate->pDependencies->IsString( this );
643 				if ( nPos != NOT_THERE )
644 					delete pCandidate->pDependencies->Remove( nPos );
645 			}
646 			i++;
647 		}
648 	}
649 	delete this;
650 	return sal_True;
651 }
652 
653 /*****************************************************************************/
654 sal_Bool SourceDirectory::CreateRecursiveMakefile( sal_Bool bAllChilds )
655 /*****************************************************************************/
656 {
657 	if ( !pSubDirectories )
658 		return sal_True;
659 
660 	fprintf( stdout, "%s", GetFullPath().GetBuffer());
661 
662 	String aTmpStr( GetFullPath(), gsl_getSystemTextEncoding());
663 	DirEntry aEntry( aTmpStr );
664 	if ( !aEntry.Exists()) {
665 		fprintf( stdout, " ... no directory!n" );
666 		return sal_False;
667 	}
668 
669 	sal_uIntPtr j = 0;
670 	while( j < pSubDirectories->Count()) {
671 		String sSubDirectory(
672 			(( SourceDirectory * ) pSubDirectories->GetObject( j ))->
673 				GetFullPath(),
674 			gsl_getSystemTextEncoding()
675 		);
676 		DirEntry aSubDirectory( sSubDirectory );
677 		if ( !aSubDirectory.Exists())
678 			(( SourceDirectory * ) pSubDirectories->GetObject( j ))->
679 				RemoveDirectoryTreeAndAllDependencies();
680 		else
681 			j++;
682 	}
683 
684 	DirEntry aRCFile( String( "makefile.rc", gsl_getSystemTextEncoding()));
685 	DirEntry aRCEntry( aEntry );
686 	aRCEntry += aRCFile;
687 
688 	DirEntry aMKFile( String( "makefile.mk", gsl_getSystemTextEncoding()));
689 	DirEntry aMKEntry( aEntry );
690 	aMKEntry += aMKFile;
691 
692 	sal_Bool bMakefileMk = sal_False;
693 	if ( aMKEntry.Exists()) {
694 		if ( nDepth == 1 && *this == ByteString( "api" ))
695 			fprintf( stdout, " ... makefile.mk exists, ignoring (hack: prj == api)!" );
696 		else {
697 			fprintf( stdout, " ... makefile.mk exists, including!" );
698 			bMakefileMk = sal_True;
699 		}
700 	}
701 
702 	SvFileStream aMakefile( aRCEntry.GetFull(), STREAM_STD_WRITE | STREAM_TRUNC );
703 	if ( !aMakefile.IsOpen()) {
704 		fprintf( stdout, " ... failed!\n" );
705 		return sal_False;
706 	}
707 
708 	ByteString sHeader(
709 		"#*************************************************************************\n"
710 		"#\n"
711 		"# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n"
712         "#\n"
713         "# Copyright 2000, 2010 Oracle and/or its affiliates.\n"
714         "#\n"
715         "# OpenOffice.org - a multi-platform office productivity suite\n"
716         "#\n"
717         "# This file is part of OpenOffice.org.\n"
718         "#\n"
719         "# OpenOffice.org is free software: you can redistribute it and/or modify\n"
720         "# it under the terms of the GNU Lesser General Public License version 3\n"
721         "# only, as published by the Free Software Foundation.\n"
722         "#\n"
723         "# OpenOffice.org is distributed in the hope that it will be useful,\n"
724         "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
725         "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
726         "# GNU Lesser General Public License version 3 for more details\n"
727         "# (a copy is included in the LICENSE file that accompanied this code).\n"
728         "#\n"
729         "# You should have received a copy of the GNU Lesser General Public License\n"
730         "# version 3 along with OpenOffice.org.  If not, see\n"
731         "# <http://www.openoffice.org/license.html>\n"
732         "# for a copy of the LGPLv3 License.\n"
733 		"#\n"
734 		"#*************************************************************************\n"
735 		"\n"
736 	);
737 	if ( !bMakefileMk ) {
738 		if ( nDepth == 0 ) {
739 		 	sHeader += ByteString(
740 				"\n"
741 				"# \n"
742 				"# mark this makefile as a recursive one\n"
743 				"# \n"
744 				"\n"
745 				"MAKEFILERC=yes\n"
746 				"\n"
747 				"# \n"
748 				"# implementation of cvs checkout\n"
749 				"# \n"
750 				"\n"
751 				".IF \"$(checkout)\"==\"\"\n"
752 				"all_target: ALLTAR\n"
753 				".ELSE\t# \"$(checkout)\"==\"\"\n"
754 				".IF \"$(checkout)\"==\"true\"\n"
755 				"% : $(NULL)\n"
756 				"\t_cvs co $@\n"
757 				".ELSE\t# \"$(checkout)\"==\"true\"\n"
758 				"% : $(NULL)\n"
759 				"\t_cvs co -r$(checkout) $@\n"
760 				".ENDIF\t# \"$(checkout)\"==\"true\"\n"
761 				"all_subdirs : $(RC_SUBDIRS)\n"
762 				".ENDIF\t# \"$(checkout)\"==\"\"\n"
763 			);
764 		}
765 		else {
766 		 	sHeader += ByteString(
767 				"\n"
768 				"# \n"
769 				"# mark this makefile as a recursive one\n"
770 				"# \n"
771 				"\n"
772 				"MAKEFILERC=yes\n"
773 			);
774 			if ( nDepth == 1 )
775 				sHeader += ByteString(
776 					".IF \"$(build_deliver)\"==\"true\"\n"
777 					"all_target:\t\t\\\n"
778 					"\tTG_DELIVER\t\\\n"
779 					"\tALLTAR\n"
780 					".ELSE # \"$(build_deliver)\"==\"true\"\n"
781 					"all_target: ALLTAR\n"
782 					".ENDIF # \"$(build_deliver)\"==\"true\"\n"
783 				);
784 			else
785 				sHeader += ByteString(
786 					"all_target: ALLTAR\n"
787 				);
788 		}
789 	}
790 	else {
791 		if ( nDepth == 1 )
792 			sHeader += ByteString(
793 				".IF \"$(build_deliver)\"==\"true\"\n"
794 				"all_target:\t\t\\\n"
795 				"\tTG_DELIVER\t\\\n"
796 				"\tALLTAR\n"
797 				".ELSE # \"$(build_deliver)\"==\"true\"\n"
798 				"all_target: ALLTAR\n"
799 				".ENDIF # \"$(build_deliver)\"==\"true\"\n"
800 			);
801 	}
802 	sHeader += ByteString(
803 		"\n"
804 		"# \n"
805 		"# macro RC_SUBDIRS handles iteration over\n"
806 		"# all mandatory sub directories\n"
807 		"# \n"
808 	);
809 
810 	aMakefile.WriteLine( sHeader );
811 	aMakefile.WriteLine( GetSubDirsTarget());
812 
813 	if ( nDepth == 0 ) {
814 		ByteString sBootstrapTarget(
815 			"# \n"
816 			"# bootstrap target\n"
817 			"# \n\n"
818 			"bootstrap .PHONY :\n"
819     		"\t@config_office/bootstrap\n\n"
820 		);
821 		aMakefile.WriteLine( sBootstrapTarget );
822 		ByteString sConfigureTarget(
823 			"# \n"
824 			"# configure target\n"
825 			"# \n\n"
826 			"configure .PHONY SETDIR=config_office :\n"
827     		"\t@configure\n"
828 		);
829 		aMakefile.WriteLine( sConfigureTarget );
830 	}
831 	else if ( nDepth == 1 ) {
832 		ByteString sDeliverTarget(
833 			"# \n"
834 			"# deliver target to handle\n"
835 			"# project dependencies\n"
836 			"# \n\n"
837 			"TG_DELIVER : $(RC_SUBDIRS)\n"
838 			"\t$(DELIVER)\n"
839 		);
840 		aMakefile.WriteLine( sDeliverTarget );
841 	}
842 
843 	if ( bMakefileMk ) {
844 		ByteString sInclude(
845 			"# \n"
846 			"# local makefile\n"
847 			"# \n"
848 			"\n"
849 			".INCLUDE : makefile.mk\n"
850 		);
851 
852 		if ( nDepth != 1 )
853 			sInclude += ByteString(
854 				"\n"
855 				"all_rc_target: ALLTAR\n"
856 			);
857 
858 		aMakefile.WriteLine( sInclude );
859 	}
860 
861 	ByteString sComment(
862 		"# \n"
863 		"# single directory targets for\n"
864 		"# dependency handling between directories\n"
865 		"# \n"
866 	);
867 	aMakefile.WriteLine( sComment );
868 
869 	for ( sal_uIntPtr i = 0; i < pSubDirectories->Count(); i++ ) {
870 		ByteString sTarget(
871 			(( SourceDirectory * )pSubDirectories->GetObject( i ))->
872 			GetTarget()
873 		);
874 		if ( sTarget.Len())
875 			aMakefile.WriteLine( sTarget );
876 	}
877 
878 	ByteString sFooter(
879 		"\n"
880 	);
881 	if ( !bMakefileMk ) {
882 		sFooter += ByteString(
883 			"# \n"
884 			"# central target makefile\n"
885 			"# \n"
886 			"\n"
887 		);
888 		if ( nDepth != 0 ) {
889 			sFooter += ByteString(
890 				".INCLUDE : target.mk\n"
891 			);
892 		}
893 		else {
894 			sFooter += ByteString(
895 				".IF \"$(checkout)\"==\"\"\n"
896 				".INCLUDE : target.mk\n"
897 				".ENDIF\t#\"$(checkout)\"==\"\"\n"
898 			);
899 		}
900 	}
901 	sFooter += ByteString(
902 		"\n"
903 		"#*************************************************************************\n"
904 	);
905 	aMakefile.WriteLine( sFooter );
906 
907 	aMakefile.Close();
908 
909 	fprintf( stdout, "\n" );
910 
911 	sal_Bool bSuccess = sal_True;
912 	if ( bAllChilds )
913 		for ( sal_uIntPtr k = 0; k < pSubDirectories->Count(); k++ )
914 			if  ( !(( SourceDirectory * ) pSubDirectories->GetObject( k ))->
915 				CreateRecursiveMakefile( sal_True ))
916 				bSuccess = sal_False;
917 
918 	return bSuccess;
919 }
920 
921 //
922 // class SourceDirectoryList
923 //
924 
925 /*****************************************************************************/
926 SourceDirectoryList::~SourceDirectoryList()
927 /*****************************************************************************/
928 {
929 	for ( sal_uIntPtr i = 0; i < Count(); i++ )
930 		delete GetObject( i );
931 }
932 
933 /*****************************************************************************/
934 SourceDirectory *SourceDirectoryList::Search(
935 	const ByteString &rDirectoryName )
936 /*****************************************************************************/
937 {
938 	sal_uIntPtr nPos = IsString( ( ByteString * ) (&rDirectoryName) );
939 	if ( nPos != LIST_ENTRY_NOTFOUND )
940 		return ( SourceDirectory * ) GetObject( nPos );
941 
942 	return NULL;
943 }
944 
945 
946