The Gaudi Framework  master (82fdf313)
Loading...
Searching...
No Matches
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
20namespace bf = boost::filesystem;
21using namespace std;
22
23static const char* path_separator = ",:";
24
25namespace 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
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
static std::string find_directory_from_list(const std::string &logical_file_name, const std::string &search_list, SearchType search_type=LocalSearch)
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
static SearchPathStatus check_search_path(const std::string &search_path)
static std::string find_directory(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
static std::string find_file_from_list(const std::string &logical_file_name, const std::string &search_list, SearchType search_type=LocalSearch)
Note: OS specific details for environment resolution.
Definition Environment.h:25
GAUDI_API std::string PathResolverFindXMLFile(const std::string &logical_file_name)
@ PR_regular_file
GAUDI_API std::vector< std::string > getEnv()
get all environment variables
Definition System.cpp:356
GAUDI_API std::string PathResolverFindDataFile(const std::string &logical_file_name)
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
Definition System.cpp:329
STL namespace.