OpenASIP  2.0
FileSystem.icc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file FileSystem.icc
26  *
27  * Inline definitions of FileSystem class.
28  *
29  * @author Pekka Jääskeläinen 2004 (pekka.jaaskelainen-no.spam-tut.fi)
30  * @author Esa Määttä 2007 (esa.maatta-no.spam-tut.fi)
31  */
32 
33 #include <boost/filesystem/operations.hpp>
34 #include <boost/filesystem/convenience.hpp>
35 #include <boost/filesystem/exception.hpp>
36 #include <boost/version.hpp>
37 
38 #include "CompilerWarnings.hh"
39 IGNORE_CLANG_WARNING("-Wkeyword-macro")
40 #include <boost/regex.hpp>
41 POP_CLANG_DIAGS
42 
43 #include "Environment.hh"
44 
45 // following includes are needed for fileIsDirectory's stat()
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 
50 /**
51  * Tests if a file or directory exists.
52  *
53  * @param fileName The file or directory to test.
54  * @return True if file or directory exists.
55  *
56  */
57 inline bool
58 FileSystem::fileExists(const std::string fileName) {
59  return (access(fileName.c_str(), F_OK) == 0);
60 }
61 
62 /**
63  * Tests if a file or directory is writable by user.
64  *
65  * @param fileName The file or directory to test.
66  * @return True if file or directory is writable.
67  *
68  */
69 inline bool
70 FileSystem::fileIsWritable(const std::string fileName) {
71  return (access(fileName.c_str(), W_OK) == 0);
72 }
73 
74 /**
75  * Tests if a file or directory is readable by user.
76  *
77  * @param fileName The file or directory to test.
78  * @return True if file or directory is readable.
79  *
80  */
81 inline bool
82 FileSystem::fileIsReadable(const std::string fileName) {
83  return (access(fileName.c_str(), R_OK) == 0);
84 }
85 
86 /**
87  * Tests if a file or directory is executable by user.
88  *
89  * @param fileName The file or directory to test.
90  * @return True if file or directory is executable.
91  *
92  */
93 inline bool
94 FileSystem::fileIsExecutable(const std::string fileName) {
95  return (access(fileName.c_str(), X_OK) == 0);
96 }
97 
98 /**
99  * Tests if the given file is a directory.
100  *
101  * @param fileName The file to test.
102  * @return True if the file is a directory.
103  *
104  */
105 inline bool
106 FileSystem::fileIsDirectory(const std::string fileName) {
107  struct stat buf;
108  if (stat(fileName.c_str(), &buf) != 0) {
109  return false;
110  }
111  return S_ISDIR(buf.st_mode);
112 }
113 
114 /**
115  * Executes a shell command.
116  *
117  * @param command Command to be executed.
118  * @return True if the command was executed successfully, otherwise false.
119  */
120 inline bool
121 FileSystem::runShellCommand(const std::string command) {
122  int returnValue = system(command.c_str());
123  if (returnValue == 0) {
124  return true;
125  } else {
126  return false;
127  }
128 }
129 
130 /**
131  * Returns the home directory of the current user.
132  *
133  * @return The home directory of the current user.
134  */
135 inline std::string
136 FileSystem::homeDirectory() {
137  std::string home = Environment::environmentVariable("HOME");
138  Path homePath(home);
139  return homePath.string();
140 }
141 
142 /**
143  * Finds regex matching files and directories from a directory.
144  *
145  * Finds files and directories that match given regular expression (perl
146  * format and case is ignored). Subdirectories are not recursively checked.
147  * Found file and directory names are appended to the given STL type
148  * container. push_back() and empty() functions are expected to exists as
149  * member functions for the STL type class.
150  * True boolean value is returned if something was found, otherwise false is
151  * returned.
152  *
153  * @param regex Perl style regular expression.
154  * @param directory Directory where to search.
155  * @param found Container where search results will be stored.
156  *
157  * @return True if something was found, otherwise false.
158  *
159  * @exception FileNotFound If the given directory does not exist.
160  */
161 template <typename STLCONT>
162 bool
163 FileSystem::findFromDirectory(
164  const std::string& regex, const std::string& directory, STLCONT& found) {
165  size_t originalSize = found.size();
166 
167  const boost::regex re(regex, boost::regex::perl|boost::regex::icase);
168 
169  std::vector<std::string> dirCont;
170  try {
171  dirCont = directoryContents(directory);
172  } catch (const FileNotFound& e) {
173  FileNotFound error(
174  __FILE__, __LINE__, __func__,
175  e.errorMessage());
176 
177  error.setCause(e);
178  throw error;
179  }
180 
181  std::vector<std::string>::iterator it = dirCont.begin();
182  while (it != dirCont.end()) {
183  if (regex_match(*it, re)) {
184  found.push_back(*it);
185  }
186  ++it;
187  }
188 
189  return found.size() > originalSize;
190 }
191 
192 /**
193  * Finds regex matching files and directories from a directory recursively.
194  *
195  * Finds files and directories that match given regular expression (perl
196  * format and case is ignored). Found file and directory names are appended
197  * to the given STL type container as strings. push_back() and empty()
198  * functions are expected to exists as member functions for the STL type
199  * class. True boolean value is returned if something was found, otherwise
200  * false is returned.
201  *
202  * @param regex Perl style regular expression.
203  * @param directory Directory where to search.
204  * @param found Container where search results will be stored.
205  *
206  * @return True if something was found, otherwise false.
207  */
208 template <typename STLCONT>
209 bool
210 FileSystem::findFromDirectoryRecursive(
211  const std::string& regex,
212  const std::string& directory,
213  STLCONT& found) {
214 
215  using namespace boost::filesystem;
216 
217  const boost::regex re(regex, boost::regex::perl|boost::regex::icase);
218 
219 #if BOOST_VERSION < 103302
220  const boost::regex reb("^\\..*|.*/\\..*",
221  boost::regex::perl|boost::regex::icase);
222  if (regex_match(directory, reb)) {
223  return false;
224  }
225 #endif
226 
227  if (!exists(Path(directory))) {
228  return false;
229  }
230 
231  directory_iterator dirIt(directory);
232  directory_iterator endIt;
233  while (dirIt != endIt) {
234 #if BOOST_VERSION < 103302
235  if (regex_match((*dirIt).string(), reb)) {
236  ++dirIt;
237  continue;
238  }
239 #endif
240  if (regex_match((*dirIt).path().string(), re)) {
241  found.push_back((*dirIt).path().string());
242  }
243  if (is_directory(*dirIt)) {
244  std::string dir = (*dirIt).path().string();
245  findFromDirectoryRecursive(regex, dir, found);
246  }
247  ++dirIt;
248  }
249 
250  return found.empty() ? false : true;
251 }
252