xref: /trunk/main/xml2cmp/source/finder/dependy.cxx (revision ab595ff6)
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 
25 #include "dependy.hxx"
26 #include <iostream>
27 #include "../support/syshelp.hxx"
28 #include "../support/list.hxx"
29 #include "../xcd/xmltree.hxx"
30 #include "../xcd/parse.hxx"
31 
32 
33 
34 Simstr 				ShortName(const Simstr & i_rService);
35 
36 
37 
Service(const char * i_sName)38 Service::Service( const char * i_sName )
39 	:	sName(i_sName)
40 		// aImplementations
41 {
42 }
43 
44 ServiceInfo &
AddImplementation(const char * i_sLibrary)45 Service::AddImplementation( const char * i_sLibrary )
46 {
47 	ServiceInfo * ret = new ServiceInfo(i_sLibrary);
48 	aImplementations.push_back(ret);
49 	return *ret;
50 }
51 
ServiceInfo(const char * i_sLibrary)52 ServiceInfo::ServiceInfo( const char * i_sLibrary )
53 	:	sImplementingLibrary(i_sLibrary)
54 		// aNeededServices
55 {
56 }
57 
58 void
AddDependency(const char * i_sNeededService)59 ServiceInfo::AddDependency( const char * i_sNeededService )
60 {
61 	aNeededServices.push_back(i_sNeededService);
62 }
63 
DependencyFinder()64 DependencyFinder::DependencyFinder()
65 {
66 }
67 
~DependencyFinder()68 DependencyFinder::~DependencyFinder()
69 {
70 }
71 
72 void
GatherData(const char * i_sSearchDirectory)73 DependencyFinder::GatherData( const char * i_sSearchDirectory )
74 {
75 	List<Simstr> aFiles;
76 	GatherFileNames( aFiles, i_sSearchDirectory );
77 
78 	for ( unsigned i = 0; i < aFiles.size(); ++i )
79 	{
80 		ReadFile( aFiles[i].str() );
81 	}
82 }
83 
84 void
FindNeededServices(StringVector & o_rLibraries,StringVector & o_rServices,const Simstr & i_rService)85 DependencyFinder::FindNeededServices( StringVector &		o_rLibraries,
86 									  StringVector &		o_rServices,
87 									  const Simstr &		i_rService )
88 {
89 	Map_Services::const_iterator itService = aServices.find(i_rService);
90 	if ( itService == aServices.end() )
91 	{
92 		std::cerr << "Error: Service \""
93 				  << i_rService.str()
94 				  << "\" not found."
95 				  << std::endl;
96 		return ;
97 	}
98 
99 	aResult_Libraries.erase( aResult_Libraries.begin(), aResult_Libraries.end() );
100 	aResult_Services.erase( aResult_Services.begin(), aResult_Services.end() );
101 
102 //	const ServiceInfo & rSInfo = (*itService).second->FirstImplementation();
103 	Add2Result( *(*itService).second );
104 
105 	for ( std::set< Simstr >::const_iterator il = aResult_Libraries.begin();
106 		  il != aResult_Libraries.end();
107 		  ++il )
108 	{
109 		o_rLibraries.push_back(*il);
110 	}
111 
112 	for ( std::set< Simstr >::const_iterator is = aResult_Services.begin();
113 		  is != aResult_Services.end();
114 		  ++is )
115 	{
116 		o_rServices.push_back(*is);
117 	}
118 }
119 
120 void
ReadFile(const char * i_sFilename)121 DependencyFinder::ReadFile(  const char * i_sFilename )
122 {
123 	ModuleDescription	aModule;
124 	X2CParser			aParser(aModule);
125 
126 	if ( !aParser.Parse(i_sFilename) )
127 	{
128 		std::cerr << "Error: File \""
129 			 << i_sFilename
130 			 << "\" could not be parsed."
131 			 << std::endl;
132 		return;
133 	}
134 
135 	// GetResults:
136 	Simstr sModule = aModule.ModuleName();
137 
138 	List < const MultipleTextElement* > aImplServices;
139 	List < const MultipleTextElement* > aNeededServices;
140 
141 	aModule.Get_SupportedServices(aImplServices);
142 	aModule.Get_ServiceDependencies(aNeededServices);
143 
144 	unsigned nImplServicesSize = aImplServices.size();
145 	unsigned nNeededServicesSize = aNeededServices.size();
146 
147 	for ( unsigned i = 0; i < nImplServicesSize; ++i )
148 	{
149 		const MultipleTextElement & rImpl = *aImplServices[i];
150 
151 		unsigned nImplDataSize = rImpl.Size();
152 		for ( unsigned di = 0; di < nImplDataSize; ++di )
153 		{
154 			Simstr sService = ShortName(rImpl.Data(di));
155 			Service * pService = aServices[sService];
156 			if (pService == 0)
157 			{
158 				pService = new Service(rImpl.Data(di));
159                 aServices[sService] = pService;
160 			}
161 			ServiceInfo & rSInfo = pService->AddImplementation(sModule);
162 
163 			for ( unsigned n = 0; n < nNeededServicesSize; ++n )
164 			{
165 				unsigned nNeededDataSize = aNeededServices[n]->Size();
166 				for ( unsigned dn = 0; dn < nNeededDataSize; ++dn )
167 				{
168 					if (! aNeededServices[n]->Data(dn).is_no_text())
169 						rSInfo.AddDependency( ShortName(aNeededServices[n]->Data(dn)) );
170 				}	// end for dn
171 			}	// end for n
172 		}	//	end for di
173 	}	// end for i
174 }
175 
176 void
Add2Result(const Service & i_rService)177 DependencyFinder::Add2Result( const Service & i_rService )
178 {
179 	const ServiceInfo & rSInfo = i_rService.FirstImplementation();
180 	aResult_Libraries.insert(rSInfo.Library());
181 
182 	const ServiceInfo::List_NeededServices & rNeededs
183 			= rSInfo.NeededServices();
184 	for ( StringVector::const_iterator it = rNeededs.begin();
185 		  it != rNeededs.end();
186 		  ++it )
187 	{
188 		std::pair< std::set< Simstr >::iterator, bool > aInsertResult
189 				= aResult_Services.insert(*it);
190 		if (aInsertResult.second)
191 		{	// Needed service not yet known
192 			Map_Services::const_iterator itFound = aServices.find(*it);
193 			if ( itFound == aServices.end() )
194 			{
195 				std::cerr << "Needed service \""
196 						  << (*it).str()
197 						  << "\" not found,"
198 						  << std::endl;
199 			}
200 			else
201 			{
202 				Add2Result( *(*itFound).second );
203 			}
204 		} 	// endif (! aInsertResult.second)
205 	} 	// end for (it)
206 }
207 
208 
209 
210 Simstr
ShortName(const Simstr & i_rService)211 ShortName(const Simstr & i_rService)
212 {
213 	const char * pStart = i_rService.str();
214 	const char * pEnd = strchr(pStart,' ');
215 	if (pEnd != 0)
216 		return Simstr(pStart, 0, int(pEnd-pStart));
217 	else
218 		return i_rService;
219 }
220 
221