libyui  3.10.0
YPath.cc
1 /*
2  Copyright (c) 2012 Björn Esser
3 
4  Permission is hereby granted, free of charge, to any person obtaining
5  a copy of this software and associated documentation files (the
6  "Software"), to deal in the Software without restriction, including
7  without limitation the rights to use, copy, modify, merge, publish,
8  distribute, sublicense, and/or sell
9  copies of the Software, and to permit persons to whom the Software is
10  furnished to do so, subject to the following conditions:
11 
12  The above copyright notice and this permission notice shall be
13  included in all copies or substantial portions of the Software.
14 
15  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18  SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 
24 
25 /*-/
26 
27  File: YPath.cc
28 
29  Author: Björn Esser <bjoern.esser@gmail.com>
30 
31 /-*/
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <sstream>
36 #include <sys/types.h>
37 #include <dirent.h>
38 #include <vector>
39 
40 #include "YPath.h"
41 #include "YSettings.h"
42 #include "Libyui_config.h"
43 
44 #define YUILogComponent "ui"
45 #include "YUILog.h"
46 
47 using std::string;
48 using std::vector;
49 
50 
51 YPath::YPath ( const string & directory, const string & filename )
52 {
53  yuiDebug() << "Given filename: " << filename << endl;
54 
55  bool isThemeDir = ! directory.compare ( THEMEDIR );
56  string progSubDir = YSettings::progDir ();
57  string fullname = "";
58  string themeSubDir = "/current";
59  size_t splitPos = fullPath.rfind( "/" );
60  bool hasProgSubDir = progSubDir.compare ( "" );
61  bool hasSubDirPrepend = ( splitPos != string::npos );
62  string filenameNoPrepend = filename.substr ( splitPos + 1, string::npos );
63  string subDirPrepend = "";
64  vector<string> dirList;
65 
66  if ( hasSubDirPrepend )
67  subDirPrepend = filename.substr ( 0, splitPos );
68 
69  yuiDebug() << "Preferring subdir: " << progSubDir << endl;
70  yuiDebug() << "Subdir given with filename: " << subDirPrepend << endl;
71  yuiDebug() << "Looking for: " << filenameNoPrepend << endl;
72 
73  if ( hasSubDirPrepend ) // prefer subdir prepended to filename
74  {
75  if ( isThemeDir ) // prefer /current inside THEMEDIR
76  {
77  if ( hasProgSubDir )
78  dirList.push_back( directory + "/" + progSubDir + themeSubDir + "/" + subDirPrepend );
79 
80  dirList.push_back( directory + themeSubDir + "/" + subDirPrepend );
81  }
82  if ( hasProgSubDir )
83  dirList.push_back( directory + "/" + progSubDir + "/" + subDirPrepend );
84 
85  dirList.push_back( directory + "/" + subDirPrepend );
86  }
87 
88  if ( isThemeDir ) // prefer /current inside THEMEDIR
89  {
90  if ( hasProgSubDir )
91  dirList.push_back( directory + "/" + progSubDir + themeSubDir );
92 
93  dirList.push_back( directory + themeSubDir );
94  }
95 
96  // the "usual" lookup
97  if ( hasProgSubDir )
98  dirList.push_back( directory + "/" + progSubDir );
99 
100  dirList.push_back ( directory );
101 
102  for ( vector<string>::const_iterator x = dirList.begin ();
103  x != dirList.end () && fullPath.compare ( "" ) == 0 ;
104  ++x )
105  {
106  vector<string> fileList = lsDir( *x );
107 
108  for ( vector<string>::const_iterator i = fileList.begin ();
109  i != fileList.end () && fullPath.compare ( "" ) == 0 ;
110  ++i )
111  {
112  if ( *i != "." && *i != ".." ) // filter out parent and curdir
113  {
114  fullname = directory + "/" + *i;
115  if ( *i == filenameNoPrepend )
116  fullPath = fullname;
117  else
118  {
119  fullPath = lookRecursive ( fullname, filenameNoPrepend );
120  }
121  }
122  }
123  }
124 
125  if( fullPath.compare( "" ) != 0 )
126  yuiDebug() << "Found " << filenameNoPrepend << " in " << dir() << endl;
127  else
128  {
129  yuiDebug() << "Could NOT find " << filename << " by looking recursive inside " << directory << endl;
130  fullPath = filename;
131  }
132 }
133 
134 
136 {
137 }
138 
139 
140 vector<string> YPath::lsDir( const string & directory )
141 {
142  vector<string> fileList;
143  DIR * dir;
144  struct dirent * ent;
145 
146  if ( ( dir = opendir( directory.c_str () ) ) != NULL )
147  {
148  yuiDebug() << "Looking in " << directory << endl;
149 
150  while ( ( ent = readdir( dir ) ) != NULL )
151  fileList.push_back( ent -> d_name );
152 
153  closedir ( dir );
154  }
155 
156  return fileList;
157 }
158 
159 
160 string YPath::lookRecursive( const string & directory, const string & filename )
161 {
162  vector<string> fileList = lsDir( directory );
163  string file = "";
164  string fullname;
165 
166  for ( vector<string>::const_iterator i = fileList.begin();
167  i != fileList.end() && file.compare ( "" ) == 0;
168  ++i )
169  {
170  if ( *i != "." && *i != ".." ) // filter out parent and curdir
171  {
172  fullname = directory + "/" + ( *i );
173 
174  if ( *i == filename )
175  file = fullname;
176  else
177  {
178  file = lookRecursive ( fullname, filename );
179  }
180  }
181  }
182 
183  return file;
184 }
185 
186 
187 string YPath::path()
188 {
189  return fullPath;
190 }
191 
192 
193 string YPath::dir()
194 {
195  return fullPath.substr ( 0, fullPath.rfind( "/" ) );
196 }
YPath::path
std::string path()
Returns the full path of the file if found; if not found just the filename given in constructor.
Definition: YPath.cc:187
YPath::~YPath
~YPath()
Destructor.
Definition: YPath.cc:135
YSettings::progDir
static std::string progDir()
Returns the value of your program's subdir.
Definition: YSettings.cc:74
YPath::dir
std::string dir()
Returns the directory where the file is found; if not found just the subdir part (if there's any) of ...
Definition: YPath.cc:193
YPath::YPath
YPath(const std::string &directory, const std::string &filename)
Constructor.
Definition: YPath.cc:51