|
a/src/aspell/rclaspell.cpp |
|
b/src/aspell/rclaspell.cpp |
|
... |
|
... |
21 |
|
21 |
|
22 |
#ifdef RCL_USE_ASPELL
|
22 |
#ifdef RCL_USE_ASPELL
|
23 |
|
23 |
|
24 |
#include <unistd.h>
|
24 |
#include <unistd.h>
|
25 |
#include <dlfcn.h>
|
25 |
#include <dlfcn.h>
|
26 |
#include <iostream>
|
|
|
27 |
#include <stdlib.h>
|
26 |
#include <stdlib.h>
|
28 |
#include <vector>
|
27 |
|
|
|
28 |
using namespace std;
|
29 |
|
29 |
|
30 |
#include ASPELL_INCLUDE
|
30 |
#include ASPELL_INCLUDE
|
31 |
|
31 |
|
32 |
#include "pathut.h"
|
32 |
#include "pathut.h"
|
33 |
#include "execmd.h"
|
33 |
#include "execmd.h"
|
34 |
#include "rclaspell.h"
|
34 |
#include "rclaspell.h"
|
35 |
#include "debuglog.h"
|
35 |
#include "debuglog.h"
|
36 |
|
36 |
#include "unacpp.h"
|
37 |
#include "ptmutex.h"
|
37 |
#include "ptmutex.h"
|
38 |
|
38 |
|
39 |
// Just a place where we keep the Aspell library entry points together
|
39 |
// Just a place where we keep the Aspell library entry points together
|
40 |
class AspellApi {
|
40 |
class AspellApi {
|
41 |
public:
|
41 |
public:
|
|
... |
|
... |
258 |
{}
|
258 |
{}
|
259 |
void newData() {
|
259 |
void newData() {
|
260 |
while (m_db.termWalkNext(m_tit, *m_input)) {
|
260 |
while (m_db.termWalkNext(m_tit, *m_input)) {
|
261 |
if (!Rcl::Db::isSpellingCandidate(*m_input))
|
261 |
if (!Rcl::Db::isSpellingCandidate(*m_input))
|
262 |
continue;
|
262 |
continue;
|
|
|
263 |
#ifndef RCL_INDEX_STRIPCHARS
|
|
|
264 |
if (!o_index_stripchars) {
|
|
|
265 |
string lower;
|
|
|
266 |
if (!unacmaybefold(*m_input, lower, "UTF-8", UNACOP_FOLD))
|
|
|
267 |
continue;
|
|
|
268 |
m_input->swap(lower);
|
|
|
269 |
}
|
|
|
270 |
#endif
|
263 |
// Got a non-empty sort-of appropriate term, let's send it to
|
271 |
// Got a non-empty sort-of appropriate term, let's send it to
|
264 |
// aspell
|
272 |
// aspell
|
|
|
273 |
LOGDEB2(("ASpExecPv: [%s]\n", m_input->c_str()));
|
265 |
m_input->append("\n");
|
274 |
m_input->append("\n");
|
266 |
return;
|
275 |
return;
|
267 |
}
|
276 |
}
|
268 |
// End of data. Tell so. Exec will close cmd.
|
277 |
// End of data. Tell so. Exec will close cmd.
|
269 |
m_input->erase();
|
278 |
m_input->erase();
|
|
... |
|
... |
333 |
}
|
342 |
}
|
334 |
m_data->m_speller = aapi.to_aspell_speller(ret);
|
343 |
m_data->m_speller = aapi.to_aspell_speller(ret);
|
335 |
return true;
|
344 |
return true;
|
336 |
}
|
345 |
}
|
337 |
|
346 |
|
338 |
bool Aspell::check(Rcl::Db &db, const string &term, string& reason)
|
347 |
bool Aspell::check(const string &iterm, string& reason)
|
339 |
{
|
348 |
{
|
340 |
LOGDEB2(("Aspell::check [%s]\n", term.c_str()));
|
349 |
LOGDEB2(("Aspell::check [%s]\n", iterm.c_str()));
|
|
|
350 |
string mterm(iterm);
|
341 |
|
351 |
|
342 |
if (!ok() || !make_speller(reason))
|
352 |
if (!ok() || !make_speller(reason))
|
343 |
return false;
|
353 |
return false;
|
344 |
if (term.empty())
|
354 |
if (iterm.empty())
|
345 |
return true; //??
|
355 |
return true; //??
|
346 |
|
356 |
|
|
|
357 |
#ifndef RCL_INDEX_STRIPCHARS
|
|
|
358 |
if (!o_index_stripchars) {
|
|
|
359 |
string lower;
|
|
|
360 |
if (!unacmaybefold(mterm, lower, "UTF-8", UNACOP_FOLD)) {
|
|
|
361 |
LOGERR(("Aspell::check : cant lowercase input\n"));
|
|
|
362 |
return false;
|
|
|
363 |
}
|
|
|
364 |
mterm.swap(lower);
|
|
|
365 |
}
|
|
|
366 |
#endif
|
|
|
367 |
|
347 |
int ret = aapi.aspell_speller_check(m_data->m_speller,
|
368 |
int ret = aapi.aspell_speller_check(m_data->m_speller,
|
348 |
term.c_str(), term.length());
|
369 |
mterm.c_str(), mterm.length());
|
349 |
reason.clear();
|
370 |
reason.clear();
|
350 |
switch (ret) {
|
371 |
switch (ret) {
|
351 |
case 0: return false;
|
372 |
case 0: return false;
|
352 |
case 1: return true;
|
373 |
case 1: return true;
|
353 |
default:
|
374 |
default:
|
|
... |
|
... |
356 |
reason.append(aapi.aspell_speller_error_message(m_data->m_speller));
|
377 |
reason.append(aapi.aspell_speller_error_message(m_data->m_speller));
|
357 |
return false;
|
378 |
return false;
|
358 |
}
|
379 |
}
|
359 |
}
|
380 |
}
|
360 |
|
381 |
|
361 |
bool Aspell::suggest(Rcl::Db &db, const string &term,
|
382 |
bool Aspell::suggest(Rcl::Db &db, const string &_term,
|
362 |
list<string>& suggestions, string& reason)
|
383 |
list<string>& suggestions, string& reason)
|
363 |
{
|
384 |
{
|
364 |
if (!ok() || !make_speller(reason))
|
385 |
if (!ok() || !make_speller(reason))
|
365 |
return false;
|
386 |
return false;
|
|
|
387 |
string mterm(_term);
|
366 |
if (term.empty())
|
388 |
if (mterm.empty())
|
367 |
return true; //??
|
389 |
return true; //??
|
|
|
390 |
|
|
|
391 |
#ifndef RCL_INDEX_STRIPCHARS
|
|
|
392 |
if (!o_index_stripchars) {
|
|
|
393 |
string lower;
|
|
|
394 |
if (!unacmaybefold(mterm, lower, "UTF-8", UNACOP_FOLD)) {
|
|
|
395 |
LOGERR(("Aspell::check : cant lowercase input\n"));
|
|
|
396 |
return false;
|
|
|
397 |
}
|
|
|
398 |
mterm.swap(lower);
|
|
|
399 |
}
|
|
|
400 |
#endif
|
368 |
|
401 |
|
369 |
AspellCanHaveError *ret;
|
402 |
AspellCanHaveError *ret;
|
370 |
|
403 |
|
371 |
const AspellWordList *wl =
|
404 |
const AspellWordList *wl =
|
372 |
aapi.aspell_speller_suggest(m_data->m_speller,
|
405 |
aapi.aspell_speller_suggest(m_data->m_speller,
|
373 |
term.c_str(), term.length());
|
406 |
mterm.c_str(), mterm.length());
|
374 |
if (wl == 0) {
|
407 |
if (wl == 0) {
|
375 |
reason = aapi.aspell_speller_error_message(m_data->m_speller);
|
408 |
reason = aapi.aspell_speller_error_message(m_data->m_speller);
|
376 |
return false;
|
409 |
return false;
|
377 |
}
|
410 |
}
|
378 |
AspellStringEnumeration *els = aapi.aspell_word_list_elements(wl);
|
411 |
AspellStringEnumeration *els = aapi.aspell_word_list_elements(wl);
|
|
... |
|
... |
383 |
// and that it stems differently to the base word (else it's not
|
416 |
// and that it stems differently to the base word (else it's not
|
384 |
// useful to expand the search). Or is it ?
|
417 |
// useful to expand the search). Or is it ?
|
385 |
// ******** This should depend if
|
418 |
// ******** This should depend if
|
386 |
// stemming is turned on or not for querying *******
|
419 |
// stemming is turned on or not for querying *******
|
387 |
string sw(word);
|
420 |
string sw(word);
|
388 |
if (db.termExists(sw) && db.stemDiffers("english", sw, term))
|
421 |
if (db.termExists(sw) && db.stemDiffers("english", sw, mterm))
|
389 |
suggestions.push_back(word);
|
422 |
suggestions.push_back(word);
|
390 |
}
|
423 |
}
|
391 |
aapi.delete_aspell_string_enumeration(els);
|
424 |
aapi.delete_aspell_string_enumeration(els);
|
392 |
return true;
|
425 |
return true;
|
393 |
}
|
426 |
}
|
|
... |
|
... |
416 |
#include "rcldb.h"
|
449 |
#include "rcldb.h"
|
417 |
#include "rclaspell.h"
|
450 |
#include "rclaspell.h"
|
418 |
|
451 |
|
419 |
static char *thisprog;
|
452 |
static char *thisprog;
|
420 |
RclConfig *rclconfig;
|
453 |
RclConfig *rclconfig;
|
421 |
Rcl::Db rcldb;
|
|
|
422 |
|
454 |
|
423 |
static char usage [] =
|
455 |
static char usage [] =
|
424 |
" -b : build dictionary\n"
|
456 |
" -b : build dictionary\n"
|
425 |
" -s <term>: suggestions for term\n"
|
457 |
" -s <term>: suggestions for term\n"
|
|
|
458 |
" -c <term>: check term\n"
|
426 |
"\n\n"
|
459 |
"\n"
|
427 |
;
|
460 |
;
|
428 |
static void
|
461 |
static void
|
429 |
Usage(void)
|
462 |
Usage(void)
|
430 |
{
|
463 |
{
|
431 |
fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
|
464 |
fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
|
|
... |
|
... |
434 |
|
467 |
|
435 |
static int op_flags;
|
468 |
static int op_flags;
|
436 |
#define OPT_MOINS 0x1
|
469 |
#define OPT_MOINS 0x1
|
437 |
#define OPT_s 0x2
|
470 |
#define OPT_s 0x2
|
438 |
#define OPT_b 0x4
|
471 |
#define OPT_b 0x4
|
|
|
472 |
#define OPT_c 0x8
|
439 |
|
473 |
|
440 |
int main(int argc, char **argv)
|
474 |
int main(int argc, char **argv)
|
441 |
{
|
475 |
{
|
442 |
string word;
|
476 |
string word;
|
443 |
|
477 |
|
|
... |
|
... |
450 |
/* Cas du "adb - core" */
|
484 |
/* Cas du "adb - core" */
|
451 |
Usage();
|
485 |
Usage();
|
452 |
while (**argv)
|
486 |
while (**argv)
|
453 |
switch (*(*argv)++) {
|
487 |
switch (*(*argv)++) {
|
454 |
case 'b': op_flags |= OPT_b; break;
|
488 |
case 'b': op_flags |= OPT_b; break;
|
|
|
489 |
case 'c': op_flags |= OPT_c; if (argc < 2) Usage();
|
|
|
490 |
word = *(++argv);
|
|
|
491 |
argc--;
|
|
|
492 |
goto b1;
|
455 |
case 's': op_flags |= OPT_s; if (argc < 2) Usage();
|
493 |
case 's': op_flags |= OPT_s; if (argc < 2) Usage();
|
456 |
word = *(++argv);
|
494 |
word = *(++argv);
|
457 |
argc--;
|
495 |
argc--;
|
458 |
goto b1;
|
496 |
goto b1;
|
459 |
default: Usage(); break;
|
497 |
default: Usage(); break;
|
|
... |
|
... |
475 |
if (dbdir.empty()) {
|
513 |
if (dbdir.empty()) {
|
476 |
fprintf(stderr, "No db directory in configuration");
|
514 |
fprintf(stderr, "No db directory in configuration");
|
477 |
exit(1);
|
515 |
exit(1);
|
478 |
}
|
516 |
}
|
479 |
|
517 |
|
|
|
518 |
Rcl::Db rcldb(rclconfig);
|
|
|
519 |
|
480 |
if (!rcldb.open(dbdir, Rcl::Db::DbRO, 0)) {
|
520 |
if (!rcldb.open(Rcl::Db::DbRO, 0)) {
|
481 |
fprintf(stderr, "Could not open database in %s\n", dbdir.c_str());
|
521 |
fprintf(stderr, "Could not open database in %s\n", dbdir.c_str());
|
482 |
exit(1);
|
522 |
exit(1);
|
483 |
}
|
523 |
}
|
484 |
|
524 |
|
485 |
Aspell aspell(rclconfig);
|
525 |
Aspell aspell(rclconfig);
|
|
... |
|
... |
490 |
}
|
530 |
}
|
491 |
if (op_flags & OPT_b) {
|
531 |
if (op_flags & OPT_b) {
|
492 |
if (!aspell.buildDict(rcldb, reason)) {
|
532 |
if (!aspell.buildDict(rcldb, reason)) {
|
493 |
cerr << "buildDict failed: " << reason << endl;
|
533 |
cerr << "buildDict failed: " << reason << endl;
|
494 |
exit(1);
|
534 |
exit(1);
|
|
|
535 |
}
|
|
|
536 |
} else if (op_flags & OPT_c) {
|
|
|
537 |
bool ret = aspell.check(word, reason);
|
|
|
538 |
if (!ret && reason.size()) {
|
|
|
539 |
cerr << "Aspell error: " << reason << endl;
|
|
|
540 |
return 1;
|
|
|
541 |
}
|
|
|
542 |
cout << word;
|
|
|
543 |
if (ret) {
|
|
|
544 |
cout << " is in dictionary" << endl;
|
|
|
545 |
} else {
|
|
|
546 |
cout << " not in dictionary" << endl;
|
495 |
}
|
547 |
}
|
496 |
} else {
|
548 |
} else {
|
497 |
list<string> suggs;
|
549 |
list<string> suggs;
|
498 |
if (!aspell.suggest(rcldb, word, suggs, reason)) {
|
550 |
if (!aspell.suggest(rcldb, word, suggs, reason)) {
|
499 |
cerr << "suggest failed: " << reason << endl;
|
551 |
cerr << "suggest failed: " << reason << endl;
|