Recent

Author Topic: NHunspell and Lazarus  (Read 6514 times)

Espectr0

  • Full Member
  • ***
  • Posts: 235
NHunspell and Lazarus
« on: June 02, 2016, 04:56:55 pm »
Hello,
I need help with NHunspell and Lazarus, in Delphi below code works like a charm,
but in Lazarus get Empty string :S


Code: Pascal  [Select][+][-]
  1. HunspellSuggest : function(Handle: Pointer; const Word: PChar): Pointer; cdecl;
  2.  
Code: Pascal  [Select][+][-]
  1. var  s: PPChar;
  2. Suggests: TStrings
  3.  

Code: Pascal  [Select][+][-]
  1.     s := HunspellSuggest(FSpell, PChar('hello'));
  2.     while s^ <> NIL do
  3.     begin
  4.       Suggests.Add(s^);
  5.       Inc(s);
  6.     end;
  7.  

Maybe need a string conversion?

Thanks a lot!

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12645
  • FPC developer.
Re: NHunspell and Lazarus
« Reply #1 on: June 02, 2016, 06:03:32 pm »
Which delphi version? Did you check  if fspell has a correct value (iow that fspell was correctly loaded?)

A small mistake with working directory in a new environment might fail loading of dynamic libs.

Espectr0

  • Full Member
  • ***
  • Posts: 235
Re: NHunspell and Lazarus
« Reply #2 on: June 02, 2016, 06:59:27 pm »
Quote
Which delphi version? Did you check  if fspell has a correct value (iow that fspell was correctly loaded?)

Tested in Delphi 10 Seattle. Yes FSpell is loaded correctly.


Quote
A small mistake with working directory in a new environment might fail loading of dynamic libs

Yes, dll root is correctly too.


Any other tip?

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12645
  • FPC developer.
Re: NHunspell and Lazarus
« Reply #3 on: June 02, 2016, 07:13:06 pm »
Quote
Which delphi version? Did you check  if fspell has a correct value (iow that fspell was correctly loaded?)

Tested in Delphi 10 Seattle. Yes FSpell is loaded correctly.

Then that is your problem. Though FPC3+ has most of the types of D2009 and later, the base model is the same as before the breaking change of Delphi 2009 that made string equal to utf16.

So pchar is equal to pwidechar under delphi and equal to pansichar under FPC.   

There is a lot that can go wrong, but a first attempt in the good direction would be:

Code: [Select]
...
  suggests.add(pwidechar(s^));

Espectr0

  • Full Member
  • ***
  • Posts: 235
Re: NHunspell and Lazarus
« Reply #4 on: June 04, 2016, 01:30:05 pm »
No work :(

I try to change all to WideChar (also at Dictionary Init):

Code: Pascal  [Select][+][-]
  1. HunspellInit: function(const AffixBuffer: PWideChar; AffixBufferSize: Integer; const DictionaryBuffer: PWideChar; DictionaryBufferSize: Integer; key: PWideChar): Pointer; cdecl;
  2.  

maybe the problem can found here ?:

Code: Pascal  [Select][+][-]
  1. function LoadDictionary(const aff, dict: String): Boolean;
  2. var
  3.   tmpDictionary,
  4.   tmpAffix: TMemoryStream;
  5. begin
  6.   Result := False;
  7.   if not FileExists(aff) or not FileExists(dict) then Exit;
  8.  
  9.   tmpDictionary := TMemoryStream.Create;
  10.   try
  11.     tmpDictionary.LoadFromFile(dict);
  12.     tmpAffix := TMemoryStream.Create;
  13.     try
  14.       tmpAffix.LoadFromFile(aff);
  15.       if Assigned(HunspellInit) then
  16.         FSpell := HunspellInit(tmpAffix.Memory, tmpAffix.Size, tmpDictionary.Memory, tmpDictionary.Size, PWideChar(''));
  17.       Result := FSpell <> NIL;
  18.     finally
  19.       FreeAndNil(tmpAffix);
  20.     end;
  21.   finally
  22.     FreeAndNil(tmpDictionary);
  23.   end;
  24. end;
  25.  

Code: Pascal  [Select][+][-]
  1. function Suggest(const Text: String; var Suggests: TStrings): Boolean;
  2. var
  3.   s: PPWideChar;
  4. begin
  5.   if (Suggests = NIL) then Suggests := TStringList.Create;
  6.   Suggests.Clear;
  7.  
  8.   if Assigned(FSpell) and Assigned(HunspellSuggest) then
  9.   begin
  10.     s := HunspellSuggest(FSpell, PWideChar(Text));
  11.     while s^ <> NIL do
  12.     begin
  13.       Suggests.Add(s^);
  14.       Inc(s);
  15.     end;
  16.   end;
  17.  
  18.   Result := Suggests.Count > 0;
  19. end;
  20.  

In Delphi10 work perfectly, now in Lazarus using WideChar get some unknown words :S

Maybe I need used hunspell instead of net version (nhunspell)?

Thanks in advance!
« Last Edit: June 04, 2016, 01:50:50 pm by Espectr0 »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: NHunspell and Lazarus
« Reply #5 on: June 04, 2016, 02:20:37 pm »
Maybe I need used hunspell instead of net version (nhunspell)?
That might be a good idea in case you want things to start working ;-)

See also here.

In case it helps, wrapper for fpc here (haven't checked myself).
« Last Edit: June 04, 2016, 03:18:08 pm by molly »

Espectr0

  • Full Member
  • ***
  • Posts: 235
Re: NHunspell and Lazarus
« Reply #6 on: June 05, 2016, 02:14:40 pm »
I change to use Hunspell instead of NHunspell

Code: Pascal  [Select][+][-]
  1. function Suggest(const Text: String; var Suggests: TStrings): Boolean;
  2. var
  3.   l, i : Integer;
  4.   s    : PPChar;
  5. begin
  6.   if (Suggests = NIL) then Suggests := TStringList.Create;
  7.   Suggests.Clear;
  8.  
  9.   if Assigned(FSpell) and Assigned(hunspell_suggest) then
  10.   begin
  11.     l := hunspell_suggest(FSpell, PChar(Text), s);
  12.     for i := 1 to l do
  13.     begin
  14.       Suggests.Add(s^);
  15.       Inc(s);
  16.     end;
  17.     hunspell_suggest_free(FSpell, s, l);
  18.   end;
  19.  
  20.   Result := Suggests.Count > 0;
  21. end;
  22.  

All OK, except now I get an Access violation at line:

Code: Pascal  [Select][+][-]
  1. Inc(s);

why?

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: NHunspell and Lazarus
« Reply #7 on: June 06, 2016, 12:43:48 am »
All OK, except now I get an Access violation at line:

why?
According to its api documentation hunspell_suggest() returns the number of entries that are returned in the PPChar list.

So, in principle (but i have no idea which wrapper you use) you should be good to go ?

This small snippet works for me with using a simple API wrapper only.
Code: Pascal  [Select][+][-]
  1. procedure Test(Dictionary: Pointer);
  2. var
  3.   word_ok       : PChar;
  4.   word_notok    : PChar;
  5.   slist         : PPChar;
  6.   slist_size    : integer;
  7.   i             : integer;
  8. begin
  9.   word_ok    := 'hello';
  10.   word_notok := 'hilo';
  11.  
  12.   WriteLn('hunspell_spell(dictionary, word_ok)    = ', hunspell_spell(Dictionary, word_ok));
  13.   WriteLn('hunspell_spell(dictionary, word_notok) = ', hunspell_spell(Dictionary, word_notok));
  14.   WriteLn('hunspell_get_dic_encoding(dictionary)  = ', hunspell_get_dic_encoding(Dictionary));
  15.  
  16.   slist_size := hunspell_suggest(Dictionary, word_notok, slist);
  17.  
  18.   for i := 0 to Pred(slist_size) do
  19.     WriteLn('Suggestion[',i,'] = ', slist[i]);
  20.  
  21.   hunspell_suggest_free(Dictionary, slist, slist_size);
  22. end;
  23.  

« Last Edit: June 06, 2016, 12:48:32 am by molly »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12645
  • FPC developer.
Re: NHunspell and Lazarus
« Reply #8 on: June 06, 2016, 07:39:02 am »
Freeing s that has been advanced is a bit strange though. Pass the point to hunspell_suggests_free as you have gotten it. Make a copy to iterate.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: NHunspell and Lazarus
« Reply #9 on: June 06, 2016, 07:54:46 am »
Freeing s that has been advanced is a bit strange though. Pass the point to hunspell_suggests_free as you have gotten it. Make a copy to iterate.
I noticed this as well (hence why used an iterator in the example i showed) but using OP's snippet didn't caused any issues for me either and produced the same results as my snippet did.

Still, it is (like you said) wrong to do.

I suspect OP is using the Delphi wrapper found in the hunspell archives but as long as i can't be sure, there is no way of telling what goes wrong  :-\

I don't quite understand the use of WideChar pointers in another snippet OP showed, perhaps that can cause issues ?

Espectr0

  • Full Member
  • ***
  • Posts: 235
Re: NHunspell and Lazarus
« Reply #10 on: June 06, 2016, 12:43:38 pm »
is working now!

using:

  Suggests.Add(String(s));

instead of:

  Suggests.Add(s^);


Thanks to all!

 

TinyPortal © 2005-2018