Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/shared/shared-nix.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "shared.h" | |
| 2 #include <dirent.h> | |
| 3 #include <pfc/wildcard.h> | |
| 4 #include <unistd.h> | |
| 5 | |
| 6 // foobar2000 SDK project method... bah | |
| 7 namespace foobar2000_io { | |
| 8 PFC_NORETURN void nix_io_op_fail(); | |
| 9 } | |
| 10 using namespace foobar2000_io; | |
| 11 | |
| 12 namespace { | |
| 13 class uFindFileImpl : public uFindFile { | |
| 14 public: | |
| 15 uFindFileImpl ( DIR * dir ) : m_dir(dir) {} | |
| 16 bool FindNext() override { | |
| 17 m_entry = readdir(m_dir); | |
| 18 return m_entry != NULL; | |
| 19 } | |
| 20 const char * GetFileName() override { | |
| 21 return m_entry->d_name; | |
| 22 } | |
| 23 bool IsDirectory() override { | |
| 24 return m_entry->d_type == DT_DIR; | |
| 25 } | |
| 26 ~uFindFileImpl() { | |
| 27 closedir(m_dir); | |
| 28 } | |
| 29 private: | |
| 30 dirent * m_entry; | |
| 31 | |
| 32 DIR * m_dir; | |
| 33 }; | |
| 34 | |
| 35 class uFindFileFiltered : public uFindFile { | |
| 36 public: | |
| 37 uFindFileFiltered( DIR * dir, const char * wc ) : m_impl(dir), m_wc(wc) {} | |
| 38 bool FindNext() override { | |
| 39 for( ;; ) { | |
| 40 if (!m_impl.FindNext()) return false; | |
| 41 if ( testWC() ) return true; | |
| 42 } | |
| 43 } | |
| 44 const char * GetFileName() override { | |
| 45 return m_impl.GetFileName(); | |
| 46 } | |
| 47 bool IsDirectory() override { | |
| 48 return m_impl.IsDirectory(); | |
| 49 } | |
| 50 bool testWC() { | |
| 51 return wildcard_helper::test(GetFileName(), m_wc); | |
| 52 } | |
| 53 | |
| 54 uFindFileImpl m_impl; | |
| 55 const pfc::string8 m_wc; | |
| 56 }; | |
| 57 } | |
| 58 | |
| 59 puFindFile uFindFirstFile(const char * path) { | |
| 60 | |
| 61 if ( wildcard_helper::has_wildcards( path ) ) { | |
| 62 size_t idx = pfc::scan_filename(path); | |
| 63 | |
| 64 try { | |
| 65 DIR * dir = opendir( pfc::string8(path, idx) ); | |
| 66 if (dir == NULL) nix_io_op_fail(); | |
| 67 try { | |
| 68 uFindFile * ff; | |
| 69 try { | |
| 70 ff = new uFindFileFiltered(dir, path + idx); | |
| 71 } catch(...) { closedir( dir ); throw; } | |
| 72 if (ff->FindNext()) return ff; | |
| 73 delete ff; | |
| 74 return NULL; | |
| 75 } catch(...) { closedir( dir ); throw; } | |
| 76 } catch(...) {return NULL;} | |
| 77 | |
| 78 } | |
| 79 | |
| 80 try { | |
| 81 DIR * dir = opendir( path ); | |
| 82 if (dir == NULL) nix_io_op_fail(); | |
| 83 try { | |
| 84 uFindFile * ff; | |
| 85 try { | |
| 86 ff = new uFindFileImpl(dir); | |
| 87 } catch(...) { closedir( dir ); throw; } | |
| 88 if (ff->FindNext()) return ff; | |
| 89 delete ff; | |
| 90 return NULL; | |
| 91 } catch(...) { closedir( dir ); throw; } | |
| 92 } catch(...) {return NULL;} | |
| 93 } | |
| 94 | |
| 95 pfc::string8 uStringPrintf(const char * fmt, ...) { | |
| 96 pfc::string8 ret; | |
| 97 va_list list; | |
| 98 va_start(list,fmt); | |
| 99 uPrintfV(ret,fmt,list); | |
| 100 va_end(list); | |
| 101 return ret; | |
| 102 } | |
| 103 | |
| 104 void uPrintfV(pfc::string_base & out,const char * fmt,va_list arglist) { | |
| 105 pfc::string_printf_here_va(out, fmt, arglist); | |
| 106 } | |
| 107 | |
| 108 void uPrintf(pfc::string_base & out,const char * fmt,...) { | |
| 109 va_list list;va_start(list,fmt);uPrintfV(out,fmt,list);va_end(list); | |
| 110 } | |
| 111 | |
| 112 | |
| 113 static int makeInfiniteWaitEvent() { | |
| 114 int fdPipe[2]; | |
| 115 pfc::createPipe(fdPipe); | |
| 116 return fdPipe[0]; // leak the other end | |
| 117 } | |
| 118 | |
| 119 int GetInfiniteWaitEvent() { | |
| 120 static int obj = makeInfiniteWaitEvent(); | |
| 121 return obj; | |
| 122 } | |
| 123 | |
| 124 | |
| 125 // DUMMY | |
| 126 void SHARED_EXPORT uAddPanicHandler(fb2k::panicHandler*) { | |
| 127 | |
| 128 } | |
| 129 void SHARED_EXPORT uRemovePanicHandler(fb2k::panicHandler*) { | |
| 130 | |
| 131 } | |
| 132 | |
| 133 void SHARED_EXPORT uOutputDebugString(const char * msg) { | |
| 134 // UGLY: underlying APIs want whole lines, calling code feeds lines terminated with \n or \r\n because Windows | |
| 135 pfc::string8 temp ( msg ); | |
| 136 if ( temp.endsWith('\n') ) temp.truncate( temp.length() - 1) ; | |
| 137 if ( temp.endsWith('\r') ) temp.truncate( temp.length() - 1) ; | |
| 138 pfc::outputDebugLine(temp); | |
| 139 } | |
| 140 namespace pfc { PFC_NORETURN void crashImpl(); } | |
| 141 PFC_NORETURN void SHARED_EXPORT uBugCheck() { | |
| 142 pfc::crashImpl(); | |
| 143 } | |
| 144 | |
| 145 int SHARED_EXPORT uStringCompare(const char * elem1, const char * elem2) { | |
| 146 return pfc::naturalSortCompareI(elem1, elem2); | |
| 147 } | |
| 148 | |
| 149 void fb2kDebugSelfTest() { | |
| 150 | |
| 151 } | |
| 152 | |
| 153 bool uGetTempPath(pfc::string_base & out) { | |
| 154 auto var = getenv("TMPDIR"); | |
| 155 if ( var == nullptr ) uBugCheck(); | |
| 156 out = var; | |
| 157 return true; | |
| 158 } | |
| 159 bool uGetTempFileName(const char * path_name,const char * prefix,unsigned unique,pfc::string_base & out) { | |
| 160 #if 0 // sample use | |
| 161 pfc::string8 temp_path, temp_file; | |
| 162 uGetTempPath(temp_path); | |
| 163 uGetTempFileName(temp_path, "img", 0, temp_file); | |
| 164 #endif | |
| 165 pfc::string8 ret; | |
| 166 if ( path_name == nullptr ) uGetTempPath( ret ); | |
| 167 else ret = path_name; | |
| 168 | |
| 169 pfc::chain_list_v2_t<pfc::string8> segments; | |
| 170 if ( prefix ) segments += prefix; | |
| 171 if ( unique ) segments += pfc::format(unique); | |
| 172 segments += pfc::print_guid(pfc::createGUID()); | |
| 173 | |
| 174 pfc::string8 fn; | |
| 175 for( auto & seg : segments ) { | |
| 176 if (seg.length() == 0) continue; | |
| 177 if ( fn.length() > 0 ) fn += "-"; | |
| 178 fn += seg; | |
| 179 } | |
| 180 | |
| 181 ret.add_filename( fn ); | |
| 182 out = ret; | |
| 183 return true; | |
| 184 } | |
| 185 | |
| 186 pfc::string8 uGetTempFileName() { | |
| 187 pfc::string8 ret; | |
| 188 uGetTempFileName(nullptr, nullptr, 0, ret); | |
| 189 return ret; | |
| 190 } | |
| 191 | |
| 192 | |
| 193 void fb2k::crashWithMessage [[noreturn]] ( const char * msg_ ) { | |
| 194 uAddDebugEvent( msg_ ); | |
| 195 pfc::crashWithMessageOnStack(msg_); | |
| 196 } | |
| 197 | |
| 198 bool uSetCurrentDirectory(const char * path) { | |
| 199 return chdir(path) == 0; | |
| 200 } | |
| 201 bool uGetCurrentDirectory(pfc::string_base & out) { | |
| 202 pfc::array_t<char> work; | |
| 203 work.resize( PATH_MAX ); | |
| 204 for(;;) { | |
| 205 errno = 0; | |
| 206 if ( getcwd(work.get_ptr(), work.size()) != nullptr ) { | |
| 207 out = work.get_ptr(); return true; | |
| 208 } | |
| 209 if ( errno != ENAMETOOLONG ) return false; | |
| 210 work.resize( work.size() * 2 ); | |
| 211 } | |
| 212 } |
