1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
4
* Copyright (C) 2007 Andris Pavenis <andris.pavenis@iki.fi>
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
* ***** END OF LICENSE BLOCK ***** */
22
#include "mozVoikkoUtils.hxx"
23
#include "mozVoikkoSpell.hxx"
24
#include <nsComponentManagerUtils.h>
26
#include <nsICategoryManager.h>
27
#include <nsIConsoleService.h>
29
#include <nsILocalFile.h>
30
#include <nsIXULRuntime.h>
31
#include <nsServiceManagerUtils.h>
32
#include <nsStringAPI.h>
35
#if defined(__linux__)
37
const char *preloadLibNames[] =
43
const unsigned numPreloadedLibs = sizeof(preloadLibNames)/sizeof(*preloadLibNames);
45
const char * libvoikkoName = "libvoikko.so.1";
50
const char *preloadLibNames[] =
59
const unsigned numPreloadedLibs = sizeof(preloadLibNames)/sizeof(*preloadLibNames);
61
const char * libvoikkoName = "libvoikko-1.dll";
65
#error Target OS not supported
69
#define CH(statement, errRetVal) do \
71
nsresult rv = statement; \
74
logMessage("%s failed in %s at line %d: error code %X", \
75
#statement, __FILE__, __LINE__, (PRUint32)rv); \
81
void logMessage(const char *fmt, ...)
85
char *msg = PR_vsmprintf(fmt, args);
88
nsCOMPtr<nsIConsoleService> aConsoleService =
89
do_GetService("@mozilla.org/consoleservice;1");
94
aConsoleService->LogStringMessage(NS_ConvertUTF8toUTF16(tmp).get());
104
nsCString prGetErrorText(void)
107
PRInt32 len = PR_GetErrorTextLength();
110
char *buffer = (char*)PR_Malloc(len);
113
PR_GetErrorText(buffer);
122
nsresult checkLeafNameAndGetParent(nsIFile *file, nsIFile **parent,
123
const nsACString &expectedLeafName)
128
rv = file->GetNativeLeafName(leafName);
129
NS_ENSURE_SUCCESS(rv, rv);
131
if (leafName.Equals(expectedLeafName))
133
rv = file->GetParent(parent);
134
NS_ENSURE_SUCCESS(rv, rv);
141
nsresult checkLeafNameAndGetParent(nsIFile *file, nsIFile **parent,
142
const nsACString& expectedLeafName1, const nsACString &expectedLeafName2)
147
rv = file->GetNativeLeafName(leafName);
148
NS_ENSURE_SUCCESS(rv, rv);
150
if (leafName.Equals(expectedLeafName1) || leafName.Equals(expectedLeafName2))
152
rv = file->GetParent(parent);
153
NS_ENSURE_SUCCESS(rv, rv);
160
nsresult findFileInSubdirectory(nsIFile *dir, nsIFile **result,
161
const nsACString &subDirName, const nsACString &fileName)
165
nsCOMPtr<nsIFile> tmp;
169
rv = dir->Clone(getter_AddRefs(tmp));
170
NS_ENSURE_SUCCESS(rv, rv);
172
rv = tmp->AppendNative(subDirName);
173
NS_ENSURE_SUCCESS(rv, rv);
175
rv = tmp->Exists(&found);
176
NS_ENSURE_SUCCESS(rv, rv);
180
rv = tmp->IsDirectory(&found);
181
NS_ENSURE_SUCCESS(rv, rv);
185
rv = tmp->AppendNative(fileName);
186
NS_ENSURE_SUCCESS(rv, rv);
188
rv = tmp->Exists(&found);
189
NS_ENSURE_SUCCESS(rv, rv);
191
rv = tmp->Clone(result);
195
nsresult getMozVoikkoLibrary(nsIFile **file)
198
char *mozVoikkoLibPathC;
202
nsCOMPtr<nsICategoryManager> catMgr =
203
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
207
logMessage("Failed to get nsICategoryManager");
208
return NS_ERROR_FAILURE;
211
rv = catMgr->GetCategoryEntry("spell-check-engine", MOZ_VOIKKOSPELL_CONTRACTID,
215
logMessage("Failed to get category entry for mozVoikko");
219
nsCString path(mozVoikkoLibPathC);
221
nsCOMPtr<nsILocalFile> mozVoikkoLib;
222
mozVoikkoLib = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
225
logMessage("Failed to create instance of nsILoclFile");
226
return NS_ERROR_FAILURE;
229
rv = mozVoikkoLib->InitWithPath(NS_ConvertUTF8toUTF16(path));
232
logMessage("Failed to set path for nsILocalFile");
236
rv = mozVoikkoLib->Clone(file);
239
logMessage("%s: Failed to clone nsIFile", __FUNCTION__);
246
nsresult getMozVoikkoBaseDirs(nsIFile **libDir, nsIFile **dataDir)
249
nsCOMPtr<nsIFile> mozVoikkoLibName;
250
nsCOMPtr<nsIFile> currDir, parentDir;
251
nsCOMPtr<nsIFile> tmpDir, tmpFile;
252
nsCString leafName, tmp;
253
nsCString shortTargetName;
254
nsCString fullTargetName;
256
// Get platform name (eg. WINNT_x86-msvc or Linux_x86_64-gcc3).
257
// WARNING: not frozen interface nsIXULRuntime is being used.
258
// String shortTargetName will contain only target OS name (like WINNT)
259
// String fullTargetName will contain additionally XPCOMAPI_NAME
261
nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/app-info;1", &rv);
263
NS_ENSURE_SUCCESS(rv, rv);
265
rv = runtime->GetOS(shortTargetName);
266
NS_ENSURE_SUCCESS(rv, rv);
268
fullTargetName = shortTargetName;
270
rv = runtime->GetXPCOMABI(tmp);
271
if (NS_SUCCEEDED(rv))
273
fullTargetName.Append("_");
274
fullTargetName.Append(tmp);
277
// Get path of mozvoikko shared library.
278
// mozVoikkoSpell::registerExtension() has saved it using nsICategory manager
279
// when registrating the extension
280
rv = getMozVoikkoLibrary(getter_AddRefs(mozVoikkoLibName));
281
NS_ENSURE_SUCCESS(rv, rv);
283
// Extract directory part
284
rv = mozVoikkoLibName->GetParent(getter_AddRefs(currDir));
285
NS_ENSURE_SUCCESS(rv, rv);
287
rv = checkLeafNameAndGetParent(currDir, getter_AddRefs(parentDir),
288
NS_LITERAL_CSTRING("components"));
289
NS_ENSURE_SUCCESS(rv, rv);
291
return NS_ERROR_FAILURE;
295
rv = findFileInSubdirectory(currDir, getter_AddRefs(tmpFile),
296
NS_LITERAL_CSTRING("voikko"), NS_LITERAL_CSTRING("voikko-fi_FI.pro"));
297
NS_ENSURE_SUCCESS(rv, rv);
301
rv = checkLeafNameAndGetParent(currDir, getter_AddRefs(parentDir),
302
shortTargetName, fullTargetName);
303
NS_ENSURE_SUCCESS(rv, rv);
308
rv = checkLeafNameAndGetParent(currDir, getter_AddRefs(parentDir),
309
NS_LITERAL_CSTRING("platform"));
310
NS_ENSURE_SUCCESS(rv, rv);
314
rv = findFileInSubdirectory(parentDir, getter_AddRefs(tmpFile),
315
NS_LITERAL_CSTRING("voikko"),
316
NS_LITERAL_CSTRING("voikko-fi_FI.pro"));
317
NS_ENSURE_SUCCESS(rv, rv);
324
return NS_ERROR_FAILURE;
327
rv = tmpFile->GetParent(dataDir);
328
NS_ENSURE_SUCCESS(rv, rv);
330
rv = (*dataDir)->Clone(getter_AddRefs(tmpDir));
331
NS_ENSURE_SUCCESS(rv, rv);
333
rv = findFileInSubdirectory(tmpDir, getter_AddRefs(tmpFile), fullTargetName,
334
nsCString(libvoikkoName));
335
NS_ENSURE_SUCCESS(rv, rv);
339
rv = tmpFile->GetParent(libDir);
343
rv = findFileInSubdirectory(tmpDir, getter_AddRefs(tmpFile), shortTargetName,
344
nsCString(libvoikkoName));
345
NS_ENSURE_SUCCESS(rv, rv);
349
rv = tmpFile->GetParent(libDir);
353
return NS_ERROR_FAILURE;
356
nsresult loadExtraLibraries(int numLibs, const char **names)
359
nsCOMPtr<nsIFile> base, baseDir;
362
rv = getMozVoikkoLibrary(getter_AddRefs(base));
366
base->GetParent(getter_AddRefs(baseDir));
368
base->GetNativePath(tmp);
369
logMessage("mozVoikko.so path is %s", tmp.get());
371
baseDir->GetNativePath(tmp);
372
logMessage("mozVoikko.so directory is %s", tmp.get());
377
PreloadedLibraries::PreloadedLibraries(nsIFile *libDir, const char **names, unsigned numLibs) :
378
ok(false), numLibs(numLibs), libraries(NULL)
382
libraries = new PRLibrary *[numLibs];
386
memset(libraries, 0, sizeof(PRLibrary*)*numLibs);
388
for (unsigned i = 0; i < numLibs; i++)
391
nsCOMPtr<nsIFile> libFile;
394
rv = libDir->Clone(getter_AddRefs(libFile));
398
rv = libFile->AppendNative(nsCString(names[i]));
402
rv = libFile->GetNativePath(libPath);
406
rv = libFile->Exists(&exists);
412
libraries[i] = PR_LoadLibrary(libPath.get());
415
logMessage("mozVoikko: failed to load library %s: %s",
416
libPath.get(), prGetErrorText().get());
422
libraries[i] = nsnull;
425
logMessage("Loaded %s", libPath.get());
431
PreloadedLibraries::~PreloadedLibraries()
435
for (unsigned i = numLibs; i > 0; i--)
438
PR_UnloadLibrary(libraries[i-1]);