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 38 Service::Service( const char * i_sName ) 39 : sName(i_sName) 40 // aImplementations 41 { 42 } 43 44 ServiceInfo & 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 52 ServiceInfo::ServiceInfo( const char * i_sLibrary ) 53 : sImplementingLibrary(i_sLibrary) 54 // aNeededServices 55 { 56 } 57 58 void 59 ServiceInfo::AddDependency( const char * i_sNeededService ) 60 { 61 aNeededServices.push_back(i_sNeededService); 62 } 63 64 DependencyFinder::DependencyFinder() 65 { 66 } 67 68 DependencyFinder::~DependencyFinder() 69 { 70 } 71 72 void 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 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 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 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 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