Line data Source code
1 :
2 : /* Copyright (c) 2009, Cedric Stalder <cedric.stalder@gmail.com>
3 : * 2009-2015, Stefan Eilemann <eile@equalizergraphics.com>
4 : *
5 : * This library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : #include "file.h"
20 :
21 : #include "debug.h"
22 : #include "os.h"
23 :
24 : #include <boost/algorithm/string/predicate.hpp>
25 : #include <boost/filesystem/path.hpp>
26 : #include <boost/foreach.hpp>
27 : #include <boost/regex.hpp>
28 : #include <boost/tokenizer.hpp>
29 : #include <sys/stat.h>
30 : #ifdef _MSC_VER
31 : # include <windows.h>
32 : #elif __APPLE__
33 : # include <dirent.h>
34 : # include <mach-o/dyld.h>
35 : #else
36 : # include <dirent.h>
37 : # include <limits.h>
38 : # include <unistd.h>
39 : #endif
40 :
41 : namespace lunchbox
42 : {
43 0 : Strings searchDirectory( const std::string& directory,
44 : const std::string& pattern )
45 : {
46 0 : Strings files;
47 0 : const boost::regex regex( pattern );
48 :
49 : #ifdef _MSC_VER
50 : WIN32_FIND_DATA file;
51 : const std::string search = directory.empty() ? "*.*" : directory + "\\*.*";
52 : HANDLE hSearch = FindFirstFile( search.c_str(), &file );
53 :
54 : if( hSearch == INVALID_HANDLE_VALUE )
55 : {
56 : LBVERB << "Error finding the first file to match " << pattern << " in "
57 : << directory << std::endl;
58 : FindClose( hSearch );
59 : return files;
60 : }
61 :
62 : if( boost::regex_match( file.cFileName, regex ))
63 : files.push_back( file.cFileName );
64 : while( FindNextFile( hSearch, &file ))
65 : {
66 : if( boost::regex_match( file.cFileName, regex ))
67 : files.push_back( file.cFileName );
68 : }
69 : FindClose( hSearch );
70 :
71 : #else
72 :
73 0 : DIR* dir = opendir( directory.c_str() );
74 0 : if( !dir )
75 : {
76 0 : LBVERB << "Can't open directory " << directory << std::endl;
77 0 : return files;
78 : }
79 :
80 : struct dirent* entry;
81 :
82 0 : while(( entry = readdir( dir )) != 0 )
83 : {
84 0 : const std::string candidate( entry->d_name );
85 0 : if( boost::regex_match( candidate, regex ))
86 0 : files.push_back( entry->d_name );
87 0 : }
88 :
89 0 : closedir(dir);
90 : #endif
91 0 : return files;
92 : }
93 :
94 0 : std::string getFilename( const std::string& filename )
95 : {
96 0 : size_t lastSeparator = 0;
97 0 : const size_t length = filename.length();
98 :
99 0 : for( size_t i = 0; i < length; ++i )
100 0 : if( filename[ i ] == '/' || filename[i] == '\\' )
101 0 : lastSeparator = i+1;
102 :
103 : return lastSeparator == 0 ? filename :
104 0 : filename.substr( lastSeparator, length );
105 : }
106 :
107 0 : std::string getDirname( const std::string& filename )
108 : {
109 0 : size_t lastSeparator = 0;
110 0 : const size_t length = filename.length();
111 :
112 0 : for( size_t i = 0; i < length; ++i )
113 0 : if( filename[ i ] == '/' || filename[i] == '\\' )
114 0 : lastSeparator = i+1;
115 :
116 0 : return lastSeparator == 0 ? "." : filename.substr( 0, lastSeparator );
117 : }
118 :
119 1 : std::string getExecutablePath()
120 : {
121 : // http://stackoverflow.com/questions/933850
122 : #ifdef _MSC_VER
123 : char result[MAX_PATH];
124 : const std::string execPath( result, GetModuleFileName( NULL, result,
125 : MAX_PATH ));
126 : #elif __APPLE__
127 : char result[PATH_MAX+1];
128 : uint32_t size = sizeof(result);
129 : if( _NSGetExecutablePath( result, &size ) != 0 )
130 : return std::string();
131 : const std::string execPath( result );
132 : #else
133 : char result[PATH_MAX];
134 1 : const ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
135 1 : const std::string execPath( result, count > 0 ? count : 0 );
136 : #endif
137 2 : const boost::filesystem::path path( execPath );
138 2 : return path.parent_path().string();
139 : }
140 :
141 0 : std::string getLibraryPath()
142 : {
143 0 : const std::string& exePath = getExecutablePath();
144 0 : if( exePath.empty( ))
145 0 : return exePath;
146 :
147 : #ifdef _MSC_VER
148 : return exePath;
149 : #elif __APPLE__
150 : const boost::filesystem::path path( exePath );
151 :
152 : // foo.app/Contents/MacOS/foo
153 : if( boost::algorithm::ends_with( exePath, ".app/Contents/MacOS" ))
154 : return path.parent_path().parent_path().parent_path().parent_path().
155 : string() + "/lib";
156 : return path.parent_path().string() + "/lib";
157 : #else
158 0 : const boost::filesystem::path path( exePath );
159 0 : return path.parent_path().string() + "/lib";
160 : #endif
161 : }
162 :
163 : #define STDSTRING( macro ) std::string( STRINGIFY( macro ))
164 : #define STRINGIFY( foo ) #foo
165 :
166 0 : Strings getLibraryPaths()
167 : {
168 0 : Strings paths;
169 0 : const std::string& appPath = getLibraryPath();
170 0 : if( !appPath.empty( ))
171 0 : paths.push_back( appPath );
172 :
173 : #ifdef _MSC_VER
174 : const char* env = ::getenv( "PATH" );
175 : boost::char_separator< char > separator(";");
176 : paths.push_back( STDSTRING( CMAKE_INSTALL_PREFIX ) + "/bin" );
177 : #elif __APPLE__
178 : const char* env = ::getenv( "LD_LIBRARY_PATH" );
179 : boost::char_separator< char > separator(":");
180 : paths.push_back( STDSTRING( CMAKE_INSTALL_PREFIX ) + "/lib" );
181 : #else
182 0 : const char* env = ::getenv( "DYLD_LIBRARY_PATH" );
183 0 : boost::char_separator< char > separator(":");
184 0 : paths.push_back( STDSTRING( CMAKE_INSTALL_PREFIX ) + "/lib" );
185 : #endif
186 :
187 0 : if( !env )
188 0 : return paths;
189 :
190 : const boost::tokenizer< boost::char_separator< char > >
191 0 : tokens( std::string( env ), separator );
192 0 : BOOST_FOREACH( const std::string& token, tokens )
193 0 : paths.push_back( token );
194 :
195 0 : return paths;
196 : }
197 :
198 :
199 81 : }
|