1 #ifdef __cplusplus
2 extern "C" {
3 #endif
4 #include "EXTERN.h"
5 #include "perl.h"
6 #include "XSUB.h"
7 #include "patchlevel.h"
8 #ifdef __cplusplus
9 }
10 #endif
11
12 #include "apse.h"
13
14 #if PATCHLEVEL < 5
15 # define PL_na na
16 #endif
17
18 MODULE = String::Approx PACKAGE = String::Approx
19
20 PROTOTYPES: DISABLE
21
22 apse_t*
23 new(CLASS, pattern, ...)
24 char* CLASS
25 SV* pattern
26 CODE:
27 apse_t* ap;
28 apse_size_t edit_distance;
29 IV pattern_size = sv_len(pattern);
30 if (items == 2)
31 edit_distance = ((pattern_size-1)/10)+1;
32 else if (items == 3)
33 edit_distance = (apse_size_t)SvIV(ST(2));
34 else {
35 warn("Usage: new(pattern[, edit_distance])\n");
36 XSRETURN_UNDEF;
37 }
38 ap = apse_create((unsigned char *)SvPV(pattern, PL_na),
39 pattern_size, edit_distance);
40 if (ap) {
41 RETVAL = ap;
42 } else {
43 warn("unable to allocate");
44 XSRETURN_UNDEF;
45 }
46 OUTPUT:
47 RETVAL
48
49 void
50 DESTROY(ap)
51 apse_t* ap
52 CODE:
53 apse_destroy(ap);
54
55 apse_bool_t
56 match(ap, text)
57 apse_t* ap
58 SV* text
59 CODE:
60 RETVAL = apse_match(ap,
61 (unsigned char *)SvPV(text, PL_na),
62 sv_len(text));
63 OUTPUT:
64 RETVAL
65
66 apse_bool_t
67 match_next(ap, text)
68 apse_t* ap
69 SV* text
70 CODE:
71 RETVAL = apse_match_next(ap,
72 (unsigned char *)SvPV(text, PL_na),
73 sv_len(text));
74 OUTPUT:
75 RETVAL
76
77 apse_ssize_t
78 index(ap, text)
79 apse_t* ap
80 SV* text
81 CODE:
82 RETVAL = apse_index(ap,
83 (unsigned char *)SvPV(text, PL_na),
84 sv_len(text));
85 OUTPUT:
86 RETVAL
87
88 void
slice(ap,text)89 slice(ap, text)
90 apse_t* ap
91 SV* text
92 PREINIT:
93 apse_size_t match_begin;
94 apse_size_t match_size;
95 PPCODE:
96 if (ap->use_minimal_distance) {
97 apse_slice(ap,
98 (unsigned char *)SvPV(text, PL_na),
99 (apse_size_t)sv_len(text),
100 &match_begin,
101 &match_size);
102 EXTEND(sp, 3);
103 PUSHs(sv_2mortal(newSViv(match_begin)));
104 PUSHs(sv_2mortal(newSViv(match_size)));
105 PUSHs(sv_2mortal(newSViv(ap->edit_distance)));
106 } else if (apse_slice(ap,
107 (unsigned char *)SvPV(text, PL_na),
108 (apse_size_t)sv_len(text),
109 &match_begin,
110 &match_size)) {
111 EXTEND(sp, 2);
112 PUSHs(sv_2mortal(newSViv(match_begin)));
113 PUSHs(sv_2mortal(newSViv(match_size)));
114 }
115
116 void
slice_next(ap,text)117 slice_next(ap, text)
118 apse_t* ap
119 SV* text
120 PREINIT:
121 apse_size_t match_begin;
122 apse_size_t match_size;
123 PPCODE:
124 if (apse_slice_next(ap,
125 (unsigned char *)SvPV(text, PL_na),
126 sv_len(text),
127 &match_begin,
128 &match_size)) {
129 EXTEND(sp, 2);
130 PUSHs(sv_2mortal(newSViv(match_begin)));
131 PUSHs(sv_2mortal(newSViv(match_size)));
132 if (ap->use_minimal_distance) {
133 EXTEND(sp, 1);
134 PUSHs(sv_2mortal(newSViv(ap->edit_distance)));
135 }
136 }
137
138 void
139 set_greedy(ap)
140 apse_t* ap
141 CODE:
142 apse_set_greedy(ap, 1);
143
144 apse_bool_t
145 set_caseignore_slice(ap, ...)
146 apse_t* ap
147 PREINIT:
148 apse_size_t offset;
149 apse_size_t size;
150 apse_bool_t ignore;
151 CODE:
152 offset = items < 2 ? 0 : (apse_size_t)SvIV(ST(1));
153 size = items < 3 ? ap->pattern_size : (apse_size_t)SvIV(ST(2));
154 ignore = items < 4 ? 1 : (apse_bool_t)SvIV(ST(3));
155 RETVAL = apse_set_caseignore_slice(ap, offset, size, ignore);
156 OUTPUT:
157 RETVAL
158
159 apse_bool_t
160 set_insertions(ap, insertions)
161 apse_t* ap
162 apse_size_t insertions = SvUV($arg);
163 CODE:
164 RETVAL = apse_set_insertions(ap, insertions);
165 OUTPUT:
166 RETVAL
167
168 apse_bool_t
169 set_deletions(ap, deletions)
170 apse_t* ap
171 apse_size_t deletions = SvUV($arg);
172 CODE:
173 RETVAL = apse_set_deletions(ap, deletions);
174 OUTPUT:
175 RETVAL
176
177 apse_bool_t
178 set_substitutions(ap, substitutions)
179 apse_t* ap
180 apse_size_t substitutions = SvUV($arg);
181 CODE:
182 RETVAL = apse_set_substitutions(ap, substitutions);
183 OUTPUT:
184 RETVAL
185
186 apse_bool_t
187 set_edit_distance(ap, edit_distance)
188 apse_t* ap
189 apse_size_t edit_distance = SvUV($arg);
190 CODE:
191 RETVAL = apse_set_edit_distance(ap, edit_distance);
192 OUTPUT:
193 RETVAL
194
195 apse_size_t
196 get_edit_distance(ap)
197 apse_t* ap
198 CODE:
199 ST(0) = sv_newmortal();
200 sv_setiv(ST(0), apse_get_edit_distance(ap));
201
202 apse_bool_t
203 set_text_initial_position(ap, text_initial_position)
204 apse_t* ap
205 apse_size_t text_initial_position = SvUV($arg);
206 CODE:
207 RETVAL = apse_set_text_initial_position(ap, text_initial_position);
208 OUTPUT:
209 RETVAL
210
211 apse_bool_t
212 set_text_final_position(ap, text_final_position)
213 apse_t* ap
214 apse_size_t text_final_position = SvUV($arg);
215 CODE:
216 RETVAL = apse_set_text_final_position(ap, text_final_position);
217 OUTPUT:
218 RETVAL
219
220 apse_bool_t
221 set_text_position_range(ap, text_position_range)
222 apse_t* ap
223 apse_size_t text_position_range = SvUV($arg);
224 CODE:
225 RETVAL = apse_set_text_position_range(ap, text_position_range);
226 OUTPUT:
227 RETVAL
228
229 void
230 set_minimal_distance(ap, b)
231 apse_t* ap
232 apse_bool_t b
233 CODE:
234 apse_set_minimal_distance(ap, b);
235