+/* =========================================================================
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#include <climits>
+#include <cstdlib>
+#include <iostream>
+#include <memory>
+#include <queue>
+#include <set>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <sys/stat.h>
+#include <unistd.h>
+
+// -------------------------------------------------------------------------
+void Split( const std::string& s, std::string& d, std::string& f )
+{
+ size_t found = s.find_last_of( "/\\" );
+ d = s.substr( 0, found );
+ f = s.substr( found + 1 );
+}
+
+// -------------------------------------------------------------------------
+inline bool Exists( const std::string& name )
+{
+ struct stat buffer;
+ return( stat( name.c_str( ), &buffer) == 0 );
+}
+
+// -------------------------------------------------------------------------
+std::string Exec( const std::string& cmd )
+{
+ std::array< char, 128 > buffer;
+ std::string result;
+ std::shared_ptr< FILE > pipe( popen( cmd.c_str( ), "r" ), pclose );
+ if( !pipe )
+ throw std::runtime_error( "popen( ) failed!" );
+ while( !feof( pipe.get( ) ) )
+ if( fgets( buffer.data( ), 128, pipe.get( ) ) != NULL )
+ result += buffer.data( );
+ return( result );
+}
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ if( argc < 3 )
+ {
+ std::cerr
+ << "Usage: " << argv[ 0 ]
+ << " entry_point objdump_tool [other_dir(s)]"
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ std::string entry_point, objdump_tool;
+ std::set< std::string > dirs;
+
+ if( !Exists( argv[ 1 ] ) )
+ {
+ std::cerr
+ << "Error: file \"" << argv[ 1 ] << "\" does not exist."
+ << std::endl;
+ return( 1 );
+
+ } // fi
+ if( !Exists( argv[ 2 ] ) )
+ {
+ std::cerr
+ << "Error: file \"" << argv[ 2 ] << "\" does not exist."
+ << std::endl;
+ return( 1 );
+
+ } // fi
+
+ entry_point = realpath( argv[ 1 ], NULL );
+ objdump_tool = realpath( argv[ 2 ], NULL );
+
+ std::string entry_point_dir, entry_point_file;
+ Split( entry_point, entry_point_dir, entry_point_file );
+
+ dirs.insert( entry_point_dir );
+ for( int i = 3; i < argc; ++i )
+ if( Exists( argv[ i ] ) )
+ dirs.insert( std::string( realpath( argv[ i ], NULL ) ) );
+
+ std::set< std::string > files;
+ std::queue< std::string > q;
+ q.push( entry_point );
+ while( !q.empty( ) )
+ {
+ std::string e = q.front( );
+ q.pop( );
+ if( files.find( e ) == files.end( ) )
+ {
+ try
+ {
+ if( Exists( e ) )
+ {
+ std::istringstream ss(
+ Exec( objdump_tool + " -x " + e + " | grep DLL\\ Name" )
+ );
+ files.insert( e );
+ std::string line;
+ while( std::getline( ss, line ) )
+ {
+ size_t p = line.find( ":" ) + 2;
+ std::set< std::string >::const_iterator d;
+ for( d = dirs.begin( ); d != dirs.end( ); ++d )
+ q.push( *d + "/" + line.substr( p ) );
+
+ } // elihw
+
+ } // fi
+ }
+ catch( std::exception& err )
+ {
+ // Just ignore
+ } // yrt
+
+ } // fi
+
+ } // elihw
+
+ for( std::string f: files )
+ std::cout << "---> " << f << std::endl;
+
+ return( 0 );
+}
+
+// eof - $RCSfile$