-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpcre_darwin.go
111 lines (87 loc) · 2.61 KB
/
pcre_darwin.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
// +build darwin !linux
package pcre
// #cgo LDFLAGS: -lpcre
// #include <pcre.h>
// #include <string.h>
//
// void call_pcre_free(void* ptr);
//
import "C"
import (
"errors"
"log"
"reflect"
"unsafe"
)
type PCREExtra C.struct_pcre_extra
func Study(code *PCRE, options Option, _ interface{}) (*PCREExtra, error) {
var errPtr *C.char
extra := C.pcre_study((*C.struct_real_pcre8_or_16)(code), C.int(options), &errPtr)
if errPtr != nil {
return nil, errors.New(C.GoString(errPtr))
}
return (*PCREExtra)(extra), nil
}
func (pcreExtra *PCREExtra) Free() { C.pcre_free_study((*C.struct_pcre_extra)(pcreExtra)) }
func (pcre *PCRE) Free() { C.call_pcre_free(unsafe.Pointer(pcre)) }
func (pcre *PCRE) Exec(extra interface{}, subject string, startOffset int, options Option, oVector []int) Error {
subjectCStr := C.CString(subject)
defer C.free(unsafe.Pointer(subjectCStr))
oVectorC := make([]C.int, len(oVector))
for n, i := range oVector {
oVectorC[n] = C.int(i)
}
var oVectorPtr *C.int
if len(oVector) > 0 {
oVectorPtr = &oVectorC[0]
}
r := C.pcre_exec((*C.struct_real_pcre8_or_16)(pcre), nil, subjectCStr, C.int(len(subject)), C.int(startOffset), C.int(options), oVectorPtr, C.int(len(oVector)))
for n, i := range oVectorC {
oVector[n] = int(i)
}
return Error(r)
}
func (pcre *PCRE) CaptureCount() int {
var i C.int
if rc := C.pcre_fullinfo((*C.struct_real_pcre8_or_16)(pcre), nil, InfoCaptureCount, unsafe.Pointer(&i)); rc != 0 {
log.Panicf("pcre_fullinfo: %v", rc)
}
return int(i)
}
func (pcre *PCRE) NameCount() int {
var i C.int
if rc := C.pcre_fullinfo((*C.struct_real_pcre8_or_16)(pcre), nil, InfoNameCount, unsafe.Pointer(&i)); rc != 0 {
log.Panicf("pcre_fullinfo: %v", rc)
}
return int(i)
}
func (pcre *PCRE) NameEntrySize() int {
var i C.int
if rc := C.pcre_fullinfo((*C.struct_real_pcre8_or_16)(pcre), nil, InfoNameEntrySize, unsafe.Pointer(&i)); rc != 0 {
log.Panicf("pcre_fullinfo: %v", rc)
}
return int(i)
}
func (pcre *PCRE) NameTable() []string {
names := make([]string, pcre.CaptureCount()+1)
if pcre.NameCount() == 0 {
return names
}
var dataPtr uintptr
if rc := C.pcre_fullinfo((*C.struct_real_pcre8_or_16)(pcre), nil, InfoNameTable, unsafe.Pointer(&dataPtr)); rc != 0 {
log.Panicf("pcre_fullinfo: %v", rc)
}
var data = *(*[]byte)(unsafe.Pointer(
&reflect.SliceHeader{
Data: dataPtr,
Len: pcre.NameCount() * pcre.NameEntrySize(),
Cap: pcre.NameCount() * pcre.NameEntrySize(),
}))
for i := 0; i < len(data); {
n := (int(data[i]) << 8) | int(data[i+1])
s := string(data[i+2 : i+pcre.NameEntrySize()-1])
names[n] = s
i += pcre.NameEntrySize()
}
return names
}