All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PathResolver.cpp
Go to the documentation of this file.
2 #include "GaudiKernel/System.h"
3 
4 #ifdef WIN32
5 // Disable warning
6 // C4996: 'std::copy': Function call with parameters that may be unsafe
7 // Probably coming from Boost classification.
8 #pragma warning(disable:4996)
9 #endif
10 
11 #include <iostream>
12 #include <string>
13 #include <vector>
14 #include <stdlib.h>
15 
16 #include <boost/algorithm/string/split.hpp>
17 #include <boost/algorithm/string/classification.hpp>
18 #include <boost/filesystem.hpp>
19 
20 namespace bf = boost::filesystem;
21 using namespace std;
22 
23 #ifdef _WIN32
24  static const char* path_separator = ",;";
25 #else
26  static const char* path_separator = ",:";
27 #endif
28 
29 //
31 //
32 
33 namespace System {
34 
35 typedef enum {
38 } PR_file_type;
39 
40 typedef enum {
44 
45 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
46 
47 static bool
48 PR_find( const bf::path& file, const string& search_list,
49  PR_file_type file_type, PathResolver::SearchType search_type,
50  string& result ) {
51 
52  bool found(false);
53 
54  // look for file as specified first
55 
56  try {
57  if ( ( file_type == PR_regular_file && is_regular_file( file ) ) ||
58  ( file_type == PR_directory && is_directory( file ) ) ) {
59  result = bf::system_complete(file).string();
60  return true;
61  }
62  } catch (bf::filesystem_error /*err*/) {
63  }
64 
65  // assume that "." is always part of the search path, so check locally first
66 
67  try {
68  bf::path local = bf::initial_path() / file;
69  if ( ( file_type == PR_regular_file && is_regular_file( local ) ) ||
70  ( file_type == PR_directory && is_directory( local ) ) ) {
71  result = bf::system_complete(file).string();
72  return true;
73  }
74  } catch (bf::filesystem_error /*err*/) {
75  }
76 
77 
78  // iterate through search list
79  vector<string> spv;
80  split(spv, search_list, boost::is_any_of( path_separator), boost::token_compress_on);
81  for (vector<string>::const_iterator itr = spv.begin();
82  itr != spv.end(); ++itr ) {
83 
84  bf::path fp = *itr / file;
85 
86  try {
87  if ( ( file_type == PR_regular_file && is_regular_file( fp ) ) ||
88  ( file_type == PR_directory && is_directory( fp ) ) ) {
89  result = bf::system_complete(fp).string();
90  return true;
91  }
92  } catch (bf::filesystem_error /*err*/) {
93  }
94 
95 
96  // if recursive searching requested, drill down
97  if (search_type == PathResolver::RecursiveSearch &&
98  is_directory( bf::path(*itr) ) ) {
99 
100  bf::recursive_directory_iterator end_itr;
101  try {
102  for ( bf::recursive_directory_iterator ritr( *itr );
103  ritr != end_itr; ++ritr) {
104 
105  // skip if not a directory
106  if (! is_directory( bf::path(*ritr) ) ) { continue; }
107 
108  bf::path fp2 = bf::path(*ritr) / file;
109  if ( ( file_type == PR_regular_file && is_regular_file( fp2 ) ) ||
110  ( file_type == PR_directory && is_directory( fp2 ) ) ) {
111  result = bf::system_complete( fp2 ).string();
112  return true;
113  }
114  }
115  } catch (bf::filesystem_error /*err*/) {
116  }
117  }
118 
119  }
120 
121  return found;
122 }
123 
124 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
125 
126 string
127 PathResolver::find_file(const std::string& logical_file_name,
128  const std::string& search_path,
129  SearchType search_type) {
130 
131  std::string path_list;
132  System::getEnv(search_path, path_list);
133 
134  return (find_file_from_list (logical_file_name, path_list, search_type));
135 }
136 
137 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
138 
139 std::string
140 PathResolver::find_file_from_list (const std::string& logical_file_name,
141  const std::string& search_list,
142  SearchType search_type)
143 {
144  std::string result("");
145 
146  bf::path lfn( logical_file_name );
147 
148  /* bool found = */
149  PR_find (lfn, search_list, PR_regular_file, search_type, result);
150 
151  // The following functionality was in the original PathResolver, but I believe
152  // that it's WRONG. It extracts the filename of the requested item, and searches
153  // for that if the preceding search fails. i.e., if you're looking for "B/a.txt",
154  // and that fails, it will look for just "a.txt" in the search list.
155 
156  // if (! found && lfn.filename() != lfn ) {
157  // result = "";
158  // PR_find (lfn.filename(), search_list, PR_regular_file, search_type, result);
159  // }
160 
161  return (result);
162 }
163 
164 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
165 
166 string PathResolver::find_directory (const std::string& logical_file_name,
167  const std::string& search_path,
168  SearchType search_type)
169 {
170  std::string path_list;
171  System::getEnv(search_path, path_list);
172 
173  return (find_directory_from_list (logical_file_name, path_list, search_type));
174 }
175 
176 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
177 
178 string
179 PathResolver::find_directory_from_list (const std::string& logical_file_name,
180  const std::string& search_list,
181  SearchType search_type)
182 {
183  std::string result;
184 
185  if (!PR_find (logical_file_name, search_list, PR_directory, search_type, result))
186  {
187  result = "";
188  }
189 
190  return (result);
191 }
192 
193 
194 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
195 
197 PathResolver::check_search_path (const std::string& search_path)
198 {
199  std::string path_list;
200  if ( ! System::getEnv(search_path, path_list) )
201  return (EnvironmentVariableUndefined);
202 
203  vector<string> spv;
204  boost::split( spv, path_list, boost::is_any_of( path_separator ), boost::token_compress_on);
205  vector<string>::iterator itr=spv.begin();
206 
207  try {
208  for (; itr!= spv.end(); ++itr) {
209  bf::path pp(*itr);
210  if (!is_directory(pp)) {
211  return (UnknownDirectory);
212  }
213  }
214  } catch(bf::filesystem_error /*err*/) {
215  return (UnknownDirectory);
216  }
217 
218  return ( Ok );
219 }
220 
221 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
222 
223 std::string PathResolverFindXMLFile (const std::string& logical_file_name)
224 {
225  return PathResolver::find_file (logical_file_name, "XMLPATH");
226 }
227 
228 std::string PathResolverFindDataFile (const std::string& logical_file_name)
229 {
230  return PathResolver::find_file (logical_file_name, "DATAPATH");
231 }
232 
233 } // System namespace
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
Definition: System.cpp:608
GAUDI_API std::string PathResolverFindXMLFile(const std::string &logical_file_name)
GAUDI_API std::string PathResolverFindDataFile(const std::string &logical_file_name)
list file
Definition: ana.py:160
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram