Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 26 27 #include <mutex> 27 #include <mutex> 28 28 29 #ifndef G4GMAKE 29 #ifndef G4GMAKE 30 #include "G4FindDataDir.hh" 30 #include "G4FindDataDir.hh" 31 #include "G4Filesystem.hh" 31 #include "G4Filesystem.hh" 32 #include "G4Exception.hh" << 33 32 34 #include <cstdio> 33 #include <cstdio> 35 #include <cstdlib> 34 #include <cstdlib> 36 #include <cstring> 35 #include <cstring> 37 36 38 #if defined(_WIN32) << 37 #if defined(_MSC_VER) 39 #define setenv(name, value, overwrite) _putenv 38 #define setenv(name, value, overwrite) _putenv_s(name, value) 40 #endif 39 #endif 41 40 42 using namespace G4fs; 41 using namespace G4fs; 43 42 44 static const char * const system_paths[] = { 43 static const char * const system_paths[] = { 45 GEANT4_INSTALL_FULL_DATADIR, 44 GEANT4_INSTALL_FULL_DATADIR, 46 CMAKE_INSTALL_PREFIX, 45 CMAKE_INSTALL_PREFIX, 47 #if defined(_MSC_VER) 46 #if defined(_MSC_VER) 48 "C:\\Program Files", 47 "C:\\Program Files", 49 "C:\\Geant4" 48 "C:\\Geant4" 50 #else 49 #else 51 "/usr/local", 50 "/usr/local", 52 "/usr", 51 "/usr", 53 "/cvmfs/geant4.cern.ch" 52 "/cvmfs/geant4.cern.ch" 54 #endif 53 #endif 55 }; 54 }; 56 55 57 static const char * const data_paths[] = { 56 static const char * const data_paths[] = { 58 ".", 57 ".", 59 GEANT4_INSTALL_DATADIR, 58 GEANT4_INSTALL_DATADIR, 60 CMAKE_INSTALL_DATADIR, 59 CMAKE_INSTALL_DATADIR, 61 "share/Geant4/data", 60 "share/Geant4/data", 62 "share/geant4/data", 61 "share/geant4/data", 63 "share/data", 62 "share/data", 64 "data" 63 "data" 65 }; 64 }; 66 65 67 static const char* G4GetDataDir(const char* na 66 static const char* G4GetDataDir(const char* name) 68 { 67 { 69 for (const auto& d : dataset_definitions) 68 for (const auto& d : dataset_definitions) 70 if (strcmp(name, d.env) == 0) 69 if (strcmp(name, d.env) == 0) 71 return d.dir; 70 return d.dir; 72 71 73 return nullptr; 72 return nullptr; 74 } 73 } 75 74 76 static const char* G4FindDataDir(const char* n 75 static const char* G4FindDataDir(const char* name, const path& prefix, const path& dataset) 77 { 76 { 78 if (!is_directory(prefix)) 77 if (!is_directory(prefix)) 79 return nullptr; 78 return nullptr; 80 79 81 for (const auto data_path : data_paths) { 80 for (const auto data_path : data_paths) { 82 path datadir = prefix; 81 path datadir = prefix; 83 if (strcmp(data_path,".") == 0) 82 if (strcmp(data_path,".") == 0) 84 datadir /= dataset; 83 datadir /= dataset; 85 else 84 else 86 datadir /= path(data_path) / dataset; 85 datadir /= path(data_path) / dataset; 87 if (is_directory(absolute(datadir))) 86 if (is_directory(absolute(datadir))) 88 return setenv(name, absolute(datadir).st 87 return setenv(name, absolute(datadir).string().c_str(), 0) == 0 ? std::getenv(name) : nullptr; 89 } 88 } 90 89 91 return nullptr; 90 return nullptr; 92 } 91 } 93 92 94 const char* G4FindDataDir(const char* name) 93 const char* G4FindDataDir(const char* name) 95 { << 94 { 96 #if defined(G4MULTITHREADED) 95 #if defined(G4MULTITHREADED) 97 static std::mutex mutex; 96 static std::mutex mutex; 98 std::lock_guard<std::mutex> lock(mutex); 97 std::lock_guard<std::mutex> lock(mutex); 99 #endif 98 #endif 100 99 101 /* If environment variable is set for this d 100 /* If environment variable is set for this dataset, use it */ 102 if (const char *datadir = std::getenv(name)) 101 if (const char *datadir = std::getenv(name)) 103 return datadir; 102 return datadir; 104 103 105 /* If we know which directory/version to sea 104 /* If we know which directory/version to search for, try to find it */ 106 if (const char *dataset = G4GetDataDir(name) 105 if (const char *dataset = G4GetDataDir(name)) { 107 /* If GEANT4_DATA_DIR environment variable 106 /* If GEANT4_DATA_DIR environment variable is set, use it and don't search further */ 108 if (const char *basedir = std::getenv("GEA << 107 if (const char *basedir = std::getenv("GEANT4_DATA_DIR")) 109 if (is_directory(basedir)) return G4Find << 108 return G4FindDataDir(name, basedir, dataset); 110 << 111 G4Exception("G4FindDataDir", "Invalid GE << 112 "Will try fallback locations << 113 } << 114 109 115 /* If GEANT4_DATA_DIR environment variable 110 /* If GEANT4_DATA_DIR environment variable is not set, search in default system paths */ 116 for (const auto prefix : system_paths) 111 for (const auto prefix : system_paths) 117 if (const auto datadir = G4FindDataDir(n 112 if (const auto datadir = G4FindDataDir(name, prefix, dataset)) 118 return datadir; 113 return datadir; 119 } 114 } 120 115 121 return nullptr; 116 return nullptr; 122 } 117 } 123 118 124 #else 119 #else 125 // Support GNUmake builds 120 // Support GNUmake builds 126 #include <cstdlib> 121 #include <cstdlib> 127 122 128 const char* G4FindDataDir(const char* name) 123 const char* G4FindDataDir(const char* name) 129 { 124 { 130 #if defined(G4MULTITHREADED) 125 #if defined(G4MULTITHREADED) 131 static std::mutex mutex; 126 static std::mutex mutex; 132 std::lock_guard<std::mutex> lock(mutex); 127 std::lock_guard<std::mutex> lock(mutex); 133 #endif 128 #endif 134 /* If environment variable is set for this d 129 /* If environment variable is set for this dataset, use it */ 135 if (const char *datadir = std::getenv(name)) 130 if (const char *datadir = std::getenv(name)) 136 return datadir; 131 return datadir; 137 132 138 return nullptr; 133 return nullptr; 139 } 134 } 140 #endif 135 #endif 141 136