line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Inline::C; |
2
|
|
|
|
|
|
|
$Inline::C::VERSION = '0.54_02'; |
3
|
|
|
|
|
|
|
$Inline::C::VERSION = eval $Inline::C::VERSION; |
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
6
|
|
|
|
|
|
|
require Inline; |
7
|
1
|
|
|
1
|
|
6
|
use Config; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
49
|
|
8
|
1
|
|
|
1
|
|
752
|
use Data::Dumper; |
|
1
|
|
|
|
|
7403
|
|
|
1
|
|
|
|
|
75
|
|
9
|
1
|
|
|
1
|
|
9
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
57
|
|
10
|
1
|
|
|
1
|
|
6
|
use Cwd qw(cwd abs_path); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
43
|
|
11
|
1
|
|
|
1
|
|
5
|
use File::Spec; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
6112
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
@Inline::C::ISA = qw(Inline); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
#============================================================================== |
16
|
|
|
|
|
|
|
# Register this module as an Inline language support module |
17
|
|
|
|
|
|
|
#============================================================================== |
18
|
|
|
|
|
|
|
sub register { |
19
|
|
|
|
|
|
|
return { |
20
|
|
|
|
|
|
|
language => 'C', |
21
|
|
|
|
|
|
|
# XXX Breaking this on purpose; let's see who screams |
22
|
|
|
|
|
|
|
# aliases => ['c'], |
23
|
|
|
|
|
|
|
type => 'compiled', |
24
|
|
|
|
|
|
|
suffix => $Config{dlext}, |
25
|
0
|
|
|
0
|
0
|
0
|
}; |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
#============================================================================== |
29
|
|
|
|
|
|
|
# Validate the C config options |
30
|
|
|
|
|
|
|
#============================================================================== |
31
|
|
|
|
|
|
|
sub usage_validate { |
32
|
0
|
|
|
0
|
0
|
0
|
my $key = shift; |
33
|
0
|
|
|
|
|
0
|
return <
|
34
|
|
|
|
|
|
|
The value of config option '$key' must be a string or an array ref |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
END |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub validate { |
40
|
1
|
|
|
1
|
0
|
3
|
my $o = shift; |
41
|
|
|
|
|
|
|
|
42
|
1
|
50
|
|
|
|
12
|
print STDERR "validate Stage\n" if $o->{CONFIG}{BUILD_NOISY}; |
43
|
1
|
|
50
|
|
|
12
|
$o->{ILSM} ||= {}; |
44
|
1
|
|
50
|
|
|
7
|
$o->{ILSM}{XS} ||= {}; |
45
|
1
|
|
50
|
|
|
7
|
$o->{ILSM}{MAKEFILE} ||= {}; |
46
|
1
|
50
|
|
|
|
8
|
if (not $o->UNTAINT) { |
47
|
0
|
|
|
|
|
0
|
require FindBin; |
48
|
0
|
0
|
|
|
|
0
|
$o->{ILSM}{MAKEFILE}{INC} = "-I\"$FindBin::Bin\"" if not defined $o->{ILSM}{MAKEFILE}{INC}; |
49
|
|
|
|
|
|
|
} |
50
|
1
|
50
|
|
|
|
6
|
$o->{ILSM}{AUTOWRAP} = 0 if not defined $o->{ILSM}{AUTOWRAP}; |
51
|
1
|
50
|
|
|
|
6
|
$o->{ILSM}{XSMODE} = 0 if not defined $o->{ILSM}{XSMODE}; |
52
|
1
|
|
50
|
|
|
6
|
$o->{ILSM}{AUTO_INCLUDE} ||= <
|
53
|
|
|
|
|
|
|
#include "EXTERN.h" |
54
|
|
|
|
|
|
|
#include "perl.h" |
55
|
|
|
|
|
|
|
#include "XSUB.h" |
56
|
|
|
|
|
|
|
#include "INLINE.h" |
57
|
|
|
|
|
|
|
END |
58
|
1
|
|
50
|
|
|
6
|
$o->{ILSM}{FILTERS} ||= []; |
59
|
|
|
|
|
|
|
$o->{STRUCT} ||= { |
60
|
1
|
|
50
|
|
|
10
|
'.macros' => '', |
61
|
|
|
|
|
|
|
'.xs' => '', |
62
|
|
|
|
|
|
|
'.any' => 0, |
63
|
|
|
|
|
|
|
'.all' => 0, |
64
|
|
|
|
|
|
|
}; |
65
|
|
|
|
|
|
|
|
66
|
1
|
|
|
|
|
7
|
while (@_) { |
67
|
0
|
|
|
|
|
0
|
my ($key, $value) = (shift, shift); |
68
|
0
|
0
|
|
|
|
0
|
if ($key eq 'PRE_HEAD') { |
69
|
0
|
0
|
|
|
|
0
|
unless( -f $value) { |
70
|
0
|
|
|
|
|
0
|
$o->{ILSM}{AUTO_INCLUDE} = $value . "\n" . $o->{ILSM}{AUTO_INCLUDE}; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
else { |
73
|
0
|
|
|
|
|
0
|
my $insert; |
74
|
0
|
0
|
|
|
|
0
|
open RD, '<', $value or die "Couldn't open $value for reading: $!"; |
75
|
0
|
|
|
|
|
0
|
while() {$insert .= $_} |
|
0
|
|
|
|
|
0
|
|
76
|
0
|
0
|
|
|
|
0
|
close RD or die "Couldn't close $value after reading: $!"; |
77
|
0
|
|
|
|
|
0
|
$o->{ILSM}{AUTO_INCLUDE} = $insert . "\n" . $o->{ILSM}{AUTO_INCLUDE}; |
78
|
|
|
|
|
|
|
} |
79
|
0
|
|
|
|
|
0
|
next; |
80
|
|
|
|
|
|
|
} |
81
|
0
|
0
|
0
|
|
|
0
|
if ($key eq 'MAKE' or |
|
|
|
0
|
|
|
|
|
82
|
|
|
|
|
|
|
$key eq 'AUTOWRAP' or |
83
|
|
|
|
|
|
|
$key eq 'XSMODE' |
84
|
|
|
|
|
|
|
) { |
85
|
0
|
|
|
|
|
0
|
$o->{ILSM}{$key} = $value; |
86
|
0
|
|
|
|
|
0
|
next; |
87
|
|
|
|
|
|
|
} |
88
|
0
|
0
|
0
|
|
|
0
|
if ($key eq 'CC' or |
89
|
|
|
|
|
|
|
$key eq 'LD') { |
90
|
0
|
|
|
|
|
0
|
$o->{ILSM}{MAKEFILE}{$key} = $value; |
91
|
0
|
|
|
|
|
0
|
next; |
92
|
|
|
|
|
|
|
} |
93
|
0
|
0
|
|
|
|
0
|
if ($key eq 'LIBS') { |
94
|
0
|
|
|
|
|
0
|
$o->add_list($o->{ILSM}{MAKEFILE}, $key, $value, []); |
95
|
0
|
|
|
|
|
0
|
next; |
96
|
|
|
|
|
|
|
} |
97
|
0
|
0
|
|
|
|
0
|
if ($key eq 'INC') { |
98
|
0
|
|
|
|
|
0
|
$o->add_string($o->{ILSM}{MAKEFILE}, $key, quote_space($value), ''); |
99
|
0
|
|
|
|
|
0
|
next; |
100
|
|
|
|
|
|
|
} |
101
|
0
|
0
|
0
|
|
|
0
|
if ($key eq 'MYEXTLIB' or |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
102
|
|
|
|
|
|
|
$key eq 'OPTIMIZE' or |
103
|
|
|
|
|
|
|
$key eq 'CCFLAGS' or |
104
|
|
|
|
|
|
|
$key eq 'LDDLFLAGS') { |
105
|
0
|
|
|
|
|
0
|
$o->add_string($o->{ILSM}{MAKEFILE}, $key, $value, ''); |
106
|
0
|
|
|
|
|
0
|
next; |
107
|
|
|
|
|
|
|
} |
108
|
0
|
0
|
|
|
|
0
|
if ($key eq 'CCFLAGSEX') { |
109
|
0
|
|
|
|
|
0
|
$o->add_string($o->{ILSM}{MAKEFILE}, 'CCFLAGS', $Config{ccflags} . ' ' . $value, ''); |
110
|
0
|
|
|
|
|
0
|
next; |
111
|
|
|
|
|
|
|
} |
112
|
0
|
0
|
|
|
|
0
|
if ($key eq 'TYPEMAPS') { |
113
|
0
|
0
|
|
|
|
0
|
unless(ref($value) eq 'ARRAY') { |
114
|
0
|
0
|
|
|
|
0
|
croak "TYPEMAPS file '$value' not found" |
115
|
|
|
|
|
|
|
unless -f $value; |
116
|
0
|
|
|
|
|
0
|
$value = File::Spec->rel2abs($value); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
else { |
119
|
0
|
|
|
|
|
0
|
for (my $i = 0; $i < scalar(@$value); $i++) { |
120
|
0
|
|
|
|
|
0
|
croak "TYPEMAPS file '${$value}[$i]' not found" |
121
|
0
|
0
|
|
|
|
0
|
unless -f ${$value}[$i]; |
|
0
|
|
|
|
|
0
|
|
122
|
0
|
|
|
|
|
0
|
${$value}[$i] = File::Spec->rel2abs(${$value}[$i]); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
} |
125
|
0
|
|
|
|
|
0
|
$o->add_list($o->{ILSM}{MAKEFILE}, $key, $value, []); |
126
|
0
|
|
|
|
|
0
|
next; |
127
|
|
|
|
|
|
|
} |
128
|
0
|
0
|
|
|
|
0
|
if ($key eq 'AUTO_INCLUDE') { |
129
|
0
|
|
|
|
|
0
|
$o->add_text($o->{ILSM}, $key, $value, ''); |
130
|
0
|
|
|
|
|
0
|
next; |
131
|
|
|
|
|
|
|
} |
132
|
0
|
0
|
|
|
|
0
|
if ($key eq 'BOOT') { |
133
|
0
|
|
|
|
|
0
|
$o->add_text($o->{ILSM}{XS}, $key, $value, ''); |
134
|
0
|
|
|
|
|
0
|
next; |
135
|
|
|
|
|
|
|
} |
136
|
0
|
0
|
|
|
|
0
|
if ($key eq 'PREFIX') { |
137
|
0
|
0
|
0
|
|
|
0
|
croak "Invalid value for 'PREFIX' option" |
138
|
|
|
|
|
|
|
unless ($value =~ /^\w*$/ and |
139
|
|
|
|
|
|
|
$value !~ /\n/); |
140
|
0
|
|
|
|
|
0
|
$o->{ILSM}{XS}{PREFIX} = $value; |
141
|
0
|
|
|
|
|
0
|
next; |
142
|
|
|
|
|
|
|
} |
143
|
0
|
0
|
|
|
|
0
|
if ($key eq 'FILTERS') { |
144
|
0
|
0
|
0
|
|
|
0
|
next if $value eq '1' or $value eq '0'; # ignore ENABLE, DISABLE |
145
|
0
|
0
|
|
|
|
0
|
$value = [$value] unless ref($value) eq 'ARRAY'; |
146
|
0
|
|
|
|
|
0
|
my %filters; |
147
|
0
|
|
|
|
|
0
|
for my $val (@$value) { |
148
|
0
|
0
|
|
|
|
0
|
if (ref($val) eq 'CODE') { |
149
|
0
|
|
|
|
|
0
|
$o->add_list($o->{ILSM}, $key, $val, []); |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
else { |
152
|
0
|
|
|
|
|
0
|
eval { require Inline::Filters }; |
|
0
|
|
|
|
|
0
|
|
153
|
0
|
0
|
|
|
|
0
|
croak "'FILTERS' option requires Inline::Filters to be installed." |
154
|
|
|
|
|
|
|
if $@; |
155
|
|
|
|
|
|
|
%filters = Inline::Filters::get_filters($o->{API}{language}) |
156
|
0
|
0
|
|
|
|
0
|
unless keys %filters; |
157
|
0
|
0
|
|
|
|
0
|
if (defined $filters{$val}) { |
158
|
|
|
|
|
|
|
my $filter = Inline::Filters->new($val, |
159
|
0
|
|
|
|
|
0
|
$filters{$val}); |
160
|
0
|
|
|
|
|
0
|
$o->add_list($o->{ILSM}, $key, $filter, []); |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
else { |
163
|
0
|
|
|
|
|
0
|
croak "Invalid filter $val specified."; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
} |
167
|
0
|
|
|
|
|
0
|
next; |
168
|
|
|
|
|
|
|
} |
169
|
0
|
0
|
|
|
|
0
|
if ($key eq 'STRUCTS') { |
170
|
|
|
|
|
|
|
# A list of struct names |
171
|
0
|
0
|
|
|
|
0
|
if (ref($value) eq 'ARRAY') { |
|
|
0
|
|
|
|
|
|
172
|
0
|
|
|
|
|
0
|
for my $val (@$value) { |
173
|
0
|
0
|
|
|
|
0
|
croak "Invalid value for 'STRUCTS' option" |
174
|
|
|
|
|
|
|
unless ($val =~ /^[_a-z][_0-9a-z]*$/i); |
175
|
0
|
|
|
|
|
0
|
$o->{STRUCT}{$val}++; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
# Enable or disable |
179
|
|
|
|
|
|
|
elsif ($value =~ /^\d+$/) { |
180
|
0
|
|
|
|
|
0
|
$o->{STRUCT}{'.any'} = $value; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
# A single struct name |
183
|
|
|
|
|
|
|
else { |
184
|
0
|
0
|
|
|
|
0
|
croak "Invalid value for 'STRUCTS' option" |
185
|
|
|
|
|
|
|
unless ($value =~ /^[_a-z][_0-9a-z]*$/i); |
186
|
0
|
|
|
|
|
0
|
$o->{STRUCT}{$value}++; |
187
|
|
|
|
|
|
|
} |
188
|
0
|
|
|
|
|
0
|
eval { require Inline::Struct }; |
|
0
|
|
|
|
|
0
|
|
189
|
0
|
0
|
|
|
|
0
|
croak "'STRUCTS' option requires Inline::Struct to be installed." |
190
|
|
|
|
|
|
|
if $@; |
191
|
0
|
|
|
|
|
0
|
$o->{STRUCT}{'.any'} = 1; |
192
|
0
|
|
|
|
|
0
|
next; |
193
|
|
|
|
|
|
|
} |
194
|
0
|
0
|
|
|
|
0
|
if($key eq 'PROTOTYPES') { |
195
|
0
|
|
|
|
|
0
|
$o->{CONFIG}{PROTOTYPES} = $value; |
196
|
0
|
0
|
|
|
|
0
|
next if $value eq 'ENABLE'; |
197
|
0
|
0
|
|
|
|
0
|
next if $value eq 'DISABLE'; |
198
|
0
|
|
|
|
|
0
|
die "PROTOTYPES can be only either 'ENABLE' or 'DISABLE' - not $value"; |
199
|
|
|
|
|
|
|
} |
200
|
0
|
0
|
|
|
|
0
|
if($key eq 'PROTOTYPE') { |
201
|
0
|
0
|
|
|
|
0
|
die "PROTOTYPE configure arg must specify a hash reference" |
202
|
|
|
|
|
|
|
unless ref($value) eq 'HASH'; |
203
|
0
|
|
|
|
|
0
|
$o->{CONFIG}{PROTOTYPE} = $value; |
204
|
0
|
|
|
|
|
0
|
next; |
205
|
|
|
|
|
|
|
} |
206
|
0
|
|
|
|
|
0
|
my $class = ref $o; # handles subclasses correctly. |
207
|
0
|
|
|
|
|
0
|
croak "'$key' is not a valid config option for $class\n"; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub add_list { |
212
|
0
|
|
|
0
|
0
|
0
|
my $o = shift; |
213
|
0
|
|
|
|
|
0
|
my ($ref, $key, $value, $default) = @_; |
214
|
0
|
0
|
|
|
|
0
|
$value = [$value] unless ref $value eq 'ARRAY'; |
215
|
0
|
|
|
|
|
0
|
for (@$value) { |
216
|
0
|
0
|
|
|
|
0
|
if (defined $_) { |
217
|
0
|
|
|
|
|
0
|
push @{$ref->{$key}}, $_; |
|
0
|
|
|
|
|
0
|
|
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
else { |
220
|
0
|
|
|
|
|
0
|
$ref->{$key} = $default; |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
sub add_string { |
226
|
0
|
|
|
0
|
0
|
0
|
my $o = shift; |
227
|
0
|
|
|
|
|
0
|
my ($ref, $key, $value, $default) = @_; |
228
|
0
|
0
|
|
|
|
0
|
$value = [$value] unless ref $value; |
229
|
0
|
0
|
|
|
|
0
|
croak usage_validate($key) unless ref($value) eq 'ARRAY'; |
230
|
0
|
|
|
|
|
0
|
for (@$value) { |
231
|
0
|
0
|
|
|
|
0
|
if (defined $_) { |
232
|
0
|
|
|
|
|
0
|
$ref->{$key} .= ' ' . $_; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
else { |
235
|
0
|
|
|
|
|
0
|
$ref->{$key} = $default; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub add_text { |
241
|
0
|
|
|
0
|
0
|
0
|
my $o = shift; |
242
|
0
|
|
|
|
|
0
|
my ($ref, $key, $value, $default) = @_; |
243
|
0
|
0
|
|
|
|
0
|
$value = [$value] unless ref $value; |
244
|
0
|
0
|
|
|
|
0
|
croak usage_validate($key) unless ref($value) eq 'ARRAY'; |
245
|
0
|
|
|
|
|
0
|
for (@$value) { |
246
|
0
|
0
|
|
|
|
0
|
if (defined $_) { |
247
|
0
|
|
|
|
|
0
|
chomp; |
248
|
0
|
|
|
|
|
0
|
$ref->{$key} .= $_ . "\n"; |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
else { |
251
|
0
|
|
|
|
|
0
|
$ref->{$key} = $default; |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
#============================================================================== |
257
|
|
|
|
|
|
|
# Return a small report about the C code.. |
258
|
|
|
|
|
|
|
#============================================================================== |
259
|
|
|
|
|
|
|
sub info { |
260
|
0
|
|
|
0
|
0
|
0
|
my $o = shift; |
261
|
0
|
0
|
|
|
|
0
|
return <{ILSM}{XSMODE}; |
262
|
|
|
|
|
|
|
No information is currently generated when using XSMODE. |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
END |
265
|
0
|
|
|
|
|
0
|
my $text = ''; |
266
|
0
|
|
|
|
|
0
|
$o->preprocess; |
267
|
0
|
|
|
|
|
0
|
$o->parse; |
268
|
0
|
0
|
|
|
|
0
|
if (defined $o->{ILSM}{parser}{data}{functions}) { |
269
|
0
|
|
|
|
|
0
|
$text .= "The following Inline $o->{API}{language} function(s) have been successfully bound to Perl:\n"; |
270
|
0
|
|
|
|
|
0
|
my $parser = $o->{ILSM}{parser}; |
271
|
0
|
|
|
|
|
0
|
my $data = $parser->{data}; |
272
|
0
|
|
|
|
|
0
|
for my $function (sort @{$data->{functions}}) { |
|
0
|
|
|
|
|
0
|
|
273
|
0
|
|
|
|
|
0
|
my $return_type = $data->{function}{$function}{return_type}; |
274
|
0
|
|
|
|
|
0
|
my @arg_names = @{$data->{function}{$function}{arg_names}}; |
|
0
|
|
|
|
|
0
|
|
275
|
0
|
|
|
|
|
0
|
my @arg_types = @{$data->{function}{$function}{arg_types}}; |
|
0
|
|
|
|
|
0
|
|
276
|
0
|
|
|
|
|
0
|
my @args = map {$_ . ' ' . shift @arg_names} @arg_types; |
|
0
|
|
|
|
|
0
|
|
277
|
0
|
|
|
|
|
0
|
$text .= "\t$return_type $function(" . join(', ', @args) . ")\n"; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
else { |
281
|
0
|
|
|
|
|
0
|
$text .= "No $o->{API}{language} functions have been successfully bound to Perl.\n\n"; |
282
|
|
|
|
|
|
|
} |
283
|
0
|
0
|
|
|
|
0
|
$text .= Inline::Struct::info($o) if $o->{STRUCT}{'.any'}; |
284
|
0
|
|
|
|
|
0
|
return $text; |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub config { |
288
|
0
|
|
|
0
|
0
|
0
|
my $o = shift; |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
#============================================================================== |
292
|
|
|
|
|
|
|
# Parse and compile C code |
293
|
|
|
|
|
|
|
#============================================================================== |
294
|
|
|
|
|
|
|
my $total_build_time; |
295
|
|
|
|
|
|
|
sub build { |
296
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
297
|
|
|
|
|
|
|
|
298
|
1
|
50
|
|
|
|
4
|
if ($o->{CONFIG}{BUILD_TIMERS}) { |
299
|
0
|
|
|
|
|
0
|
eval {require Time::HiRes}; |
|
0
|
|
|
|
|
0
|
|
300
|
0
|
0
|
|
|
|
0
|
croak "You need Time::HiRes for BUILD_TIMERS option:\n$@" if $@; |
301
|
0
|
|
|
|
|
0
|
$total_build_time = Time::HiRes::time(); |
302
|
|
|
|
|
|
|
} |
303
|
1
|
|
|
|
|
5
|
$o->call('preprocess', 'Build Preprocess'); |
304
|
1
|
|
|
|
|
4
|
$o->call('parse', 'Build Parse'); |
305
|
1
|
|
|
|
|
5
|
$o->call('write_XS', 'Build Glue 1'); |
306
|
1
|
|
|
|
|
3
|
$o->call('write_Inline_headers', 'Build Glue 2'); |
307
|
1
|
|
|
|
|
4
|
$o->call('write_Makefile_PL', 'Build Glue 3'); |
308
|
1
|
|
|
|
|
3
|
$o->call('compile', 'Build Compile'); |
309
|
0
|
0
|
|
|
|
0
|
if ($o->{CONFIG}{BUILD_TIMERS}) { |
310
|
0
|
|
|
|
|
0
|
$total_build_time = Time::HiRes::time() - $total_build_time; |
311
|
0
|
|
|
|
|
0
|
printf STDERR "Total Build Time: %5.4f secs\n", $total_build_time; |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
sub call { |
316
|
8
|
|
|
8
|
0
|
25
|
my ($o, $method, $header, $indent) = (@_, 0); |
317
|
8
|
|
|
|
|
11
|
my $time; |
318
|
8
|
|
|
|
|
23
|
my $i = ' ' x $indent; |
319
|
8
|
50
|
|
|
|
22
|
print STDERR "${i}Starting $header Stage\n" if $o->{CONFIG}{BUILD_NOISY}; |
320
|
|
|
|
|
|
|
$time = Time::HiRes::time() |
321
|
8
|
50
|
|
|
|
21
|
if $o->{CONFIG}{BUILD_TIMERS}; |
322
|
|
|
|
|
|
|
|
323
|
8
|
|
|
|
|
36
|
$o->$method(); |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
$time = Time::HiRes::time() - $time |
326
|
6
|
50
|
|
|
|
19154
|
if $o->{CONFIG}{BUILD_TIMERS}; |
327
|
6
|
50
|
|
|
|
20
|
print STDERR "${i}Finished $header Stage\n" if $o->{CONFIG}{BUILD_NOISY}; |
328
|
|
|
|
|
|
|
printf STDERR "${i}Time for $header Stage: %5.4f secs\n", $time |
329
|
6
|
50
|
|
|
|
17
|
if $o->{CONFIG}{BUILD_TIMERS}; |
330
|
6
|
50
|
|
|
|
32
|
print STDERR "\n" if $o->{CONFIG}{BUILD_NOISY}; |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
#============================================================================== |
334
|
|
|
|
|
|
|
# Apply any |
335
|
|
|
|
|
|
|
#============================================================================== |
336
|
|
|
|
|
|
|
sub preprocess { |
337
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
338
|
1
|
50
|
|
|
|
4
|
return if $o->{ILSM}{parser}; |
339
|
1
|
|
|
|
|
5
|
$o->get_maps; |
340
|
1
|
|
|
|
|
3
|
$o->get_types; |
341
|
1
|
|
|
|
|
2
|
$o->{ILSM}{code} = $o->filter(@{$o->{ILSM}{FILTERS}}); |
|
1
|
|
|
|
|
17
|
|
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
#============================================================================== |
345
|
|
|
|
|
|
|
# Parse the function definition information out of the C code |
346
|
|
|
|
|
|
|
#============================================================================== |
347
|
|
|
|
|
|
|
sub parse { |
348
|
1
|
|
|
1
|
0
|
1
|
my $o = shift; |
349
|
1
|
50
|
|
|
|
4
|
return if $o->{ILSM}{parser}; |
350
|
1
|
50
|
|
|
|
4
|
return if $o->{ILSM}{XSMODE}; |
351
|
1
|
|
|
|
|
3
|
my $parser = $o->{ILSM}{parser} = $o->get_parser; |
352
|
1
|
|
|
|
|
75096
|
$parser->{data}{typeconv} = $o->{ILSM}{typeconv}; |
353
|
1
|
|
|
|
|
4
|
$parser->{data}{AUTOWRAP} = $o->{ILSM}{AUTOWRAP}; |
354
|
1
|
50
|
|
|
|
7
|
Inline::Struct::parse($o) if $o->{STRUCT}{'.any'}; |
355
|
|
|
|
|
|
|
$parser->code($o->{ILSM}{code}) |
356
|
1
|
50
|
|
|
|
13
|
or croak <
|
357
|
0
|
|
|
|
|
0
|
Bad $o->{API}{language} code passed to Inline at @{[caller(2)]} |
358
|
|
|
|
|
|
|
END |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
# Create and initialize a parser |
362
|
|
|
|
|
|
|
sub get_parser { |
363
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
364
|
1
|
50
|
|
|
|
4
|
Inline::C::_parser_test("Inline::C::get_parser called\n") if $o->{CONFIG}{_TESTING}; |
365
|
1
|
|
|
|
|
472
|
require Inline::C::ParseRecDescent; |
366
|
1
|
|
|
|
|
4
|
Inline::C::ParseRecDescent::get_parser($o); |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
#============================================================================== |
370
|
|
|
|
|
|
|
# Gather the path names of all applicable typemap files. |
371
|
|
|
|
|
|
|
#============================================================================== |
372
|
|
|
|
|
|
|
sub get_maps { |
373
|
1
|
|
|
1
|
0
|
1
|
my $o = shift; |
374
|
|
|
|
|
|
|
|
375
|
1
|
50
|
|
|
|
5
|
print STDERR "get_maps Stage\n" if $o->{CONFIG}{BUILD_NOISY}; |
376
|
1
|
|
|
|
|
3
|
my $typemap = ''; |
377
|
1
|
|
|
|
|
3
|
my $file; |
378
|
1
|
|
|
|
|
88
|
$file = File::Spec->catfile($Config::Config{installprivlib},"ExtUtils","typemap"); |
379
|
1
|
50
|
|
|
|
48
|
$typemap = $file if -f $file; |
380
|
1
|
|
|
|
|
15
|
$file = File::Spec->catfile($Config::Config{privlibexp} ,"ExtUtils","typemap"); |
381
|
1
|
50
|
33
|
|
|
8
|
$typemap = $file |
382
|
|
|
|
|
|
|
if (not $typemap and -f $file); |
383
|
1
|
0
|
33
|
|
|
4
|
warn "Can't find the default system typemap file" |
384
|
|
|
|
|
|
|
if (not $typemap and $^W); |
385
|
|
|
|
|
|
|
|
386
|
1
|
50
|
|
|
|
4
|
unshift(@{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}, $typemap) if $typemap; |
|
1
|
|
|
|
|
4
|
|
387
|
|
|
|
|
|
|
|
388
|
1
|
50
|
|
|
|
5
|
if (not $o->UNTAINT) { |
389
|
0
|
|
|
|
|
0
|
require FindBin; |
390
|
0
|
|
|
|
|
0
|
$file = File::Spec->catfile($FindBin::Bin,"typemap"); |
391
|
0
|
0
|
|
|
|
0
|
if ( -f $file ) { |
392
|
0
|
|
|
|
|
0
|
push(@{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}, $file); |
|
0
|
|
|
|
|
0
|
|
393
|
|
|
|
|
|
|
} |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
#============================================================================== |
398
|
|
|
|
|
|
|
# This routine parses XS typemap files to get a list of valid types to create |
399
|
|
|
|
|
|
|
# bindings to. This code is mostly hacked out of Larry Wall's xsubpp program. |
400
|
|
|
|
|
|
|
#============================================================================== |
401
|
|
|
|
|
|
|
sub get_types { |
402
|
1
|
|
|
1
|
0
|
2
|
my (%type_kind, %proto_letter, %input_expr, %output_expr); |
403
|
1
|
|
|
|
|
2
|
my $o = shift; |
404
|
1
|
|
|
|
|
2
|
local $_; |
405
|
|
|
|
|
|
|
croak "No typemaps specified for Inline C code" |
406
|
1
|
50
|
|
|
|
2
|
unless @{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}; |
|
1
|
|
|
|
|
4
|
|
407
|
|
|
|
|
|
|
|
408
|
1
|
|
|
|
|
3
|
my $proto_re = "[" . quotemeta('\$%&*@;') . "]"; |
409
|
1
|
|
|
|
|
1
|
foreach my $typemap (@{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}) { |
|
1
|
|
|
|
|
4
|
|
410
|
1
|
50
|
|
|
|
23
|
next unless -e $typemap; |
411
|
|
|
|
|
|
|
# skip directories, binary files etc. |
412
|
1
|
50
|
|
|
|
50
|
warn("Warning: ignoring non-text typemap file '$typemap'\n"), next |
413
|
|
|
|
|
|
|
unless -T $typemap; |
414
|
1
|
50
|
|
|
|
30
|
open(TYPEMAP, $typemap) |
415
|
|
|
|
|
|
|
or warn ("Warning: could not open typemap file '$typemap': $!\n"), next; |
416
|
1
|
|
|
|
|
3
|
my $mode = 'Typemap'; |
417
|
1
|
|
|
|
|
2
|
my $junk = ""; |
418
|
1
|
|
|
|
|
2
|
my $current = \$junk; |
419
|
1
|
|
|
|
|
13
|
while () { |
420
|
447
|
100
|
|
|
|
1060
|
next if /^\s*\#/; |
421
|
438
|
|
|
|
|
580
|
my $line_no = $. + 1; |
422
|
438
|
100
|
|
|
|
746
|
if (/^INPUT\s*$/) {$mode = 'Input'; $current = \$junk; next} |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
10
|
|
423
|
437
|
100
|
|
|
|
714
|
if (/^OUTPUT\s*$/) {$mode = 'Output'; $current = \$junk; next} |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
6
|
|
424
|
436
|
50
|
|
|
|
702
|
if (/^TYPEMAP\s*$/) {$mode = 'Typemap'; $current = \$junk; next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
425
|
436
|
100
|
|
|
|
1210
|
if ($mode eq 'Typemap') { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
426
|
54
|
|
|
|
|
71
|
chomp; |
427
|
54
|
|
|
|
|
102
|
my $line = $_; |
428
|
54
|
|
|
|
|
87
|
TrimWhitespace($_); |
429
|
|
|
|
|
|
|
# skip blank lines and comment lines |
430
|
54
|
100
|
66
|
|
|
264
|
next if /^$/ or /^\#/; |
431
|
51
|
50
|
|
|
|
454
|
my ($type,$kind, $proto) = |
432
|
|
|
|
|
|
|
/^\s*(.*?\S)\s+(\S+)\s*($proto_re*)\s*$/ or |
433
|
|
|
|
|
|
|
warn("Warning: File '$typemap' Line $. '$line' TYPEMAP entry needs 2 or 3 columns\n"), next; |
434
|
51
|
|
|
|
|
89
|
$type = TidyType($type); |
435
|
51
|
|
|
|
|
96
|
$type_kind{$type} = $kind; |
436
|
|
|
|
|
|
|
# prototype defaults to '$' |
437
|
51
|
50
|
|
|
|
98
|
$proto = "\$" unless $proto; |
438
|
51
|
50
|
|
|
|
65
|
warn("Warning: File '$typemap' Line $. '$line' Invalid prototype '$proto'\n") |
439
|
|
|
|
|
|
|
unless ValidProtoString($proto); |
440
|
51
|
|
|
|
|
75
|
$proto_letter{$type} = C_string($proto); |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
elsif (/^\s/) { |
443
|
296
|
|
|
|
|
1225
|
$$current .= $_; |
444
|
|
|
|
|
|
|
} |
445
|
|
|
|
|
|
|
elsif ($mode eq 'Input') { |
446
|
43
|
|
|
|
|
161
|
s/\s+$//; |
447
|
43
|
|
|
|
|
108
|
$input_expr{$_} = ''; |
448
|
43
|
|
|
|
|
186
|
$current = \$input_expr{$_}; |
449
|
|
|
|
|
|
|
} |
450
|
|
|
|
|
|
|
else { |
451
|
43
|
|
|
|
|
149
|
s/\s+$//; |
452
|
43
|
|
|
|
|
94
|
$output_expr{$_} = ''; |
453
|
43
|
|
|
|
|
200
|
$current = \$output_expr{$_}; |
454
|
|
|
|
|
|
|
} |
455
|
|
|
|
|
|
|
} |
456
|
1
|
|
|
|
|
12
|
close(TYPEMAP); |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
my %valid_types = |
460
|
51
|
|
|
|
|
55
|
map {($_, 1)} |
461
|
1
|
|
|
|
|
15
|
grep {defined $input_expr{$type_kind{$_}}} |
|
51
|
|
|
|
|
61
|
|
462
|
|
|
|
|
|
|
keys %type_kind; |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
my %valid_rtypes = |
465
|
52
|
|
|
|
|
46
|
map {($_, 1)} |
466
|
1
|
|
|
|
|
9
|
(grep {defined $output_expr{$type_kind{$_}}} |
|
51
|
|
|
|
|
50
|
|
467
|
|
|
|
|
|
|
keys %type_kind), 'void'; |
468
|
|
|
|
|
|
|
|
469
|
1
|
|
|
|
|
6
|
$o->{ILSM}{typeconv}{type_kind} = \%type_kind; |
470
|
1
|
|
|
|
|
3
|
$o->{ILSM}{typeconv}{input_expr} = \%input_expr; |
471
|
1
|
|
|
|
|
1
|
$o->{ILSM}{typeconv}{output_expr} = \%output_expr; |
472
|
1
|
|
|
|
|
3
|
$o->{ILSM}{typeconv}{valid_types} = \%valid_types; |
473
|
1
|
|
|
|
|
8
|
$o->{ILSM}{typeconv}{valid_rtypes} = \%valid_rtypes; |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
sub ValidProtoString ($) { |
477
|
51
|
|
|
51
|
0
|
60
|
my $string = shift; |
478
|
51
|
|
|
|
|
48
|
my $proto_re = "[" . quotemeta('\$%&*@;') . "]"; |
479
|
51
|
50
|
|
|
|
323
|
return ($string =~ /^$proto_re+$/) ? $string : 0; |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
sub TrimWhitespace { |
483
|
105
|
|
|
105
|
0
|
401
|
$_[0] =~ s/^\s+|\s+$//go; |
484
|
|
|
|
|
|
|
} |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
sub TidyType { |
487
|
51
|
|
|
51
|
0
|
70
|
local $_ = shift; |
488
|
51
|
|
|
|
|
102
|
s|\s*(\*+)\s*|$1|g; |
489
|
51
|
|
|
|
|
102
|
s|(\*+)| $1 |g; |
490
|
51
|
|
|
|
|
98
|
s|\s+| |g; |
491
|
51
|
|
|
|
|
72
|
TrimWhitespace($_); |
492
|
51
|
|
|
|
|
92
|
$_; |
493
|
|
|
|
|
|
|
} |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
sub C_string ($) { |
496
|
51
|
|
|
51
|
0
|
68
|
(my $string = shift) =~ s|\\|\\\\|g; |
497
|
51
|
|
|
|
|
314
|
$string; |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
#============================================================================== |
501
|
|
|
|
|
|
|
# Write the XS code |
502
|
|
|
|
|
|
|
#============================================================================== |
503
|
|
|
|
|
|
|
sub write_XS { |
504
|
1
|
|
|
1
|
0
|
1
|
my $o = shift; |
505
|
1
|
|
|
|
|
4
|
my $modfname = $o->{API}{modfname}; |
506
|
1
|
|
|
|
|
2
|
my $module = $o->{API}{module}; |
507
|
1
|
|
|
|
|
18
|
$o->mkpath($o->{API}{build_dir}); |
508
|
1
|
50
|
|
|
|
166
|
open XS, "> ".File::Spec->catfile($o->{API}{build_dir},"$modfname.xs") |
509
|
|
|
|
|
|
|
or croak $!; |
510
|
1
|
50
|
|
|
|
6
|
if ($o->{ILSM}{XSMODE}) { |
511
|
0
|
0
|
0
|
|
|
0
|
warn <{ILSM}{code} !~ /MODULE\s*=\s*$module\b/; |
512
|
|
|
|
|
|
|
While using Inline XSMODE, your XS code does not have a line with |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
MODULE = $module |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
You should use the Inline NAME config option, and it should match the |
517
|
|
|
|
|
|
|
XS MODULE name. |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
END |
520
|
0
|
|
|
|
|
0
|
print XS $o->xs_code; |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
else { |
523
|
1
|
|
|
|
|
4
|
print XS $o->xs_generate; |
524
|
|
|
|
|
|
|
} |
525
|
1
|
|
|
|
|
36
|
close XS; |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
#============================================================================== |
529
|
|
|
|
|
|
|
# Generate the XS glue code (piece together lots of snippets) |
530
|
|
|
|
|
|
|
#============================================================================== |
531
|
|
|
|
|
|
|
sub xs_generate { |
532
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
533
|
1
|
|
|
|
|
4
|
return join '', ($o->xs_includes, |
534
|
|
|
|
|
|
|
$o->xs_struct_macros, |
535
|
|
|
|
|
|
|
$o->xs_code, |
536
|
|
|
|
|
|
|
$o->xs_struct_code, |
537
|
|
|
|
|
|
|
$o->xs_bindings, |
538
|
|
|
|
|
|
|
$o->xs_boot, |
539
|
|
|
|
|
|
|
); |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
sub xs_includes { |
543
|
1
|
|
|
1
|
0
|
1
|
my $o = shift; |
544
|
1
|
|
|
|
|
6
|
return $o->{ILSM}{AUTO_INCLUDE}; |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
sub xs_struct_macros { |
548
|
1
|
|
|
1
|
0
|
1
|
my $o = shift; |
549
|
1
|
|
|
|
|
5
|
return $o->{STRUCT}{'.macros'}; |
550
|
|
|
|
|
|
|
} |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
sub xs_code { |
553
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
554
|
1
|
|
|
|
|
4
|
return $o->{ILSM}{code}; |
555
|
|
|
|
|
|
|
} |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
sub xs_struct_code { |
558
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
559
|
1
|
|
|
|
|
4
|
return $o->{STRUCT}{'.xs'}; |
560
|
|
|
|
|
|
|
} |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
sub xs_boot { |
563
|
1
|
|
|
1
|
0
|
1
|
my $o = shift; |
564
|
1
|
0
|
33
|
|
|
3
|
if (defined $o->{ILSM}{XS}{BOOT} and |
565
|
|
|
|
|
|
|
$o->{ILSM}{XS}{BOOT}) { |
566
|
0
|
|
|
|
|
0
|
return <
|
567
|
|
|
|
|
|
|
BOOT: |
568
|
|
|
|
|
|
|
$o->{ILSM}{XS}{BOOT} |
569
|
|
|
|
|
|
|
END |
570
|
|
|
|
|
|
|
} |
571
|
1
|
|
|
|
|
15
|
return ''; |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
sub xs_bindings { |
575
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
576
|
1
|
|
|
|
|
3
|
my $dir = '_Inline_test'; |
577
|
|
|
|
|
|
|
|
578
|
1
|
50
|
|
|
|
4
|
if($o->{CONFIG}{_TESTING}) { |
579
|
0
|
0
|
|
|
|
0
|
if(! -d $dir) { |
580
|
0
|
|
|
|
|
0
|
my $ok = mkdir $dir; |
581
|
0
|
0
|
|
|
|
0
|
warn $! if !$ok; |
582
|
|
|
|
|
|
|
} |
583
|
|
|
|
|
|
|
|
584
|
0
|
0
|
|
|
|
0
|
if(! -f "$dir/void_test") { |
585
|
0
|
0
|
|
|
|
0
|
warn $! if !open(TEST_FH, '>', "$dir/void_test"); |
586
|
0
|
0
|
|
|
|
0
|
warn $! if !close(TEST_FH); |
587
|
|
|
|
|
|
|
} |
588
|
|
|
|
|
|
|
} |
589
|
|
|
|
|
|
|
|
590
|
1
|
|
|
|
|
4
|
my ($pkg, $module) = @{$o->{API}}{qw(pkg module)}; |
|
1
|
|
|
|
|
4
|
|
591
|
1
|
50
|
|
|
|
4
|
my $prefix = (($o->{ILSM}{XS}{PREFIX}) ? |
592
|
|
|
|
|
|
|
"PREFIX = $o->{ILSM}{XS}{PREFIX}" : |
593
|
|
|
|
|
|
|
''); |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
my $prototypes = defined($o->{CONFIG}{PROTOTYPES}) ? $o->{CONFIG}{PROTOTYPES} |
596
|
1
|
50
|
|
|
|
5
|
: 'DISABLE'; |
597
|
|
|
|
|
|
|
|
598
|
1
|
|
|
|
|
6
|
my $XS = <
|
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
MODULE = $module PACKAGE = $pkg $prefix |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
PROTOTYPES: $prototypes |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
END |
605
|
|
|
|
|
|
|
|
606
|
1
|
|
|
|
|
3
|
my $parser = $o->{ILSM}{parser}; |
607
|
1
|
|
|
|
|
2
|
my $data = $parser->{data}; |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
warn("Warning. No Inline C functions bound to Perl in ", $o->{API}{script}, "\n" . |
610
|
|
|
|
|
|
|
"Check your C function definition(s) for Inline compatibility\n\n") |
611
|
1
|
0
|
33
|
|
|
4
|
if ((not defined$data->{functions}) and ($^W)); |
612
|
|
|
|
|
|
|
|
613
|
1
|
|
|
|
|
2
|
for my $function (@{$data->{functions}}) { |
|
1
|
|
|
|
|
3
|
|
614
|
1
|
|
|
|
|
3
|
my $return_type = $data->{function}->{$function}->{return_type}; |
615
|
1
|
|
|
|
|
3
|
my @arg_names = @{$data->{function}->{$function}->{arg_names}}; |
|
1
|
|
|
|
|
3
|
|
616
|
1
|
|
|
|
|
3
|
my @arg_types = @{$data->{function}->{$function}->{arg_types}}; |
|
1
|
|
|
|
|
4
|
|
617
|
|
|
|
|
|
|
|
618
|
1
|
|
|
|
|
5
|
$XS .= join '', ("\n$return_type\n$function (", |
619
|
|
|
|
|
|
|
join(', ', @arg_names), ")\n"); |
620
|
|
|
|
|
|
|
|
621
|
1
|
|
|
|
|
3
|
for my $arg_name (@arg_names) { |
622
|
2
|
|
|
|
|
4
|
my $arg_type = shift @arg_types; |
623
|
2
|
50
|
|
|
|
8
|
last if $arg_type eq '...'; |
624
|
2
|
|
|
|
|
5
|
$XS .= "\t$arg_type\t$arg_name\n"; |
625
|
|
|
|
|
|
|
} |
626
|
|
|
|
|
|
|
|
627
|
1
|
|
|
|
|
2
|
my %h; |
628
|
1
|
50
|
|
|
|
5
|
if (defined($o->{CONFIG}{PROTOTYPE})) { |
629
|
0
|
|
|
|
|
0
|
%h = %{$o->{CONFIG}{PROTOTYPE}}; |
|
0
|
|
|
|
|
0
|
|
630
|
|
|
|
|
|
|
} |
631
|
|
|
|
|
|
|
|
632
|
1
|
50
|
|
|
|
4
|
if(defined($h{$function})) { |
633
|
0
|
|
|
|
|
0
|
$XS .= " PROTOTYPE: $h{$function}\n"; |
634
|
|
|
|
|
|
|
} |
635
|
|
|
|
|
|
|
|
636
|
1
|
|
|
|
|
2
|
my $listargs = ''; |
637
|
1
|
50
|
33
|
|
|
7
|
$listargs = pop @arg_names if (@arg_names and |
638
|
|
|
|
|
|
|
$arg_names[-1] eq '...'); |
639
|
1
|
|
|
|
|
3
|
my $arg_name_list = join(', ', @arg_names); |
640
|
|
|
|
|
|
|
|
641
|
1
|
50
|
|
|
|
9
|
if ($return_type eq 'void') { |
|
|
50
|
|
|
|
|
|
642
|
0
|
0
|
|
|
|
0
|
if($o->{CONFIG}{_TESTING}) { |
643
|
0
|
|
|
|
|
0
|
$XS .= <
|
644
|
|
|
|
|
|
|
PREINIT: |
645
|
|
|
|
|
|
|
PerlIO* stream; |
646
|
|
|
|
|
|
|
I32* temp; |
647
|
|
|
|
|
|
|
PPCODE: |
648
|
|
|
|
|
|
|
temp = PL_markstack_ptr++; |
649
|
|
|
|
|
|
|
$function($arg_name_list); |
650
|
|
|
|
|
|
|
stream = PerlIO_open(\"$dir/void_test\", \"a\"); |
651
|
|
|
|
|
|
|
if(stream == NULL) warn(\"%s\\n\", \"Unable to open $dir/void_test for appending\"); |
652
|
|
|
|
|
|
|
if (PL_markstack_ptr != temp) { |
653
|
|
|
|
|
|
|
PerlIO_printf(stream, \"%s\\n\", \"TRULY_VOID\"); |
654
|
|
|
|
|
|
|
PerlIO_close(stream); |
655
|
|
|
|
|
|
|
PL_markstack_ptr = temp; |
656
|
|
|
|
|
|
|
XSRETURN_EMPTY; /* return empty stack */ |
657
|
|
|
|
|
|
|
} |
658
|
|
|
|
|
|
|
PerlIO_printf(stream, \"%s\\n\", \"LIST_CONTEXT\"); |
659
|
|
|
|
|
|
|
PerlIO_close(stream); |
660
|
|
|
|
|
|
|
return; /* assume stack size is correct */ |
661
|
|
|
|
|
|
|
END |
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
else { |
664
|
0
|
|
|
|
|
0
|
$XS .= <
|
665
|
|
|
|
|
|
|
PREINIT: |
666
|
|
|
|
|
|
|
I32* temp; |
667
|
|
|
|
|
|
|
PPCODE: |
668
|
|
|
|
|
|
|
temp = PL_markstack_ptr++; |
669
|
|
|
|
|
|
|
$function($arg_name_list); |
670
|
|
|
|
|
|
|
if (PL_markstack_ptr != temp) { |
671
|
|
|
|
|
|
|
/* truly void, because dXSARGS not invoked */ |
672
|
|
|
|
|
|
|
PL_markstack_ptr = temp; |
673
|
|
|
|
|
|
|
XSRETURN_EMPTY; /* return empty stack */ |
674
|
|
|
|
|
|
|
} |
675
|
|
|
|
|
|
|
/* must have used dXSARGS; list context implied */ |
676
|
|
|
|
|
|
|
return; /* assume stack size is correct */ |
677
|
|
|
|
|
|
|
END |
678
|
|
|
|
|
|
|
} |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
elsif ($listargs) { |
681
|
0
|
|
|
|
|
0
|
$XS .= <
|
682
|
|
|
|
|
|
|
PREINIT: |
683
|
|
|
|
|
|
|
I32* temp; |
684
|
|
|
|
|
|
|
CODE: |
685
|
|
|
|
|
|
|
temp = PL_markstack_ptr++; |
686
|
|
|
|
|
|
|
RETVAL = $function($arg_name_list); |
687
|
|
|
|
|
|
|
PL_markstack_ptr = temp; |
688
|
|
|
|
|
|
|
OUTPUT: |
689
|
|
|
|
|
|
|
RETVAL |
690
|
|
|
|
|
|
|
END |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
} |
693
|
1
|
|
|
|
|
2
|
$XS .= "\n"; |
694
|
1
|
|
|
|
|
5
|
return $XS; |
695
|
|
|
|
|
|
|
} |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
#============================================================================== |
698
|
|
|
|
|
|
|
# Generate the INLINE.h file. |
699
|
|
|
|
|
|
|
#============================================================================== |
700
|
|
|
|
|
|
|
sub write_Inline_headers { |
701
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
702
|
|
|
|
|
|
|
|
703
|
1
|
50
|
|
|
|
69
|
open HEADER, "> ".File::Spec->catfile($o->{API}{build_dir},"INLINE.h") |
704
|
|
|
|
|
|
|
or croak; |
705
|
|
|
|
|
|
|
|
706
|
1
|
|
|
|
|
7
|
print HEADER <<'END'; |
707
|
|
|
|
|
|
|
#define Inline_Stack_Vars dXSARGS |
708
|
|
|
|
|
|
|
#define Inline_Stack_Items items |
709
|
|
|
|
|
|
|
#define Inline_Stack_Item(x) ST(x) |
710
|
|
|
|
|
|
|
#define Inline_Stack_Reset sp = mark |
711
|
|
|
|
|
|
|
#define Inline_Stack_Push(x) XPUSHs(x) |
712
|
|
|
|
|
|
|
#define Inline_Stack_Done PUTBACK |
713
|
|
|
|
|
|
|
#define Inline_Stack_Return(x) XSRETURN(x) |
714
|
|
|
|
|
|
|
#define Inline_Stack_Void XSRETURN(0) |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
#define INLINE_STACK_VARS Inline_Stack_Vars |
717
|
|
|
|
|
|
|
#define INLINE_STACK_ITEMS Inline_Stack_Items |
718
|
|
|
|
|
|
|
#define INLINE_STACK_ITEM(x) Inline_Stack_Item(x) |
719
|
|
|
|
|
|
|
#define INLINE_STACK_RESET Inline_Stack_Reset |
720
|
|
|
|
|
|
|
#define INLINE_STACK_PUSH(x) Inline_Stack_Push(x) |
721
|
|
|
|
|
|
|
#define INLINE_STACK_DONE Inline_Stack_Done |
722
|
|
|
|
|
|
|
#define INLINE_STACK_RETURN(x) Inline_Stack_Return(x) |
723
|
|
|
|
|
|
|
#define INLINE_STACK_VOID Inline_Stack_Void |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
#define inline_stack_vars Inline_Stack_Vars |
726
|
|
|
|
|
|
|
#define inline_stack_items Inline_Stack_Items |
727
|
|
|
|
|
|
|
#define inline_stack_item(x) Inline_Stack_Item(x) |
728
|
|
|
|
|
|
|
#define inline_stack_reset Inline_Stack_Reset |
729
|
|
|
|
|
|
|
#define inline_stack_push(x) Inline_Stack_Push(x) |
730
|
|
|
|
|
|
|
#define inline_stack_done Inline_Stack_Done |
731
|
|
|
|
|
|
|
#define inline_stack_return(x) Inline_Stack_Return(x) |
732
|
|
|
|
|
|
|
#define inline_stack_void Inline_Stack_Void |
733
|
|
|
|
|
|
|
END |
734
|
|
|
|
|
|
|
|
735
|
1
|
|
|
|
|
33
|
close HEADER; |
736
|
|
|
|
|
|
|
} |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
#============================================================================== |
739
|
|
|
|
|
|
|
# Generate the Makefile.PL |
740
|
|
|
|
|
|
|
#============================================================================== |
741
|
|
|
|
|
|
|
sub write_Makefile_PL { |
742
|
1
|
|
|
1
|
0
|
1
|
my $o = shift; |
743
|
1
|
|
|
|
|
3
|
$o->{ILSM}{xsubppargs} = ''; |
744
|
1
|
|
|
|
|
1
|
my $i = 0; |
745
|
1
|
|
|
|
|
2
|
for (@{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}) { |
|
1
|
|
|
|
|
5
|
|
746
|
1
|
|
|
|
|
5
|
$o->{ILSM}{xsubppargs} .= "-typemap \"$_\" "; |
747
|
1
|
|
|
|
|
4
|
$o->{ILSM}{MAKEFILE}{TYPEMAPS}->[$i++] = fix_space($_); |
748
|
|
|
|
|
|
|
} |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
my %options = ( |
751
|
|
|
|
|
|
|
VERSION => $o->{API}{version} || '0.00', |
752
|
1
|
|
|
|
|
6
|
%{$o->{ILSM}{MAKEFILE}}, |
753
|
|
|
|
|
|
|
NAME => $o->{API}{module}, |
754
|
1
|
|
50
|
|
|
8
|
); |
755
|
|
|
|
|
|
|
|
756
|
1
|
50
|
|
|
|
64
|
open MF, "> ".File::Spec->catfile($o->{API}{build_dir},"Makefile.PL") |
757
|
|
|
|
|
|
|
or croak; |
758
|
|
|
|
|
|
|
|
759
|
1
|
|
|
|
|
4
|
print MF <
|
760
|
|
|
|
|
|
|
use ExtUtils::MakeMaker; |
761
|
|
|
|
|
|
|
my %options = %\{ |
762
|
|
|
|
|
|
|
END |
763
|
|
|
|
|
|
|
|
764
|
1
|
|
|
|
|
3
|
local $Data::Dumper::Terse = 1; |
765
|
1
|
|
|
|
|
2
|
local $Data::Dumper::Indent = 1; |
766
|
1
|
|
|
|
|
6
|
print MF Data::Dumper::Dumper(\ %options); |
767
|
|
|
|
|
|
|
|
768
|
1
|
|
|
|
|
116
|
print MF <
|
769
|
|
|
|
|
|
|
\}; |
770
|
|
|
|
|
|
|
WriteMakefile(\%options); |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
# Remove the Makefile dependency. Causes problems on a few systems. |
773
|
|
|
|
|
|
|
sub MY::makefile { '' } |
774
|
|
|
|
|
|
|
END |
775
|
1
|
|
|
|
|
29
|
close MF; |
776
|
|
|
|
|
|
|
} |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
#============================================================================== |
779
|
|
|
|
|
|
|
# Run the build process. |
780
|
|
|
|
|
|
|
#============================================================================== |
781
|
|
|
|
|
|
|
sub compile { |
782
|
1
|
|
|
1
|
0
|
2
|
my $o = shift; |
783
|
|
|
|
|
|
|
|
784
|
1
|
|
|
|
|
2
|
my $build_dir = $o->{API}{build_dir}; |
785
|
1
|
|
|
|
|
2576
|
my $cwd = &cwd; |
786
|
1
|
50
|
|
|
|
21
|
($cwd) = $cwd =~ /(.*)/ if $o->UNTAINT; |
787
|
|
|
|
|
|
|
|
788
|
1
|
|
|
|
|
24
|
chdir $build_dir; |
789
|
|
|
|
|
|
|
# Run these in an eval block, so that we get to chdir back to |
790
|
|
|
|
|
|
|
# $cwd if there's a failure. (Ticket #81375.) |
791
|
1
|
|
|
|
|
3
|
eval { |
792
|
1
|
|
|
|
|
11
|
$o->call('makefile_pl', '"perl Makefile.PL"', 2); |
793
|
1
|
|
|
|
|
8
|
$o->call('make', '"make"', 2); |
794
|
0
|
|
|
|
|
0
|
$o->call('make_install', '"make install"', 2); |
795
|
|
|
|
|
|
|
}; |
796
|
1
|
|
|
|
|
1521
|
chdir $cwd; |
797
|
1
|
50
|
|
|
|
57
|
die if $@; #Die now that we've done the chdir back to $cwd. (#81375) |
798
|
0
|
|
|
|
|
0
|
$o->call('cleanup', 'Cleaning Up', 2); |
799
|
|
|
|
|
|
|
} |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
sub makefile_pl { |
802
|
1
|
|
|
1
|
0
|
3
|
my ($o) = @_; |
803
|
1
|
|
|
|
|
3
|
my $perl; |
804
|
|
|
|
|
|
|
-f ($perl = $Config::Config{perlpath}) |
805
|
1
|
50
|
33
|
|
|
126
|
or ($perl = $^X) |
806
|
|
|
|
|
|
|
or croak "Can't locate your perl binary"; |
807
|
1
|
50
|
|
|
|
7
|
$perl = qq{"$perl"} if $perl =~ m/\s/; |
808
|
1
|
|
|
|
|
9
|
$o->system_call("$perl Makefile.PL", 'out.Makefile_PL'); |
809
|
1
|
|
|
|
|
17
|
$o->fix_make; |
810
|
|
|
|
|
|
|
} |
811
|
|
|
|
|
|
|
sub make { |
812
|
1
|
|
|
1
|
0
|
4
|
my ($o) = @_; |
813
|
|
|
|
|
|
|
my $make = $o->{ILSM}{MAKE} || $Config::Config{make} |
814
|
1
|
50
|
33
|
|
|
115
|
or croak "Can't locate your make binary"; |
815
|
1
|
|
|
|
|
15
|
local $ENV{MAKEFLAGS} = $ENV{MAKEFLAGS} =~ s/(--jobserver-fds=[\d,]+)//; |
816
|
1
|
|
|
|
|
8
|
$o->system_call("$make", 'out.make'); |
817
|
|
|
|
|
|
|
} |
818
|
|
|
|
|
|
|
sub make_install { |
819
|
0
|
|
|
0
|
0
|
0
|
my ($o) = @_; |
820
|
|
|
|
|
|
|
my $make = $o->{ILSM}{MAKE} || $Config::Config{make} |
821
|
0
|
0
|
0
|
|
|
0
|
or croak "Can't locate your make binary"; |
822
|
0
|
|
|
|
|
0
|
local $ENV{MAKEFLAGS} = $ENV{MAKEFLAGS} =~ s/(--jobserver-fds=[\d,]+)//; |
823
|
0
|
|
|
|
|
0
|
$o->system_call("$make pure_install", 'out.make_install'); |
824
|
|
|
|
|
|
|
} |
825
|
|
|
|
|
|
|
sub cleanup { |
826
|
0
|
|
|
0
|
0
|
0
|
my ($o) = @_; |
827
|
|
|
|
|
|
|
my ($modpname, $modfname, $install_lib) = |
828
|
0
|
|
|
|
|
0
|
@{$o->{API}}{qw(modpname modfname install_lib)}; |
|
0
|
|
|
|
|
0
|
|
829
|
0
|
0
|
|
|
|
0
|
if ($o->{API}{cleanup}) { |
830
|
0
|
|
|
|
|
0
|
$o->rmpath(File::Spec->catdir($o->{API}{directory},'build'), |
831
|
|
|
|
|
|
|
$modpname); |
832
|
0
|
|
|
|
|
0
|
my $autodir = File::Spec->catdir($install_lib,'auto',$modpname); |
833
|
0
|
|
|
|
|
0
|
unlink (File::Spec->catfile($autodir,'.packlist'), |
834
|
|
|
|
|
|
|
File::Spec->catfile($autodir,'$modfname.bs'), |
835
|
|
|
|
|
|
|
File::Spec->catfile($autodir,'$modfname.exp'), #MSWin32 |
836
|
|
|
|
|
|
|
File::Spec->catfile($autodir,'$modfname.lib'), #MSWin32 |
837
|
|
|
|
|
|
|
); |
838
|
|
|
|
|
|
|
} |
839
|
|
|
|
|
|
|
} |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
sub system_call { |
842
|
2
|
|
|
2
|
0
|
8
|
my ($o, $cmd, $output_file) = @_; |
843
|
|
|
|
|
|
|
my $build_noisy = |
844
|
|
|
|
|
|
|
defined $ENV{PERL_INLINE_BUILD_NOISY} |
845
|
|
|
|
|
|
|
? $ENV{PERL_INLINE_BUILD_NOISY} |
846
|
2
|
50
|
|
|
|
10
|
: $o->{CONFIG}{BUILD_NOISY}; |
847
|
2
|
0
|
33
|
|
|
10
|
$build_noisy = undef if $build_noisy and $^O eq 'MSWin32' and $Config::Config{sh} =~ /^cmd/; |
|
|
|
33
|
|
|
|
|
848
|
2
|
50
|
|
|
|
11
|
if (not $build_noisy) { |
849
|
2
|
|
|
|
|
10
|
$cmd = "$cmd > $output_file 2>&1"; |
850
|
|
|
|
|
|
|
} |
851
|
2
|
50
|
|
|
|
20
|
($cmd) = $cmd =~ /(.*)/ if $o->UNTAINT; |
852
|
2
|
100
|
|
|
|
207003
|
system($cmd) == 0 |
853
|
|
|
|
|
|
|
or croak($o->build_error_message($cmd, $output_file, $build_noisy)); |
854
|
|
|
|
|
|
|
} |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
sub build_error_message { |
857
|
1
|
|
|
1
|
0
|
15
|
my ($o, $cmd, $output_file, $build_noisy) = @_; |
858
|
1
|
|
|
|
|
7
|
my $build_dir = $o->{API}{build_dir}; |
859
|
1
|
|
|
|
|
6
|
my $output = ''; |
860
|
1
|
50
|
33
|
|
|
58
|
if (not $build_noisy and |
861
|
|
|
|
|
|
|
open(OUTPUT, $output_file) |
862
|
|
|
|
|
|
|
) { |
863
|
1
|
|
|
|
|
16
|
local $/; |
864
|
1
|
|
|
|
|
271
|
$output = |
865
|
1
|
|
|
|
|
13
|
close OUTPUT; |
866
|
|
|
|
|
|
|
} |
867
|
|
|
|
|
|
|
|
868
|
1
|
|
|
|
|
9
|
my $errcode = $? >> 8; |
869
|
1
|
|
|
|
|
37
|
$output .= <
|
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
A problem was encountered while attempting to compile and install your Inline |
872
|
|
|
|
|
|
|
$o->{API}{language} code. The command that failed was: |
873
|
|
|
|
|
|
|
\"$cmd\" with error code $errcode |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
The build directory was: |
876
|
|
|
|
|
|
|
$build_dir |
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
To debug the problem, cd to the build directory, and inspect the output files. |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
END |
881
|
1
|
50
|
|
|
|
16
|
if ($cmd =~ /^make >/) { |
882
|
1
|
|
|
|
|
33
|
for (sort keys %ENV) { |
883
|
28
|
100
|
|
|
|
72
|
$output .= "$_ = $ENV{$_}\n" if /^MAKE/; |
884
|
|
|
|
|
|
|
} |
885
|
|
|
|
|
|
|
} |
886
|
1
|
|
|
|
|
59
|
return $output; |
887
|
|
|
|
|
|
|
} |
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
#============================================================================== |
890
|
|
|
|
|
|
|
# This routine fixes problems with the MakeMaker Makefile. |
891
|
|
|
|
|
|
|
#============================================================================== |
892
|
|
|
|
|
|
|
my %fixes = ( |
893
|
|
|
|
|
|
|
INSTALLSITEARCH => 'install_lib', |
894
|
|
|
|
|
|
|
INSTALLDIRS => 'installdirs', |
895
|
|
|
|
|
|
|
XSUBPPARGS => 'xsubppargs', |
896
|
|
|
|
|
|
|
INSTALLSITELIB => 'install_lib', |
897
|
|
|
|
|
|
|
); |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
sub fix_make { |
900
|
1
|
|
|
1
|
|
13
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
940
|
|
901
|
1
|
|
|
1
|
0
|
3
|
my (@lines, $fix); |
902
|
1
|
|
|
|
|
4
|
my $o = shift; |
903
|
|
|
|
|
|
|
|
904
|
1
|
|
|
|
|
12
|
$o->{ILSM}{install_lib} = $o->{API}{install_lib}; |
905
|
1
|
|
|
|
|
6
|
$o->{ILSM}{installdirs} = 'site'; |
906
|
|
|
|
|
|
|
|
907
|
1
|
50
|
|
|
|
39
|
open(MAKEFILE, '< Makefile') |
908
|
|
|
|
|
|
|
or croak "Can't open Makefile for input: $!\n"; |
909
|
1
|
|
|
|
|
1000
|
@lines = ; |
910
|
1
|
|
|
|
|
79
|
close MAKEFILE; |
911
|
|
|
|
|
|
|
|
912
|
1
|
50
|
|
|
|
75
|
open(MAKEFILE, '> Makefile') |
913
|
|
|
|
|
|
|
or croak "Can't open Makefile for output: $!\n"; |
914
|
1
|
|
|
|
|
5
|
for (@lines) { |
915
|
1034
|
100
|
100
|
|
|
2774
|
if (/^(\w+)\s*=\s*\S+.*$/ and |
916
|
|
|
|
|
|
|
$fix = $fixes{$1} |
917
|
|
|
|
|
|
|
) { |
918
|
4
|
|
|
|
|
7
|
my $fixed = $o->{ILSM}{$fix}; |
919
|
4
|
100
|
|
|
|
44
|
$fixed = fix_space($fixed) if $fix eq 'install_lib'; |
920
|
4
|
|
|
|
|
13
|
print MAKEFILE "$1 = $fixed\n"; |
921
|
|
|
|
|
|
|
} |
922
|
|
|
|
|
|
|
else { |
923
|
1030
|
|
|
|
|
1635
|
print MAKEFILE; |
924
|
|
|
|
|
|
|
} |
925
|
|
|
|
|
|
|
} |
926
|
1
|
|
|
|
|
171
|
close MAKEFILE; |
927
|
|
|
|
|
|
|
} |
928
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
sub quote_space { |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
# Do nothing if $ENV{NO_INSANE_DIRNAMES} is set |
932
|
0
|
0
|
|
0
|
0
|
0
|
return $_[0] if $ENV{NO_INSANE_DIRNAMES}; |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
# If $_[0] contains one or more doublequote characters, assume |
935
|
|
|
|
|
|
|
# that whitespace has already been quoted as required. Hence, |
936
|
|
|
|
|
|
|
# do nothing other than immediately return $_[0] as is. |
937
|
|
|
|
|
|
|
# We currently don't properly handle tabs either, so we'll |
938
|
|
|
|
|
|
|
# do the same if $_[0] =~ /\t/. |
939
|
0
|
0
|
0
|
|
|
0
|
return $_[0] if ($_[0] =~ /"/ || $_[0] =~ /\t/); |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
# We want to split on /\s\-I/ not /\-I/ |
942
|
0
|
|
|
|
|
0
|
my @in = split /\s\-I/, $_[0]; |
943
|
0
|
|
|
|
|
0
|
my $s = @in - 1; |
944
|
0
|
|
|
|
|
0
|
my %s; |
945
|
|
|
|
|
|
|
my %q; |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
# First up, let's reinstate the ' ' characters that split |
948
|
|
|
|
|
|
|
# removed |
949
|
0
|
|
|
|
|
0
|
for(my $i = 0; $i < $s; $i++) { |
950
|
0
|
|
|
|
|
0
|
$in[$i] .= ' '; |
951
|
|
|
|
|
|
|
} |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
# This for{} block dies if it finds that any of the ' -I' |
954
|
|
|
|
|
|
|
# occurrences in $_[0] are part of a directory name. |
955
|
0
|
|
|
|
|
0
|
for(my $i = 1; $i < $s; $i++) { |
956
|
0
|
|
|
|
|
0
|
my $t = $in[$i + 1]; |
957
|
0
|
|
|
|
|
0
|
while($t =~ /\s$/) {chop $t} |
|
0
|
|
|
|
|
0
|
|
958
|
0
|
0
|
|
|
|
0
|
die "Found a '", $in[$i], "-I", $t, "' directory.", |
959
|
|
|
|
|
|
|
" INC Config argument is ambiguous.", |
960
|
|
|
|
|
|
|
" Please use doublequotes to signify your intentions" |
961
|
|
|
|
|
|
|
if -d ($in[$i] . "-I" . $t); |
962
|
|
|
|
|
|
|
} |
963
|
|
|
|
|
|
|
|
964
|
0
|
|
|
|
|
0
|
$s++; # Now the same as scalar(@in) |
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
# Remove (but also Keep track of the amount of) whitespace |
967
|
|
|
|
|
|
|
# at the end of each element of @in. |
968
|
0
|
|
|
|
|
0
|
for(my $i = 0; $i < $s; $i++) { |
969
|
0
|
|
|
|
|
0
|
my $count = 0; |
970
|
0
|
|
|
|
|
0
|
while($in[$i] =~ /\s$/) { |
971
|
0
|
|
|
|
|
0
|
chop $in[$i]; |
972
|
0
|
|
|
|
|
0
|
$count++; |
973
|
|
|
|
|
|
|
} |
974
|
0
|
|
|
|
|
0
|
$s{$i} = $count; |
975
|
|
|
|
|
|
|
} |
976
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
# Note which elements of @in still contain whitespace. These |
978
|
|
|
|
|
|
|
# (and only these) elements will be quoted |
979
|
0
|
|
|
|
|
0
|
for(my $i = 0; $i < $s; $i++) { |
980
|
0
|
0
|
|
|
|
0
|
$q{$i} = 1 if $in[$i] =~ /\s/; |
981
|
|
|
|
|
|
|
} |
982
|
|
|
|
|
|
|
|
983
|
|
|
|
|
|
|
# Reinstate the occurrences of '-I' that were removed by split(), |
984
|
|
|
|
|
|
|
# insert any quotes that are needed, reinstate the whitespace |
985
|
|
|
|
|
|
|
# that was removed earlier, then join() the array back together |
986
|
|
|
|
|
|
|
# again. |
987
|
0
|
|
|
|
|
0
|
for(my $i = 0; $i < $s; $i++) { |
988
|
0
|
0
|
|
|
|
0
|
$in[$i] = '-I' . $in[$i] if $i; |
989
|
0
|
0
|
|
|
|
0
|
$in[$i] = '"' . $in[$i] . '"' if $q{$i}; |
990
|
0
|
|
|
|
|
0
|
$in[$i] .= ' ' x $s{$i}; |
991
|
|
|
|
|
|
|
} |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
# Note: If there was no whitespace that needed quoting, the |
994
|
|
|
|
|
|
|
# original argument should not have changed in any way. |
995
|
|
|
|
|
|
|
|
996
|
0
|
|
|
|
|
0
|
my $out = join '', @in; |
997
|
0
|
|
|
|
|
0
|
$out =~ s/"\-I\s+\//"\-I\//g; |
998
|
0
|
|
|
|
|
0
|
$_[0] = $out; |
999
|
|
|
|
|
|
|
} |
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
sub fix_space { |
1002
|
3
|
50
|
|
3
|
0
|
11
|
$_[0] =~ s/ /\\ /g if $_[0] =~ / /; |
1003
|
3
|
|
|
|
|
6
|
$_[0]; |
1004
|
|
|
|
|
|
|
} |
1005
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
#============================================================================== |
1007
|
|
|
|
|
|
|
# This routine used by C/t/09parser to test that the expected parser is in use |
1008
|
|
|
|
|
|
|
#============================================================================== |
1009
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
sub _parser_test { |
1011
|
0
|
|
|
0
|
|
|
my $dir = '_Inline_test'; |
1012
|
0
|
0
|
|
|
|
|
if(! -d $dir) { |
1013
|
0
|
|
|
|
|
|
my $ok = mkdir $dir; |
1014
|
0
|
0
|
|
|
|
|
warn $! if !$ok; |
1015
|
|
|
|
|
|
|
} |
1016
|
|
|
|
|
|
|
|
1017
|
0
|
0
|
|
|
|
|
warn $! if !open(TEST_FH, '>>', "$dir/parser_id"); |
1018
|
0
|
|
|
|
|
|
print TEST_FH $_[0]; |
1019
|
0
|
0
|
|
|
|
|
warn $! if !close(TEST_FH); |
1020
|
|
|
|
|
|
|
} |
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
#======================================================================= |
1023
|
|
|
|
|
|
|
# This routine used to cleanup files created by _TESTING (config option) |
1024
|
|
|
|
|
|
|
#======================================================================= |
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
sub _testing_cleanup { |
1027
|
0
|
|
|
0
|
|
|
my $dir = '_Inline_test'; |
1028
|
|
|
|
|
|
|
|
1029
|
0
|
0
|
|
|
|
|
if(-f "$dir/parser_id") { |
1030
|
0
|
0
|
|
|
|
|
warn "Failed to unlink C/$dir/parser_id\n" if !unlink("$dir/parser_id"); |
1031
|
|
|
|
|
|
|
} |
1032
|
|
|
|
|
|
|
|
1033
|
0
|
0
|
|
|
|
|
if(-f "$dir/void_test") { |
1034
|
0
|
0
|
|
|
|
|
warn "Failed to unlink C/$dir/void_test\n" if !unlink("$dir/void_test"); |
1035
|
|
|
|
|
|
|
} |
1036
|
|
|
|
|
|
|
} |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
1; |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
__END__ |