36 #include <boost/date_time/posix_time/posix_time.hpp>
37 #include <boost/filesystem.hpp>
38 #include "boost/lexical_cast.hpp"
39 #include "boost/shared_ptr.hpp"
49 std::vector<const Node*> lMatches;
53 if ( ( aAddress >= lIt->getAddress() ) and ( aAddress < ( lIt->getAddress() + lIt->getSize() ) ) )
54 lMatches.push_back(&*lIt);
57 if ( lIt->getAddress() == aAddress )
58 lMatches.push_back(&*lIt);
62 if ( lMatches.empty() )
63 return "no matching nodes";
64 else if ( lMatches.size() == 1 )
65 return "node \"" + lMatches.front()->getPath() +
"\"";
67 const Node* lCommonAncestor = lMatches.front();
68 std::vector<const Node*> lCommonAncestorLineage = lCommonAncestor->
getLineage(aNode);
70 for ( std::vector<const Node*>::const_iterator lIt = lMatches.begin()+1; lIt != lMatches.end(); lIt++ ) {
71 const std::vector<const Node*> lLineage = (*lIt)->getLineage(aNode);
74 for ( ; i <
std::min(lLineage.size(), lCommonAncestorLineage.size()); i++ ) {
75 if ( lCommonAncestorLineage.at(i) != lLineage.at(i) )
78 lCommonAncestor = lLineage.at(i - 1);
79 lCommonAncestorLineage.assign(lLineage.begin(), lLineage.begin() + i);
82 if ( (aMaxListSize != 0) and (lMatches.size() > aMaxListSize) )
84 if ( lCommonAncestor == &aNode )
85 return boost::lexical_cast<std::string>(lMatches.size()) +
" nodes match";
87 return boost::lexical_cast<std::string>(lMatches.size()) +
" nodes under \"" + lCommonAncestor->
getPath() +
"\" match";
91 const std::string lCommonAncestorPath(lCommonAncestor->
getPath());
92 const size_t lCommonPathLength(lCommonAncestor == &aNode ? 0 : lCommonAncestorPath.size() + 1);
93 std::ostringstream lOSS;
94 lOSS <<
"nodes \"" << lMatches.front()->getPath().substr(lCommonPathLength) <<
"\"";
95 for (std::vector<const Node*>::const_iterator lIt = lMatches.begin() + 1; lIt < lMatches.end(); lIt++)
96 lOSS <<
", \"" << (*lIt)->getPath().substr(lCommonPathLength) <<
"\"";
98 if (lCommonAncestor != &aNode)
99 lOSS <<
" under \"" << lCommonAncestorPath <<
"\"";
123 std::vector<const Node*> lNodes;
125 lNodes.push_back(&*lIt);
128 std::vector<std::pair<const Node*, const Node*> > lOverlappingNodes;
129 if (lNodes.size() < 2)
130 return lOverlappingNodes;
132 for (std::vector<const Node*>::const_iterator lIt1 = lNodes.begin() ; lIt1 != (lNodes.end() - 1); lIt1++)
134 const Node& lNode1 = **lIt1;
140 for (std::vector<const Node*>::const_iterator lIt2(lIt1 + 1) ; (lIt2 != lNodes.end()) and (*lIt2)->getAddress() <= lMaxAddr1; lIt2++)
145 const Node& lNode2 = **lIt2;
148 lOverlappingNodes.push_back( std::make_pair(&lNode1, &lNode2) );
161 lOverlappingNodes.push_back( std::make_pair(&lNode1, &lNode2) );
166 return lOverlappingNodes;
172 std::ios_base::fmtflags lInitialFlags = aStream.flags();
173 char lInitialFillChar = aStream.fill(
'0');
176 aStream <<
"Node '" << aNode1.
getPath() <<
"' [";
178 aStream <<
"addresses 0x" << std::setw ( 8 ) << aNode1.
getAddress() <<
" - 0x" << std::setw ( 8 ) << aNode1.
getAddress() + aNode1.
getSize() - 1;
180 aStream <<
"address 0x" << std::setw ( 8 ) << aNode1.
getAddress();
182 aStream <<
"address 0x" << std::setw ( 8 ) << aNode1.
getAddress() <<
", mask 0x" << std::setw ( 8 ) << aNode1.
getMask();
184 aStream <<
"] overlaps with '" << aNode2.
getPath() <<
"' [";
186 aStream <<
"addresses 0x" << std::setw ( 8 ) << aNode2.
getAddress() <<
" - 0x" << std::setw ( 8 ) << aNode2.
getAddress() + aNode2.
getSize() - 1;
188 aStream <<
"address 0x" << std::setw ( 8 ) << aNode2.
getAddress();
190 aStream <<
"address 0x" << std::setw ( 8 ) << aNode2.
getAddress() <<
", mask 0x" << std::setw ( 8 ) << aNode2.
getMask();
193 aStream.flags(lInitialFlags);
194 aStream.fill(lInitialFillChar);
198 bool writeNodeOverlapReport(
const std::string& aFilePath,
const std::vector<std::pair<const Node*, const Node*> >& aNodes,
const std::string& aHeader)
201 std::stringstream lReport;
202 lReport <<
std::hex << std::setfill (
'0' );
204 for (std::vector<std::pair<const Node*, const Node*> >::const_iterator lIt = aNodes.begin(); lIt != aNodes.end(); lIt++)
207 lReport << std::endl;
211 const bool lNewlyCreatedFile = not boost::filesystem::is_regular_file( boost::filesystem::path(aFilePath) );
212 std::ofstream lReportFile ( aFilePath.c_str() );
214 if ( lReportFile.is_open() )
216 lReportFile << aHeader << std::endl;
217 lReportFile <<
"Written at " << boost::posix_time::microsec_clock::local_time() <<
"." << std::endl;
218 lReportFile << std::endl;
219 lReportFile << lReport.rdbuf();
222 if ( lNewlyCreatedFile )
224 boost::filesystem::permissions( aFilePath , boost::filesystem::perms( 0666 ) );