Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules 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 <stdlib.h>
13 #include <string>
14 #include <vector>
15 
16 #include <boost/algorithm/string/classification.hpp>
17 #include <boost/algorithm/string/split.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 
36 
38 
39  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40 
41  static bool PR_find( const bf::path& file, const string& search_list, PR_file_type file_type,
42  PathResolver::SearchType search_type, string& result ) {
43 
44  bool found( false );
45 
46  // look for file as specified first
47 
48  try {
49  if ( ( file_type == PR_regular_file && is_regular_file( file ) ) ||
50  ( file_type == PR_directory && is_directory( file ) ) ) {
51  result = bf::system_complete( file ).string();
52  return true;
53  }
54  } catch ( const bf::filesystem_error& /*err*/ ) {}
55 
56  // assume that "." is always part of the search path, so check locally first
57 
58  try {
59  bf::path local = bf::initial_path() / file;
60  if ( ( file_type == PR_regular_file && is_regular_file( local ) ) ||
61  ( file_type == PR_directory && is_directory( local ) ) ) {
62  result = bf::system_complete( file ).string();
63  return true;
64  }
65  } catch ( const bf::filesystem_error& /*err*/ ) {}
66 
67  // iterate through search list
68  vector<string> spv;
69  split( spv, search_list, boost::is_any_of( path_separator ), boost::token_compress_on );
70  for ( const auto& itr : spv ) {
71 
72  bf::path fp = itr / file;
73 
74  try {
75  if ( ( file_type == PR_regular_file && is_regular_file( fp ) ) ||
76  ( file_type == PR_directory && is_directory( fp ) ) ) {
77  result = bf::system_complete( fp ).string();
78  return true;
79  }
80  } catch ( const bf::filesystem_error& /*err*/ ) {}
81 
82  // if recursive searching requested, drill down
83  if ( search_type == PathResolver::RecursiveSearch && is_directory( bf::path( itr ) ) ) {
84 
85  bf::recursive_directory_iterator end_itr;
86  try {
87  for ( bf::recursive_directory_iterator ritr( itr ); ritr != end_itr; ++ritr ) {
88 
89  // skip if not a directory
90  if ( !is_directory( bf::path( *ritr ) ) ) { continue; }
91 
92  bf::path fp2 = bf::path( *ritr ) / file;
93  if ( ( file_type == PR_regular_file && is_regular_file( fp2 ) ) ||
94  ( file_type == PR_directory && is_directory( fp2 ) ) ) {
95  result = bf::system_complete( fp2 ).string();
96  return true;
97  }
98  }
99  } catch ( const bf::filesystem_error& /*err*/ ) {}
100  }
101  }
102 
103  return found;
104  }
105 
106  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
107 
108  string PathResolver::find_file( const std::string& logical_file_name, const std::string& search_path,
109  SearchType search_type ) {
110 
111  std::string path_list;
112  System::getEnv( search_path, path_list );
113 
114  return ( find_file_from_list( logical_file_name, path_list, search_type ) );
115  }
116 
117  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
118 
119  std::string PathResolver::find_file_from_list( const std::string& logical_file_name, const std::string& search_list,
120  SearchType search_type ) {
121  std::string result( "" );
122 
123  bf::path lfn( logical_file_name );
124 
125  /* bool found = */
126  PR_find( lfn, search_list, PR_regular_file, search_type, result );
127 
128  // The following functionality was in the original PathResolver, but I believe
129  // that it's WRONG. It extracts the filename of the requested item, and searches
130  // for that if the preceding search fails. i.e., if you're looking for "B/a.txt",
131  // and that fails, it will look for just "a.txt" in the search list.
132 
133  // if (! found && lfn.filename() != lfn ) {
134  // result = "";
135  // PR_find (lfn.filename(), search_list, PR_regular_file, search_type, result);
136  // }
137 
138  return ( result );
139  }
140 
141  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
142 
143  string PathResolver::find_directory( const std::string& logical_file_name, const std::string& search_path,
144  SearchType search_type ) {
145  std::string path_list;
146  System::getEnv( search_path, path_list );
147 
148  return ( find_directory_from_list( logical_file_name, path_list, search_type ) );
149  }
150 
151  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
152 
153  string PathResolver::find_directory_from_list( const std::string& logical_file_name, const std::string& search_list,
154  SearchType search_type ) {
155  std::string result;
156 
157  if ( !PR_find( logical_file_name, search_list, PR_directory, search_type, result ) ) { result = ""; }
158 
159  return ( result );
160  }
161 
162  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
163 
164  PathResolver::SearchPathStatus PathResolver::check_search_path( const std::string& search_path ) {
165  std::string path_list;
166  if ( !System::getEnv( search_path, path_list ) ) return ( EnvironmentVariableUndefined );
167 
168  vector<string> spv;
169  boost::split( spv, path_list, boost::is_any_of( path_separator ), boost::token_compress_on );
170 
171  try {
172  for ( const auto& itr : spv ) {
173  bf::path pp( itr );
174  if ( !is_directory( pp ) ) { return ( UnknownDirectory ); }
175  }
176  } catch ( const bf::filesystem_error& /*err*/ ) { return ( UnknownDirectory ); }
177 
178  return ( Ok );
179  }
180 
181  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
182 
183  std::string PathResolverFindXMLFile( const std::string& logical_file_name ) {
184  return PathResolver::find_file( logical_file_name, "XMLPATH" );
185  }
186 
187  std::string PathResolverFindDataFile( const std::string& logical_file_name ) {
188  return PathResolver::find_file( logical_file_name, "DATAPATH" );
189  }
190 
191 } // namespace System
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
Definition: System.cpp:380
Note: OS specific details for environment resolution.
Definition: Debugger.h:19
GAUDI_API std::string PathResolverFindXMLFile(const std::string &logical_file_name)
STL namespace.
GAUDI_API std::string PathResolverFindDataFile(const std::string &logical_file_name)
T string(T...args)
STL class.