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