The Gaudi Framework  master (37c0b60a)
PathResolver.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 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 
14 #ifdef WIN32
15 // Disable warning
16 // C4996: 'std::copy': Function call with parameters that may be unsafe
17 // Probably coming from Boost classification.
18 # pragma warning( disable : 4996 )
19 #endif
20 
21 #include <iostream>
22 #include <stdlib.h>
23 #include <string>
24 #include <vector>
25 
26 #include <boost/algorithm/string/classification.hpp>
27 #include <boost/algorithm/string/split.hpp>
28 #include <boost/filesystem.hpp>
29 
30 namespace bf = boost::filesystem;
31 using namespace std;
32 
33 #ifdef _WIN32
34 static const char* path_separator = ",;";
35 #else
36 static const char* path_separator = ",:";
37 #endif
38 
39 //
41 //
42 
43 namespace System {
44 
46 
48 
49  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
50 
51  static bool PR_find( const bf::path& file, const string& search_list, PR_file_type file_type,
52  PathResolver::SearchType search_type, string& result ) {
53 
54  bool found( false );
55 
56  // look for file as specified first
57 
58  try {
59  if ( ( file_type == PR_regular_file && is_regular_file( file ) ) ||
60  ( file_type == PR_directory && is_directory( file ) ) ) {
61  result = bf::system_complete( file ).string();
62  return true;
63  }
64  } catch ( const bf::filesystem_error& /*err*/ ) {}
65 
66  // assume that "." is always part of the search path, so check locally first
67 
68  try {
69  bf::path local = bf::initial_path() / file;
70  if ( ( file_type == PR_regular_file && is_regular_file( local ) ) ||
71  ( file_type == PR_directory && is_directory( local ) ) ) {
72  result = bf::system_complete( file ).string();
73  return true;
74  }
75  } catch ( const bf::filesystem_error& /*err*/ ) {}
76 
77  // iterate through search list
78  vector<string> spv;
79  split( spv, search_list, boost::is_any_of( path_separator ), boost::token_compress_on );
80  for ( const auto& itr : spv ) {
81 
82  bf::path fp = itr / file;
83 
84  try {
85  if ( ( file_type == PR_regular_file && is_regular_file( fp ) ) ||
86  ( file_type == PR_directory && is_directory( fp ) ) ) {
87  result = bf::system_complete( fp ).string();
88  return true;
89  }
90  } catch ( const bf::filesystem_error& /*err*/ ) {}
91 
92  // if recursive searching requested, drill down
93  if ( search_type == PathResolver::RecursiveSearch && is_directory( bf::path( itr ) ) ) {
94 
95  bf::recursive_directory_iterator end_itr;
96  try {
97  for ( bf::recursive_directory_iterator ritr( itr ); ritr != end_itr; ++ritr ) {
98 
99  // skip if not a directory
100  if ( !is_directory( bf::path( *ritr ) ) ) { continue; }
101 
102  bf::path fp2 = bf::path( *ritr ) / file;
103  if ( ( file_type == PR_regular_file && is_regular_file( fp2 ) ) ||
104  ( file_type == PR_directory && is_directory( fp2 ) ) ) {
105  result = bf::system_complete( fp2 ).string();
106  return true;
107  }
108  }
109  } catch ( const bf::filesystem_error& /*err*/ ) {}
110  }
111  }
112 
113  return found;
114  }
115 
116  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
117 
118  string PathResolver::find_file( const std::string& logical_file_name, const std::string& search_path,
119  SearchType search_type ) {
120 
121  std::string path_list;
122  System::getEnv( search_path, path_list );
123 
124  return ( find_file_from_list( logical_file_name, path_list, search_type ) );
125  }
126 
127  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
128 
129  std::string PathResolver::find_file_from_list( const std::string& logical_file_name, const std::string& search_list,
130  SearchType search_type ) {
131  std::string result( "" );
132 
133  bf::path lfn( logical_file_name );
134 
135  /* bool found = */
136  PR_find( lfn, search_list, PR_regular_file, search_type, result );
137 
138  // The following functionality was in the original PathResolver, but I believe
139  // that it's WRONG. It extracts the filename of the requested item, and searches
140  // for that if the preceding search fails. i.e., if you're looking for "B/a.txt",
141  // and that fails, it will look for just "a.txt" in the search list.
142 
143  // if (! found && lfn.filename() != lfn ) {
144  // result = "";
145  // PR_find (lfn.filename(), search_list, PR_regular_file, search_type, result);
146  // }
147 
148  return ( result );
149  }
150 
151  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
152 
153  string PathResolver::find_directory( const std::string& logical_file_name, const std::string& search_path,
154  SearchType search_type ) {
155  std::string path_list;
156  System::getEnv( search_path, path_list );
157 
158  return ( find_directory_from_list( logical_file_name, path_list, search_type ) );
159  }
160 
161  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
162 
163  string PathResolver::find_directory_from_list( const std::string& logical_file_name, const std::string& search_list,
164  SearchType search_type ) {
165  std::string result;
166 
167  if ( !PR_find( logical_file_name, search_list, PR_directory, search_type, result ) ) { result = ""; }
168 
169  return ( result );
170  }
171 
172  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
173 
174  PathResolver::SearchPathStatus PathResolver::check_search_path( const std::string& search_path ) {
175  std::string path_list;
176  if ( !System::getEnv( search_path, path_list ) ) return ( EnvironmentVariableUndefined );
177 
178  vector<string> spv;
179  boost::split( spv, path_list, boost::is_any_of( path_separator ), boost::token_compress_on );
180 
181  try {
182  for ( const auto& itr : spv ) {
183  bf::path pp( itr );
184  if ( !is_directory( pp ) ) { return ( UnknownDirectory ); }
185  }
186  } catch ( const bf::filesystem_error& /*err*/ ) { return ( UnknownDirectory ); }
187 
188  return ( Ok );
189  }
190 
191  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
192 
193  std::string PathResolverFindXMLFile( const std::string& logical_file_name ) {
194  return PathResolver::find_file( logical_file_name, "XMLPATH" );
195  }
196 
197  std::string PathResolverFindDataFile( const std::string& logical_file_name ) {
198  return PathResolver::find_file( logical_file_name, "DATAPATH" );
199  }
200 
201 } // namespace System
System::PR_recursive
@ PR_recursive
Definition: PathResolver.cpp:47
std::string::string
T string(T... args)
System::PathResolverFindXMLFile
GAUDI_API std::string PathResolverFindXMLFile(const std::string &logical_file_name)
Definition: PathResolver.cpp:193
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
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:390
std::vector
STL class.
System::PR_regular_file
@ PR_regular_file
Definition: PathResolver.cpp:45
System::PathResolverFindDataFile
GAUDI_API std::string PathResolverFindDataFile(const std::string &logical_file_name)
Definition: PathResolver.cpp:197
System::PR_file_type
PR_file_type
Definition: PathResolver.cpp:45
System::PR_local
@ PR_local
Definition: PathResolver.cpp:47
System::PR_directory
@ PR_directory
Definition: PathResolver.cpp:45
std
STL namespace.
System::PR_search_type
PR_search_type
Definition: PathResolver.cpp:47
System
Note: OS specific details for environment resolution.
Definition: Debugger.h:29
PathResolver.h
compareOutputFiles.pp
pp
Definition: compareOutputFiles.py:507
System::PathResolver::SearchType
SearchType
Definition: PathResolver.h:25
System::PathResolver::SearchPathStatus
SearchPathStatus
Definition: PathResolver.h:23