File Coverage

blib/lib/InlineX/C2XS/Context.pm
Criterion Covered Total %
statement 6 58 10.3
branch 0 46 0.0
condition 0 15 0.0
subroutine 2 4 50.0
pod 0 2 0.0
total 8 125 6.4


line stmt bran cond sub pod time code
1             package InlineX::C2XS::Context;
2              
3 15     15   102 use strict;
  15         21  
  15         411  
4 15     15   76 use warnings;
  15         28  
  15         16826  
5              
6             our $VERSION = '0.25';
7              
8             ###################################
9             ###################################
10              
11             sub apply_context_args {
12              
13             # $_[0]: The XS file to which we want to apply the context args (aTHX, aTHX_, pTHX, pTHX_).
14             # $_[1]: A reference to a list/array of the C functions to which we wish to apply the
15             # context args.
16              
17 0 0   0 0   die "Usage: InlineX::C2XS::Context::apply_context_args(\$xs_file, \\\@functions)"
18             unless @_ == 2;
19              
20 0 0         open RD, '<', $_[0] or die $!;
21 0           my @xs = ;
22 0 0         close RD or die $!;
23 0 0         open WR, '>', $_[0] or die $!;
24              
25 0           my($aTHX_warn, $pTHX_warn) = (0, 0);
26              
27 0           for(@xs) {
28 0 0         $pTHX_warn = 1 if $_ =~ /pTHX/;
29 0 0         $aTHX_warn = 1 if $_ =~ /aTHX/;
30             }
31              
32 0 0         warn "Potential problem: the string 'aTHX' was found in $_[0]"
33             if $aTHX_warn;
34              
35 0 0         warn "Potential problem: the string 'pTHX' was found in $_[0]"
36             if $pTHX_warn;
37              
38 0           for my $f(@{$_[1]}) {
  0            
39 0           my $seen_pthx = 0;
40 0           for(my $i = 1; $i < @xs; $i++) {
41              
42 0 0 0       if($xs[$i] =~ /.+\b$f\b(\s+)?\(/ && !$seen_pthx) {
43 0 0         $xs[$i] !~ /\((\s+)?(void)?(\s+)?\)/
    0          
44             ? $xs[$i] =~ /(a|p)THX/ ? $xs[$i] = $xs[$i]
45             : $xs[$i] =~ s/\(/\(pTHX_ /
46             : $xs[$i] =~ s/\((\s+)?(void)?(\s+)?\)/\(pTHX\)/;
47 0 0         $seen_pthx = 1 if $xs[$i] =~ /pTHX/;
48             }
49              
50              
51 0 0 0       if(
      0        
52             (
53             $xs[$i] =~ /^(S|H|A)V \*\n/ ||
54             $xs[$i] =~ /^(signed |unsigned )?(long)?\s?int(\s\*)?\n/ ||
55             $xs[$i] =~ /^(long)?\s?double(\s\*)?\n/ ||
56             $xs[$i] =~ /^(signed |unsigned )?long(\s\*)?\n/
57             )
58             && $xs[$i + 1] =~ /^$f\b/
59             ) {
60 0           my $function = $xs[$i + 1];
61 0           chomp $function;
62 0           my $jump = scalar(split /,/, $xs[$i + 1]);
63 0 0         if($xs[$i + 1] !~ /\(\)/) {$function =~ s/\(/\(aTHX_ /}
  0            
64             else {
65 0           $function =~ s/\(\)/\(aTHX\)/;
66 0           $jump--;
67             }
68 0           $function .= ';';
69 0 0         unless($xs[$i + 2 + $jump] =~ /\S/) {
70 0           $xs[$i + 2 + $jump] = "CODE:\n RETVAL = $function\nOUTPUT: RETVAL\n\n";
71             }
72 0           else { warn "$i: $xs[$i + 2 + $jump]\n"}
73             }
74             }
75             }
76              
77             # The following can break if $f appears in comments.
78 0           for my $f (@{$_[1]}) {
  0            
79 0           my $seen_pthx = 0;
80 0           for(my $i = 1; $i < @xs; $i++) {
81 0 0         if($seen_pthx) {
82 0 0         $xs[$i] =~ s/\b$f(\s+)?\((\s+)?\)/$f(aTHX)/
83             unless $xs[$i] =~ /^$f\b/; # XS section - we don't want aTHX/aTHX_ here.
84 0 0 0       $xs[$i] =~ s/\b$f(\s+)?\(/$f(aTHX_ /
85             unless ($xs[$i] =~ /aTHX|pTHX/
86             ||
87             $xs[$i] =~ /^$f\b/); # XS section - we don't want aTHX/aTHX_ here.
88             }
89             else {
90 0 0 0       if($xs[$i] =~ /\b$f\b/ && $xs[$i] =~ /\bpTHX\b|\bpTHX_\b/) {
91 0           $seen_pthx = 1;
92 0           next;
93             }
94 0 0         $seen_pthx = 1 if $xs[$i] =~ /\b$f(\s+)?\(/;
95 0           $xs[$i] =~ s/\b$f(\s+)?\((\s+)?(void)(\s+)?\)/$f(pTHX)/;
96 0 0         $xs[$i] =~ s/\b$f(\s+)?\(/$f(pTHX_ /
97             unless $xs[$i] =~ /(p|a)THX/;
98             }
99             }
100             }
101              
102 0           for(@xs) {print WR $_}
  0            
103              
104 0 0         close WR or die $!;
105              
106 0           print "$_[0] has been rewritten for PERL_NO_GET_CONTEXT\n";
107              
108             }
109              
110             ###################################
111             ###################################
112              
113             sub exclude {
114 0     0 0   my @exclusions = @{$_[1]};
  0            
115              
116 0           for(@exclusions) {
117 0 0         return 1 if $_[0] =~ /$_/;
118             }
119 0           return 0;
120             }
121              
122             1;