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