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 );
+    }
+}