file_util.cpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2014, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 // *****************************************************************************
29 
31 
32 #include <string>
33 
34 #include <boost/regex.hpp>
35 
36 namespace swri_system_util
37 {
38  boost::filesystem::path NaiveUncomplete(
39  boost::filesystem::path const path,
40  boost::filesystem::path const base)
41  {
42  // This implementation was derived from:
43  // https://svn.boost.org/trac/boost/ticket/1976#comment:2
44 
45  // Cache system-dependent dot, double-dot and slash strings
46 
47  #if BOOST_FILESYSTEM_VERSION == 3
48  const boost::filesystem::path _dot = boost::filesystem::path(".").native();
49  const boost::filesystem::path _dot_sep = boost::filesystem::path("./").native();
50  const boost::filesystem::path _dots = boost::filesystem::path("..").native();
51  const boost::filesystem::path _dots_sep = boost::filesystem::path("../").native();
52  const boost::filesystem::path _sep = boost::filesystem::path("/").native();
53  #else
54  const boost::filesystem::path _dot = std::string(1, boost::filesystem::dot<boost::filesystem::path>::value);
55  const boost::filesystem::path _sep = std::string(1, boost::filesystem::slash<boost::filesystem::path>::value);
56  const boost::filesystem::path _dot_sep = _dot.string() + _sep.string();
57  const boost::filesystem::path _dots = std::string(2, boost::filesystem::dot<boost::filesystem::path>::value);
58  const boost::filesystem::path _dots_sep = _dots.string() + _sep.string();
59  #endif // BOOST_FILESYSTE_VERSION == 3
60 
61  if (path == base) return _dot_sep;
62 
63  boost::filesystem::path from_path;
64  boost::filesystem::path from_base;
65  boost::filesystem::path output;
66 
67  boost::filesystem::path::iterator path_it = path.begin();
68  boost::filesystem::path::iterator base_it = base.begin();
69 
70  if ((path_it == path.end()) || (base_it == base.end()))
71  {
72  return "";
73  }
74 
75  while (true)
76  {
77  if (*path_it != *base_it)
78  {
79  for (; base_it != base.end(); ++base_it)
80  {
81  if (*base_it == _dot)
82  continue;
83  else if (*base_it == _sep)
84  continue;
85  output /= _dots_sep;
86  }
87 
88  boost::filesystem::path::iterator path_it_start = path_it;
89  for (; path_it != path.end(); ++path_it)
90  {
91  if (path_it != path_it_start)
92  output /= _sep;
93 
94  if (*path_it == _dot)
95  continue;
96 
97  if (*path_it == _sep)
98  continue;
99 
100  output /= *path_it;
101  }
102  break;
103  }
104 
105  from_path /= boost::filesystem::path(*path_it);
106  from_base /= boost::filesystem::path(*base_it);
107 
108  ++path_it, ++base_it;
109  }
110 
111  return output;
112  }
113 
114  std::vector<std::string> load_all_files(const std::string& path, std::string& directory)
115  {
116  std::vector< std::string > all_matching_files;
117  // Extract the directory from the path
118  std::string direct = path.substr(0, path.find_last_of("/\\"));
119  // Extract the filename from the path
120  std::string filename = path.substr(path.find_last_of("/\\")+1);
121  boost::filesystem::path p(direct);
122  if ( !exists( p ) )
123  {
124  printf("Path %s does not exists\n", p.string().c_str());
125  return all_matching_files;
126  }
127  const boost::regex my_filter(filename.replace(filename.find("*"), std::string("*").length(), ".*\\") );
128 
129  boost::filesystem::directory_iterator end_itr; // Default construction yields past-the-end
130  for( boost::filesystem::directory_iterator i( p ); i != end_itr; ++i )
131  {
132  // Skip if not a file
133  // if( !boost::filesystem::is_regular_file( i->status() ) ) continue;
134 
135  //It it is a directory then search within
136  if ( boost::filesystem::is_directory(i->status()) )
137  {
138  std::string path2 = i->path().string() + std::string("/") + path.substr(path.find_last_of("/\\")+1);
139  std::string directory2;
140  std::vector<std::string> matching_files = load_all_files( path2, directory2 );
141  all_matching_files.insert(all_matching_files.end(), matching_files.begin(), matching_files.end());
142  }
143  else if (boost::filesystem::is_regular_file( i->status())) // Check if a file
144  {
145  boost::smatch what;
146  // Skip if no match
147  #if BOOST_FILESYSTEM_VERSION == 3
148  if( !boost::regex_match( i->path().filename().string(), what, my_filter ) ) continue;
149  #else
150  if( !boost::regex_match( i->leaf(), what, my_filter ) ) continue;
151  #endif // BOOST_FILESYSTE_VERSION == 3
152 
153  // File matches, store it
154  all_matching_files.push_back( i->path().string() );
155  }
156  std::sort(all_matching_files.begin(), all_matching_files.end());
157  }
158  directory = direct;
159  return all_matching_files;
160  }
161 
162  std::vector<std::string> Find(
163  const std::string& path,
164  const std::string& expression,
165  int max_depth)
166  {
167  std::vector<std::string> files;
168 
169  boost::filesystem::path root(path);
170  if(!boost::filesystem::exists(root) || !boost::filesystem::is_directory(root))
171  {
172  return files;
173  }
174 
175  boost::regex filter(expression);
176  boost::filesystem::recursive_directory_iterator it(root);
177  boost::filesystem::recursive_directory_iterator end_it;
178  while (it != end_it)
179  {
180  if (max_depth >= 0 && it.level() >= max_depth)
181  {
182  it.no_push();
183  }
184 
185  boost::smatch what;
186  std::string filename = it->path().filename().string();
187  if (boost::regex_match(filename, what, filter))
188  {
189  files.push_back(it->path().string());
190  }
191 
192  ++it;
193  }
194 
195  return files;
196  }
197 }
std::vector< std::string > Find(const std::string &path, const std::string &expression, int max_depth=-1)
Definition: file_util.cpp:162
boost::filesystem::path NaiveUncomplete(boost::filesystem::path const path, boost::filesystem::path const base)
Definition: file_util.cpp:38
std::vector< std::string > load_all_files(const std::string &path, std::string &directory)
Definition: file_util.cpp:114
ROSCPP_DECL bool exists(const std::string &service_name, bool print_failure_reason)


swri_system_util
Author(s): Marc Alban
autogenerated on Tue Apr 6 2021 02:50:44