From bd518adc7a74c470912c75c74d5735e0ced9081a Mon Sep 17 00:00:00 2001
From: Bill Hoffman <bill.hoffman@kitware.com>
Date: Mon, 4 Dec 2006 17:26:40 -0500
Subject: [PATCH] ENH: merge in changes for beos support

---
 DynamicLoader.cxx     | 107 +++++++++++++++++++++++++++++++++++++++++-
 DynamicLoader.hxx.in  |   4 ++
 SystemTools.cxx       |  32 ++++++++++++-
 testDynamicLoader.cxx |   6 +++
 4 files changed, 147 insertions(+), 2 deletions(-)

diff --git a/DynamicLoader.cxx b/DynamicLoader.cxx
index 0502046..5ef0ef8 100644
--- a/DynamicLoader.cxx
+++ b/DynamicLoader.cxx
@@ -319,7 +319,112 @@ const char* DynamicLoader::LastError()
 #endif //_WIN32
 
 // ---------------------------------------------------------------
-// 4. Implementation for default UNIX machines.
+// 4. Implementation for BeOS
+#ifdef __BEOS__
+#include <string.h> // for strerror()
+#include <be/kernel/image.h>
+#include <be/support/Errors.h>
+#define DYNAMICLOADER_DEFINED 1
+
+namespace KWSYS_NAMESPACE
+{
+
+static image_id last_dynamic_err = B_OK;
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+{
+  // image_id's are integers, errors are negative. Add one just in case we
+  //  get a valid image_id of zero (is that even possible?).
+  image_id rc = load_add_on(libname);
+  if (rc < 0)
+    {
+    last_dynamic_err = rc;
+    return 0;
+    }
+
+  return rc+1;
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+  if (!lib)
+    {
+      last_dynamic_err = B_BAD_VALUE;
+      return 0;
+    }
+  else
+    {
+    // The function dlclose() returns 0 on success, and non-zero on error.
+    status_t rc = unload_add_on(lib-1);
+    if (rc != B_OK)
+      {
+      last_dynamic_err = rc;
+      return 0;
+      }
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+  DynamicLoader::LibraryHandle lib, const char* sym)
+{
+  // Hack to cast pointer-to-data to pointer-to-function.
+  union 
+  {
+    void* pvoid;
+    DynamicLoader::SymbolPointer psym;
+  } result;
+
+  result.psym = NULL;
+
+  if (!lib)
+    {
+      last_dynamic_err = B_BAD_VALUE;
+    }
+  else
+    {
+    // !!! FIXME: BeOS can do function-only lookups...does this ever
+    // !!! FIXME:  actually _want_ a data symbol lookup, or was this union
+    // !!! FIXME:  a leftover of dlsym()? (s/ANY/TEXT for functions only).
+    status_t rc = get_image_symbol(lib-1,sym,B_SYMBOL_TYPE_ANY,&result.pvoid);
+    if (rc != B_OK)
+      {
+      last_dynamic_err = rc;
+      result.psym = NULL;
+      }
+    }
+  return result.psym;
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LibPrefix()
+{
+  return "lib";
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LibExtension()
+{
+  return ".so";
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+{
+  const char *retval = strerror(last_dynamic_err);
+  last_dynamic_err = B_OK;
+  return retval;
+}
+
+} // namespace KWSYS_NAMESPACE
+#endif
+
+// ---------------------------------------------------------------
+// 5. Implementation for default UNIX machines.
 // if nothing has been defined then use this
 #ifndef DYNAMICLOADER_DEFINED
 #define DYNAMICLOADER_DEFINED 1
diff --git a/DynamicLoader.hxx.in b/DynamicLoader.hxx.in
index a32f84e..752297f 100644
--- a/DynamicLoader.hxx.in
+++ b/DynamicLoader.hxx.in
@@ -25,6 +25,8 @@
   #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
     #include <mach-o/dyld.h>
   #endif
+#elif defined(__BEOS__)
+  #include <be/kernel/image.h>
 #endif
 
 namespace @KWSYS_NAMESPACE@
@@ -62,6 +64,8 @@ public:
   #else
     typedef void* LibraryHandle;
   #endif
+#elif defined(__BEOS__)
+  typedef image_id LibraryHandle;
 #else
   typedef void* LibraryHandle;
 #endif
diff --git a/SystemTools.cxx b/SystemTools.cxx
index b59d825..f933389 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -108,6 +108,34 @@ public:
 #define _chdir chdir
 #endif
 
+#if defined(__BEOS__) && !defined(__ZETA__)
+#include <be/kernel/OS.h>
+#include <be/storage/Path.h>
+
+// BeOS 5 doesn't have usleep(), but it has snooze(), which is identical.
+static inline void usleep(unsigned int msec)
+{
+  ::snooze(msec);
+}
+
+// BeOS 5 also doesn't have realpath(), but its C++ API offers something close.
+static inline char *realpath(const char *path, char *resolved_path)
+{
+  const size_t maxlen = KWSYS_SYSTEMTOOLS_MAXPATH;
+  snprintf(resolved_path, maxlen, "%s", path);
+  BPath normalized(resolved_path, NULL, true);
+  const char *resolved = normalized.Path();
+  if (resolved != NULL)   // NULL == No such file. 
+    {
+    if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen) 
+      {
+      return resolved_path;
+      }
+    }
+  return NULL;   // something went wrong.
+}
+#endif
+
 #if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)) 
 inline int Mkdir(const char* dir)
 {
@@ -291,7 +319,9 @@ void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char
     kwsys_stl::string::size_type endpos = pathEnv.find(pathSep, start);
     if(endpos != kwsys_stl::string::npos)
       {
-      path.push_back(pathEnv.substr(start, endpos-start));
+      kwsys_stl::string convertedPath;
+      Realpath(pathEnv.substr(start, endpos-start).c_str(), convertedPath);
+      path.push_back(convertedPath);
       start = endpos+1;
       }
     else
diff --git a/testDynamicLoader.cxx b/testDynamicLoader.cxx
index d53afc0..f31606e 100644
--- a/testDynamicLoader.cxx
+++ b/testDynamicLoader.cxx
@@ -17,6 +17,10 @@
 #include KWSYS_HEADER(ios/iostream)
 #include KWSYS_HEADER(stl/string)
 
+#if defined(__BEOS__)
+#include <be/kernel/OS.h>  /* disable_debugger() API. */
+#endif
+
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
@@ -88,6 +92,8 @@ int main(int argc, char *argv[])
 {
 #if defined(_WIN32)
   SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
+#elif defined(__BEOS__)
+  disable_debugger(1);
 #endif
   int res;
   if( argc == 3 )
-- 
GitLab