xref: /AOO41X/main/xml2cmp/source/finder/dependy.cxx (revision ab595ff673037ca65571681ab9d2dfec8bce159c)
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