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 SH_DEBUG_PRINT(
"Looking up " << name);
00109
00110 HMODULE
mod = NULL;
00111 std::string libname(
"LIBSH");
00112 libname += name;
00113
#ifdef SH_DEBUG
00114
libname +=
"D";
00115
#endif
00116
libname +=
".DLL";
00117
mod = LoadLibrary(libname.c_str());
00118
00119
if (!
mod) {
00120 SH_DEBUG_ERROR(
"Could not open " << libname);
00121
return 0;
00122 }
00123
00124
for (ShBackendList::iterator I = begin(); I != end(); ++I) {
00125
if ((*I)->name() == name) {
00126 SH_DEBUG_PRINT(
"Found " << name <<
" at " << I->object());
00127
return *I;
00128 }
00129 }
00130
00131 SH_DEBUG_ERROR(
"Could not find " << name <<
"backend");
00132
00133
return 0;
00134
#endif
00135
}
00136
00137
void ShBackend::init()
00138 {
00139
if (m_doneInit)
return;
00140 SH_DEBUG_PRINT(
"Initializing backend system");
00141
00142 m_backends =
new ShBackendList();
00143
00144
#ifndef WIN32
00145
if (lt_dlinit()) {
00146 SH_DEBUG_ERROR(
"Error initializing ltdl: " << lt_dlerror());
00147 }
00148
00149 std::string searchpath(SH_INSTALL_PREFIX);
00150 searchpath +=
"/lib/sh";
00151
00152
if (lt_dladdsearchdir(searchpath.c_str())) {
00153 SH_DEBUG_ERROR(
"Could not add " + searchpath +
" to search dir: " << lt_dlerror());
00154 }
00155
#endif
00156
00157 m_doneInit =
true;
00158 }
00159
00160 }