libyui
3.0.10
|
00001 /* 00002 Copyright (c) 2012 Björn Esser 00003 00004 Permission is hereby granted, free of charge, to any person obtaining 00005 a copy of this software and associated documentation files (the 00006 "Software"), to deal in the Software without restriction, including 00007 without limitation the rights to use, copy, modify, merge, publish, 00008 distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be 00013 included in all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 00018 SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00019 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 00020 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 00021 THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00022 */ 00023 00024 00025 /*-/ 00026 00027 File: YPath.cc 00028 00029 Author: Björn Esser <bjoern.esser@gmail.com> 00030 00031 /-*/ 00032 00033 #include <stdio.h> 00034 #include <string.h> 00035 #include <sstream> 00036 #include <sys/types.h> 00037 #include <dirent.h> 00038 #include <vector> 00039 00040 #include "YPath.h" 00041 #include "YSettings.h" 00042 #include "Libyui_config.h" 00043 00044 #define YUILogComponent "ui" 00045 #include "YUILog.h" 00046 00047 YPath::YPath ( const std::string & directory, const std::string & filename ) 00048 { 00049 yuiMilestone () << "Given filename: " << filename << std::endl; 00050 00051 bool isThemeDir = ! directory.compare ( THEMEDIR ); 00052 std::string progSubDir = YSettings::progDir (); 00053 std::string fullname = ""; 00054 std::string themeSubDir = "/current"; 00055 size_t splitPos = fullPath.rfind( "/" ); 00056 bool hasProgSubDir = progSubDir.compare ( "" ); 00057 bool hasSubDirPrepend = ( splitPos != std::string::npos ); 00058 std::string filenameNoPrepend = filename.substr ( splitPos + 1, std::string::npos ); 00059 std::string subDirPrepend = ""; 00060 std::vector<std::string> dirList; 00061 00062 if ( hasSubDirPrepend ) 00063 subDirPrepend = filename.substr ( 0, splitPos ); 00064 00065 yuiMilestone () << "Preferring subdir: " << progSubDir << std::endl; 00066 yuiMilestone () << "Subdir given with filename: " << subDirPrepend << std::endl; 00067 yuiMilestone () << "Looking for: " << filenameNoPrepend << std::endl; 00068 00069 if ( hasSubDirPrepend ) // prefer subdir prepended to filename 00070 { 00071 if ( isThemeDir ) // prefer /current inside THEMEDIR 00072 { 00073 if ( hasProgSubDir ) 00074 dirList.push_back ( directory + "/" + progSubDir + themeSubDir + "/" + subDirPrepend ); 00075 00076 dirList.push_back ( directory + themeSubDir + "/" + subDirPrepend ); 00077 } 00078 if ( hasProgSubDir ) 00079 dirList.push_back ( directory + "/" + progSubDir + "/" + subDirPrepend ); 00080 00081 dirList.push_back ( directory + "/" + subDirPrepend ); 00082 } 00083 00084 if ( isThemeDir ) // prefer /current inside THEMEDIR 00085 { 00086 if ( hasProgSubDir ) 00087 dirList.push_back ( directory + "/" + progSubDir + themeSubDir ); 00088 00089 dirList.push_back ( directory + themeSubDir ); 00090 } 00091 00092 // the "usual" lookup 00093 if ( hasProgSubDir ) 00094 dirList.push_back ( directory + "/" + progSubDir ); 00095 00096 dirList.push_back ( directory ); 00097 00098 for ( std::vector<std::string>::const_iterator x = dirList.begin () ; x != dirList.end () && fullPath.compare ( "" ) == 0 ; ++x ) 00099 { 00100 std::vector<std::string> fileList = lsDir( *x ); 00101 00102 for ( std::vector<std::string>::const_iterator i = fileList.begin () ; i != fileList.end () && fullPath.compare ( "" ) == 0 ; ++i ) 00103 { 00104 if ( *i != "." && *i != ".." ) // filter out parent and curdir 00105 { 00106 fullname = directory + "/" + *i; 00107 if ( *i == filenameNoPrepend ) 00108 fullPath = fullname; 00109 else 00110 { 00111 fullPath = lookRecursive ( fullname, filenameNoPrepend ); 00112 } 00113 } 00114 } 00115 } 00116 00117 if( fullPath.compare ( "" ) != 0 ) 00118 yuiMilestone() << "Found " << filenameNoPrepend << " in " << dir() << std::endl; 00119 else 00120 { 00121 yuiMilestone() << "Could NOT find " << filename << " by looking recursive inside " << directory << std::endl; 00122 fullPath = filename; 00123 } 00124 } 00125 00126 YPath::~YPath() 00127 { 00128 } 00129 00130 std::vector<std::string> YPath::lsDir( const std::string & directory ) 00131 { 00132 std::vector<std::string> fileList; 00133 DIR * dir; 00134 struct dirent * ent; 00135 00136 if ( ( dir = opendir( directory.c_str () ) ) != NULL ) 00137 { 00138 yuiMilestone() << "Looking in " << directory << std::endl; 00139 00140 while ( ( ent = readdir ( dir ) ) != NULL ) 00141 fileList.push_back ( ent -> d_name ); 00142 00143 closedir ( dir ); 00144 } 00145 00146 return fileList; 00147 } 00148 00149 std::string YPath::lookRecursive( const std::string & directory, const std::string & filename ) 00150 { 00151 std::vector<std::string> fileList = lsDir( directory ); 00152 std::string file = ""; 00153 std::string fullname; 00154 00155 for ( std::vector<std::string>::const_iterator i = fileList.begin() ; i != fileList.end() && file.compare ( "" ) == 0 ; ++i ) 00156 { 00157 if ( *i != "." && *i != ".." ) // filter out parent and curdir 00158 { 00159 fullname = directory + "/" + ( *i ); 00160 if ( *i == filename ) 00161 file = fullname; 00162 else 00163 { 00164 file = lookRecursive ( fullname, filename ); 00165 } 00166 } 00167 } 00168 return file; 00169 } 00170 00171 std::string YPath::path() 00172 { 00173 return fullPath; 00174 } 00175 00176 std::string YPath::dir() 00177 { 00178 return fullPath.substr ( 0, fullPath.rfind( "/" ) ); 00179 }