xref: /aoo41x/main/soldep/bootstrp/prodmap.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir  /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "prodmap.hxx"
29*cdf0e10cSrcweir #include <tools/geninfo.hxx>
30*cdf0e10cSrcweir #include <tools/fsys.hxx>
31*cdf0e10cSrcweir #include "minormk.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <stdio.h>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #define PRODUCT_KEY 	"TARGETDESCRIPTION/PRODUCTS"
36*cdf0e10cSrcweir #define DEPENDS_ON_KEY	"TARGETDESCRIPTION/DEPENDSON"
37*cdf0e10cSrcweir #define BASED_ON_KEY	"TARGETDESCRIPTION/BASEDON"
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir //
40*cdf0e10cSrcweir // class ProductMapper
41*cdf0e10cSrcweir //
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir /*****************************************************************************/
44*cdf0e10cSrcweir ProductMapper::ProductMapper()
45*cdf0e10cSrcweir /*****************************************************************************/
46*cdf0e10cSrcweir 				: pVersionList( NULL ),
47*cdf0e10cSrcweir 				pProductList( NULL )
48*cdf0e10cSrcweir {
49*cdf0e10cSrcweir }
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir /*****************************************************************************/
52*cdf0e10cSrcweir ProductMapper::ProductMapper( GenericInformationList *pVerList )
53*cdf0e10cSrcweir /*****************************************************************************/
54*cdf0e10cSrcweir 				: pVersionList( pVerList ),
55*cdf0e10cSrcweir 				pProductList( NULL )
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir 	if ( pVerList )
58*cdf0e10cSrcweir 		CreateProductList( pVerList );
59*cdf0e10cSrcweir }
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir /*****************************************************************************/
62*cdf0e10cSrcweir ProductMapper::~ProductMapper()
63*cdf0e10cSrcweir /*****************************************************************************/
64*cdf0e10cSrcweir {
65*cdf0e10cSrcweir 	delete pProductList;
66*cdf0e10cSrcweir }
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir /*****************************************************************************/
69*cdf0e10cSrcweir void ProductMapper::CreateProductList( GenericInformationList *pVerList )
70*cdf0e10cSrcweir /*****************************************************************************/
71*cdf0e10cSrcweir {
72*cdf0e10cSrcweir 	/*
73*cdf0e10cSrcweir 	creates a list of the following format:
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir 	ProductName Workspace                // 6.0 Final SRC641
76*cdf0e10cSrcweir 	{                                    // {
77*cdf0e10cSrcweir 		DependsOn                        //     DependsOn
78*cdf0e10cSrcweir 		{                                //     {
79*cdf0e10cSrcweir 			product1                     //
80*cdf0e10cSrcweir 			product2                     //
81*cdf0e10cSrcweir 			...                          //
82*cdf0e10cSrcweir 		}                                //
83*cdf0e10cSrcweir 		BasedOn                          //
84*cdf0e10cSrcweir 		{                                //
85*cdf0e10cSrcweir 			productX                     //
86*cdf0e10cSrcweir 			productY                     //
87*cdf0e10cSrcweir 			...                          //
88*cdf0e10cSrcweir 		}                                //
89*cdf0e10cSrcweir 	}                                    //
90*cdf0e10cSrcweir 	*/
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir 	delete pProductList;
93*cdf0e10cSrcweir 	pProductList = NULL;
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir 	pVersionList = pVerList;
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 	if ( pVersionList ) {
98*cdf0e10cSrcweir 		ByteString sProductKey( PRODUCT_KEY );
99*cdf0e10cSrcweir 		ByteString sDependsOnKey( DEPENDS_ON_KEY );
100*cdf0e10cSrcweir 		ByteString sBasedOnKey( BASED_ON_KEY );
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir 		for ( sal_uIntPtr i = 0; i < pVersionList->Count(); i++ ) {
103*cdf0e10cSrcweir 			GenericInformation *pVersion = pVersionList->GetObject( i );
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir 			GenericInformation *pProducts = pVersion->GetSubInfo( sProductKey, sal_True );
106*cdf0e10cSrcweir 			if ( pProducts ) {
107*cdf0e10cSrcweir 				ByteString sProducts = pProducts->GetValue();
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir 				ByteString sDependsOn;
110*cdf0e10cSrcweir 				GenericInformation *pDependsOn = pVersion->GetSubInfo( sDependsOnKey, sal_True );
111*cdf0e10cSrcweir 				if ( pDependsOn )
112*cdf0e10cSrcweir 					sDependsOn = pDependsOn->GetValue();
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir 				ByteString sBasedOn;
115*cdf0e10cSrcweir 				GenericInformation *pBasedOn = pVersion->GetSubInfo( sBasedOnKey, sal_True );
116*cdf0e10cSrcweir 				if ( pBasedOn )
117*cdf0e10cSrcweir 					sBasedOn = pBasedOn->GetValue();
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir 				for ( sal_uInt16 x = 0; x < sProducts.GetTokenCount( ';' ); x++ ) {
120*cdf0e10cSrcweir 					ByteString sProduct( sProducts.GetToken( x, ';' ));
121*cdf0e10cSrcweir 					if( sProduct.Len()) {
122*cdf0e10cSrcweir 						if ( !pProductList )
123*cdf0e10cSrcweir 							pProductList = new GenericInformationList();
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir 						pProductList->InsertInfo( sProduct, *pVersion, sal_True, sal_True );
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir 						for ( sal_uInt16 y = 0; y < sDependsOn.GetTokenCount( ';' ); y++ ) {
128*cdf0e10cSrcweir 							ByteString sDependsOnKey_l = sProduct;
129*cdf0e10cSrcweir 							sDependsOnKey_l += "/DependsOn/";
130*cdf0e10cSrcweir 							sDependsOnKey_l += sDependsOn.GetToken( y, ';' );
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir 							pProductList->InsertInfo( sDependsOnKey_l, "", sal_True, sal_True );
133*cdf0e10cSrcweir 						}
134*cdf0e10cSrcweir 						for ( sal_uInt16 z = 0; z < sBasedOn.GetTokenCount( ';' ); z++ ) {
135*cdf0e10cSrcweir 							ByteString sBasedOnKey_l = sProduct;
136*cdf0e10cSrcweir 							sBasedOnKey_l += "/BasedOn/";
137*cdf0e10cSrcweir 							sBasedOnKey_l += sBasedOn.GetToken( z, ';' );
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 							pProductList->InsertInfo( sBasedOnKey_l, "", sal_True, sal_True );
140*cdf0e10cSrcweir 						}
141*cdf0e10cSrcweir 					}
142*cdf0e10cSrcweir 				}
143*cdf0e10cSrcweir 			}
144*cdf0e10cSrcweir 		}
145*cdf0e10cSrcweir 	}
146*cdf0e10cSrcweir }
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir /*****************************************************************************/
149*cdf0e10cSrcweir sal_uInt16 ProductMapper::GetProductInformation(
150*cdf0e10cSrcweir 	const ByteString &rProduct, GenericInformation *& pProductInfo )
151*cdf0e10cSrcweir /*****************************************************************************/
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir 	pProductInfo = NULL;
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 	if ( !pVersionList )
156*cdf0e10cSrcweir 		return PRODUCT_MAPPER_NO_VERSION_INFORMATION;
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 	if ( !pProductList )
159*cdf0e10cSrcweir 		return PRODUCT_MAPPER_NO_PRODUCT;
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 	ByteString sProductKey( rProduct );
162*cdf0e10cSrcweir 	pProductInfo = pProductList->GetInfo( sProductKey, sal_True );
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 	if ( !pProductInfo )
165*cdf0e10cSrcweir 		return PRODUCT_MAPPER_NO_PRODUCT;
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir 	return PRODUCT_MAPPER_OK;
168*cdf0e10cSrcweir }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir /*****************************************************************************/
171*cdf0e10cSrcweir sal_uInt16 ProductMapper::PrintDependentTargets(
172*cdf0e10cSrcweir 	const ByteString &rProduct, sal_uInt16 nLevel )
173*cdf0e10cSrcweir /*****************************************************************************/
174*cdf0e10cSrcweir {
175*cdf0e10cSrcweir 	GenericInformation *pProductInfo;
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir 	sal_uInt16 nReturn = GetProductInformation( rProduct, pProductInfo );
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 	if ( nReturn == PRODUCT_MAPPER_OK ) {
180*cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < nLevel; i++ )
181*cdf0e10cSrcweir 			fprintf( stdout, "    " );
182*cdf0e10cSrcweir 		fprintf( stdout, "%s (%s)\n", pProductInfo->GetBuffer(),
183*cdf0e10cSrcweir 			pProductInfo->GetValue().GetBuffer());
184*cdf0e10cSrcweir 		aPrintedList.PutString( new ByteString( *pProductInfo ));
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir 		for ( sal_uIntPtr j = 0; j < pProductList->Count(); j++ ) {
187*cdf0e10cSrcweir 			GenericInformation *pCandidate = pProductList->GetObject( j );
188*cdf0e10cSrcweir 			ByteString sKey( "DEPENDSON/" );
189*cdf0e10cSrcweir 			sKey += rProduct;
190*cdf0e10cSrcweir 			GenericInformation *pDependsOn = pCandidate->GetSubInfo( sKey, sal_True );
191*cdf0e10cSrcweir 			if ( pDependsOn )
192*cdf0e10cSrcweir 				PrintDependentTargets( *pCandidate, nLevel + 1 );
193*cdf0e10cSrcweir 		}
194*cdf0e10cSrcweir 		if ( !nLevel ) {
195*cdf0e10cSrcweir 			ByteString sKey( "BASEDON" );
196*cdf0e10cSrcweir 			GenericInformation *pBasedOn = pProductInfo->GetSubInfo( sKey );
197*cdf0e10cSrcweir 			if ( pBasedOn ) {
198*cdf0e10cSrcweir 				GenericInformationList *pBases = pBasedOn->GetSubList();
199*cdf0e10cSrcweir 				if ( pBases ) {
200*cdf0e10cSrcweir 					for ( sal_uIntPtr k = 0; k < pBases->Count(); k++ ) {
201*cdf0e10cSrcweir 						aBaseList.PutString( new ByteString( *pBases->GetObject( k )));
202*cdf0e10cSrcweir 					}
203*cdf0e10cSrcweir 				}
204*cdf0e10cSrcweir 			}
205*cdf0e10cSrcweir 		}
206*cdf0e10cSrcweir 	}
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 	return nReturn;
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir /*****************************************************************************/
212*cdf0e10cSrcweir sal_uInt16 ProductMapper::PrintAndDeleteBaseList()
213*cdf0e10cSrcweir /*****************************************************************************/
214*cdf0e10cSrcweir {
215*cdf0e10cSrcweir 	if ( aBaseList.Count()) {
216*cdf0e10cSrcweir 		fprintf( stdout, "\nbased on\n" );
217*cdf0e10cSrcweir 		while ( aBaseList.Count()) {
218*cdf0e10cSrcweir 			ByteString sProduct( *aBaseList.GetObject(( sal_uIntPtr ) 0 ));
219*cdf0e10cSrcweir 			if ( aPrintedList.IsString( aBaseList.GetObject(( sal_uIntPtr ) 0 )) == NOT_THERE ) {
220*cdf0e10cSrcweir 				aPrintedList.PutString( aBaseList.GetObject(( sal_uIntPtr ) 0 ));
221*cdf0e10cSrcweir 				PrintDependentTargets( sProduct );
222*cdf0e10cSrcweir 			}
223*cdf0e10cSrcweir 			else
224*cdf0e10cSrcweir 				delete aBaseList.GetObject(( sal_uIntPtr ) 0 );
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir 			aBaseList.Remove(( sal_uIntPtr ) 0 );
227*cdf0e10cSrcweir 		}
228*cdf0e10cSrcweir 		while ( aPrintedList.Count())
229*cdf0e10cSrcweir 			delete aPrintedList.Remove(( sal_uIntPtr ) 0 );
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir 		fprintf( stdout, "\n" );
232*cdf0e10cSrcweir 	}
233*cdf0e10cSrcweir 	return PRODUCT_MAPPER_OK;
234*cdf0e10cSrcweir }
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir /*****************************************************************************/
237*cdf0e10cSrcweir sal_uInt16 ProductMapper::PrintDependencies( const ByteString &rProduct )
238*cdf0e10cSrcweir /*****************************************************************************/
239*cdf0e10cSrcweir {
240*cdf0e10cSrcweir 	sal_uInt16 nResult = PrintDependentTargets( rProduct );
241*cdf0e10cSrcweir 	PrintAndDeleteBaseList();
242*cdf0e10cSrcweir 	return nResult;
243*cdf0e10cSrcweir }
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir /*****************************************************************************/
246*cdf0e10cSrcweir sal_uInt16 ProductMapper::PrintProductList()
247*cdf0e10cSrcweir /*****************************************************************************/
248*cdf0e10cSrcweir {
249*cdf0e10cSrcweir 	if ( !pVersionList )
250*cdf0e10cSrcweir 		return PRODUCT_MAPPER_NO_VERSION_INFORMATION;
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 	if ( !pProductList || !pProductList->Count())
253*cdf0e10cSrcweir 		return PRODUCT_MAPPER_NO_PRODUCT;
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 	if ( pProductList->Count()) {
256*cdf0e10cSrcweir 		for ( sal_uIntPtr i = 0; i < pProductList->Count(); i++ )
257*cdf0e10cSrcweir 			fprintf( stdout, "%s (%s)\n",
258*cdf0e10cSrcweir 				pProductList->GetObject( i )->GetBuffer(),
259*cdf0e10cSrcweir 				pProductList->GetObject( i )->GetValue().GetBuffer());
260*cdf0e10cSrcweir 		fprintf( stdout, "\n" );
261*cdf0e10cSrcweir 	}
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 	return PRODUCT_MAPPER_OK;
264*cdf0e10cSrcweir }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir /*****************************************************************************/
267*cdf0e10cSrcweir SByteStringList *ProductMapper::GetMinorList(
268*cdf0e10cSrcweir 	const ByteString &rVersion, const ByteString &rEnvironment )
269*cdf0e10cSrcweir /*****************************************************************************/
270*cdf0e10cSrcweir {
271*cdf0e10cSrcweir 	SByteStringList *pList = NULL;
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 	if ( pVersionList ) {
274*cdf0e10cSrcweir 		String sRoot( GetVersionRoot( pVersionList, rVersion ));
275*cdf0e10cSrcweir 		if ( sRoot.Len()) {
276*cdf0e10cSrcweir 			DirEntry aEntry( sRoot );
277*cdf0e10cSrcweir 			aEntry += DirEntry( String( rEnvironment, RTL_TEXTENCODING_ASCII_US ));
278*cdf0e10cSrcweir 			String sWildcard( String::CreateFromAscii( "inc.*" ));
279*cdf0e10cSrcweir 			aEntry += DirEntry( sWildcard );
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir 			Dir aDir( aEntry, FSYS_KIND_DIR );
282*cdf0e10cSrcweir 			for ( sal_uInt16 i = 0; i < aDir.Count(); i++ ) {
283*cdf0e10cSrcweir 				ByteString sInc( aDir[ i ].GetName(), RTL_TEXTENCODING_ASCII_US );
284*cdf0e10cSrcweir 				if ( sInc.GetTokenCount( '.' ) > 1 ) {
285*cdf0e10cSrcweir 					if ( !pList )
286*cdf0e10cSrcweir 						pList = new SByteStringList();
287*cdf0e10cSrcweir 					pList->PutString( new ByteString( sInc.GetToken( 1, '.' )));
288*cdf0e10cSrcweir 				}
289*cdf0e10cSrcweir 			}
290*cdf0e10cSrcweir 		}
291*cdf0e10cSrcweir 	}
292*cdf0e10cSrcweir 	return pList;
293*cdf0e10cSrcweir }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir /*****************************************************************************/
296*cdf0e10cSrcweir String ProductMapper::GetVersionRoot(
297*cdf0e10cSrcweir 	GenericInformationList *pList, const ByteString &rVersion )
298*cdf0e10cSrcweir /*****************************************************************************/
299*cdf0e10cSrcweir {
300*cdf0e10cSrcweir 	ByteString sKey( rVersion );
301*cdf0e10cSrcweir 	GenericInformation *pVersion = pList->GetInfo( sKey );
302*cdf0e10cSrcweir 	if ( pVersion ) {
303*cdf0e10cSrcweir #ifdef UNX
304*cdf0e10cSrcweir 		sKey = "drives/o:/unixvolume";
305*cdf0e10cSrcweir 		GenericInformation *pUnixVolume = pVersion->GetSubInfo( sKey, sal_True );
306*cdf0e10cSrcweir 		ByteString sPath;
307*cdf0e10cSrcweir 		if ( pUnixVolume )
308*cdf0e10cSrcweir 			sPath = pUnixVolume->GetValue();
309*cdf0e10cSrcweir 		sPath += "/";
310*cdf0e10cSrcweir #else
311*cdf0e10cSrcweir 		ByteString sPath( "o:\\" );
312*cdf0e10cSrcweir #endif
313*cdf0e10cSrcweir 		sKey = "settings/path";
314*cdf0e10cSrcweir 		GenericInformation *pPath = pVersion->GetSubInfo( sKey, sal_True );
315*cdf0e10cSrcweir 		if ( pPath ) {
316*cdf0e10cSrcweir 			sPath += pPath->GetValue().GetToken( 0, '\\' );
317*cdf0e10cSrcweir 			sPath += "/";
318*cdf0e10cSrcweir 		}
319*cdf0e10cSrcweir #ifdef UNX
320*cdf0e10cSrcweir 		sPath.SearchAndReplaceAll( "\\", "/" );
321*cdf0e10cSrcweir 		while( sPath.SearchAndReplace( "//", "/" ) != STRING_NOTFOUND ) {};
322*cdf0e10cSrcweir #else
323*cdf0e10cSrcweir 		sPath.SearchAndReplaceAll( "/", "\\" );
324*cdf0e10cSrcweir 		while( sPath.SearchAndReplace( "\\\\", "\\" ) != STRING_NOTFOUND ) {};
325*cdf0e10cSrcweir #endif
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir 		return String( sPath, RTL_TEXTENCODING_ASCII_US );
328*cdf0e10cSrcweir 	}
329*cdf0e10cSrcweir 	return String();
330*cdf0e10cSrcweir }
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir /*****************************************************************************/
333*cdf0e10cSrcweir BaseProductList *ProductMapper::GetBases(
334*cdf0e10cSrcweir 	GenericInformation *pProductInfo, sal_uInt16 nLevel,
335*cdf0e10cSrcweir 	BaseProductList *pBases )
336*cdf0e10cSrcweir /*****************************************************************************/
337*cdf0e10cSrcweir {
338*cdf0e10cSrcweir 	if ( !pBases )
339*cdf0e10cSrcweir 		pBases = new BaseProductList();
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir 	if ( pProductInfo ) {
342*cdf0e10cSrcweir 		ByteString sCandidate( *pProductInfo );
343*cdf0e10cSrcweir 		sCandidate += " (";
344*cdf0e10cSrcweir 		sCandidate += pProductInfo->GetValue();
345*cdf0e10cSrcweir 		sCandidate += ")";
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir 		ByteString sKey( "BASEDON" );
348*cdf0e10cSrcweir 		GenericInformation *pBasedOn = pProductInfo->GetSubInfo( sKey );
349*cdf0e10cSrcweir 		if ( pBasedOn ) {
350*cdf0e10cSrcweir 			GenericInformationList *pBasesInfo = pBasedOn->GetSubList();
351*cdf0e10cSrcweir 			if ( pBasesInfo ) {
352*cdf0e10cSrcweir 				for ( sal_uIntPtr k = 0; k < pBasesInfo->Count(); k++ ) {
353*cdf0e10cSrcweir 					GenericInformation *pBaseProduct;
354*cdf0e10cSrcweir 					if ( GetProductInformation( *pBasesInfo->GetObject( k ), pBaseProduct ) == PRODUCT_MAPPER_OK )
355*cdf0e10cSrcweir 						GetBases( pBaseProduct, ++ nLevel, pBases );
356*cdf0e10cSrcweir 				}
357*cdf0e10cSrcweir 			}
358*cdf0e10cSrcweir 		}
359*cdf0e10cSrcweir 		sal_Bool bFound = sal_False;
360*cdf0e10cSrcweir 		ByteString sUpperCandidate( sCandidate );
361*cdf0e10cSrcweir 		sUpperCandidate.ToUpperAscii();
362*cdf0e10cSrcweir 		for ( sal_uInt16 i = 0; i < pBases->Count() && !bFound; i++ ) {
363*cdf0e10cSrcweir 			ByteString sTest( *pBases->GetObject( i ));
364*cdf0e10cSrcweir 			if ( sTest.ToUpperAscii() == sUpperCandidate )
365*cdf0e10cSrcweir 				bFound = sal_True;
366*cdf0e10cSrcweir 		}
367*cdf0e10cSrcweir 		if ( !bFound )
368*cdf0e10cSrcweir 			pBases->Insert( new ByteString( sCandidate ), ( sal_uIntPtr ) 0 );
369*cdf0e10cSrcweir 	}
370*cdf0e10cSrcweir 	return pBases;
371*cdf0e10cSrcweir }
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir /*****************************************************************************/
374*cdf0e10cSrcweir sal_uInt16 ProductMapper::PrintMinorList(
375*cdf0e10cSrcweir 	const ByteString rProduct, const ByteString rEnvironment )
376*cdf0e10cSrcweir /*****************************************************************************/
377*cdf0e10cSrcweir {
378*cdf0e10cSrcweir 	if ( !pVersionList )
379*cdf0e10cSrcweir 		return PRODUCT_MAPPER_NO_VERSION_INFORMATION;
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir 	if ( !pProductList || !pProductList->Count())
382*cdf0e10cSrcweir 		return PRODUCT_MAPPER_NO_PRODUCT;
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir 	GenericInformation *pProductInfo;
385*cdf0e10cSrcweir 	GetProductInformation( rProduct, pProductInfo );
386*cdf0e10cSrcweir 	if ( !pProductInfo )
387*cdf0e10cSrcweir 		return PRODUCT_MAPPER_NO_PRODUCT;
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir 	BaseProductList *pBases = GetBases( pProductInfo );
390*cdf0e10cSrcweir 	if ( pBases->Count()) {
391*cdf0e10cSrcweir 		if ( pBases->Count() > 1 )
392*cdf0e10cSrcweir 			fprintf( stdout, "Product \"%s\" based on ", pBases->GetObject(( sal_uIntPtr ) 0 )->GetBuffer());
393*cdf0e10cSrcweir 		else
394*cdf0e10cSrcweir 			fprintf( stdout, "Product \"%s\" based on no other products", pBases->GetObject(( sal_uIntPtr ) 0 )->GetBuffer());
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir 		for ( sal_uIntPtr i = 1; i < pBases->Count(); i++ ) {
397*cdf0e10cSrcweir 			fprintf( stdout, "\"%s\"", pBases->GetObject( i )->GetBuffer());
398*cdf0e10cSrcweir 			if ( i < pBases->Count() - 1 )
399*cdf0e10cSrcweir 				fprintf( stdout, ", " );
400*cdf0e10cSrcweir 		}
401*cdf0e10cSrcweir 		fprintf( stdout, "\n\n" );
402*cdf0e10cSrcweir 	}
403*cdf0e10cSrcweir 	sal_uInt16 nResult = PRODUCT_MAPPER_OK;
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir 	if ( rEnvironment.Len())
406*cdf0e10cSrcweir 		nResult = PrintSingleMinorList( pProductInfo, pBases, rEnvironment );
407*cdf0e10cSrcweir 	else {
408*cdf0e10cSrcweir 		ByteString sEnvKey( pProductInfo->GetValue());
409*cdf0e10cSrcweir 		sEnvKey += "/Environments";
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir 		GenericInformation *pEnvironmentInfo = pVersionList->GetInfo( sEnvKey, sal_True );
412*cdf0e10cSrcweir 		if ( pEnvironmentInfo ) {
413*cdf0e10cSrcweir 			GenericInformationList *pEnvironmentList = pEnvironmentInfo->GetSubList();
414*cdf0e10cSrcweir 			if ( pEnvironmentList ) {
415*cdf0e10cSrcweir 				for ( sal_uIntPtr i = 0; i < pEnvironmentList->Count(); i++ ) {
416*cdf0e10cSrcweir 					sal_uInt16 nTmp = PrintSingleMinorList( pProductInfo, pBases, *pEnvironmentList->GetObject( i ));
417*cdf0e10cSrcweir 					if ( nTmp != PRODUCT_MAPPER_OK )
418*cdf0e10cSrcweir 						nResult = nTmp;
419*cdf0e10cSrcweir 				}
420*cdf0e10cSrcweir 			}
421*cdf0e10cSrcweir 		}
422*cdf0e10cSrcweir 	}
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir 	for ( sal_uIntPtr m = 0; m < pBases->Count(); m++ )
425*cdf0e10cSrcweir 		delete pBases->GetObject( m );
426*cdf0e10cSrcweir 	delete pBases;
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir 	return nResult;
429*cdf0e10cSrcweir }
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir /*****************************************************************************/
432*cdf0e10cSrcweir sal_uInt16 ProductMapper::PrintSingleMinorList(
433*cdf0e10cSrcweir 	GenericInformation *pProductInfo, BaseProductList *pBases,
434*cdf0e10cSrcweir 	const ByteString rEnvironment )
435*cdf0e10cSrcweir /*****************************************************************************/
436*cdf0e10cSrcweir {
437*cdf0e10cSrcweir 	DirEntry aRoot( GetVersionRoot( pVersionList, pProductInfo->GetValue()));
438*cdf0e10cSrcweir 	aRoot += DirEntry( String( rEnvironment, RTL_TEXTENCODING_ASCII_US ));
439*cdf0e10cSrcweir 	if ( !aRoot.Exists())
440*cdf0e10cSrcweir 		return PRODUCT_MAPPER_OK;
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir 	SByteStringList *pMinors = GetMinorList( pProductInfo->GetValue(), rEnvironment );
443*cdf0e10cSrcweir 	if ( !pMinors )
444*cdf0e10cSrcweir 		pMinors = new SByteStringList();
445*cdf0e10cSrcweir 	pMinors->Insert( new ByteString( "" ), LIST_APPEND );
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir 	SByteStringList aOutputList;
448*cdf0e10cSrcweir 	sal_Bool bUnknownMinor = sal_False;
449*cdf0e10cSrcweir 	for ( sal_uIntPtr i = 0; i < pMinors->Count(); i++ ) {
450*cdf0e10cSrcweir 		ByteString sOutput;
451*cdf0e10cSrcweir 		ByteString sProductVersion;
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir 		for ( sal_uIntPtr j = 0; j < pBases->Count(); j++ ) {
454*cdf0e10cSrcweir 			ByteString sCurProduct( *pBases->GetObject( j ));
455*cdf0e10cSrcweir 			ByteString sVersion( sCurProduct.GetToken( sCurProduct.GetTokenCount( '(' ) - 1, '(' ).GetToken( 0, ')' ));
456*cdf0e10cSrcweir 			if ( !j )
457*cdf0e10cSrcweir 				sProductVersion = sVersion;
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir 			MinorMk *pMinorMk = new MinorMk(
460*cdf0e10cSrcweir 				pVersionList, sProductVersion, sVersion, rEnvironment, *pMinors->GetObject( i ));
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir 			ByteString sMinor( pMinorMk->GetLastMinor().GetBuffer());
463*cdf0e10cSrcweir 			if ( !sMinor.Len()) {
464*cdf0e10cSrcweir 				sMinor = "!";
465*cdf0e10cSrcweir 				bUnknownMinor = sal_True;
466*cdf0e10cSrcweir 			}
467*cdf0e10cSrcweir 			if ( j == 0 ) {
468*cdf0e10cSrcweir 				sOutput += pMinorMk->GetBuildNr();
469*cdf0e10cSrcweir 				sOutput += " ";
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir 				if ( i == pMinors->Count() - 1 )
472*cdf0e10cSrcweir 					sOutput += "flat: ";
473*cdf0e10cSrcweir 				else
474*cdf0e10cSrcweir 					sOutput += "      ";
475*cdf0e10cSrcweir 			}
476*cdf0e10cSrcweir 			sOutput += sVersion;
477*cdf0e10cSrcweir 			sOutput += ".";
478*cdf0e10cSrcweir 			sOutput += sMinor;
479*cdf0e10cSrcweir 			sOutput += "(";
480*cdf0e10cSrcweir 			sOutput += pMinorMk->GetBuildNr();
481*cdf0e10cSrcweir 			sOutput += ")  ";
482*cdf0e10cSrcweir 		}
483*cdf0e10cSrcweir 		aOutputList.PutString( new ByteString( sOutput ));
484*cdf0e10cSrcweir 	}
485*cdf0e10cSrcweir 	ByteString sOldMinor;
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir 	if ( aOutputList.Count())
488*cdf0e10cSrcweir 		fprintf( stdout, "Available builds on %s:\n", rEnvironment.GetBuffer());
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir 	for ( sal_uIntPtr o = 0; o < aOutputList.Count(); o++ ) {
491*cdf0e10cSrcweir 		ByteString sOutput( *aOutputList.GetObject( o ));
492*cdf0e10cSrcweir 		sOutput = sOutput.Copy( sOutput.GetToken( 0, ' ' ).Len() + 1 );
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir 		ByteString sCurMinor( sOutput.GetToken( 1, '.' ).GetToken( 0, '(' ));
495*cdf0e10cSrcweir 		if ( sOldMinor.Len() && sCurMinor < sOldMinor ) {
496*cdf0e10cSrcweir 			fprintf( stdout, "      ----------\n" );
497*cdf0e10cSrcweir 		}
498*cdf0e10cSrcweir 		sOldMinor = sCurMinor;
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir 		fprintf( stdout, "%s\n", sOutput.GetBuffer());
501*cdf0e10cSrcweir 		delete aOutputList.GetObject( o );
502*cdf0e10cSrcweir 	}
503*cdf0e10cSrcweir 	if ( bUnknownMinor )
504*cdf0e10cSrcweir 		fprintf( stdout, "Symbol ! indcates that at least one minor could not be found\n\n" );
505*cdf0e10cSrcweir 	else if ( aOutputList.Count())
506*cdf0e10cSrcweir 		fprintf( stdout, "\n" );
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir 	for ( sal_uIntPtr l = 0; l < pMinors->Count(); l++ )
509*cdf0e10cSrcweir 		delete pMinors->GetObject( l );
510*cdf0e10cSrcweir 	delete pMinors;
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir 	return PRODUCT_MAPPER_OK;
513*cdf0e10cSrcweir }
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir 
518