Don't ignore path when prompting for file in SaveAs()
[wxWidgets.git] / src / common / dynlib.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dynlib.cpp
3 // Purpose: Dynamic library management
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: 20/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Guilhem Lavaux
9 // 2000-2005 Vadim Zeitlin
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 //FIXME: This class isn't really common at all, it should be moved into
14 // platform dependent files (already done for Windows and Unix)
15
16 // ============================================================================
17 // declarations
18 // ============================================================================
19
20 // ----------------------------------------------------------------------------
21 // headers
22 // ----------------------------------------------------------------------------
23
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #if wxUSE_DYNLIB_CLASS
31
32 #include "wx/dynlib.h"
33
34 #ifndef WX_PRECOMP
35 #include "wx/intl.h"
36 #include "wx/log.h"
37 #include "wx/app.h"
38 #include "wx/utils.h"
39 #endif //WX_PRECOMP
40
41 #include "wx/filefn.h"
42 #include "wx/filename.h" // for SplitPath()
43 #include "wx/platinfo.h"
44
45 #include "wx/arrimpl.cpp"
46
47 #if defined(__WXMAC__)
48 #include "wx/mac/private.h"
49 #endif
50
51 WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray)
52
53 // ============================================================================
54 // implementation
55 // ============================================================================
56
57 // ---------------------------------------------------------------------------
58 // wxDynamicLibrary
59 // ---------------------------------------------------------------------------
60
61 #if defined(__WXPM__) || defined(__EMX__)
62 const wxString wxDynamicLibrary::ms_dllext(_T(".dll"));
63 #endif
64
65 // for MSW/Unix it is defined in platform-specific file
66 #if !(defined(__WXMSW__) || defined(__UNIX__)) || defined(__EMX__)
67
68 wxDllType wxDynamicLibrary::GetProgramHandle()
69 {
70 wxFAIL_MSG( wxT("GetProgramHandle() is not implemented under this platform"));
71 return 0;
72 }
73
74 #endif // __WXMSW__ || __UNIX__
75
76
77 bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
78 {
79 wxASSERT_MSG(m_handle == 0, _T("Library already loaded."));
80
81 // add the proper extension for the DLL ourselves unless told not to
82 wxString libname = libnameOrig;
83 if ( !(flags & wxDL_VERBATIM) )
84 {
85 // and also check that the libname doesn't already have it
86 wxString ext;
87 wxFileName::SplitPath(libname, NULL, NULL, &ext);
88 if ( ext.empty() )
89 {
90 libname += GetDllExt();
91 }
92 }
93
94 // different ways to load a shared library
95 //
96 // FIXME: should go to the platform-specific files!
97 #if defined(__WXPM__) || defined(__EMX__)
98 char err[256] = "";
99 DosLoadModule(err, sizeof(err), libname.c_str(), &m_handle);
100 #else // this should be the only remaining branch eventually
101 m_handle = RawLoad(libname, flags);
102 #endif
103
104 if ( m_handle == 0 && !(flags & wxDL_QUIET) )
105 {
106 #ifdef wxHAVE_DYNLIB_ERROR
107 Error();
108 #else
109 wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
110 #endif
111 }
112
113 return IsLoaded();
114 }
115
116 // for MSW and Unix this is implemented in the platform-specific file
117 //
118 // TODO: move the rest to os2/dlpm.cpp and mac/dlmac.cpp!
119 #if (!defined(__WXMSW__) && !defined(__UNIX__)) || defined(__EMX__)
120
121 /* static */
122 void wxDynamicLibrary::Unload(wxDllType handle)
123 {
124 #if defined(__OS2__) || defined(__EMX__)
125 DosFreeModule( handle );
126 #else
127 #error "runtime shared lib support not implemented"
128 #endif
129 }
130
131 #endif // !(__WXMSW__ || __UNIX__)
132
133 void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
134 {
135 wxCHECK_MSG( IsLoaded(), NULL,
136 _T("Can't load symbol from unloaded library") );
137
138 void *symbol = 0;
139
140 wxUnusedVar(symbol);
141 #if defined(__WXPM__) || defined(__EMX__)
142 DosQueryProcAddr( m_handle, 1L, name.c_str(), (PFN*)symbol );
143 #else
144 symbol = RawGetSymbol(m_handle, name);
145 #endif
146
147 if ( success )
148 *success = symbol != NULL;
149
150 return symbol;
151 }
152
153 void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
154 {
155 void *symbol = DoGetSymbol(name, success);
156 if ( !symbol )
157 {
158 #ifdef wxHAVE_DYNLIB_ERROR
159 Error();
160 #else
161 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
162 name.c_str());
163 #endif
164 }
165
166 return symbol;
167 }
168
169 // ----------------------------------------------------------------------------
170 // informational methods
171 // ----------------------------------------------------------------------------
172
173 /*static*/
174 wxString
175 wxDynamicLibrary::CanonicalizeName(const wxString& name,
176 wxDynamicLibraryCategory cat)
177 {
178 wxString nameCanonic;
179
180 // under Unix the library names usually start with "lib" prefix, add it
181 #if defined(__UNIX__) && !defined(__EMX__)
182 switch ( cat )
183 {
184 default:
185 wxFAIL_MSG( _T("unknown wxDynamicLibraryCategory value") );
186 // fall through
187
188 case wxDL_MODULE:
189 // don't do anything for modules, their names are arbitrary
190 break;
191
192 case wxDL_LIBRARY:
193 // library names should start with "lib" under Unix
194 nameCanonic = _T("lib");
195 break;
196 }
197 #else // !__UNIX__
198 wxUnusedVar(cat);
199 #endif // __UNIX__/!__UNIX__
200
201 nameCanonic << name << GetDllExt();
202 return nameCanonic;
203 }
204
205 /*static*/
206 wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
207 wxPluginCategory cat)
208 {
209 wxString suffix;
210 if ( cat == wxDL_PLUGIN_GUI )
211 {
212 suffix = wxPlatformInfo::Get().GetPortIdShortName();
213 }
214 #if wxUSE_UNICODE
215 suffix << _T('u');
216 #endif
217 #ifdef __WXDEBUG__
218 suffix << _T('d');
219 #endif
220
221 if ( !suffix.empty() )
222 suffix = wxString(_T("_")) + suffix;
223
224 #define WXSTRINGIZE(x) #x
225 #if defined(__UNIX__) && !defined(__EMX__)
226 #if (wxMINOR_VERSION % 2) == 0
227 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y)
228 #else
229 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z)
230 #endif
231 #else
232 #if (wxMINOR_VERSION % 2) == 0
233 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y)
234 #else
235 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z)
236 #endif
237 #endif
238
239 suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
240 wxRELEASE_NUMBER));
241 #undef wxDLLVER
242 #undef WXSTRINGIZE
243
244 #ifdef __WINDOWS__
245 // Add compiler identification:
246 #if defined(__GNUG__)
247 suffix << _T("_gcc");
248 #elif defined(__VISUALC__)
249 suffix << _T("_vc");
250 #elif defined(__WATCOMC__)
251 suffix << _T("_wat");
252 #elif defined(__BORLANDC__)
253 suffix << _T("_bcc");
254 #endif
255 #endif
256
257 return CanonicalizeName(name + suffix, wxDL_MODULE);
258 }
259
260 /*static*/
261 wxString wxDynamicLibrary::GetPluginsDirectory()
262 {
263 #ifdef __UNIX__
264 wxString format = wxGetInstallPrefix();
265 wxString dir;
266 format << wxFILE_SEP_PATH
267 << wxT("lib") << wxFILE_SEP_PATH
268 << wxT("wx") << wxFILE_SEP_PATH
269 #if (wxMINOR_VERSION % 2) == 0
270 << wxT("%i.%i");
271 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
272 #else
273 << wxT("%i.%i.%i");
274 dir.Printf(format.c_str(),
275 wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER);
276 #endif
277 return dir;
278
279 #else // ! __UNIX__
280 return wxEmptyString;
281 #endif
282 }
283
284
285 #endif // wxUSE_DYNLIB_CLASS