File Coverage

Fuzzy.xs
Criterion Covered Total %
statement 55 68 80.8
branch 61 268 22.7
condition n/a
subroutine n/a
pod n/a
total 116 336 34.5


line stmt bran cond sub pod time code
1             #include
2              
3             #include "EXTERN.h"
4             #include "perl.h"
5             #include "XSUB.h"
6             #include "ppport.h"
7              
8             #define ERROR_HANDLER perl_error_handler
9             #define TEXT_FUZZY_USER_ERROR tfp_text_fuzzy_error
10              
11             #include "config.h"
12             #define PERL_MEMORY_MANAGEMENT
13             #include "text-fuzzy-single.c"
14             #include "text-fuzzy-perl.c"
15              
16             #undef TEXT_FUZZY_USER_ERROR
17             #define TEXT_FUZZY_USER_ERROR
18              
19             typedef text_fuzzy_t * Text__Fuzzy;
20              
21             MODULE=Text::Fuzzy PACKAGE=Text::Fuzzy
22              
23             PROTOTYPES: ENABLE
24              
25             BOOT:
26             /* Set the error handler in "text-fuzzy.c" to be the error
27             handler defined in "text-fuzzy-perl.c". */
28              
29 12           text_fuzzy_error_handler = perl_error_handler;
30              
31              
32             Text::Fuzzy
33             new (class, search_term, ...)
34             const char * class;
35             SV * search_term;
36             PREINIT:
37             int i;
38             text_fuzzy_t * r;
39             CODE:
40 43           r = 0;
41              
42 43           sv_to_text_fuzzy (search_term, & r);
43              
44 43 50         if (! r) {
45 0           croak ("error making %s.\n", class);
46             }
47              
48             /* Loop over the parameters in "...". The first two terms are
49             "class" and "search_term", so we start from 2 here. */
50              
51 70 100         for (i = 2; i < items; i++) {
52             SV * x;
53             const char * p;
54             STRLEN len;
55              
56 27 50         if (i >= items - 1) {
57 0           warn ("Odd number of parameters %d of %d",
58             i, (int) items);
59 0           break;
60             }
61              
62             /* Read in parameters in the "form max => 22",
63             "no_exact => 1", etc. */
64              
65 27           x = ST (i);
66 27 50         p = (char *) SvPV (x, len);
67 27 100         if (strncmp (p, "max", strlen ("max")) == 0) {
68             int max;
69 4 50         max = SvIV (ST (i + 1));
70 4 50         if (max < 0) {
71 0 0         TEXT_FUZZY (set_max_distance (r, NO_MAX_DISTANCE));
72             }
73             else {
74 4 50         TEXT_FUZZY (set_max_distance (r, max));
75             }
76             }
77 23 50         else if (strncmp (p, "no_exact", strlen ("no_exact")) == 0) {
78 0 0         r->no_exact = SvTRUE (ST (i + 1)) ? 1 : 0;
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
79             }
80 23 50         else if (strncmp (p, "trans", strlen ("trans")) == 0) {
81 23 50         r->transpositions_ok = SvTRUE (ST (i + 1)) ? 1 : 0;
    50          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    0          
82             }
83             else {
84 0           warn ("Unknown parameter %s", p);
85             }
86 27           i++;
87             }
88 43           RETVAL = r;
89             OUTPUT:
90             RETVAL
91              
92             SV *
93             get_max_distance (tf)
94             Text::Fuzzy tf;
95             PREINIT:
96             int maximum;
97             CODE:
98 7 50         TEXT_FUZZY (get_max_distance (tf, & maximum));
99 7 100         if (maximum >= 0) {
100 3           RETVAL = newSViv (maximum);
101             }
102             else {
103 4           RETVAL = &PL_sv_undef;
104             }
105             OUTPUT:
106             RETVAL
107              
108             void
109             set_max_distance (tf, max_distance = &PL_sv_undef)
110             Text::Fuzzy tf;
111             SV * max_distance;
112             PREINIT:
113             int maximum;
114             CODE:
115             /* Set the maximum distance to "none". */
116              
117 8           maximum = NO_MAX_DISTANCE;
118 8 100         if (SvOK (max_distance)) {
    50          
    50          
119 6 50         maximum = (int) SvIV (max_distance);
120 6 50         if (maximum < 0) {
121 0           maximum = NO_MAX_DISTANCE;
122             }
123             }
124 8 50         TEXT_FUZZY (set_max_distance (tf, maximum));
125              
126             void
127             transpositions_ok (tf, trans)
128             Text::Fuzzy tf;
129             SV * trans;
130             CODE:
131 6 50         if (SvTRUE (trans)) {
    50          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
132 3 50         TEXT_FUZZY (set_transpositions (tf, 1));
133             }
134             else {
135 3 50         TEXT_FUZZY (set_transpositions (tf, 0));
136             }
137              
138             int
139             get_trans (tf)
140             Text::Fuzzy tf;
141             CODE:
142 1 50         TEXT_FUZZY (get_transpositions (tf, & RETVAL));
143             OUTPUT:
144             RETVAL
145              
146             int
147             distance (tf, word)
148             Text::Fuzzy tf;
149             SV * word;
150             CODE:
151 42           RETVAL = text_fuzzy_sv_distance (tf, word);
152             OUTPUT:
153             RETVAL
154              
155              
156             void
157             nearest (tf, words)
158             Text::Fuzzy tf;
159             AV * words;
160             PREINIT:
161             int i;
162             int n;
163             AV * wantarray;
164             PPCODE:
165              
166 17           wantarray = 0;
167              
168 17 50         if (GIMME_V == G_ARRAY) {
    100          
169              
170             /* The user wants an array containing all of the
171             nearest values. */
172              
173 5           wantarray = newAV ();
174             /* Free the array */
175 5           sv_2mortal ((SV *) wantarray);
176 5           n = text_fuzzy_av_distance (tf, words, wantarray);
177             }
178             else {
179             /* Even in void context, we still do the search, in
180             case the user just wants to know the minimum
181             distance and ignores the actual values. */
182              
183 12           n = text_fuzzy_av_distance (tf, words, 0);
184             }
185              
186 17 100         if (wantarray) {
187             SV * e;
188 5           int wasize = av_len (wantarray) + 1;
189 5 50         EXTEND (SP, wasize);
    50          
190 15 100         for (i = 0; i < wasize; i++) {
191 10           e = * av_fetch (wantarray, i, 0);
192 10           SvREFCNT_inc_simple_void_NN (e);
193 10           PUSHs (sv_2mortal (e));
194             }
195             }
196             else {
197 12 100         if (n >= 0) {
198 8           PUSHs (sv_2mortal (newSViv (n)));
199             }
200             else {
201 4           PUSHs (& PL_sv_undef);
202             }
203             }
204              
205              
206             int
207             last_distance (tf)
208             Text::Fuzzy tf;
209             CODE:
210 4 50         TEXT_FUZZY (last_distance (tf, & RETVAL));
211             OUTPUT:
212             RETVAL
213              
214              
215             SV *
216             unicode_length (tf)
217             Text::Fuzzy tf;
218             PREINIT:
219             int unicode_length;
220             CODE:
221 2 50         TEXT_FUZZY (get_unicode_length (tf, & unicode_length));
222 2 50         if (unicode_length == TEXT_FUZZY_INVALID_UNICODE_LENGTH) {
223 0           RETVAL = &PL_sv_undef;
224             }
225             else {
226 2           RETVAL = newSViv (tf->text.ulength);
227             }
228             OUTPUT:
229             RETVAL
230              
231              
232             void
233             no_alphabet (tf, yes_no)
234             Text::Fuzzy tf;
235             SV * yes_no;
236             CODE:
237 0 0         TEXT_FUZZY (no_alphabet (tf, SvTRUE (yes_no)));
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
238              
239              
240             int
241             ualphabet_rejections (tf)
242             Text::Fuzzy tf;
243             CODE:
244 2 50         TEXT_FUZZY (ualphabet_rejections (tf, & RETVAL));
245             OUTPUT:
246             RETVAL
247              
248              
249             int
250             length_rejections (tf)
251             Text::Fuzzy tf;
252             CODE:
253 2 50         TEXT_FUZZY (get_length_rejections (tf, & RETVAL));
254             OUTPUT:
255             RETVAL
256              
257              
258             SV *
259             scan_file (tf, file_name)
260             Text::Fuzzy tf;
261             char * file_name;
262             PREINIT:
263             char * nearest;
264             int nearest_length;
265             CODE:
266 0 0         TEXT_FUZZY (scan_file (tf, file_name, & nearest, & nearest_length));
267 0           RETVAL = newSVpv (nearest, (STRLEN) nearest_length);
268 0 0         TEXT_FUZZY (scan_file_free (nearest));
269             OUTPUT:
270             RETVAL
271              
272              
273             void
274             no_exact (tf, yes_no)
275             Text::Fuzzy tf;
276             SV * yes_no;
277             CODE:
278 0 0         TEXT_FUZZY (set_no_exact (tf, SvTRUE (yes_no)));
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
279              
280             int
281             alphabet_rejections (tf)
282             Text::Fuzzy tf;
283             CODE:
284 2 50         TEXT_FUZZY (alphabet_rejections (tf, & RETVAL));
285             OUTPUT:
286             RETVAL
287              
288             void
289             DESTROY (tf)
290             Text::Fuzzy tf;
291             CODE:
292 43           text_fuzzy_free (tf);
293