00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027 #ifdef HAVE_CONFIG_H
00028 #include "config.h"
00029 #endif
00030
00031 #ifndef WIN32
00032 #include <ltdl.h>
00033 #else
00034 #include <windows.h>
00035 #endif
00036
00037 #include <algorithm>
00038
00039 #include "ShBackend.hpp"
00040 #include "ShProgram.hpp"
00041 #include "ShDebug.hpp"
00042 #include "ShEnvironment.hpp"
00043 #include "ShInternals.hpp"
00044 #include "ShTransformer.hpp"
00045
00046 namespace SH {
00047
00048 ShBackend::ShBackendList* ShBackend::m_backends = 0;
00049 bool ShBackend::m_doneInit = false;
00050
00051 ShBackendCode::~ShBackendCode()
00052 {
00053 }
00054
00055 ShBackend::ShBackend()
00056 {
00057 init();
00058 m_backends->push_back(this);
00059 }
00060
00061 ShBackend::~ShBackend()
00062 {
00063 m_backends->erase(std::remove(begin(), end(), ShBackendPtr(this)), end());
00064 }
00065
00066 ShBackend::ShBackendList::iterator ShBackend::begin()
00067 {
00068 init();
00069 return m_backends->begin();
00070 }
00071
00072 ShBackend::ShBackendList::iterator ShBackend::end()
00073 {
00074 init();
00075 if (!m_backends) m_backends = new ShBackendList();
00076 return m_backends->end();
00077 }
00078
00079 ShPointer<ShBackend> ShBackend::lookup(const std::string& name)
00080 {
00081 init();
00082
00083 for (ShBackendList::iterator I = begin(); I != end(); ++I) {
00084 if ((*I)->name() == name) return *I;
00085 }
00086 #ifndef WIN32
00087 std::string libname(SH_INSTALL_PREFIX);
00088 libname += "/lib/sh/libsh" + name + ".so";
00089
00090 lt_dlhandle handle = lt_dlopenext(libname.c_str());
00091
00092 if (!handle) {
00093 SH_DEBUG_ERROR("Could not open " << libname << ": " << lt_dlerror());
00094 return 0;
00095 }
00096
00097 for (ShBackendList::iterator I = begin(); I != end(); ++I) {
00098 if ((*I)->name() == name) {
00099 return *I;
00100 }
00101 }
00102
00103 SH_DEBUG_ERROR("Could not find " << name << "backend");
00104
00105 return 0;
00106 #else
00107
00108 HMODULE mod = NULL;
00109 std::string libname("LIBSH");
00110 libname += name;
00111 #ifdef SH_DEBUG
00112 libname += "D";
00113 #endif
00114 libname += ".DLL";
00115 mod = LoadLibrary(libname.c_str());
00116
00117 if (!mod) {
00118 SH_DEBUG_ERROR("Could not open " << libname);
00119 return 0;
00120 }
00121
00122 for (ShBackendList::iterator I = begin(); I != end(); ++I) {
00123 if ((*I)->name() == name) {
00124 return *I;
00125 }
00126 }
00127
00128 SH_DEBUG_ERROR("Could not find " << name << "backend");
00129
00130 return 0;
00131 #endif
00132 }
00133
00134 void ShBackend::init()
00135 {
00136 if (m_doneInit) return;
00137
00138
00139 m_backends = new ShBackendList();
00140
00141 #ifndef WIN32
00142 if (lt_dlinit()) {
00143 SH_DEBUG_ERROR("Error initializing ltdl: " << lt_dlerror());
00144 }
00145
00146 std::string searchpath(SH_INSTALL_PREFIX);
00147 searchpath += "/lib/sh";
00148
00149 if (lt_dladdsearchdir(searchpath.c_str())) {
00150 SH_DEBUG_ERROR("Could not add " + searchpath + " to search dir: " << lt_dlerror());
00151 }
00152 #endif
00153
00154 m_doneInit = true;
00155 }
00156
00157 }