os.cpp (4339B)
1 #include "os.h" 2 3 #include "baseLib/filesystem.h" 4 5 #include "dsp56kEmu/logging.h" 6 7 #ifndef _WIN32 8 // filesystem is only available on macOS Catalina 10.15+ 9 // filesystem causes linker errors in gcc-8 if linked statically 10 #define USE_DIRENT 11 #include <cstdlib> 12 #include <cstring> 13 #include <pwd.h> 14 #endif 15 16 #ifdef USE_DIRENT 17 #include <dirent.h> 18 #include <unistd.h> 19 #include <sys/stat.h> 20 #else 21 #include <filesystem> 22 #endif 23 24 #ifdef _WIN32 25 #define NOMINMAX 26 #define NOSERVICE 27 #include <Windows.h> 28 #include <shlobj_core.h> 29 #else 30 #include <dlfcn.h> 31 #endif 32 33 #ifdef _MSC_VER 34 #include <cfloat> 35 #elif defined(HAVE_SSE) 36 #include <immintrin.h> 37 #endif 38 39 #ifdef __APPLE__ 40 #include <sys/types.h> 41 #include <sys/sysctl.h> 42 #endif 43 44 using namespace baseLib::filesystem; 45 46 namespace synthLib 47 { 48 std::string getModulePath(bool _stripPluginComponentFolders/* = true*/) 49 { 50 std::string path; 51 #ifdef _WIN32 52 char buffer[MAX_PATH]; 53 HMODULE hm = nullptr; 54 55 if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 56 reinterpret_cast<LPCSTR>(&getModulePath), &hm) == 0) 57 { 58 LOG("GetModuleHandle failed, error = " << GetLastError()); 59 return {}; 60 } 61 if (GetModuleFileName(hm, buffer, sizeof(buffer)) == 0) 62 { 63 LOG("GetModuleFileName failed, error = " << GetLastError()); 64 return {}; 65 } 66 67 path = buffer; 68 #else 69 Dl_info info; 70 if (!dladdr(reinterpret_cast<const void *>(&getModulePath), &info)) 71 { 72 LOG("Failed to get module path"); 73 return std::string(); 74 } 75 else 76 { 77 path = info.dli_fname; 78 } 79 #endif 80 81 auto fixPathWithDelim = [&](const std::string& _key, const char _delim) 82 { 83 const auto end = path.rfind(_key + _delim); 84 85 // strip folders such as "/foo.vst/" but do NOT strip "/.vst/" 86 if (end != std::string::npos && (path.find(_delim + _key) + 1) != end) 87 path = path.substr(0, end); 88 }; 89 90 auto fixPath = [&](const std::string& _key) 91 { 92 fixPathWithDelim(_key, '/'); 93 fixPathWithDelim(_key, '\\'); 94 }; 95 96 if(_stripPluginComponentFolders) 97 { 98 fixPath(".vst"); 99 fixPath(".vst3"); 100 fixPath(".clap"); 101 fixPath(".component"); 102 fixPath(".app"); 103 } 104 105 const auto end = path.find_last_of("/\\"); 106 107 if (end != std::string::npos) 108 path = path.substr(0, end + 1); 109 110 return validatePath(path); 111 } 112 113 namespace 114 { 115 std::string findFile(const std::string& _extension, const size_t _minSize, const size_t _maxSize, const bool _stripPluginComponentFolders) 116 { 117 std::string path = getModulePath(_stripPluginComponentFolders); 118 119 if(path.empty()) 120 path = getCurrentDirectory(); 121 122 return baseLib::filesystem::findFile(path, _extension, _minSize, _maxSize); 123 } 124 } 125 126 std::string findFile(const std::string& _extension, const size_t _minSize, const size_t _maxSize) 127 { 128 auto res = findFile(_extension, _minSize, _maxSize, true); 129 if (!res.empty()) 130 return res; 131 return findFile(_extension, _minSize, _maxSize, false); 132 } 133 134 std::string findROM(const size_t _minSize, const size_t _maxSize) 135 { 136 std::string path = getModulePath(); 137 138 if(path.empty()) 139 path = getCurrentDirectory(); 140 141 auto f = baseLib::filesystem::findFile(path, ".bin", _minSize, _maxSize); 142 if(!f.empty()) 143 return f; 144 145 path = getModulePath(false); 146 147 return baseLib::filesystem::findFile(path, ".bin", _minSize, _maxSize); 148 } 149 150 std::string findROM(const size_t _expectedSize) 151 { 152 return findROM(_expectedSize, _expectedSize); 153 } 154 155 void setFlushDenormalsToZero() 156 { 157 #if defined(_MSC_VER) 158 _controlfp(_DN_FLUSH, _MCW_DN); 159 #elif defined(HAVE_SSE) 160 _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); 161 #endif 162 } 163 164 bool isRunningUnderRosetta() 165 { 166 #ifdef __APPLE__ 167 int ret = 0; 168 size_t size = sizeof(ret); 169 if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) 170 { 171 if (errno == ENOENT) 172 return false; // no, native 173 return false; // unable to tell, assume native 174 } 175 return ret == 1; // Rosetta if result is 1 176 #else 177 return false; 178 #endif 179 } 180 } // namespace synthLib