-
Notifications
You must be signed in to change notification settings - Fork 3
/
hunspell.go
120 lines (92 loc) · 2.66 KB
/
hunspell.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Forked from https://github.com/akhenakh/hunspellgo
package hunspell
// #cgo linux LDFLAGS: -lhunspell
// #cgo darwin LDFLAGS: -lhunspell-1.3 -L/usr/local/Cellar/hunspell/1.3.2/lib
// #cgo darwin CFLAGS: -I/usr/local/Cellar/hunspell/1.3.2/include
// #cgo freebsd CFLAGS: -I/usr/local/include
// #cgo freebsd LDFLAGS: -L/usr/local/lib -lhunspell-1.3
//
// #include <stdlib.h>
// #include <stdio.h>
// #include <hunspell/hunspell.h>
import "C"
import (
"sync"
"unsafe"
"reflect"
"runtime"
)
type Hunhandle struct {
handle *C.Hunhandle
lock *sync.Mutex
}
func Hunspell(affpath string, dpath string) *Hunhandle {
affpathcs := C.CString(affpath)
defer C.free(unsafe.Pointer(affpathcs))
dpathcs := C.CString(dpath)
defer C.free(unsafe.Pointer(dpathcs))
h := &Hunhandle{lock: new(sync.Mutex)}
h.handle = C.Hunspell_create(affpathcs, dpathcs)
runtime.SetFinalizer(h, func(handle *Hunhandle) {
C.Hunspell_destroy(handle.handle)
h.handle = nil
})
return h
}
func CArrayToString(c **C.char, l int) []string {
s := []string{}
hdr := reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(c)),
Len: l,
Cap: l,
}
for _, v := range *(*[]*C.char)(unsafe.Pointer(&hdr)) {
s = append(s, C.GoString(v))
}
return s
}
func (handle *Hunhandle) Suggest(word string) []string {
wordcs := C.CString(word)
defer C.free(unsafe.Pointer(wordcs))
var carray **C.char
var length C.int
handle.lock.Lock()
length = C.Hunspell_suggest(handle.handle, &carray, wordcs)
handle.lock.Unlock()
words := CArrayToString(carray, int(length))
C.Hunspell_free_list(handle.handle, &carray, length)
return words
}
func (handle *Hunhandle) Add(word string) bool {
cWord := C.CString(word)
defer C.free(unsafe.Pointer(cWord))
var r C.int
r = C.Hunspell_add(handle.handle, cWord)
if int(r) != 0 {
return false
}
return true
}
func (handle *Hunhandle) Stem(word string) []string {
wordcs := C.CString(word)
defer C.free(unsafe.Pointer(wordcs))
var carray **C.char
var length C.int
handle.lock.Lock()
length = C.Hunspell_stem(handle.handle, &carray, wordcs)
handle.lock.Unlock()
words := CArrayToString(carray, int(length))
C.Hunspell_free_list(handle.handle, &carray, length)
return words
}
func (handle *Hunhandle) Spell(word string) bool {
wordcs := C.CString(word)
defer C.free(unsafe.Pointer(wordcs))
handle.lock.Lock()
res := C.Hunspell_spell(handle.handle, wordcs)
handle.lock.Unlock()
if int(res) == 0 {
return false
}
return true
}