The Gaudi Framework  v40r0 (475e45c1)
PathResolver.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
12 #include <GaudiKernel/System.h>
13 #include <boost/algorithm/string/classification.hpp>
14 #include <boost/algorithm/string/split.hpp>
15 #include <boost/filesystem.hpp>
16 #include <stdlib.h>
17 #include <string>
18 #include <vector>
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 namespace System {
30 
32 
34 
35  static bool PR_find( const bf::path& file, const string& search_list, PR_file_type file_type,
36  PathResolver::SearchType search_type, string& result ) {
37 
38  bool found( false );
39 
40  // look for file as specified first
41 
42  try {
43  if ( ( file_type == PR_regular_file && is_regular_file( file ) ) ||
44  ( file_type == PR_directory && is_directory( file ) ) ) {
45  result = bf::system_complete( file ).string();
46  return true;
47  }
48  } catch ( const bf::filesystem_error& /*err*/ ) {}
49 
50  // assume that "." is always part of the search path, so check locally first
51 
52  try {
53  bf::path local = bf::initial_path() / file;
54  if ( ( file_type == PR_regular_file && is_regular_file( local ) ) ||
55  ( file_type == PR_directory && is_directory( local ) ) ) {
56  result = bf::system_complete( file ).string();
57  return true;
58  }
59  } catch ( const bf::filesystem_error& /*err*/ ) {}
60 
61  // iterate through search list
62  vector<string> spv;
63  split( spv, search_list, boost::is_any_of( path_separator ), boost::token_compress_on );
64  for ( const auto& itr : spv ) {
65 
66  bf::path fp = itr / file;
67 
68  try {
69  if ( ( file_type == PR_regular_file && is_regular_file( fp ) ) ||
70  ( file_type == PR_directory && is_directory( fp ) ) ) {
71  result = bf::system_complete( fp ).string();
72  return true;
73  }
74  } catch ( const bf::filesystem_error& /*err*/ ) {}
75 
76  // if recursive searching requested, drill down
77  if ( search_type == PathResolver::RecursiveSearch && is_directory( bf::path( itr ) ) ) {
78 
79  bf::recursive_directory_iterator end_itr;
80  try {
81  for ( bf::recursive_directory_iterator ritr( itr ); ritr != end_itr; ++ritr ) {
82 
83  // skip if not a directory
84  if ( !is_directory( bf::path( *ritr ) ) ) { continue; }
85 
86  bf::path fp2 = bf::path( *ritr ) / file;
87  if ( ( file_type == PR_regular_file && is_regular_file( fp2 ) ) ||
88  ( file_type == PR_directory && is_directory( fp2 ) ) ) {
89  result = bf::system_complete( fp2 ).string();
90  return true;
91  }
92  }
93  } catch ( const bf::filesystem_error& /*err*/ ) {}
94  }
95  }
96 
97  return found;
98  }
99 
100  string PathResolver::find_file( const std::string& logical_file_name, const std::string& search_path,
101  SearchType search_type ) {
102 
103  std::string path_list;
104  System::getEnv( search_path, path_list );
105 
106  return ( find_file_from_list( logical_file_name, path_list, search_type ) );
107  }
108 
109  std::string PathResolver::find_file_from_list( const std::string& logical_file_name, const std::string& search_list,
110  SearchType search_type ) {
111  std::string result( "" );
112 
113  bf::path lfn( logical_file_name );
114 
115  /* bool found = */
116  PR_find( lfn, search_list, PR_regular_file, search_type, result );
117 
118  // The following functionality was in the original PathResolver, but I believe
119  // that it's WRONG. It extracts the filename of the requested item, and searches
120  // for that if the preceding search fails. i.e., if you're looking for "B/a.txt",
121  // and that fails, it will look for just "a.txt" in the search list.
122 
123  // if (! found && lfn.filename() != lfn ) {
124  // result = "";
125  // PR_find (lfn.filename(), search_list, PR_regular_file, search_type, result);
126  // }
127 
128  return ( result );
129  }
130 
131  string PathResolver::find_directory( const std::string& logical_file_name, const std::string& search_path,
132  SearchType search_type ) {
133  std::string path_list;
134  System::getEnv( search_path, path_list );
135 
136  return ( find_directory_from_list( logical_file_name, path_list, search_type ) );
137  }
138 
139  string PathResolver::find_directory_from_list( const std::string& logical_file_name, const std::string& search_list,
140  SearchType search_type ) {
141  std::string result;
142 
143  if ( !PR_find( logical_file_name, search_list, PR_directory, search_type, result ) ) { result = ""; }
144 
145  return ( result );
146  }
147 
148  PathResolver::SearchPathStatus PathResolver::check_search_path( const std::string& search_path ) {
149  std::string path_list;
150  if ( !System::getEnv( search_path, path_list ) ) return ( EnvironmentVariableUndefined );
151 
152  vector<string> spv;
153  boost::split( spv, path_list, boost::is_any_of( path_separator ), boost::token_compress_on );
154 
155  try {
156  for ( const auto& itr : spv ) {
157  bf::path pp( itr );
158  if ( !is_directory( pp ) ) { return ( UnknownDirectory ); }
159  }
160  } catch ( const bf::filesystem_error& /*err*/ ) { return ( UnknownDirectory ); }
161 
162  return ( Ok );
163  }
164 
165  std::string PathResolverFindXMLFile( const std::string& logical_file_name ) {
166  return PathResolver::find_file( logical_file_name, "XMLPATH" );
167  }
168 
169  std::string PathResolverFindDataFile( const std::string& logical_file_name ) {
170  return PathResolver::find_file( logical_file_name, "DATAPATH" );
171  }
172 } // namespace System
System::PR_recursive
@ PR_recursive
Definition: PathResolver.cpp:33
System::PathResolverFindXMLFile
GAUDI_API std::string PathResolverFindXMLFile(const std::string &logical_file_name)
Definition: PathResolver.cpp:165
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
GaudiPartProp.decorators.std
std
Definition: decorators.py:32
System.h
System::getEnv
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
Definition: System.cpp:376
System::PR_regular_file
@ PR_regular_file
Definition: PathResolver.cpp:31
System::PathResolverFindDataFile
GAUDI_API std::string PathResolverFindDataFile(const std::string &logical_file_name)
Definition: PathResolver.cpp:169
System::PR_file_type
PR_file_type
Definition: PathResolver.cpp:31
System::PR_local
@ PR_local
Definition: PathResolver.cpp:33
System::PR_directory
@ PR_directory
Definition: PathResolver.cpp:31
System::PR_search_type
PR_search_type
Definition: PathResolver.cpp:33
System
Note: OS specific details for environment resolution.
Definition: Debugger.h:15
PathResolver.h
compareOutputFiles.pp
pp
Definition: compareOutputFiles.py:507
System::PathResolver::SearchType
SearchType
Definition: PathResolver.h:24
System::PathResolver::SearchPathStatus
SearchPathStatus
Definition: PathResolver.h:22