File Coverage

LibPkgConf.xs
Criterion Covered Total %
statement 161 171 94.1
branch 64 90 71.1
condition n/a
subroutine n/a
pod n/a
total 225 261 86.2


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #include
6              
7             struct my_client_t {
8             pkgconf_client_t client;
9             FILE *auditf;
10             int maxdepth;
11             SV *error_handler;
12             };
13              
14             typedef struct my_client_t my_client_t;
15              
16             static bool
17 2           my_error_handler(const char *msg, const pkgconf_client_t *_, const void *data)
18             {
19 2           dSP;
20              
21             int count;
22             bool value;
23 2           const my_client_t *client = (const my_client_t*)data;
24            
25 2           ENTER;
26 2           SAVETMPS;
27            
28 2 50         PUSHMARK(SP);
29 2 50         EXTEND(SP, 1);
30 2           PUSHs(sv_2mortal(newSVpv(msg, 0)));
31 2           PUTBACK;
32            
33 2           count = call_sv(client->error_handler, G_SCALAR);
34            
35 2           SPAGAIN;
36            
37 2 50         value = count > 0 && POPi;
    50          
    50          
38            
39 2           PUTBACK;
40 2 50         FREETMPS;
41 2           LEAVE;
42              
43 2           return value;
44             }
45              
46             static bool
47 3           my_pkg_iterator(const pkgconf_pkg_t *pkg, void *data)
48             {
49 3           dSP;
50            
51             int count;
52             bool value;
53 3           SV *callback = (SV*)data;
54            
55 3           ENTER;
56 3           SAVETMPS;
57            
58 3 50         PUSHMARK(SP);
59 3 50         EXTEND(SP,1);
60 3           PUSHs(sv_2mortal(newSViv(PTR2IV(pkg))));
61 3           PUTBACK;
62            
63 3           count = call_sv(callback, G_SCALAR);
64            
65 3           SPAGAIN;
66            
67 3 50         value = count > 0 && POPi;
    50          
    50          
68            
69 3           PUTBACK;
70 3 50         FREETMPS;
71 3           LEAVE;
72            
73 3           return value;
74             }
75              
76             static bool
77 102           directory_filter(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data)
78             {
79 102 100         if(pkgconf_fragment_has_system_dir(client, frag))
80 2           return false;
81 100           return true;
82             }
83              
84             MODULE = PkgConfig::LibPkgConf PACKAGE = PkgConfig::LibPkgConf::Client
85              
86              
87             void
88             _init(object, error_handler, maxdepth)
89             SV *object
90             SV *error_handler
91             int maxdepth
92             INIT:
93             my_client_t *self;
94             CODE:
95 41           Newxz(self, 1, my_client_t);
96 41           self->auditf = NULL;
97 41           self->error_handler = SvREFCNT_inc(error_handler);
98 41           self->maxdepth = maxdepth;
99 41           pkgconf_client_init(&self->client, my_error_handler, self, pkgconf_cross_personality_default());
100 41           pkgconf_client_set_flags(&self->client, PKGCONF_PKG_PKGF_NONE);
101 41           hv_store((HV*)SvRV(object), "ptr", 3, newSViv(PTR2IV(self)), 0);
102              
103              
104             void
105             audit_set_log(self, filename, mode)
106             my_client_t *self
107             const char *filename
108             const char *mode
109             CODE:
110 1 50         if(self->auditf != NULL)
111             {
112 0           fclose(self->auditf);
113 0           self->auditf = NULL;
114             }
115 1           self->auditf = fopen(filename, mode);
116 1 50         if(self->auditf != NULL)
117             {
118 1           pkgconf_audit_set_log(&self->client, self->auditf);
119             }
120             else
121             {
122             /* TODO: call error ? */
123             }
124              
125              
126             const char *
127             sysroot_dir(self, ...)
128             my_client_t *self
129             CODE:
130 3 100         if(items > 1)
131             {
132 1 50         pkgconf_client_set_sysroot_dir(&self->client, SvPV_nolen(ST(1)));
133             }
134 3           RETVAL = pkgconf_client_get_sysroot_dir(&self->client);
135             OUTPUT:
136             RETVAL
137              
138              
139             const char *
140             buildroot_dir(self, ...)
141             my_client_t *self
142             CODE:
143 3 100         if(items > 1)
144             {
145 1 50         pkgconf_client_set_buildroot_dir(&self->client, SvPV_nolen(ST(1)));
146             }
147 3           RETVAL = pkgconf_client_get_buildroot_dir(&self->client);
148             OUTPUT:
149             RETVAL
150              
151              
152             int
153             maxdepth(self, ...)
154             my_client_t *self
155             CODE:
156 4 100         if(items > 1)
157             {
158 1 50         self->maxdepth = SvIV(ST(1));
159             }
160 4           RETVAL = self->maxdepth;
161             OUTPUT:
162             RETVAL
163              
164              
165             void
166             path(self)
167             my_client_t *self
168             INIT:
169             pkgconf_node_t *n;
170             pkgconf_path_t *pnode;
171 6           int count = 0;
172             CODE:
173 19 100         PKGCONF_FOREACH_LIST_ENTRY(self->client.dir_list.head, n)
174             {
175 13           pnode = n->data;
176 13           ST(count++) = sv_2mortal(newSVpv(pnode->path, 0));
177             }
178 6           XSRETURN(count);
179              
180              
181             void
182             filter_lib_dirs(self)
183             my_client_t *self
184             INIT:
185             pkgconf_node_t *n;
186             pkgconf_path_t *pnode;
187 3           int count = 0;
188             CODE:
189 10 100         PKGCONF_FOREACH_LIST_ENTRY(self->client.filter_libdirs.head, n)
190             {
191 7           pnode = n->data;
192 7           ST(count++) = sv_2mortal(newSVpv(pnode->path, 0));
193             }
194 3           XSRETURN(count);
195              
196              
197             void
198             filter_include_dirs(self)
199             my_client_t *self
200             INIT:
201             pkgconf_node_t *n;
202             pkgconf_path_t *pnode;
203 3           int count = 0;
204             CODE:
205 9 100         PKGCONF_FOREACH_LIST_ENTRY(self->client.filter_includedirs.head, n)
206             {
207 6           pnode = n->data;
208 6           ST(count++) = sv_2mortal(newSVpv(pnode->path, 0));
209             }
210 3           XSRETURN(count);
211              
212              
213             void
214             DESTROY(self)
215             my_client_t *self;
216             CODE:
217 41 100         if(self->auditf != NULL)
218             {
219 1           fclose(self->auditf);
220 1           self->auditf = NULL;
221             }
222 41           pkgconf_client_deinit(&self->client);
223 41           SvREFCNT_dec(self->error_handler);
224 41           Safefree(self);
225              
226              
227             IV
228             _find(self, name)
229             my_client_t *self
230             const char *name
231             CODE:
232 18           RETVAL = PTR2IV(pkgconf_pkg_find(&self->client, name));
233             OUTPUT:
234             RETVAL
235              
236              
237             IV
238             _package_from_file(self, filename)
239             my_client_t *self
240             const char *filename
241             INIT:
242             FILE *fp;
243             CODE:
244 1           fp = fopen(filename, "r");
245 1 50         if(fp != NULL)
246 1           RETVAL = PTR2IV(pkgconf_pkg_new_from_file(&self->client, filename, fp));
247             else
248 0           RETVAL = 0;
249             OUTPUT:
250             RETVAL
251              
252              
253             void
254             _scan_all(self, sub)
255             my_client_t *self
256             SV* sub
257             CODE:
258 1           pkgconf_scan_all(&self->client, sub, my_pkg_iterator);
259            
260              
261             void
262             _dir_list_build(self, env_only)
263             my_client_t *self
264             int env_only
265             INIT:
266             int old_flags;
267             CODE:
268 41 100         if(env_only)
269             {
270 11           old_flags = pkgconf_client_get_flags(&self->client);
271 11           pkgconf_client_set_flags(&self->client, old_flags | PKGCONF_PKG_PKGF_ENV_ONLY);
272             }
273 41           pkgconf_client_dir_list_build(&self->client, pkgconf_cross_personality_default());
274 41 100         if(env_only)
275             {
276 11           pkgconf_client_set_flags(&self->client, old_flags);
277             }
278              
279              
280             void
281             _set_global(self, kv)
282             my_client_t *self
283             const char *kv
284             CODE:
285 4           pkgconf_tuple_define_global(&self->client, kv);
286              
287              
288             const char *
289             _get_global(self, key)
290             my_client_t *self
291             const char *key
292             INIT:
293             const char *val;
294             CODE:
295 7           val = pkgconf_tuple_find_global(&self->client, key);
296 7 100         if(val == NULL)
297 1           XSRETURN_EMPTY;
298             else
299 6           RETVAL = val;
300             OUTPUT:
301             RETVAL
302            
303              
304              
305             MODULE = PkgConfig::LibPkgConf PACKAGE = PkgConfig::LibPkgConf::Package
306              
307              
308             int
309             refcount(self)
310             pkgconf_pkg_t* self
311             CODE:
312 4           RETVAL = self->refcount;
313             OUTPUT:
314             RETVAL
315              
316              
317             const char *
318             id(self)
319             pkgconf_pkg_t* self
320             CODE:
321 7           RETVAL = self->id;
322             OUTPUT:
323             RETVAL
324              
325              
326             const char *
327             filename(self)
328             pkgconf_pkg_t* self
329             CODE:
330 3           RETVAL = self->filename;
331             OUTPUT:
332             RETVAL
333              
334              
335             const char *
336             realname(self)
337             pkgconf_pkg_t* self
338             CODE:
339 4           RETVAL = self->realname;
340             OUTPUT:
341             RETVAL
342              
343              
344             const char *
345             version(self)
346             pkgconf_pkg_t* self
347             CODE:
348 5           RETVAL = self->version;
349             OUTPUT:
350             RETVAL
351              
352              
353             const char *
354             description(self)
355             pkgconf_pkg_t* self
356             CODE:
357 4           RETVAL = self->description;
358             OUTPUT:
359             RETVAL
360              
361              
362             const char *
363             url(self)
364             pkgconf_pkg_t* self
365             CODE:
366 0           RETVAL = self->url;
367             OUTPUT:
368             RETVAL
369              
370              
371             const char *
372             pc_filedir(self)
373             pkgconf_pkg_t* self
374             CODE:
375 0           RETVAL = self->pc_filedir;
376             OUTPUT:
377             RETVAL
378              
379              
380             SV *
381             _get_string(self, client, type)
382             pkgconf_pkg_t *self
383             my_client_t *client
384             int type
385             INIT:
386 27           pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
387 27           pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
388             size_t len;
389             int eflag;
390             int flags;
391             int old_flags;
392 27           bool escape = true;
393             CODE:
394 27           old_flags = flags = pkgconf_client_get_flags(&client->client);
395 27 100         if(type % 2)
396 10           flags = flags | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS;
397 27           pkgconf_client_set_flags(&client->client, flags);
398             /*
399             * TODO: attribute for max depth (also in the list version below)
400             */
401 54 100         eflag = type > 1
402 15           ? pkgconf_pkg_cflags(&client->client, self, &unfiltered_list, client->maxdepth)
403 12           : pkgconf_pkg_libs(&client->client, self, &unfiltered_list, client->maxdepth);
404 27           pkgconf_client_set_flags(&client->client, old_flags);
405             /*
406             * TODO: throw an exception (also in the list verson below)
407             */
408 27 50         if(eflag != PKGCONF_PKG_ERRF_OK)
409 0           XSRETURN_EMPTY;
410 27           pkgconf_fragment_filter(&client->client, &filtered_list, &unfiltered_list, directory_filter, NULL);
411 27           len = pkgconf_fragment_render_len(&filtered_list, escape, NULL);
412 27 50         RETVAL = newSV(len == 1 ? len : len-1);
413 27           SvPOK_on(RETVAL);
414 27           SvCUR_set(RETVAL, len-1);
415 27           pkgconf_fragment_render_buf(&filtered_list, SvPVX(RETVAL), len, escape, NULL);
416 27           pkgconf_fragment_free(&filtered_list);
417 27           pkgconf_fragment_free(&unfiltered_list);
418             OUTPUT:
419             RETVAL
420              
421              
422             void
423             _get_list(self, client, type)
424             pkgconf_pkg_t *self
425             my_client_t *client
426             int type
427             INIT:
428 12           pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
429 12           pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
430             pkgconf_node_t *node;
431             pkgconf_fragment_t *frag;
432 12           int count = 0;
433             HV *h;
434             int eflag;
435             int flags;
436             int old_flags;
437             CODE:
438 12           old_flags = flags = pkgconf_client_get_flags(&client->client);
439 12 100         if(type % 2)
440 4           flags = flags | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS;
441 12           pkgconf_client_set_flags(&client->client, flags);
442             /*
443             * TODO: attribute for max depth
444             */
445 24 100         eflag = type > 1
446 7           ? pkgconf_pkg_cflags(&client->client, self, &unfiltered_list, client->maxdepth)
447 5           : pkgconf_pkg_libs(&client->client, self, &unfiltered_list, client->maxdepth);
448 12           pkgconf_client_set_flags(&client->client, old_flags);
449             /*
450             * TODO: throw an exception
451             */
452 12 50         if(eflag != PKGCONF_PKG_ERRF_OK)
453 0           XSRETURN_EMPTY;
454 12           pkgconf_fragment_filter(&client->client, &filtered_list, &unfiltered_list, directory_filter, NULL);
455 46 100         PKGCONF_FOREACH_LIST_ENTRY(filtered_list.head, node)
456             {
457 34           h = newHV();
458 34           frag = node->data;
459 34 50         if(frag->type)
460 34           hv_store(h, "type", 4, newSVpvf("%c", frag->type), 0);
461             else
462 0           hv_store(h, "type", 4, newSVsv(&PL_sv_undef), 0);
463 34 50         if(frag->data)
464 34           hv_store(h, "data", 4, newSVpv(frag->data, strlen(frag->data)), 0);
465             else
466 0           hv_store(h, "data", 4, newSVsv(&PL_sv_undef), 0);
467 34           ST(count++) = newRV_noinc((SV*) h);
468             }
469 12           pkgconf_fragment_free(&filtered_list);
470 12           pkgconf_fragment_free(&unfiltered_list);
471 12           XSRETURN(count);
472              
473              
474             void
475             _get_variable(self, client, key)
476             pkgconf_pkg_t *self
477             my_client_t *client
478             const char *key
479             INIT:
480             pkgconf_node_t *node;
481             pkgconf_tuple_t *tup;
482             CODE:
483 20 100         PKGCONF_FOREACH_LIST_ENTRY(self->vars.head, node)
484             {
485 18           tup = node->data;
486 18 100         if(!strcmp(tup->key, key))
487             {
488 2           XSRETURN_PV(tup->value);
489             }
490             }
491 2           XSRETURN_EMPTY;
492            
493              
494             MODULE = PkgConfig::LibPkgConf PACKAGE = PkgConfig::LibPkgConf::Util
495              
496              
497             void
498             argv_split(src)
499             const char *src
500             INIT:
501             int argc, ret, i;
502             char **argv;
503             PPCODE:
504 1           ret = pkgconf_argv_split(src, &argc, &argv);
505 1 50         if(ret == 0)
506             {
507 4 100         for(i=0; i
508             {
509 3 50         XPUSHs(sv_2mortal(newSVpv(argv[i],0)));
510             }
511 1           pkgconf_argv_free(argv);
512             }
513             else
514             {
515 0           croak("error in argv_split");
516             }
517              
518              
519             int
520             compare_version(a,b)
521             const char *a
522             const char *b
523             CODE:
524 2           RETVAL = pkgconf_compare_version(a,b);
525             OUTPUT:
526             RETVAL
527              
528              
529             char *
530             path_sep()
531             CODE:
532 24           RETVAL = PKG_CONFIG_PATH_SEP_S;
533             OUTPUT:
534             RETVAL
535              
536              
537             #define STRINGIZE(x) #x
538             #define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
539              
540              
541             const char *
542             version()
543             CODE:
544 1           RETVAL = STRINGIZE_VALUE_OF(MY_PKGCONF_VERSION);
545             OUTPUT:
546             RETVAL
547              
548              
549             SV *
550             path_relocate(in)
551             const char *in;
552             INIT:
553             char out[PKGCONF_BUFSIZE];
554             bool ok;
555             CODE:
556 17           strncpy(out, in, PKGCONF_BUFSIZE-1);
557 17           ok = pkgconf_path_relocate(out, sizeof out);
558 17 50         RETVAL = newSVpv(ok ? out : in, 0);
559             OUTPUT:
560             RETVAL
561              
562              
563             MODULE = PkgConfig::LibPkgConf PACKAGE = PkgConfig::LibPkgConf::Test
564              
565              
566             IV
567             send_error(client, msg)
568             my_client_t *client
569             const char *msg
570             CODE:
571 2           RETVAL = pkgconf_error(&client->client, "%s", msg);
572             OUTPUT:
573             RETVAL
574            
575              
576             void
577             send_log(client, msg)
578             my_client_t *client
579             const char *msg
580             CODE:
581 2           pkgconf_audit_log(&client->client, "%s", msg);
582