Mercurial > foo_out_sdl
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/shared/shared-nix.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,212 @@ +#include "shared.h" +#include <dirent.h> +#include <pfc/wildcard.h> +#include <unistd.h> + +// foobar2000 SDK project method... bah +namespace foobar2000_io { + PFC_NORETURN void nix_io_op_fail(); +} +using namespace foobar2000_io; + +namespace { + class uFindFileImpl : public uFindFile { + public: + uFindFileImpl ( DIR * dir ) : m_dir(dir) {} + bool FindNext() override { + m_entry = readdir(m_dir); + return m_entry != NULL; + } + const char * GetFileName() override { + return m_entry->d_name; + } + bool IsDirectory() override { + return m_entry->d_type == DT_DIR; + } + ~uFindFileImpl() { + closedir(m_dir); + } + private: + dirent * m_entry; + + DIR * m_dir; + }; + + class uFindFileFiltered : public uFindFile { + public: + uFindFileFiltered( DIR * dir, const char * wc ) : m_impl(dir), m_wc(wc) {} + bool FindNext() override { + for( ;; ) { + if (!m_impl.FindNext()) return false; + if ( testWC() ) return true; + } + } + const char * GetFileName() override { + return m_impl.GetFileName(); + } + bool IsDirectory() override { + return m_impl.IsDirectory(); + } + bool testWC() { + return wildcard_helper::test(GetFileName(), m_wc); + } + + uFindFileImpl m_impl; + const pfc::string8 m_wc; + }; +} + +puFindFile uFindFirstFile(const char * path) { + + if ( wildcard_helper::has_wildcards( path ) ) { + size_t idx = pfc::scan_filename(path); + + try { + DIR * dir = opendir( pfc::string8(path, idx) ); + if (dir == NULL) nix_io_op_fail(); + try { + uFindFile * ff; + try { + ff = new uFindFileFiltered(dir, path + idx); + } catch(...) { closedir( dir ); throw; } + if (ff->FindNext()) return ff; + delete ff; + return NULL; + } catch(...) { closedir( dir ); throw; } + } catch(...) {return NULL;} + + } + + try { + DIR * dir = opendir( path ); + if (dir == NULL) nix_io_op_fail(); + try { + uFindFile * ff; + try { + ff = new uFindFileImpl(dir); + } catch(...) { closedir( dir ); throw; } + if (ff->FindNext()) return ff; + delete ff; + return NULL; + } catch(...) { closedir( dir ); throw; } + } catch(...) {return NULL;} +} + +pfc::string8 uStringPrintf(const char * fmt, ...) { + pfc::string8 ret; + va_list list; + va_start(list,fmt); + uPrintfV(ret,fmt,list); + va_end(list); + return ret; +} + +void uPrintfV(pfc::string_base & out,const char * fmt,va_list arglist) { + pfc::string_printf_here_va(out, fmt, arglist); +} + +void uPrintf(pfc::string_base & out,const char * fmt,...) { + va_list list;va_start(list,fmt);uPrintfV(out,fmt,list);va_end(list); +} + + +static int makeInfiniteWaitEvent() { + int fdPipe[2]; + pfc::createPipe(fdPipe); + return fdPipe[0]; // leak the other end +} + +int GetInfiniteWaitEvent() { + static int obj = makeInfiniteWaitEvent(); + return obj; +} + + +// DUMMY +void SHARED_EXPORT uAddPanicHandler(fb2k::panicHandler*) { + +} +void SHARED_EXPORT uRemovePanicHandler(fb2k::panicHandler*) { + +} + +void SHARED_EXPORT uOutputDebugString(const char * msg) { + // UGLY: underlying APIs want whole lines, calling code feeds lines terminated with \n or \r\n because Windows + pfc::string8 temp ( msg ); + if ( temp.endsWith('\n') ) temp.truncate( temp.length() - 1) ; + if ( temp.endsWith('\r') ) temp.truncate( temp.length() - 1) ; + pfc::outputDebugLine(temp); +} +namespace pfc { PFC_NORETURN void crashImpl(); } +PFC_NORETURN void SHARED_EXPORT uBugCheck() { + pfc::crashImpl(); +} + +int SHARED_EXPORT uStringCompare(const char * elem1, const char * elem2) { + return pfc::naturalSortCompareI(elem1, elem2); +} + +void fb2kDebugSelfTest() { + +} + +bool uGetTempPath(pfc::string_base & out) { + auto var = getenv("TMPDIR"); + if ( var == nullptr ) uBugCheck(); + out = var; + return true; +} +bool uGetTempFileName(const char * path_name,const char * prefix,unsigned unique,pfc::string_base & out) { +#if 0 // sample use + pfc::string8 temp_path, temp_file; + uGetTempPath(temp_path); + uGetTempFileName(temp_path, "img", 0, temp_file); +#endif + pfc::string8 ret; + if ( path_name == nullptr ) uGetTempPath( ret ); + else ret = path_name; + + pfc::chain_list_v2_t<pfc::string8> segments; + if ( prefix ) segments += prefix; + if ( unique ) segments += pfc::format(unique); + segments += pfc::print_guid(pfc::createGUID()); + + pfc::string8 fn; + for( auto & seg : segments ) { + if (seg.length() == 0) continue; + if ( fn.length() > 0 ) fn += "-"; + fn += seg; + } + + ret.add_filename( fn ); + out = ret; + return true; +} + +pfc::string8 uGetTempFileName() { + pfc::string8 ret; + uGetTempFileName(nullptr, nullptr, 0, ret); + return ret; +} + + +void fb2k::crashWithMessage [[noreturn]] ( const char * msg_ ) { + uAddDebugEvent( msg_ ); + pfc::crashWithMessageOnStack(msg_); +} + +bool uSetCurrentDirectory(const char * path) { + return chdir(path) == 0; +} +bool uGetCurrentDirectory(pfc::string_base & out) { + pfc::array_t<char> work; + work.resize( PATH_MAX ); + for(;;) { + errno = 0; + if ( getcwd(work.get_ptr(), work.size()) != nullptr ) { + out = work.get_ptr(); return true; + } + if ( errno != ENAMETOOLONG ) return false; + work.resize( work.size() * 2 ); + } +}
