File Coverage

lib/Eshu.xs
Criterion Covered Total %
statement 194 222 87.3
branch 198 366 54.1
condition n/a
subroutine n/a
pod n/a
total 392 588 66.6


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #include "eshu.h"
7             #include "eshu_c.h"
8             #include "eshu_pl.h"
9             #include "eshu_xs.h"
10             #include "eshu_xml.h"
11             #include "eshu_css.h"
12              
13             MODULE = Eshu PACKAGE = Eshu
14              
15             PROTOTYPES: DISABLE
16              
17             SV *
18             detect_lang(class, filename_sv)
19             SV * class
20             SV * filename_sv
21             CODE:
22             {
23             const char *filename;
24             const char *dot;
25             STRLEN len;
26              
27             PERL_UNUSED_VAR(class);
28 67           RETVAL = &PL_sv_undef;
29              
30 67 50         if (SvOK(filename_sv)) {
31 67           filename = SvPV(filename_sv, len);
32 67           dot = NULL;
33             /* find last dot */
34             {
35 67           const char *p = filename + len;
36 218 100         while (p > filename) {
37 217           p--;
38 217 100         if (*p == '.') { dot = p + 1; break; }
39             }
40             }
41 67 100         if (dot) {
42 66           STRLEN ext_len = (filename + len) - dot;
43 66 100         if ((ext_len == 1 && (dot[0] == 'c' || dot[0] == 'C'))
    100          
    50          
44 55 100         || (ext_len == 1 && (dot[0] == 'h' || dot[0] == 'H'))) {
    100          
    50          
45 12           RETVAL = newSVpvs("c");
46 54 100         } else if (ext_len == 2
47 36 100         && (dot[0] == 'x' || dot[0] == 'X')
    50          
48 1 50         && (dot[1] == 's' || dot[1] == 'S')) {
    0          
49 1           RETVAL = newSVpvs("xs");
50 53 100         } else if ((ext_len == 2
51 35 100         && (dot[0] == 'p' || dot[0] == 'P')
    50          
52 33 100         && (dot[1] == 'l' || dot[1] == 'L'))
    50          
53 47 100         || (ext_len == 2
54 29 100         && (dot[0] == 'p' || dot[0] == 'P')
    50          
55 27 50         && (dot[1] == 'm' || dot[1] == 'M'))
    0          
56 20 100         || (ext_len == 1
57 1 50         && (dot[0] == 't' || dot[0] == 'T'))) {
    0          
58 34           RETVAL = newSVpvs("perl");
59 19 100         } else if ((ext_len == 3
60 11 100         && (dot[0] == 'x' || dot[0] == 'X')
    50          
61 3 100         && (dot[1] == 'm' || dot[1] == 'M')
    50          
62 2 50         && (dot[2] == 'l' || dot[2] == 'L'))
    0          
63 17 100         || (ext_len == 3
64 9 100         && (dot[0] == 'x' || dot[0] == 'X')
    50          
65 1 50         && (dot[1] == 's' || dot[1] == 'S')
    0          
66 1 50         && (dot[2] == 'l' || dot[2] == 'L'))
    0          
67 16 100         || (ext_len == 4
68 5 100         && (dot[0] == 'x' || dot[0] == 'X')
    50          
69 1 50         && (dot[1] == 's' || dot[1] == 'S')
    0          
70 1 50         && (dot[2] == 'l' || dot[2] == 'L')
    0          
71 1 50         && (dot[3] == 't' || dot[3] == 'T'))
    0          
72 15 100         || (ext_len == 3
73 8 100         && (dot[0] == 's' || dot[0] == 'S')
    50          
74 1 50         && (dot[1] == 'v' || dot[1] == 'V')
    0          
75 1 50         && (dot[2] == 'g' || dot[2] == 'G'))
    0          
76 14 100         || (ext_len == 5
77 1 50         && (dot[0] == 'x' || dot[0] == 'X')
    0          
78 1 50         && (dot[1] == 'h' || dot[1] == 'H')
    0          
79 1 50         && (dot[2] == 't' || dot[2] == 'T')
    0          
80 1 50         && (dot[3] == 'm' || dot[3] == 'M')
    0          
81 1 50         && (dot[4] == 'l' || dot[4] == 'L'))) {
    0          
82 6           RETVAL = newSVpvs("xml");
83 13 100         } else if ((ext_len == 4
84 4 100         && (dot[0] == 'h' || dot[0] == 'H')
    50          
85 1 50         && (dot[1] == 't' || dot[1] == 'T')
    0          
86 1 50         && (dot[2] == 'm' || dot[2] == 'M')
    0          
87 1 50         && (dot[3] == 'l' || dot[3] == 'L'))
    0          
88 12 100         || (ext_len == 3
89 7 100         && (dot[0] == 'h' || dot[0] == 'H')
    50          
90 1 50         && (dot[1] == 't' || dot[1] == 'T')
    0          
91 1 50         && (dot[2] == 'm' || dot[2] == 'M'))
    0          
92 11 100         || (ext_len == 4
93 3 100         && (dot[0] == 't' || dot[0] == 'T')
    50          
94 1 50         && (dot[1] == 'm' || dot[1] == 'M')
    0          
95 1 50         && (dot[2] == 'p' || dot[2] == 'P')
    0          
96 1 50         && (dot[3] == 'l' || dot[3] == 'L'))
    0          
97 10 100         || (ext_len == 2
98 2 100         && (dot[0] == 't' || dot[0] == 'T')
    50          
99 1 50         && (dot[1] == 't' || dot[1] == 'T'))
    0          
100 9 100         || (ext_len == 2
101 1 50         && (dot[0] == 'e' || dot[0] == 'E')
    0          
102 1 50         && (dot[1] == 'p' || dot[1] == 'P'))) {
    0          
103 5           RETVAL = newSVpvs("html");
104 8 100         } else if ((ext_len == 3
105 6 100         && (dot[0] == 'c' || dot[0] == 'C')
    100          
106 3 100         && (dot[1] == 's' || dot[1] == 'S')
    50          
107 3 100         && (dot[2] == 's' || dot[2] == 'S'))
    50          
108 5 100         || (ext_len == 4
109 2 100         && (dot[0] == 's' || dot[0] == 'S')
    50          
110 1 50         && (dot[1] == 'c' || dot[1] == 'C')
    0          
111 1 50         && (dot[2] == 's' || dot[2] == 'S')
    0          
112 1 50         && (dot[3] == 's' || dot[3] == 'S'))
    0          
113 4 100         || (ext_len == 4
114 1 50         && (dot[0] == 'l' || dot[0] == 'L')
    0          
115 1 50         && (dot[1] == 'e' || dot[1] == 'E')
    0          
116 1 50         && (dot[2] == 's' || dot[2] == 'S')
    0          
117 1 50         && (dot[3] == 's' || dot[3] == 'S'))) {
    0          
118 5           RETVAL = newSVpvs("css");
119             }
120             }
121             }
122             }
123             OUTPUT:
124             RETVAL
125              
126             SV *
127             indent_c(class, src_sv, ...)
128             SV * class
129             SV * src_sv
130             CODE:
131             {
132             const char *src;
133             STRLEN src_len;
134             eshu_config_t cfg;
135             char *result;
136             size_t out_len;
137             int i;
138              
139             PERL_UNUSED_VAR(class);
140 59           src = SvPV(src_sv, src_len);
141 59           cfg = eshu_default_config();
142              
143 66 100         for (i = 2; i + 1 < items; i += 2) {
144 7           const char *key = SvPV_nolen(ST(i));
145 7           SV *val = ST(i + 1);
146 7 100         if (strEQ(key, "indent_char")) {
147 1           const char *ic = SvPV_nolen(val);
148 1 50         cfg.indent_char = (*ic == ' ') ? ' ' : '\t';
149 6 100         } else if (strEQ(key, "indent_width")) {
150 1           cfg.indent_width = SvIV(val);
151 5 100         } else if (strEQ(key, "indent_pp")) {
152 1           cfg.indent_pp = SvTRUE(val) ? 1 : 0;
153 4 100         } else if (strEQ(key, "range_start")) {
154 2           cfg.range_start = SvIV(val);
155 2 50         } else if (strEQ(key, "range_end")) {
156 2           cfg.range_end = SvIV(val);
157             }
158             }
159              
160 59           result = eshu_indent_c(src, (size_t)src_len, &cfg, &out_len);
161 59           RETVAL = newSVpvn(result, out_len);
162 59           free(result);
163             }
164             OUTPUT:
165             RETVAL
166              
167             SV *
168             indent_pl(class, src_sv, ...)
169             SV * class
170             SV * src_sv
171             CODE:
172             {
173             const char *src;
174             STRLEN src_len;
175             eshu_config_t cfg;
176             char *result;
177             size_t out_len;
178             int i;
179              
180             PERL_UNUSED_VAR(class);
181 69           src = SvPV(src_sv, src_len);
182 69           cfg = eshu_default_config();
183 69           cfg.lang = ESHU_LANG_PERL;
184              
185 73 100         for (i = 2; i + 1 < items; i += 2) {
186 4           const char *key = SvPV_nolen(ST(i));
187 4           SV *val = ST(i + 1);
188 4 100         if (strEQ(key, "indent_char")) {
189 1           const char *ic = SvPV_nolen(val);
190 1 50         cfg.indent_char = (*ic == ' ') ? ' ' : '\t';
191 3 100         } else if (strEQ(key, "indent_width")) {
192 1           cfg.indent_width = SvIV(val);
193 2 100         } else if (strEQ(key, "range_start")) {
194 1           cfg.range_start = SvIV(val);
195 1 50         } else if (strEQ(key, "range_end")) {
196 1           cfg.range_end = SvIV(val);
197             }
198             }
199              
200 69           result = eshu_indent_pl(src, (size_t)src_len, &cfg, &out_len);
201 69           RETVAL = newSVpvn(result, out_len);
202 69           free(result);
203             }
204             OUTPUT:
205             RETVAL
206              
207             SV *
208             indent_xs(class, src_sv, ...)
209             SV * class
210             SV * src_sv
211             CODE:
212             {
213             const char *src;
214             STRLEN src_len;
215             eshu_config_t cfg;
216             char *result;
217             size_t out_len;
218             int i;
219              
220             PERL_UNUSED_VAR(class);
221 32           src = SvPV(src_sv, src_len);
222 32           cfg = eshu_default_config();
223 32           cfg.lang = ESHU_LANG_XS;
224              
225 32 50         for (i = 2; i + 1 < items; i += 2) {
226 0           const char *key = SvPV_nolen(ST(i));
227 0           SV *val = ST(i + 1);
228 0 0         if (strEQ(key, "indent_char")) {
229 0           const char *ic = SvPV_nolen(val);
230 0 0         cfg.indent_char = (*ic == ' ') ? ' ' : '\t';
231 0 0         } else if (strEQ(key, "indent_width")) {
232 0           cfg.indent_width = SvIV(val);
233 0 0         } else if (strEQ(key, "indent_pp")) {
234 0           cfg.indent_pp = SvTRUE(val) ? 1 : 0;
235 0 0         } else if (strEQ(key, "range_start")) {
236 0           cfg.range_start = SvIV(val);
237 0 0         } else if (strEQ(key, "range_end")) {
238 0           cfg.range_end = SvIV(val);
239             }
240             }
241              
242 32           result = eshu_indent_xs(src, (size_t)src_len, &cfg, &out_len);
243 32           RETVAL = newSVpvn(result, out_len);
244 32           free(result);
245             }
246             OUTPUT:
247             RETVAL
248              
249             SV *
250             indent_xml(class, src_sv, ...)
251             SV * class
252             SV * src_sv
253             CODE:
254             {
255             const char *src;
256             STRLEN src_len;
257             eshu_config_t cfg;
258             char *result;
259             size_t out_len;
260             int i;
261              
262             PERL_UNUSED_VAR(class);
263 32           src = SvPV(src_sv, src_len);
264 32           cfg = eshu_default_config();
265 32           cfg.lang = ESHU_LANG_XML;
266              
267 42 100         for (i = 2; i + 1 < items; i += 2) {
268 10           const char *key = SvPV_nolen(ST(i));
269 10           SV *val = ST(i + 1);
270 10 100         if (strEQ(key, "indent_char")) {
271 1           const char *ic = SvPV_nolen(val);
272 1 50         cfg.indent_char = (*ic == ' ') ? ' ' : '\t';
273 9 100         } else if (strEQ(key, "indent_width")) {
274 1           cfg.indent_width = SvIV(val);
275 8 50         } else if (strEQ(key, "lang")) {
276 8           const char *l = SvPV_nolen(val);
277 8 50         if (strEQ(l, "html") || strEQ(l, "htm")) {
    0          
278 8           cfg.lang = ESHU_LANG_HTML;
279             }
280 0 0         } else if (strEQ(key, "range_start")) {
281 0           cfg.range_start = SvIV(val);
282 0 0         } else if (strEQ(key, "range_end")) {
283 0           cfg.range_end = SvIV(val);
284             }
285             }
286              
287 32           result = eshu_indent_xml(src, (size_t)src_len, &cfg, &out_len);
288 32           RETVAL = newSVpvn(result, out_len);
289 32           free(result);
290             }
291             OUTPUT:
292             RETVAL
293              
294             SV *
295             indent_css(class, src_sv, ...)
296             SV * class
297             SV * src_sv
298             CODE:
299             {
300             const char *src;
301             STRLEN src_len;
302             eshu_config_t cfg;
303             char *result;
304             size_t out_len;
305             int i;
306              
307             PERL_UNUSED_VAR(class);
308 29           src = SvPV(src_sv, src_len);
309 29           cfg = eshu_default_config();
310 29           cfg.lang = ESHU_LANG_CSS;
311              
312 31 100         for (i = 2; i + 1 < items; i += 2) {
313 2           const char *key = SvPV_nolen(ST(i));
314 2           SV *val = ST(i + 1);
315 2 100         if (strEQ(key, "indent_char")) {
316 1           const char *ic = SvPV_nolen(val);
317 1 50         cfg.indent_char = (*ic == ' ') ? ' ' : '\t';
318 1 50         } else if (strEQ(key, "indent_width")) {
319 1           cfg.indent_width = SvIV(val);
320 0 0         } else if (strEQ(key, "range_start")) {
321 0           cfg.range_start = SvIV(val);
322 0 0         } else if (strEQ(key, "range_end")) {
323 0           cfg.range_end = SvIV(val);
324             }
325             }
326              
327 29           result = eshu_indent_css(src, (size_t)src_len, &cfg, &out_len);
328 29           RETVAL = newSVpvn(result, out_len);
329 29           free(result);
330             }
331             OUTPUT:
332             RETVAL
333              
334             SV *
335             indent_string(class, src_sv, ...)
336             SV * class
337             SV * src_sv
338             CODE:
339             {
340             const char *src;
341             STRLEN src_len;
342             eshu_config_t cfg;
343             char *result;
344             size_t out_len;
345 50           const char *lang = "c";
346             int i;
347              
348             PERL_UNUSED_VAR(class);
349 50           src = SvPV(src_sv, src_len);
350 50           cfg = eshu_default_config();
351              
352 104 100         for (i = 2; i + 1 < items; i += 2) {
353 54           const char *key = SvPV_nolen(ST(i));
354 54           SV *val = ST(i + 1);
355 54 100         if (strEQ(key, "lang")) {
356 50           lang = SvPV_nolen(val);
357 4 100         } else if (strEQ(key, "indent_char")) {
358 2           const char *ic = SvPV_nolen(val);
359 2 100         cfg.indent_char = (*ic == ' ') ? ' ' : '\t';
360 2 50         } else if (strEQ(key, "indent_width")) {
361 2           cfg.indent_width = SvIV(val);
362 0 0         } else if (strEQ(key, "indent_pp")) {
363 0           cfg.indent_pp = SvTRUE(val) ? 1 : 0;
364 0 0         } else if (strEQ(key, "range_start")) {
365 0           cfg.range_start = SvIV(val);
366 0 0         } else if (strEQ(key, "range_end")) {
367 0           cfg.range_end = SvIV(val);
368             }
369             }
370              
371 50 100         if (strEQ(lang, "c")) {
372 13           result = eshu_indent_c(src, (size_t)src_len, &cfg, &out_len);
373 37 100         } else if (strEQ(lang, "perl") || strEQ(lang, "pl")) {
    50          
374 31           cfg.lang = ESHU_LANG_PERL;
375 31           result = eshu_indent_pl(src, (size_t)src_len, &cfg, &out_len);
376 6 100         } else if (strEQ(lang, "xs")) {
377 1           cfg.lang = ESHU_LANG_XS;
378 1           result = eshu_indent_xs(src, (size_t)src_len, &cfg, &out_len);
379 5 100         } else if (strEQ(lang, "xml") || strEQ(lang, "svg")) {
    50          
380 2           cfg.lang = ESHU_LANG_XML;
381 2           result = eshu_indent_xml(src, (size_t)src_len, &cfg, &out_len);
382 3 100         } else if (strEQ(lang, "html") || strEQ(lang, "htm")) {
    50          
383 1           cfg.lang = ESHU_LANG_HTML;
384 1           result = eshu_indent_xml(src, (size_t)src_len, &cfg, &out_len);
385 2 50         } else if (strEQ(lang, "css") || strEQ(lang, "scss") || strEQ(lang, "less")) {
    0          
    0          
386 2           cfg.lang = ESHU_LANG_CSS;
387 2           result = eshu_indent_css(src, (size_t)src_len, &cfg, &out_len);
388             } else {
389 0           croak("Eshu: unsupported language '%s'", lang);
390             result = NULL; /* not reached */
391             out_len = 0;
392             }
393              
394 50           RETVAL = newSVpvn(result, out_len);
395 50           free(result);
396             }
397             OUTPUT:
398             RETVAL