File Coverage

blib/lib/ExtUtils/ParseXS.pm
Criterion Covered Total %
statement 935 1105 84.6
branch 374 608 61.5
condition 119 217 54.8
subroutine 54 57 94.7
pod 3 40 7.5
total 1485 2027 73.2


line stmt bran cond sub pod time code
1             package ExtUtils::ParseXS;
2 18     18   292398 use strict;
  18         83  
  18         521  
3              
4 18     18   420 use 5.006001;
  18         58  
5 18     18   97 use Cwd;
  18         40  
  18         1288  
6 18     18   116 use Config;
  18         36  
  18         743  
7 18     18   128 use Exporter 'import';
  18         32  
  18         689  
8 18     18   129 use File::Basename;
  18         70  
  18         1902  
9 18     18   134 use File::Spec;
  18         47  
  18         595  
10 18     18   7347 use Symbol;
  18         12268  
  18         2561  
11              
12             our $VERSION;
13             BEGIN {
14 18     18   71 $VERSION = '3.51';
15 18         7693 require ExtUtils::ParseXS::Constants; ExtUtils::ParseXS::Constants->VERSION($VERSION);
  18         360  
16 18         7646 require ExtUtils::ParseXS::CountLines; ExtUtils::ParseXS::CountLines->VERSION($VERSION);
  18         382  
17 18         8566 require ExtUtils::ParseXS::Utilities; ExtUtils::ParseXS::Utilities->VERSION($VERSION);
  18         389  
18 18         7758 require ExtUtils::ParseXS::Eval; ExtUtils::ParseXS::Eval->VERSION($VERSION);
  18         1501  
19             }
20             $VERSION = eval $VERSION if $VERSION =~ /_/;
21              
22 18         48898 use ExtUtils::ParseXS::Utilities qw(
23             standard_typemap_locations
24             trim_whitespace
25             C_string
26             valid_proto_string
27             process_typemaps
28             map_type
29             standard_XS_defs
30             assign_func_args
31             analyze_preprocessor_statements
32             set_cond
33             Warn
34             WarnHint
35             current_line_number
36             blurt
37             death
38             check_conditional_preprocessor_statements
39             escape_file_for_line_directive
40             report_typemap_failure
41 18     18   128 );
  18         36  
42              
43             our @EXPORT_OK = qw(
44             process_file
45             report_error_count
46             errors
47             );
48              
49             ##############################
50             # A number of "constants"
51             our $DIE_ON_ERROR;
52             our $AUTHOR_WARNINGS;
53             $AUTHOR_WARNINGS = ($ENV{AUTHOR_WARNINGS} || 0)
54             unless defined $AUTHOR_WARNINGS;
55             our ($C_group_rex, $C_arg);
56             # Group in C (no support for comments or literals)
57             $C_group_rex = qr/ [({\[]
58             (?: (?> [^()\[\]{}]+ ) | (??{ $C_group_rex }) )*
59             [)}\]] /x;
60             # Chunk in C without comma at toplevel (no comments):
61             $C_arg = qr/ (?: (?> [^()\[\]{},"']+ )
62             | (??{ $C_group_rex })
63             | " (?: (?> [^\\"]+ )
64             | \\.
65             )* " # String literal
66             | ' (?: (?> [^\\']+ ) | \\. )* ' # Char literal
67             )* /xs;
68              
69             # "impossible" keyword (multiple newline)
70             my $END = "!End!\n\n";
71             # Match an XS Keyword
72             my $BLOCK_regexp = '\s*(' . $ExtUtils::ParseXS::Constants::XSKeywordsAlternation . "|$END)\\s*:";
73              
74              
75              
76             sub new {
77 25     25 1 505403 return bless {} => shift;
78             }
79              
80             our $Singleton = __PACKAGE__->new;
81              
82             sub process_file {
83 8     8 1 6914 my $self;
84             # Allow for $package->process_file(%hash), $obj->process_file, and process_file()
85 8 100       54 if (@_ % 2) {
86 7         30 my $invocant = shift;
87 7 100       54 $self = ref($invocant) ? $invocant : $invocant->new;
88             }
89             else {
90 1         3 $self = $Singleton;
91             }
92              
93 8         51 my %options = @_;
94 8         50 $self->{ProtoUsed} = exists $options{prototypes};
95              
96             # Set defaults.
97 8         94 my %args = (
98             argtypes => 1,
99             csuffix => '.c',
100             except => 0,
101             hiertype => 0,
102             inout => 1,
103             linenumbers => 1,
104             optimize => 1,
105             output => \*STDOUT,
106             prototypes => 0,
107             typemap => [],
108             versioncheck => 1,
109             FH => Symbol::gensym(),
110             die_on_error => $DIE_ON_ERROR, # if true we die() and not exit() after errors
111             author_warnings => $AUTHOR_WARNINGS,
112             %options,
113             );
114 8 50       336 $args{except} = $args{except} ? ' TRY' : '';
115              
116             # Global Constants
117              
118 8         17 my ($Is_VMS, $SymSet);
119 8 50       40 if ($^O eq 'VMS') {
120 0         0 $Is_VMS = 1;
121             # Establish set of global symbols with max length 28, since xsubpp
122             # will later add the 'XS_' prefix.
123 0         0 require ExtUtils::XSSymSet;
124 0         0 $SymSet = ExtUtils::XSSymSet->new(28);
125             }
126 8         26 @{ $self->{XSStack} } = ({type => 'none'});
  8         35  
127 8         28 $self->{InitFileCode} = [ @ExtUtils::ParseXS::Constants::InitFileCode ];
128 8         19 $self->{Overloaded} = {}; # hashref of Package => Packid
129 8         19 $self->{Fallback} = {}; # hashref of Package => fallback setting
130 8         20 $self->{errors} = 0; # count
131              
132             # Most of the 1500 lines below uses these globals. We'll have to
133             # clean this up sometime, probably. For now, we just pull them out
134             # of %args. -Ken
135              
136 8         16 $self->{RetainCplusplusHierarchicalTypes} = $args{hiertype};
137 8         20 $self->{WantPrototypes} = $args{prototypes};
138 8         17 $self->{WantVersionChk} = $args{versioncheck};
139 8         17 $self->{WantLineNumbers} = $args{linenumbers};
140 8         29 $self->{IncludedFiles} = {};
141              
142 8         21 $self->{die_on_error} = $args{die_on_error};
143 8         25 $self->{author_warnings} = $args{author_warnings};
144              
145 8 50       25 die "Missing required parameter 'filename'" unless $args{filename};
146 8         21 $self->{filepathname} = $args{filename};
147             ($self->{dir}, $self->{filename}) =
148 8         926 (dirname($args{filename}), basename($args{filename}));
149 8         45 $self->{filepathname} =~ s/\\/\\\\/g;
150 8         43 $self->{IncludedFiles}->{$args{filename}}++;
151              
152             # Open the output file if given as a string. If they provide some
153             # other kind of reference, trust them that we can print to it.
154 8 100       40 if (not ref $args{output}) {
155 4 50       539 open my($fh), "> $args{output}" or die "Can't create $args{output}: $!";
156 4         28 $args{outfile} = $args{output};
157 4         13 $args{output} = $fh;
158             }
159              
160             # Really, we shouldn't have to chdir() or select() in the first
161             # place. For now, just save and restore.
162 8         32286 my $orig_cwd = cwd();
163 8         223 my $orig_fh = select();
164              
165 8         191 chdir($self->{dir});
166 8         26652 my $pwd = cwd();
167 8         200 my $csuffix = $args{csuffix};
168              
169 8 100       147 if ($self->{WantLineNumbers}) {
170 6         48 my $cfile;
171 6 100       93 if ( $args{outfile} ) {
172 3         54 $cfile = $args{outfile};
173             }
174             else {
175 3         35 $cfile = $args{filename};
176 3 50       113 $cfile =~ s/\.xs$/$csuffix/i or $cfile .= $csuffix;
177             }
178 6         371 tie(*PSEUDO_STDOUT, 'ExtUtils::ParseXS::CountLines', $cfile, $args{output});
179 6         103 select PSEUDO_STDOUT;
180             }
181             else {
182 2         61 select $args{output};
183             }
184              
185 8         175 $self->{typemap} = process_typemaps( $args{typemap}, $pwd );
186              
187             # Move more settings from parameters to object
188 8         104 foreach my $datum ( qw| argtypes except inout optimize | ) {
189 32         277 $self->{$datum} = $args{$datum};
190             }
191 8         49 $self->{strip_c_func_prefix} = $args{s};
192              
193             # Identify the version of xsubpp used
194 8         272 print <
195             /*
196             * This file was generated automatically by ExtUtils::ParseXS version $VERSION from the
197             * contents of $self->{filename}. Do not edit this file, edit $self->{filename} instead.
198             *
199             * ANY CHANGES MADE HERE WILL BE LOST!
200             *
201             */
202              
203             EOM
204              
205              
206             print("#line 1 \"" . escape_file_for_line_directive($self->{filepathname}) . "\"\n")
207 8 100       183 if $self->{WantLineNumbers};
208              
209             # Open the input file (using $self->{filename} which
210             # is a basename'd $args{filename} due to chdir above)
211 8 50       535 open($self->{FH}, '<', $self->{filename}) or die "cannot open $self->{filename}: $!\n";
212              
213             FIRSTMODULE:
214 8         458 while (readline($self->{FH})) {
215 183 100       609 if (/^=/) {
216 1         23 my $podstartline = $.;
217             do {
218 5 100       31 if (/^=cut\s*$/) {
219             # We can't just write out a /* */ comment, as our embedded
220             # POD might itself be in a comment. We can't put a /**/
221             # comment inside #if 0, as the C standard says that the source
222             # file is decomposed into preprocessing characters in the stage
223             # before preprocessing commands are executed.
224             # I don't want to leave the text as barewords, because the spec
225             # isn't clear whether macros are expanded before or after
226             # preprocessing commands are executed, and someone pathological
227             # may just have defined one of the 3 words as a macro that does
228             # something strange. Multiline strings are illegal in C, so
229             # the "" we write must be a string literal. And they aren't
230             # concatenated until 2 steps later, so we are safe.
231             # - Nicholas Clark
232 1         4 print("#if 0\n \"Skipped embedded POD.\"\n#endif\n");
233             printf("#line %d \"%s\"\n", $. + 1, escape_file_for_line_directive($self->{filepathname}))
234 1 50       8 if $self->{WantLineNumbers};
235 1         33 next FIRSTMODULE;
236             }
237              
238 1         6 } while (readline($self->{FH}));
239             # At this point $. is at end of file so die won't state the start
240             # of the problem, and as we haven't yet read any lines &death won't
241             # show the correct line in the message either.
242             die ("Error: Unterminated pod in $self->{filename}, line $podstartline\n")
243 0 0       0 unless $self->{lastline};
244             }
245 182 100       618 last if ($self->{Package}, $self->{Prefix}) =
246             /^MODULE\s*=\s*[\w:]+(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/;
247              
248 174         368 print $_;
249             }
250 8 50       53 unless (defined $_) {
251 0         0 warn "Didn't find a 'MODULE ... PACKAGE ... PREFIX' line\n";
252 0         0 exit 0; # Not a fatal error for the caller process
253             }
254              
255 8 100       82 print 'ExtUtils::ParseXS::CountLines'->end_marker, "\n" if $self->{WantLineNumbers};
256              
257 8         105 standard_XS_defs();
258              
259 8 100       57 print 'ExtUtils::ParseXS::CountLines'->end_marker, "\n" if $self->{WantLineNumbers};
260              
261 8         50 $self->{lastline} = $_;
262 8         107 $self->{lastline_no} = $.;
263              
264 8         44 my $BootCode_ref = [];
265 8         18 my $XSS_work_idx = 0;
266 8         23 my $cpp_next_tmp = 'XSubPPtmpAAAA';
267             PARAGRAPH:
268 8         86 while ($self->fetch_para()) {
269 88         183 my $outlist_ref = [];
270             # Print initial preprocessor statements and blank lines
271 88   100     150 while (@{ $self->{line} } && $self->{line}->[0] !~ /^[^\#]/) {
  93         595  
272 5         11 my $ln = shift(@{ $self->{line} });
  5         13  
273 5         24 print $ln, "\n";
274 5 100       39 next unless $ln =~ /^\#\s*((if)(?:n?def)?|elsif|else|endif)\b/;
275 3         11 my $statement = $+;
276 3         25 ( $self, $XSS_work_idx, $BootCode_ref ) =
277             analyze_preprocessor_statements(
278             $self, $statement, $XSS_work_idx, $BootCode_ref
279             );
280             }
281              
282 88 100       150 next PARAGRAPH unless @{ $self->{line} };
  88         247  
283              
284 71 100 100     212 if ($XSS_work_idx && !$self->{XSStack}->[$XSS_work_idx]{varname}) {
285             # We are inside an #if, but have not yet #defined its xsubpp variable.
286 1         12 print "#define $cpp_next_tmp 1\n\n";
287 1         9 push(@{ $self->{InitFileCode} }, "#if $cpp_next_tmp\n");
  1         6  
288 1         3 push(@{ $BootCode_ref }, "#if $cpp_next_tmp");
  1         5  
289 1         12 $self->{XSStack}->[$XSS_work_idx]{varname} = $cpp_next_tmp++;
290             }
291              
292             $self->death(
293             "Code is not inside a function"
294             ." (maybe last function was ended by a blank line "
295             ." followed by a statement on column one?)")
296 71 50       204 if $self->{line}->[0] =~ /^\s/;
297              
298             # initialize info arrays
299 71         187 foreach my $member (qw(args_match var_types defaults arg_list
300             argtype_seen in_out lengthof))
301             {
302 497         1272 $self->{$member} = {};
303             }
304 71         172 $self->{proto_arg} = [];
305 71         126 $self->{processing_arg_with_types} = 0; # bool
306 71         118 $self->{proto_in_this_xsub} = 0; # counter & bool
307 71         137 $self->{scope_in_this_xsub} = 0; # counter & bool
308 71         117 $self->{interface} = 0; # bool
309 71         134 $self->{interface_macro} = 'XSINTERFACE_FUNC';
310 71         128 $self->{interface_macro_set} = 'XSINTERFACE_FUNC_SET';
311 71         144 $self->{ProtoThisXSUB} = $self->{WantPrototypes}; # states 0 (none), 1 (yes), 2 (empty prototype)
312 71         132 $self->{ScopeThisXSUB} = 0; # bool
313 71         134 $self->{OverloadsThisXSUB} = {}; # overloaded operators (as hash keys, to de-dup)
314              
315 71         137 my $xsreturn = 0;
316              
317 71         102 $_ = shift(@{ $self->{line} });
  71         181  
318 71         274 while (my $kwd = $self->check_keyword("REQUIRE|PROTOTYPES|EXPORT_XSUB_SYMBOLS|FALLBACK|VERSIONCHECK|INCLUDE(?:_COMMAND)?|SCOPE")) {
319 14         55 my $method = $kwd . "_handler";
320 14         162 $self->$method($_);
321 14 50       33 next PARAGRAPH unless @{ $self->{line} };
  14         132  
322 0         0 $_ = shift(@{ $self->{line} });
  0         0  
323             }
324              
325 57 100       225 if ($self->check_keyword("BOOT")) {
326 1         8 check_conditional_preprocessor_statements($self);
327 1         6 push (@{ $BootCode_ref }, "#line $self->{line_no}->[@{ $self->{line_no} } - @{ $self->{line} }] \""
  1         3  
  1         7  
328             . escape_file_for_line_directive($self->{filepathname}) . "\"")
329 1 50 33     26 if $self->{WantLineNumbers} && $self->{line}->[0] !~ /^\s*#\s*line\b/;
330 1         3 push (@{ $BootCode_ref }, @{ $self->{line} }, "");
  1         2  
  1         2  
331 1         4 next PARAGRAPH;
332             }
333              
334             # extract return type, function name and arguments
335 56         267 ($self->{ret_type}) = ExtUtils::Typemaps::tidy_type($_);
336 56 50       172 my $RETVAL_no_return = 1 if $self->{ret_type} =~ s/^NO_OUTPUT\s+//;
337              
338             # Allow one-line ANSI-like declaration
339 0         0 unshift @{ $self->{line} }, $2
340             if $self->{argtypes}
341 56 50 33     346 and $self->{ret_type} =~ s/^(.*?\w.*?)\s*\b(\w+\s*\(.*)/$1/s;
342              
343             # a function definition needs at least 2 lines
344             $self->blurt("Error: Function definition too short '$self->{ret_type}'"), next PARAGRAPH
345 56 50       102 unless @{ $self->{line} };
  56         156  
346              
347 56 50       159 my $externC = 1 if $self->{ret_type} =~ s/^extern "C"\s+//;
348 56 50       126 my $static = 1 if $self->{ret_type} =~ s/^static\s+//;
349              
350 56         78 my $func_header = shift(@{ $self->{line} });
  56         123  
351 56 50       501 $self->blurt("Error: Cannot parse function definition from '$func_header'"), next PARAGRAPH
352             unless $func_header =~ /^(?:([\w:]*)::)?(\w+)\s*\(\s*(.*?)\s*\)\s*(const)?\s*(;\s*)?$/s;
353              
354 56         111 my ($class, $orig_args);
355 56         317 ($class, $self->{func_name}, $orig_args) = ($1, $2, $3);
356 56 50       249 $class = "$4 $class" if $4;
357 56         516 ($self->{pname} = $self->{func_name}) =~ s/^($self->{Prefix})?/$self->{Packprefix}/;
358 56         127 my $clean_func_name;
359 56         279 ($clean_func_name = $self->{func_name}) =~ s/^$self->{Prefix}//;
360 56         193 $self->{Full_func_name} = "$self->{Packid}_$clean_func_name";
361 56 50       131 if ($Is_VMS) {
362 0         0 $self->{Full_func_name} = $SymSet->addsym( $self->{Full_func_name} );
363             }
364              
365             # Check for duplicate function definition
366 56         103 for my $tmp (@{ $self->{XSStack} }) {
  56         169  
367 59 50       282 next unless defined $tmp->{functions}{ $self->{Full_func_name} };
368 0         0 Warn( $self, "Warning: duplicate function definition '$clean_func_name' detected");
369 0         0 last;
370             }
371 56         313 $self->{XSStack}->[$XSS_work_idx]{functions}{ $self->{Full_func_name} }++;
372 56         116 delete $self->{XsubAliases};
373 56         97 delete $self->{XsubAliasValues};
374 56         90 %{ $self->{Interfaces} } = ();
  56         142  
375 56         94 @{ $self->{Attributes} } = ();
  56         102  
376 56         94 $self->{DoSetMagic} = 1;
377              
378 56         133 $orig_args =~ s/\\\s*/ /g; # process line continuations
379 56         132 my @args;
380              
381             my (@fake_INPUT_pre); # For length(s) generated variables
382 56         0 my (@fake_INPUT);
383 56         112 my $only_C_inlist_ref = {}; # Not in the signature of Perl function
384 56 100 66     392 if ($self->{argtypes} and $orig_args =~ /\S/) {
385 47         128 my $args = "$orig_args ,";
386 18     18   198 use re 'eval';
  18         49  
  18         2460  
387 47 50       226 if ($args =~ /^( (??{ $C_arg }) , )* $ /x) {
388 47         156 @args = ($args =~ /\G ( (??{ $C_arg }) ) , /xg);
389 18     18   143 no re 'eval';
  18         41  
  18         8666  
390 47         131 for ( @args ) {
391 70         204 s/^\s+//;
392 70         261 s/\s+$//;
393 70         369 my ($arg, $default) = ($_ =~ m/ ( [^=]* ) ( (?: = .* )? ) /x);
394 70         425 my ($pre, $len_name) = ($arg =~ /(.*?) \s*
395             \b ( \w+ | length\( \s*\w+\s* \) )
396             \s* $ /x);
397 70 100 100     457 next unless defined($pre) && length($pre);
398 13         23 my $out_type = '';
399 13         21 my $inout_var;
400 13 100 66     89 if ($self->{inout} and s/^(IN|IN_OUTLIST|OUTLIST|OUT|IN_OUT)\b\s*//) {
401 5         12 my $type = $1;
402 5 100       13 $out_type = $type if $type ne 'IN';
403 5         17 $arg =~ s/^(IN|IN_OUTLIST|OUTLIST|OUT|IN_OUT)\b\s*//;
404 5         17 $pre =~ s/^(IN|IN_OUTLIST|OUTLIST|OUT|IN_OUT)\b\s*//;
405             }
406 13         20 my $islength;
407 13 100       30 if ($len_name =~ /^length\( \s* (\w+) \s* \)\z/x) {
408 1         4 $len_name = "XSauto_length_of_$1";
409 1         2 $islength = 1;
410 1 50       3 die "Default value on length() argument: '$_'"
411             if length $default;
412             }
413 13 50 33     31 if (length $pre or $islength) { # Has a type
414 13 100       25 if ($islength) {
415 1         3 push @fake_INPUT_pre, $arg;
416             }
417             else {
418 12         24 push @fake_INPUT, $arg;
419             }
420             # warn "pushing '$arg'\n";
421 13         31 $self->{argtype_seen}->{$len_name}++;
422 13         70 $_ = "$len_name$default"; # Assigns to @args
423             }
424 13 100 100     91 $only_C_inlist_ref->{$_} = 1 if $out_type eq "OUTLIST" or $islength;
425 13 100       35 push @{ $outlist_ref }, $len_name if $out_type =~ /OUTLIST$/;
  4         9  
426 13 100       37 $self->{in_out}->{$len_name} = $out_type if $out_type;
427             }
428             }
429             else {
430 18     18   153 no re 'eval';
  18         60  
  18         269656  
431 0         0 @args = split(/\s*,\s*/, $orig_args);
432 0         0 Warn( $self, "Warning: cannot parse argument list '$orig_args', fallback to split");
433             }
434             }
435             else {
436 9         54 @args = split(/\s*,\s*/, $orig_args);
437 9         28 for (@args) {
438 0 0 0     0 if ($self->{inout} and s/^(IN|IN_OUTLIST|OUTLIST|IN_OUT|OUT)\b\s*//) {
439 0         0 my $out_type = $1;
440 0 0       0 next if $out_type eq 'IN';
441 0 0       0 $only_C_inlist_ref->{$_} = 1 if $out_type eq "OUTLIST";
442 0 0       0 if ($out_type =~ /OUTLIST$/) {
443 0         0 push @{ $outlist_ref }, undef;
  0         0  
444             }
445 0         0 $self->{in_out}->{$_} = $out_type;
446             }
447             }
448             }
449 56 50       162 if (defined($class)) {
450 0 0 0     0 my $arg0 = ((defined($static) or $self->{func_name} eq 'new')
451             ? "CLASS" : "THIS");
452 0         0 unshift(@args, $arg0);
453             }
454 56         91 my $extra_args = 0;
455 56         99 my @args_num = ();
456 56         79 my $num_args = 0;
457 56         91 my $report_args = '';
458 56         81 my $ellipsis;
459 56         164 foreach my $i (0 .. $#args) {
460 70 100       248 if ($args[$i] =~ s/\.\.\.//) {
461 4         9 $ellipsis = 1;
462 4 50 33     24 if ($args[$i] eq '' && $i == $#args) {
463 4         11 $report_args .= ", ...";
464 4         7 pop(@args);
465 4         8 last;
466             }
467             }
468 66 100       167 if ($only_C_inlist_ref->{$args[$i]}) {
469 5         7 push @args_num, undef;
470             }
471             else {
472 61         109 push @args_num, ++$num_args;
473 61         130 $report_args .= ", $args[$i]";
474             }
475 66 100       147 if ($args[$i] =~ /^([^=]*[^\s=])\s*=\s*(.*)/s) {
476 1         2 $extra_args++;
477 1         3 $args[$i] = $1;
478 1         4 $self->{defaults}->{$args[$i]} = $2;
479 1         3 $self->{defaults}->{$args[$i]} =~ s/"/\\"/g;
480             }
481 66 100       239 $self->{proto_arg}->[$i+1] = '$' unless $only_C_inlist_ref->{$args[$i]};
482             }
483 56         122 my $min_args = $num_args - $extra_args;
484 56         118 $report_args =~ s/"/\\"/g;
485 56         180 $report_args =~ s/^,\s+//;
486 56         225 $self->{func_args} = assign_func_args($self, \@args, $class);
487 56         116 @{ $self->{args_match} }{@args} = @args_num;
  56         234  
488              
489 56         95 my $PPCODE = grep(/^\s*PPCODE\s*:/, @{ $self->{line} });
  56         275  
490 56         106 my $CODE = grep(/^\s*CODE\s*:/, @{ $self->{line} });
  56         247  
491             # Detect CODE: blocks which use ST(n)= or XST_m*(n,v)
492             # to set explicit return values.
493 56   66     203 my $EXPLICIT_RETURN = ($CODE &&
494             ("@{ $self->{line} }" =~ /(\bST\s*\([^;]*=) | (\bXST_m\w+\s*\()/x ));
495              
496 56         99 $self->{ALIAS} = grep(/^\s*ALIAS\s*:/, @{ $self->{line} });
  56         355  
497              
498 56         105 my $INTERFACE = grep(/^\s*INTERFACE\s*:/, @{ $self->{line} });
  56         174  
499              
500 56 50       120 $xsreturn = 1 if $EXPLICIT_RETURN;
501              
502 56 50       174 $externC = $externC ? qq[extern "C"] : "";
503              
504             # print function header
505 56         289 print Q(<<"EOF");
506             #$externC
507             #XS_EUPXS(XS_$self->{Full_func_name}); /* prototype to pass -Wmissing-prototypes */
508             #XS_EUPXS(XS_$self->{Full_func_name})
509             #[[
510             # dVAR; dXSARGS;
511             EOF
512 56 100       291 print Q(<<"EOF") if $self->{ALIAS};
513             # dXSI32;
514             EOF
515 56 100       136 print Q(<<"EOF") if $INTERFACE;
516             # dXSFUNCTION($self->{ret_type});
517             EOF
518              
519 56         211 $self->{cond} = set_cond($ellipsis, $min_args, $num_args);
520              
521 56 50       144 print Q(<<"EOF") if $self->{except};
522             # char errbuf[1024];
523             # *errbuf = '\\0';
524             EOF
525              
526 56 100       113 if($self->{cond}) {
527 54         239 print Q(<<"EOF");
528             # if ($self->{cond})
529             # croak_xs_usage(cv, "$report_args");
530             EOF
531             }
532             else {
533             # cv and items likely to be unused
534 2         7 print Q(<<"EOF");
535             # PERL_UNUSED_VAR(cv); /* -W */
536             # PERL_UNUSED_VAR(items); /* -W */
537             EOF
538             }
539              
540             #gcc -Wall: if an xsub has PPCODE is used
541             #it is possible none of ST, XSRETURN or XSprePUSH macros are used
542             #hence 'ax' (setup by dXSARGS) is unused
543             #XXX: could breakup the dXSARGS; into dSP;dMARK;dITEMS
544             #but such a move could break third-party extensions
545 56 100       248 print Q(<<"EOF") if $PPCODE;
546             # PERL_UNUSED_VAR(ax); /* -Wall */
547             EOF
548              
549 56 100       130 print Q(<<"EOF") if $PPCODE;
550             # SP -= items;
551             EOF
552              
553             # Now do a block of some sort.
554              
555 56         108 $self->{condnum} = 0;
556 56         98 $self->{cond} = ''; # last CASE: conditional
557 56         78 push(@{ $self->{line} }, "$END:");
  56         170  
558 56         89 push(@{ $self->{line_no} }, $self->{line_no}->[-1]);
  56         122  
559 56         163 $_ = '';
560 56         207 check_conditional_preprocessor_statements();
561 56         95 while (@{ $self->{line} }) {
  57         156  
562              
563 57 100       155 $self->CASE_handler($_) if $self->check_keyword("CASE");
564 57         279 print Q(<<"EOF");
565             # $self->{except} [[
566             EOF
567              
568             # do initialization of input variables
569 57         248 $self->{thisdone} = 0;
570 57         104 $self->{retvaldone} = 0;
571 57         107 $self->{deferred} = "";
572 57         101 %{ $self->{arg_list} } = ();
  57         121  
573 57         112 $self->{gotRETVAL} = 0;
574 57         260 $self->INPUT_handler($_);
575 57         236 $self->process_keyword("INPUT|PREINIT|INTERFACE_MACRO|C_ARGS|ALIAS|ATTRS|PROTOTYPE|SCOPE|OVERLOAD");
576              
577 57 50       237 print Q(<<"EOF") if $self->{ScopeThisXSUB};
578             # ENTER;
579             # [[
580             EOF
581              
582 57 50 33     298 if (!$self->{thisdone} && defined($class)) {
583 0 0 0     0 if (defined($static) or $self->{func_name} eq 'new') {
584 0         0 print "\tchar *";
585 0         0 $self->{var_types}->{"CLASS"} = "char *";
586 0         0 $self->generate_init( {
587             type => "char *",
588             num => 1,
589             var => "CLASS",
590             printed_name => undef,
591             } );
592             }
593             else {
594 0         0 print "\t" . map_type($self, "$class *");
595 0         0 $self->{var_types}->{"THIS"} = "$class *";
596 0         0 $self->generate_init( {
597             type => "$class *",
598             num => 1,
599             var => "THIS",
600             printed_name => undef,
601             } );
602             }
603             }
604              
605             # These are set if OUTPUT is found and/or CODE using RETVAL
606 57         131 $self->{have_OUTPUT} = $self->{have_CODE_with_RETVAL} = 0;
607              
608 57         97 my ($wantRETVAL);
609             # do code
610 57 50       139 if (/^\s*NOT_IMPLEMENTED_YET/) {
611 0         0 print "\n\tPerl_croak(aTHX_ \"$self->{pname}: not implemented yet\");\n";
612 0         0 $_ = '';
613             }
614             else {
615 57 100       159 if ($self->{ret_type} ne "void") {
616             print "\t" . map_type($self, $self->{ret_type}, 'RETVAL') . ";\n"
617 36 50       175 if !$self->{retvaldone};
618 36         200 $self->{args_match}->{"RETVAL"} = 0;
619 36         93 $self->{var_types}->{"RETVAL"} = $self->{ret_type};
620 36         146 my $outputmap = $self->{typemap}->get_outputmap( ctype => $self->{ret_type} );
621             print "\tdXSTARG;\n"
622 36 100 33     292 if $self->{optimize} and $outputmap and $outputmap->targetable;
      66        
623             }
624              
625 57 100 66     310 if (@fake_INPUT or @fake_INPUT_pre) {
626 7         12 unshift @{ $self->{line} }, @fake_INPUT_pre, @fake_INPUT, $_;
  7         22  
627 7         16 $_ = "";
628 7         11 $self->{processing_arg_with_types} = 1;
629 7         15 $self->INPUT_handler($_);
630             }
631 57         194 print $self->{deferred};
632              
633 57         220 $self->process_keyword("INIT|ALIAS|ATTRS|PROTOTYPE|INTERFACE_MACRO|INTERFACE|C_ARGS|OVERLOAD");
634              
635 57 100 33     245 if ($self->check_keyword("PPCODE")) {
    100          
    50          
636 4         23 $self->print_section();
637 4 50       8 $self->death("PPCODE must be last thing") if @{ $self->{line} };
  4         15  
638 4 50       12 print "\tLEAVE;\n" if $self->{ScopeThisXSUB};
639 4 50       17 print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
640             "#pragma diag_suppress 2111\n",
641             "#endif\n"
642             if $^O eq "hpux";
643 4         10 print "\tPUTBACK;\n\treturn;\n";
644 4 50       23 print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
645             "#pragma diag_default 2111\n",
646             "#endif\n"
647             if $^O eq "hpux";
648              
649             }
650             elsif ($self->check_keyword("CODE")) {
651 35         131 my $consumed_code = $self->print_section();
652 35 100       188 if ($consumed_code =~ /\bRETVAL\b/) {
653 27         70 $self->{have_CODE_with_RETVAL} = 1;
654             }
655             }
656             elsif (defined($class) and $self->{func_name} eq "DESTROY") {
657 0         0 print "\n\t";
658 0         0 print "delete THIS;\n";
659             }
660             else {
661 18         64 print "\n\t";
662 18 100       101 if ($self->{ret_type} ne "void") {
663 9         23 print "RETVAL = ";
664 9         22 $wantRETVAL = 1;
665             }
666 18 50       60 if (defined($static)) {
    50          
667 0 0       0 if ($self->{func_name} eq 'new') {
668 0         0 $self->{func_name} = "$class";
669             }
670             else {
671 0         0 print "${class}::";
672             }
673             }
674             elsif (defined($class)) {
675 0 0       0 if ($self->{func_name} eq 'new') {
676 0         0 $self->{func_name} .= " $class";
677             }
678             else {
679 0         0 print "THIS->";
680             }
681             }
682 18         36 my $strip = $self->{strip_c_func_prefix};
683 18 50       36 $self->{func_name} =~ s/^\Q$strip//
684             if defined $strip;
685 18 100       45 $self->{func_name} = 'XSFUNCTION' if $self->{interface};
686 18         77 print "$self->{func_name}($self->{func_args});\n";
687             }
688             }
689              
690             # do output variables
691 57         145 $self->{gotRETVAL} = 0; # 1 if RETVAL seen in OUTPUT section;
692 57         108 undef $self->{RETVAL_code} ; # code to set RETVAL (from OUTPUT section);
693             # $wantRETVAL set if 'RETVAL =' autogenerated
694 57 50       118 ($wantRETVAL, $self->{ret_type}) = (0, 'void') if $RETVAL_no_return;
695 57         81 undef %{ $self->{outargs} };
  57         138  
696              
697 57         195 $self->process_keyword("POSTCALL|OUTPUT|ALIAS|ATTRS|PROTOTYPE|OVERLOAD");
698              
699             # A CODE section with RETVAL, but no OUTPUT? FAIL!
700 57 50 66     313 if ($self->{have_CODE_with_RETVAL} and not $self->{have_OUTPUT} and $self->{ret_type} ne 'void') {
      33        
701 0         0 $self->Warn("Warning: Found a 'CODE' section which seems to be using 'RETVAL' but no 'OUTPUT' section.");
702             }
703              
704             $self->generate_output( {
705             type => $self->{var_types}->{$_},
706             num => $self->{args_match}->{$_},
707             var => $_,
708             do_setmagic => $self->{DoSetMagic},
709             do_push => undef,
710 57         100 } ) for grep $self->{in_out}->{$_} =~ /OUT$/, sort keys %{ $self->{in_out} };
  57         265  
711              
712 57         99 my $outlist_count = @{ $outlist_ref };
  57         107  
713 57 100       125 if ($outlist_count) {
714 3         5 my $ext = $outlist_count;
715 3 100 66     23 ++$ext if $self->{gotRETVAL} || $wantRETVAL;
716 3         12 print "\tXSprePUSH;";
717 3         12 print "\tEXTEND(SP,$ext);\n";
718             }
719             # all OUTPUT done, so now push the return value on the stack
720 57 50 66     351 if ($self->{gotRETVAL} && $self->{RETVAL_code}) {
    100 100        
721 0         0 print "\t$self->{RETVAL_code}\n";
722 0 0       0 print "\t++SP;\n" if $outlist_count;
723             }
724             elsif ($self->{gotRETVAL} || $wantRETVAL) {
725 32         137 my $outputmap = $self->{typemap}->get_outputmap( ctype => $self->{ret_type} );
726 32   66     252 my $trgt = $self->{optimize} && $outputmap && $outputmap->targetable;
727 32         63 my $var = 'RETVAL';
728 32         62 my $type = $self->{ret_type};
729              
730 32 100       75 if ($trgt) {
731             my $what = $self->eval_output_typemap_code(
732             qq("$trgt->{what}"),
733             {var => $var, type => $self->{ret_type}}
734 27         209 );
735 27 50 33     218 if (not $trgt->{with_size} and $trgt->{type} eq 'p') { # sv_setpv
736             # PUSHp corresponds to sv_setpvn. Treat sv_setpv directly
737 0         0 print "\tsv_setpv(TARG, $what);\n";
738 0 0       0 print "\tXSprePUSH;\n" unless $outlist_count;
739 0         0 print "\tPUSHTARG;\n";
740             }
741             else {
742 27         93 my $tsize = $trgt->{what_size};
743 27 50       82 $tsize = '' unless defined $tsize;
744             $tsize = $self->eval_output_typemap_code(
745             qq("$tsize"),
746             {var => $var, type => $self->{ret_type}}
747 27         159 );
748 27 100       151 print "\tXSprePUSH;\n" unless $outlist_count;
749 27         169 print "\tPUSH$trgt->{type}($what$tsize);\n";
750             }
751             }
752             else {
753             # RETVAL almost never needs SvSETMAGIC()
754             $self->generate_output( {
755             type => $self->{ret_type},
756 5         91 num => 0,
757             var => 'RETVAL',
758             do_setmagic => 0,
759             do_push => undef,
760             } );
761 5 100       26 print "\t++SP;\n" if $outlist_count;
762             }
763             }
764              
765 57 100       217 $xsreturn = 1 if $self->{ret_type} ne "void";
766 57         100 my $num = $xsreturn;
767 57         96 $xsreturn += $outlist_count;
768             $self->generate_output( {
769             type => $self->{var_types}->{$_},
770             num => $num++,
771             var => $_,
772             do_setmagic => 0,
773             do_push => 1,
774 57         103 } ) for @{ $outlist_ref };
  57         137  
775              
776             # do cleanup
777 57         181 $self->process_keyword("CLEANUP|ALIAS|ATTRS|PROTOTYPE|OVERLOAD");
778              
779 57 50       223 print Q(<<"EOF") if $self->{ScopeThisXSUB};
780             # ]]
781             EOF
782 57 50 33     185 print Q(<<"EOF") if $self->{ScopeThisXSUB} and not $PPCODE;
783             # LEAVE;
784             EOF
785              
786             # print function trailer
787 57         136 print Q(<<"EOF");
788             # ]]
789             EOF
790 57 50       281 print Q(<<"EOF") if $self->{except};
791             # BEGHANDLERS
792             # CATCHALL
793             # sprintf(errbuf, "%s: %s\\tpropagated", Xname, Xreason);
794             # ENDHANDLERS
795             EOF
796 57 100       137 if ($self->check_keyword("CASE")) {
797             $self->blurt("Error: No 'CASE:' at top of function")
798 1 50       5 unless $self->{condnum};
799 1         4 $_ = "CASE: $_"; # Restore CASE: label
800 1         3 next;
801             }
802 56 50       286 last if $_ eq "$END:";
803 0 0       0 $self->death(/^$BLOCK_regexp/o ? "Misplaced '$1:'" : "Junk at end of function ($_)");
804             }
805              
806 56 50       144 print Q(<<"EOF") if $self->{except};
807             # if (errbuf[0])
808             # Perl_croak(aTHX_ errbuf);
809             EOF
810 56 50       213 print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
811             "#pragma diag_suppress 2128\n",
812             "#endif\n"
813             if $^O eq "hpux";
814              
815 56 100       130 if ($xsreturn) {
816 36 50       159 print Q(<<"EOF") unless $PPCODE;
817             # XSRETURN($xsreturn);
818             EOF
819             }
820             else {
821 20 100       56 print Q(<<"EOF") unless $PPCODE;
822             # XSRETURN_EMPTY;
823             EOF
824             }
825 56 50       260 print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
826             "#pragma diag_default 2128\n",
827             "#endif\n"
828             if $^O eq "hpux";
829              
830 56         118 print Q(<<"EOF");
831             #]]
832             #
833             EOF
834              
835 56         221 $self->{proto} = "";
836 56 100       147 unless($self->{ProtoThisXSUB}) {
837 39         68 $self->{newXS} = "newXS_deffile";
838 39         69 $self->{file} = "";
839             }
840             else {
841             # Build the prototype string for the xsub
842 17         38 $self->{newXS} = "newXSproto_portable";
843 17         27 $self->{file} = ", file";
844              
845 17 50       53 if ($self->{ProtoThisXSUB} eq 2) {
    100          
846             # User has specified empty prototype
847             }
848             elsif ($self->{ProtoThisXSUB} eq 1) {
849 16         30 my $s = ';';
850 16 50       69 if ($min_args < $num_args) {
851 0         0 $s = '';
852 0         0 $self->{proto_arg}->[$min_args] .= ";";
853             }
854 16 100       42 push @{ $self->{proto_arg} }, "$s\@"
  2         6  
855             if $ellipsis;
856              
857 16         24 $self->{proto} = join ("", grep defined, @{ $self->{proto_arg} } );
  16         72  
858             }
859             else {
860             # User has specified a prototype
861 1         2 $self->{proto} = $self->{ProtoThisXSUB};
862             }
863 17         43 $self->{proto} = qq{, "$self->{proto}"};
864             }
865              
866 56 100 66     217 if ($self->{XsubAliases} and keys %{ $self->{XsubAliases} }) {
  6 100       52  
    100          
    100          
867             $self->{XsubAliases}->{ $self->{pname} } = 0
868 6 100       50 unless defined $self->{XsubAliases}->{ $self->{pname} };
869 6         17 foreach my $xname (sort keys %{ $self->{XsubAliases} }) {
  6         66  
870 21         46 my $value = $self->{XsubAliases}{$xname};
871 21         29 push(@{ $self->{InitFileCode} }, Q(<<"EOF"));
  21         110  
872             # cv = $self->{newXS}(\"$xname\", XS_$self->{Full_func_name}$self->{file}$self->{proto});
873             # XSANY.any_i32 = $value;
874             EOF
875             }
876             }
877 50         251 elsif (@{ $self->{Attributes} }) {
878 1         2 push(@{ $self->{InitFileCode} }, Q(<<"EOF"));
  1         9  
879             # cv = $self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}$self->{file}$self->{proto});
880 1         4 # apply_attrs_string("$self->{Package}", cv, "@{ $self->{Attributes} }", 0);
881             EOF
882             }
883             elsif ($self->{interface}) {
884 1         4 foreach my $yname (sort keys %{ $self->{Interfaces} }) {
  1         12  
885 1         3 my $value = $self->{Interfaces}{$yname};
886 1 50       20 $yname = "$self->{Package}\::$yname" unless $yname =~ /::/;
887 1         6 push(@{ $self->{InitFileCode} }, Q(<<"EOF"));
  1         13  
888             # cv = $self->{newXS}(\"$yname\", XS_$self->{Full_func_name}$self->{file}$self->{proto});
889             # $self->{interface_macro_set}(cv,$value);
890             EOF
891             }
892             }
893             elsif($self->{newXS} eq 'newXS_deffile'){ # work around P5NCI's empty newXS macro
894 33         49 push(@{ $self->{InitFileCode} },
  33         199  
895             " $self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}$self->{file}$self->{proto});\n");
896             }
897             else {
898 15         25 push(@{ $self->{InitFileCode} },
  15         99  
899             " (void)$self->{newXS}(\"$self->{pname}\", XS_$self->{Full_func_name}$self->{file}$self->{proto});\n");
900             }
901              
902 56         114 for my $operator (sort keys %{ $self->{OverloadsThisXSUB} }) {
  56         542  
903 1         8 $self->{Overloaded}->{$self->{Package}} = $self->{Packid};
904 1         5 my $overload = "$self->{Package}\::($operator";
905 1         2 push(@{ $self->{InitFileCode} },
  1         11  
906             " (void)$self->{newXS}(\"$overload\", XS_$self->{Full_func_name}$self->{file}$self->{proto});\n");
907             }
908             } # END 'PARAGRAPH' 'while' loop
909              
910 8         53 for my $package (sort keys %{ $self->{Overloaded} }) { # make them findable with fetchmethod
  8         61  
911 1         17 my $packid = $self->{Overloaded}->{$package};
912 1         22 print Q(<<"EOF");
913             #XS_EUPXS(XS_${packid}_nil); /* prototype to pass -Wmissing-prototypes */
914             #XS_EUPXS(XS_${packid}_nil)
915             #{
916             # dXSARGS;
917             # PERL_UNUSED_VAR(items);
918             # XSRETURN_EMPTY;
919             #}
920             #
921             EOF
922 1         10 unshift(@{ $self->{InitFileCode} }, Q(<<"MAKE_FETCHMETHOD_WORK"));
  1         10  
923             # /* Making a sub named "${package}::()" allows the package */
924             # /* to be findable via fetchmethod(), and causes */
925             # /* overload::Overloaded("$package") to return true. */
926             # (void)newXS_deffile("${package}::()", XS_${packid}_nil);
927             MAKE_FETCHMETHOD_WORK
928             }
929              
930             # print initialization routine
931              
932 8         37 print Q(<<"EOF");
933             ##ifdef __cplusplus
934             #extern "C" {
935             ##endif
936             EOF
937              
938 8         86 print Q(<<"EOF");
939             #XS_EXTERNAL(boot_$self->{Module_cname}); /* prototype to pass -Wmissing-prototypes */
940             #XS_EXTERNAL(boot_$self->{Module_cname})
941             #[[
942             ##if PERL_VERSION_LE(5, 21, 5)
943             # dVAR; dXSARGS;
944             ##else
945             # dVAR; ${\($self->{WantVersionChk} ?
946 8 100       71 'dXSBOOTARGSXSAPIVERCHK;' : 'dXSBOOTARGSAPIVERCHK;')}
947             ##endif
948             EOF
949              
950             #Under 5.8.x and lower, newXS is declared in proto.h as expecting a non-const
951             #file name argument. If the wrong qualifier is used, it causes breakage with
952             #C++ compilers and warnings with recent gcc.
953             #-Wall: if there is no $self->{Full_func_name} there are no xsubs in this .xs
954             #so 'file' is unused
955 8 50       104 print Q(<<"EOF") if $self->{Full_func_name};
956             ##if PERL_VERSION_LE(5, 8, 999) /* PERL_VERSION_LT is 5.33+ */
957             # char* file = __FILE__;
958             ##else
959             # const char* file = __FILE__;
960             ##endif
961             #
962             # PERL_UNUSED_VAR(file);
963             EOF
964              
965 8         53 print Q("#\n");
966              
967 8         62 print Q(<<"EOF");
968             # PERL_UNUSED_VAR(cv); /* -W */
969             # PERL_UNUSED_VAR(items); /* -W */
970             EOF
971              
972 8 100       237 if( $self->{WantVersionChk}){
973 7         27 print Q(<<"EOF") ;
974             ##if PERL_VERSION_LE(5, 21, 5)
975             # XS_VERSION_BOOTCHECK;
976             ## ifdef XS_APIVERSION_BOOTCHECK
977             # XS_APIVERSION_BOOTCHECK;
978             ## endif
979             ##endif
980              
981             EOF
982             } else {
983 1         5 print Q(<<"EOF") ;
984             ##if PERL_VERSION_LE(5, 21, 5) && defined(XS_APIVERSION_BOOTCHECK)
985             # XS_APIVERSION_BOOTCHECK;
986             ##endif
987              
988             EOF
989             }
990              
991 8 100 66     166 print Q(<<"EOF") if defined $self->{XsubAliases} or defined $self->{interfaces};
992             # {
993             # CV * cv;
994             #
995             EOF
996              
997 8 100       28 if (keys %{ $self->{Overloaded} }) {
  8         69  
998             # once if any overloads
999 1         14 print Q(<<"EOF");
1000             # /* register the overloading (type 'A') magic */
1001             ##if PERL_VERSION_LE(5, 8, 999) /* PERL_VERSION_LT is 5.33+ */
1002             # PL_amagic_generation++;
1003             ##endif
1004             EOF
1005 1         5 for my $package (sort keys %{ $self->{Overloaded} }) {
  1         11  
1006             # once for each package with overloads
1007 1   50     6 my $fallback = $self->{Fallback}->{$package} || "&PL_sv_undef";
1008 1         7 print Q(<<"EOF");
1009             # /* The magic for overload gets a GV* via gv_fetchmeth as */
1010             # /* mentioned above, and looks in the SV* slot of it for */
1011             # /* the "fallback" status. */
1012             # sv_setsv(
1013             # get_sv( "${package}::()", TRUE ),
1014             # $fallback
1015             # );
1016             EOF
1017             }
1018             }
1019              
1020 8         22 print @{ $self->{InitFileCode} };
  8         38  
1021              
1022 8 100 66     135 print Q(<<"EOF") if defined $self->{XsubAliases} or defined $self->{interfaces};
1023             # }
1024             EOF
1025              
1026 8 100       25 if (@{ $BootCode_ref }) {
  8         40  
1027 1         7 print "\n /* Initialisation Section */\n\n";
1028 1         8 @{ $self->{line} } = @{ $BootCode_ref };
  1         5  
  1         6  
1029 1         6 $self->print_section();
1030 1         20 print "\n /* End of Initialisation Section */\n\n";
1031             }
1032              
1033 8         37 print Q(<<'EOF');
1034             ##if PERL_VERSION_LE(5, 21, 5)
1035             ## if PERL_VERSION_GE(5, 9, 0)
1036             # if (PL_unitcheckav)
1037             # call_list(PL_scopestack_ix, PL_unitcheckav);
1038             ## endif
1039             # XSRETURN_YES;
1040             ##else
1041             # Perl_xs_boot_epilog(aTHX_ ax);
1042             ##endif
1043             #]]
1044             #
1045             ##ifdef __cplusplus
1046             #}
1047             ##endif
1048             EOF
1049              
1050             warn("Please specify prototyping behavior for $self->{filename} (see perlxs manual)\n")
1051 8 50       64 unless $self->{ProtoUsed};
1052              
1053 8         200 chdir($orig_cwd);
1054 8         127 select($orig_fh);
1055 8 100       72 untie *PSEUDO_STDOUT if tied *PSEUDO_STDOUT;
1056 8         157 close $self->{FH};
1057              
1058 8         1217 return 1;
1059             }
1060              
1061             sub report_error_count {
1062 2 100   2 1 604186 if (@_) {
1063 1   50     11 return $_[0]->{errors}||0;
1064             }
1065             else {
1066 1   50     64 return $Singleton->{errors}||0;
1067             }
1068             }
1069             *errors = \&report_error_count;
1070              
1071             # Input: ($self, $_, @{ $self->{line} }) == unparsed input.
1072             # Output: ($_, @{ $self->{line} }) == (rest of line, following lines).
1073             # Return: the matched keyword if found, otherwise 0
1074             sub check_keyword {
1075 633     633 0 1043 my $self = shift;
1076 633   66     2226 $_ = shift(@{ $self->{line} }) while !/\S/ && @{ $self->{line} };
  56         197  
  56         270  
1077 633 100       21986 s/^(\s*)($_[0])\s*:\s*(?:#.*)?/$1/s && $2;
1078             }
1079              
1080             sub print_section {
1081 48     48 0 90 my $self = shift;
1082              
1083             # the "do" is required for right semantics
1084 48   33     73 do { $_ = shift(@{ $self->{line} }) } while !/\S/ && @{ $self->{line} };
  0         0  
  48         97  
  48         327  
1085              
1086 48         4609 my $consumed_code = '';
1087              
1088 33         74 print("#line ", $self->{line_no}->[@{ $self->{line_no} } - @{ $self->{line} } -1], " \"",
  33         146  
1089             escape_file_for_line_directive($self->{filepathname}), "\"\n")
1090 48 100 100     348 if $self->{WantLineNumbers} && !/^\s*#\s*line\b/ && !/^#if XSubPPtmp/;
      66        
1091 48   100     750 for (; defined($_) && !/^$BLOCK_regexp/o; $_ = shift(@{ $self->{line} })) {
  83         493  
1092 83         289 print "$_\n";
1093 83         421 $consumed_code .= "$_\n";
1094             }
1095 48 100       210 print 'ExtUtils::ParseXS::CountLines'->end_marker, "\n" if $self->{WantLineNumbers};
1096              
1097 48         175 return $consumed_code;
1098             }
1099              
1100             sub merge_section {
1101 5     5 0 9 my $self = shift;
1102 5         11 my $in = '';
1103              
1104 5   66     53 while (!/\S/ && @{ $self->{line} }) {
  5         34  
1105 5         9 $_ = shift(@{ $self->{line} });
  5         51  
1106             }
1107              
1108 5   66     354 for (; defined($_) && !/^$BLOCK_regexp/o; $_ = shift(@{ $self->{line} })) {
  5         54  
1109 5         26 $in .= "$_\n";
1110             }
1111 5         15 chomp $in;
1112 5         14 return $in;
1113             }
1114              
1115             sub process_keyword {
1116 228     228 0 574 my($self, $pattern) = @_;
1117              
1118 228         553 while (my $kwd = $self->check_keyword($pattern)) {
1119 53         178 my $method = $kwd . "_handler";
1120 53         409 $self->$method($_);
1121             }
1122             }
1123              
1124             sub CASE_handler {
1125 2     2 0 5 my $self = shift;
1126 2         3 $_ = shift;
1127             $self->blurt("Error: 'CASE:' after unconditional 'CASE:'")
1128 2 50 66     24 if $self->{condnum} && $self->{cond} eq '';
1129 2         5 $self->{cond} = $_;
1130 2         8 trim_whitespace($self->{cond});
1131 2 100       21 print " ", ($self->{condnum}++ ? " else" : ""), ($self->{cond} ? " if ($self->{cond})\n" : "\n");
    50          
1132 2         15 $_ = '';
1133             }
1134              
1135             sub INPUT_handler {
1136 64     64 0 123 my $self = shift;
1137 64         97 $_ = shift;
1138 64         835 for (; !/^$BLOCK_regexp/o; $_ = shift(@{ $self->{line} })) {
  71         542  
1139 71 50       175 last if /^\s*NOT_IMPLEMENTED_YET/;
1140 71 100       264 next unless /\S/; # skip blank lines
1141              
1142 62         219 trim_whitespace($_);
1143 62         133 my $ln = $_;
1144              
1145             # remove trailing semicolon if no initialisation
1146 62 100       251 s/\s*;$//g unless /[=;+].*\S/;
1147              
1148             # Process the length(foo) declarations
1149 62 100       164 if (s/^([^=]*)\blength\(\s*(\w+)\s*\)\s*$/$1 XSauto_length_of_$2=NO_INIT/x) {
1150 1         7 print "\tSTRLEN\tSTRLEN_length_of_$2;\n";
1151 1         4 $self->{lengthof}->{$2} = undef;
1152 1         13 $self->{deferred} .= "\n\tXSauto_length_of_$2 = STRLEN_length_of_$2;\n";
1153             }
1154              
1155             # check for optional initialisation code
1156 62         125 my $var_init = '';
1157 62 100       288 $var_init = $1 if s/\s*([=;+].*)$//s;
1158 62         114 $var_init =~ s/"/\\"/g;
1159             # *sigh* It's valid to supply explicit input typemaps in the argument list...
1160 62         121 my $is_overridden_typemap = $var_init =~ /ST\s*\(|\$arg\b/;
1161              
1162 62         250 s/\s+/ /g;
1163 62 50       555 my ($var_type, $var_addr, $var_name) = /^(.*?[^&\s])\s*(\&?)\s*\b(\w+)$/s
1164             or $self->blurt("Error: invalid argument declaration '$ln'"), next;
1165              
1166             # Check for duplicate definitions
1167             $self->blurt("Error: duplicate definition of argument '$var_name' ignored"), next
1168             if $self->{arg_list}->{$var_name}++
1169 62 50 66     472 or defined $self->{argtype_seen}->{$var_name} and not $self->{processing_arg_with_types};
      33        
1170              
1171 62         151 $self->{thisdone} |= $var_name eq "THIS";
1172 62         101 $self->{retvaldone} |= $var_name eq "RETVAL";
1173 62         143 $self->{var_types}->{$var_name} = $var_type;
1174             # XXXX This check is a safeguard against the unfinished conversion of
1175             # generate_init(). When generate_init() is fixed,
1176             # one can use 2-args map_type() unconditionally.
1177 62         87 my $printed_name;
1178 62 50       150 if ($var_type =~ / \( \s* \* \s* \) /x) {
1179             # Function pointers are not yet supported with output_init()!
1180 0         0 print "\t" . map_type($self, $var_type, $var_name);
1181 0         0 $printed_name = 1;
1182             }
1183             else {
1184 62         191 print "\t" . map_type($self, $var_type, undef);
1185 62         175 $printed_name = 0;
1186             }
1187 62         206 $self->{var_num} = $self->{args_match}->{$var_name};
1188              
1189 62 100       178 if ($self->{var_num}) {
1190 56         234 my $typemap = $self->{typemap}->get_typemap(ctype => $var_type);
1191 56 0 33     175 $self->report_typemap_failure($self->{typemap}, $var_type, "death")
1192             if not $typemap and not $is_overridden_typemap;
1193 56   50     261 $self->{proto_arg}->[$self->{var_num}] = ($typemap && $typemap->proto) || "\$";
1194             }
1195 62 50       175 $self->{func_args} =~ s/\b($var_name)\b/&$1/ if $var_addr;
1196 62 100 66     463 if ($var_init =~ /^[=;]\s*NO_INIT\s*;?\s*$/
    100 66        
    50 100        
1197             or $self->{in_out}->{$var_name} and $self->{in_out}->{$var_name} =~ /^OUT/
1198             and $var_init !~ /\S/) {
1199 5 50       14 if ($printed_name) {
1200 0         0 print ";\n";
1201             }
1202             else {
1203 5         18 print "\t$var_name;\n";
1204             }
1205             }
1206             elsif ($var_init =~ /\S/) {
1207             $self->output_init( {
1208             type => $var_type,
1209             num => $self->{var_num},
1210 2         45 var => $var_name,
1211             init => $var_init,
1212             printed_name => $printed_name,
1213             } );
1214             }
1215             elsif ($self->{var_num}) {
1216             $self->generate_init( {
1217             type => $var_type,
1218             num => $self->{var_num},
1219 55         424 var => $var_name,
1220             printed_name => $printed_name,
1221             } );
1222             }
1223             else {
1224 0         0 print ";\n";
1225             }
1226             }
1227             }
1228              
1229             sub OUTPUT_handler {
1230 31     31 0 54 my $self = shift;
1231 31         64 $self->{have_OUTPUT} = 1;
1232              
1233 31         48 $_ = shift;
1234 31         335 for (; !/^$BLOCK_regexp/o; $_ = shift(@{ $self->{line} })) {
  50         344  
1235 50 100       205 next unless /\S/;
1236 31 50       75 if (/^\s*SETMAGIC\s*:\s*(ENABLE|DISABLE)\s*/) {
1237 0 0       0 $self->{DoSetMagic} = ($1 eq "ENABLE" ? 1 : 0);
1238 0         0 next;
1239             }
1240 31         188 my ($outarg, $outcode) = /^\s*(\S+)\s*(.*?)\s*$/s;
1241             $self->blurt("Error: duplicate OUTPUT argument '$outarg' ignored"), next
1242 31 50       152 if $self->{outargs}->{$outarg}++;
1243 31 100 66     177 if (!$self->{gotRETVAL} and $outarg eq 'RETVAL') {
1244             # deal with RETVAL last
1245 23         70 $self->{RETVAL_code} = $outcode;
1246 23         44 $self->{gotRETVAL} = 1;
1247 23         53 next;
1248             }
1249             $self->blurt("Error: OUTPUT $outarg not an argument"), next
1250 8 50       27 unless defined($self->{args_match}->{$outarg});
1251             $self->blurt("Error: No input definition for OUTPUT argument '$outarg' - ignored"), next
1252 8 50       23 unless defined $self->{var_types}->{$outarg};
1253 8         19 $self->{var_num} = $self->{args_match}->{$outarg};
1254 8 50       18 if ($outcode) {
1255 0         0 print "\t$outcode\n";
1256 0 0       0 print "\tSvSETMAGIC(ST(" , $self->{var_num} - 1 , "));\n" if $self->{DoSetMagic};
1257             }
1258             else {
1259             $self->generate_output( {
1260             type => $self->{var_types}->{$outarg},
1261             num => $self->{var_num},
1262             var => $outarg,
1263             do_setmagic => $self->{DoSetMagic},
1264 8         53 do_push => undef,
1265             } );
1266             }
1267             delete $self->{in_out}->{$outarg} # No need to auto-OUTPUT
1268 8 50 33     84 if exists $self->{in_out}->{$outarg} and $self->{in_out}->{$outarg} =~ /OUT$/;
1269             }
1270             }
1271              
1272             sub C_ARGS_handler {
1273 4     4 0 13 my $self = shift;
1274 4         8 $_ = shift;
1275 4         13 my $in = $self->merge_section();
1276              
1277 4         24 trim_whitespace($in);
1278 4         22 $self->{func_args} = $in;
1279             }
1280              
1281             sub INTERFACE_MACRO_handler {
1282 0     0 0 0 my $self = shift;
1283 0         0 $_ = shift;
1284 0         0 my $in = $self->merge_section();
1285              
1286 0         0 trim_whitespace($in);
1287 0 0       0 if ($in =~ /\s/) { # two
1288 0         0 ($self->{interface_macro}, $self->{interface_macro_set}) = split ' ', $in;
1289             }
1290             else {
1291 0         0 $self->{interface_macro} = $in;
1292 0         0 $self->{interface_macro_set} = 'UNKNOWN_CVT'; # catch later
1293             }
1294 0         0 $self->{interface} = 1; # local
1295 0         0 $self->{interfaces} = 1; # global
1296             }
1297              
1298             sub INTERFACE_handler {
1299 1     1 0 2 my $self = shift;
1300 1         2 $_ = shift;
1301 1         3 my $in = $self->merge_section();
1302              
1303 1         5 trim_whitespace($in);
1304              
1305 1         10 foreach (split /[\s,]+/, $in) {
1306 1         8 my $iface_name = $_;
1307 1         20 $iface_name =~ s/^$self->{Prefix}//;
1308 1         10 $self->{Interfaces}->{$iface_name} = $_;
1309             }
1310 1         16 print Q(<<"EOF");
1311             # XSFUNCTION = $self->{interface_macro}($self->{ret_type},cv,XSANY.any_dptr);
1312             EOF
1313 1         3 $self->{interface} = 1; # local
1314 1         4 $self->{interfaces} = 1; # global
1315             }
1316              
1317             sub CLEANUP_handler {
1318 1     1 0 3 my $self = shift;
1319 1         3 $self->print_section();
1320             }
1321              
1322             sub PREINIT_handler {
1323 4     4 0 13 my $self = shift;
1324 4         19 $self->print_section();
1325             }
1326              
1327             sub POSTCALL_handler {
1328 1     1 0 2 my $self = shift;
1329 1         4 $self->print_section();
1330             }
1331              
1332             sub INIT_handler {
1333 2     2 0 6 my $self = shift;
1334 2         6 $self->print_section();
1335             }
1336              
1337             sub get_aliases {
1338 16     16 0 26 my $self = shift;
1339 16         74 my ($line) = @_;
1340 16         33 my ($orig) = $line;
1341              
1342             # we use this later for symbolic aliases
1343 16         44 my $fname = $self->{Packprefix} . $self->{func_name};
1344              
1345             # Parse alias definitions
1346             # format is
1347             # alias = value Pack::alias = value ...
1348             # or
1349             # alias => other
1350             # or
1351             # alias => Pack::other
1352             # or
1353             # Pack::alias => Other::alias
1354              
1355 16         95 while ($line =~ s/^\s*([\w:]+)\s*=(>?)\s*([\w:]+)\s*//) {
1356 16         63 my ($alias, $is_symbolic, $value) = ($1, $2, $3);
1357 16         30 my $orig_alias = $alias;
1358              
1359 16 50 33     88 blurt( $self, "Error: In alias definition for '$alias' the value may not"
1360             . " contain ':' unless it is symbolic.")
1361             if !$is_symbolic and $value=~/:/;
1362              
1363             # check for optional package definition in the alias
1364 16 100       80 $alias = $self->{Packprefix} . $alias if $alias !~ /::/;
1365              
1366 16 50       40 if ($is_symbolic) {
1367 0         0 my $orig_value = $value;
1368 0 0       0 $value = $self->{Packprefix} . $value if $value !~ /::/;
1369 0 0       0 if (defined $self->{XsubAliases}->{$value}) {
    0          
1370 0         0 $value = $self->{XsubAliases}->{$value};
1371             } elsif ($value eq $fname) {
1372 0         0 $value = 0;
1373             } else {
1374 0         0 blurt( $self, "Error: Unknown alias '$value' in symbolic definition for '$orig_alias'");
1375             }
1376             }
1377              
1378             # check for duplicate alias name & duplicate value
1379 16         43 my $prev_value = $self->{XsubAliases}->{$alias};
1380 16 50       39 if (defined $prev_value) {
1381 0 0       0 if ($prev_value eq $value) {
1382 0         0 Warn( $self, "Warning: Ignoring duplicate alias '$orig_alias'")
1383             } else {
1384 0         0 Warn( $self, "Warning: Conflicting duplicate alias '$orig_alias'"
1385             . " changes definition from '$prev_value' to '$value'");
1386 0         0 delete $self->{XsubAliasValues}->{$prev_value}{$alias};
1387             }
1388             }
1389              
1390             # Check and see if this alias results in two aliases having the same
1391             # value, we only check non-symbolic definitions as the whole point of
1392             # symbolic definitions is to say we want to duplicate the value and
1393             # it is NOT a mistake.
1394 16 50       35 unless ($is_symbolic) {
1395 16 50       22 my @keys= sort keys %{$self->{XsubAliasValues}->{$value}||{}};
  16         107  
1396             # deal with an alias of 0, which might not be in the XsubAlias dataset
1397             # yet as 0 is the default for the base function ($fname)
1398             push @keys, $fname
1399 16 50 33     61 if $value eq "0" and !defined $self->{XsubAlias}{$fname};
1400 16 0 33     49 if (@keys and $self->{author_warnings}) {
1401             # We do not warn about value collisions unless author_warnings
1402             # are enabled. They aren't helpful to a module consumer, only
1403             # the module author.
1404 0         0 @keys= map { "'$_'" }
1405 0         0 map { my $copy= $_;
  0         0  
1406 0         0 $copy=~s/^$self->{Packprefix}//;
1407 0         0 $copy
1408             } @keys;
1409             WarnHint( $self,
1410             "Warning: Aliases '$orig_alias' and "
1411             . join(", ", @keys)
1412             . " have identical values of $value"
1413             . ( $value eq "0"
1414             ? " - the base function"
1415             : "" ),
1416 0 0       0 !$self->{XsubAliasValueClashHinted}++
    0          
1417             ? "If this is deliberate use a symbolic alias instead."
1418             : undef
1419             );
1420             }
1421             }
1422              
1423 16         61 $self->{XsubAliases}->{$alias} = $value;
1424 16         143 $self->{XsubAliasValues}->{$value}{$alias}++;
1425             }
1426              
1427 16 50       63 blurt( $self, "Error: Cannot parse ALIAS definitions from '$orig'")
1428             if $line;
1429             }
1430              
1431             sub ATTRS_handler {
1432 1     1 0 2 my $self = shift;
1433 1         2 $_ = shift;
1434              
1435 1         138 for (; !/^$BLOCK_regexp/o; $_ = shift(@{ $self->{line} })) {
  1         11  
1436 1 50       7 next unless /\S/;
1437 1         5 trim_whitespace($_);
1438 1         4 push @{ $self->{Attributes} }, $_;
  1         4  
1439             }
1440             }
1441              
1442             sub ALIAS_handler {
1443 6     6 0 21 my $self = shift;
1444 6         12 $_ = shift;
1445              
1446 6         402 for (; !/^$BLOCK_regexp/o; $_ = shift(@{ $self->{line} })) {
  22         160  
1447 22 100       123 next unless /\S/;
1448 16         5062 trim_whitespace($_);
1449 16 50       88 $self->get_aliases($_) if $_;
1450             }
1451             }
1452              
1453             sub OVERLOAD_handler {
1454 1     1 0 2 my $self = shift;
1455 1         3 $_ = shift;
1456              
1457 1         150 for (; !/^$BLOCK_regexp/o; $_ = shift(@{ $self->{line} })) {
  1         12  
1458 1 50       11 next unless /\S/;
1459 1         7 trim_whitespace($_);
1460 1         9 while ( s/^\s*([\w:"\\)\+\-\*\/\%\<\>\.\&\|\^\!\~\{\}\=]+)\s*//) {
1461 1         7 $self->{OverloadsThisXSUB}->{$1} = 1;
1462             }
1463             }
1464             }
1465              
1466             sub FALLBACK_handler {
1467 1     1 0 3 my ($self, $setting) = @_;
1468              
1469             # the rest of the current line should contain either TRUE,
1470             # FALSE or UNDEF
1471              
1472 1         5 trim_whitespace($setting);
1473 1         4 $setting = uc($setting);
1474              
1475 1         24 my %map = (
1476             TRUE => "&PL_sv_yes", 1 => "&PL_sv_yes",
1477             FALSE => "&PL_sv_no", 0 => "&PL_sv_no",
1478             UNDEF => "&PL_sv_undef",
1479             );
1480              
1481             # check for valid FALLBACK value
1482 1 50       6 $self->death("Error: FALLBACK: TRUE/FALSE/UNDEF") unless exists $map{$setting};
1483              
1484 1         12 $self->{Fallback}->{$self->{Package}} = $map{$setting};
1485             }
1486              
1487              
1488             sub REQUIRE_handler {
1489             # the rest of the current line should contain a version number
1490 1     1 0 5 my ($self, $ver) = @_;
1491              
1492 1         5 trim_whitespace($ver);
1493              
1494 1 50       3 $self->death("Error: REQUIRE expects a version number")
1495             unless $ver;
1496              
1497             # check that the version number is of the form n.n
1498 1 50       21 $self->death("Error: REQUIRE: expected a number, got '$ver'")
1499             unless $ver =~ /^\d+(\.\d*)?/;
1500              
1501 1 50       19 $self->death("Error: xsubpp $ver (or better) required--this is only $VERSION.")
1502             unless $VERSION >= $ver;
1503             }
1504              
1505             sub VERSIONCHECK_handler {
1506             # the rest of the current line should contain either ENABLE or
1507             # DISABLE
1508 1     1 0 22 my ($self, $setting) = @_;
1509              
1510 1         5 trim_whitespace($setting);
1511              
1512             # check for ENABLE/DISABLE
1513 1 50       10 $self->death("Error: VERSIONCHECK: ENABLE/DISABLE")
1514             unless $setting =~ /^(ENABLE|DISABLE)/i;
1515              
1516 1 50       17 $self->{WantVersionChk} = 1 if $1 eq 'ENABLE';
1517 1 50       18 $self->{WantVersionChk} = 0 if $1 eq 'DISABLE';
1518              
1519             }
1520              
1521             sub PROTOTYPE_handler {
1522 1     1 0 3 my $self = shift;
1523 1         2 $_ = shift;
1524              
1525 1         2 my $specified;
1526              
1527             $self->death("Error: Only 1 PROTOTYPE definition allowed per xsub")
1528 1 50       4 if $self->{proto_in_this_xsub}++;
1529              
1530 1         145 for (; !/^$BLOCK_regexp/o; $_ = shift(@{ $self->{line} })) {
  1         11  
1531 1 50       8 next unless /\S/;
1532 1         3 $specified = 1;
1533 1         5 trim_whitespace($_);
1534 1 50       14 if ($_ eq 'DISABLE') {
    50          
1535 0         0 $self->{ProtoThisXSUB} = 0;
1536             }
1537             elsif ($_ eq 'ENABLE') {
1538 0         0 $self->{ProtoThisXSUB} = 1;
1539             }
1540             else {
1541             # remove any whitespace
1542 1         4 s/\s+//g;
1543 1 50       15 $self->death("Error: Invalid prototype '$_'")
1544             unless valid_proto_string($_);
1545 1         5 $self->{ProtoThisXSUB} = C_string($_);
1546             }
1547             }
1548              
1549             # If no prototype specified, then assume empty prototype ""
1550 1 50       4 $self->{ProtoThisXSUB} = 2 unless $specified;
1551              
1552 1         5 $self->{ProtoUsed} = 1;
1553             }
1554              
1555             sub SCOPE_handler {
1556             # Rest of line should be either ENABLE or DISABLE
1557 1     1 0 4 my ($self, $setting) = @_;
1558              
1559             $self->death("Error: Only 1 SCOPE declaration allowed per xsub")
1560 1 50       5 if $self->{scope_in_this_xsub}++;
1561              
1562 1         5 trim_whitespace($setting);
1563 1 50       9 $self->death("Error: SCOPE: ENABLE/DISABLE")
1564             unless $setting =~ /^(ENABLE|DISABLE)\b/i;
1565 1         6 $self->{ScopeThisXSUB} = ( uc($1) eq 'ENABLE' );
1566             }
1567              
1568             sub PROTOTYPES_handler {
1569             # the rest of the current line should contain either ENABLE or
1570             # DISABLE
1571 8     8 0 38 my ($self, $setting) = @_;
1572              
1573 8         51 trim_whitespace($setting);
1574              
1575             # check for ENABLE/DISABLE
1576 8 50       114 $self->death("Error: PROTOTYPES: ENABLE/DISABLE")
1577             unless $setting =~ /^(ENABLE|DISABLE)/i;
1578              
1579 8 100       51 $self->{WantPrototypes} = 1 if $1 eq 'ENABLE';
1580 8 100       46 $self->{WantPrototypes} = 0 if $1 eq 'DISABLE';
1581 8         39 $self->{ProtoUsed} = 1;
1582             }
1583              
1584             sub EXPORT_XSUB_SYMBOLS_handler {
1585             # the rest of the current line should contain either ENABLE or
1586             # DISABLE
1587 0     0 0 0 my ($self, $setting) = @_;
1588              
1589 0         0 trim_whitespace($setting);
1590              
1591             # check for ENABLE/DISABLE
1592 0 0       0 $self->death("Error: EXPORT_XSUB_SYMBOLS: ENABLE/DISABLE")
1593             unless $setting =~ /^(ENABLE|DISABLE)/i;
1594              
1595 0 0       0 my $xs_impl = $1 eq 'ENABLE' ? 'XS_EXTERNAL' : 'XS_INTERNAL';
1596              
1597 0         0 print Q(<<"EOF");
1598             ##undef XS_EUPXS
1599             ##if defined(PERL_EUPXS_ALWAYS_EXPORT)
1600             ## define XS_EUPXS(name) XS_EXTERNAL(name)
1601             ##elif defined(PERL_EUPXS_NEVER_EXPORT)
1602             ## define XS_EUPXS(name) XS_INTERNAL(name)
1603             ##else
1604             ## define XS_EUPXS(name) $xs_impl(name)
1605             ##endif
1606             EOF
1607             }
1608              
1609              
1610             sub PushXSStack {
1611 2     2 0 6 my $self = shift;
1612 2         7 my %args = @_;
1613             # Save the current file context.
1614 2         38 push(@{ $self->{XSStack} }, {
1615             type => 'file',
1616             LastLine => $self->{lastline},
1617             LastLineNo => $self->{lastline_no},
1618             Line => $self->{line},
1619             LineNo => $self->{line_no},
1620             Filename => $self->{filename},
1621             Filepathname => $self->{filepathname},
1622             Handle => $self->{FH},
1623 2         4 IsPipe => scalar($self->{filename} =~ /\|\s*$/),
1624             %args,
1625             });
1626              
1627             }
1628              
1629             sub INCLUDE_handler {
1630 1     1 0 9 my $self = shift;
1631 1         3 $_ = shift;
1632             # the rest of the current line should contain a valid filename
1633              
1634 1         8 trim_whitespace($_);
1635              
1636 1 50       17 $self->death("INCLUDE: filename missing")
1637             unless $_;
1638              
1639 1 50       17 $self->death("INCLUDE: output pipe is illegal")
1640             if /^\s*\|/;
1641              
1642             # simple minded recursion detector
1643             $self->death("INCLUDE loop detected")
1644 1 50       12 if $self->{IncludedFiles}->{$_};
1645              
1646 1 50       17 ++$self->{IncludedFiles}->{$_} unless /\|\s*$/;
1647              
1648 1 50 33     18 if (/\|\s*$/ && /^\s*perl\s/) {
1649 0         0 Warn( $self, "The INCLUDE directive with a command is discouraged." .
1650             " Use INCLUDE_COMMAND instead! In particular using 'perl'" .
1651             " in an 'INCLUDE: ... |' directive is not guaranteed to pick" .
1652             " up the correct perl. The INCLUDE_COMMAND directive allows" .
1653             " the use of \$^X as the currently running perl, see" .
1654             " 'perldoc perlxs' for details.");
1655             }
1656              
1657 1         6 $self->PushXSStack();
1658              
1659 1         23 $self->{FH} = Symbol::gensym();
1660              
1661             # open the new file
1662 1 50       133 open($self->{FH}, $_) or $self->death("Cannot open '$_': $!");
1663              
1664 1         16 print Q(<<"EOF");
1665             #
1666             #/* INCLUDE: Including '$_' from '$self->{filename}' */
1667             #
1668             EOF
1669              
1670 1         7 $self->{filename} = $_;
1671             $self->{filepathname} = ( $^O =~ /^mswin/i )
1672             ? qq($self->{dir}/$self->{filename}) # See CPAN RT #61908: gcc doesn't like backslashes on win32?
1673 1 50       76 : File::Spec->catfile($self->{dir}, $self->{filename});
1674              
1675             # Prime the pump by reading the first
1676             # non-blank line
1677              
1678             # skip leading blank lines
1679 1         64 while (readline($self->{FH})) {
1680 2 100       24 last unless /^\s*$/;
1681             }
1682              
1683 1         16 $self->{lastline} = $_;
1684 1         16 $self->{lastline_no} = $.;
1685             }
1686              
1687             sub QuoteArgs {
1688 0     0 0 0 my $cmd = shift;
1689 0         0 my @args = split /\s+/, $cmd;
1690 0         0 $cmd = shift @args;
1691 0         0 for (@args) {
1692 0 0 0     0 $_ = q(").$_.q(") if !/^\"/ && length($_) > 0;
1693             }
1694 0         0 return join (' ', ($cmd, @args));
1695             }
1696              
1697             # code copied from CPAN::HandleConfig::safe_quote
1698             # - that has doc saying leave if start/finish with same quote, but no code
1699             # given text, will conditionally quote it to protect from shell
1700             {
1701             my ($quote, $use_quote) = $^O eq 'MSWin32'
1702             ? (q{"}, q{"})
1703             : (q{"'}, q{'});
1704             sub _safe_quote {
1705 1     1   4 my ($self, $command) = @_;
1706             # Set up quote/default quote
1707 1 50 33     18 if (defined($command)
      33        
1708             and $command =~ /\s/
1709             and $command !~ /[$quote]/) {
1710 0         0 return qq{$use_quote$command$use_quote}
1711             }
1712 1         4 return $command;
1713             }
1714             }
1715              
1716             sub INCLUDE_COMMAND_handler {
1717 1     1 0 12 my $self = shift;
1718 1         3 $_ = shift;
1719             # the rest of the current line should contain a valid command
1720              
1721 1         4 trim_whitespace($_);
1722              
1723 1 50       5 $_ = QuoteArgs($_) if $^O eq 'VMS';
1724              
1725 1 50       4 $self->death("INCLUDE_COMMAND: command missing")
1726             unless $_;
1727              
1728 1 50 33     19 $self->death("INCLUDE_COMMAND: pipes are illegal")
1729             if /^\s*\|/ or /\|\s*$/;
1730              
1731 1         11 $self->PushXSStack( IsPipe => 1 );
1732              
1733 1         21 $self->{FH} = Symbol::gensym();
1734              
1735             # If $^X is used in INCLUDE_COMMAND, we know it's supposed to be
1736             # the same perl interpreter as we're currently running
1737 1         41 my $X = $self->_safe_quote($^X); # quotes if has spaces
1738 1         11 s/^\s*\$\^X/$X/;
1739              
1740             # open the new file
1741 1 50       3617 open ($self->{FH}, "-|", $_)
1742             or $self->death( $self, "Cannot run command '$_' to include its output: $!");
1743              
1744 1         59 print Q(<<"EOF");
1745             #
1746             #/* INCLUDE_COMMAND: Including output of '$_' from '$self->{filename}' */
1747             #
1748             EOF
1749              
1750 1         25 $self->{filename} = $_;
1751 1         23 $self->{filepathname} = $self->{filename};
1752             #$self->{filepathname} =~ s/\"/\\"/g; # Fails? See CPAN RT #53938: MinGW Broken after 2.21
1753 1         13 $self->{filepathname} =~ s/\\/\\\\/g; # Works according to reporter of #53938
1754              
1755             # Prime the pump by reading the first
1756             # non-blank line
1757              
1758             # skip leading blank lines
1759 1         3743 while (readline($self->{FH})) {
1760 2 100       55 last unless /^\s*$/;
1761             }
1762              
1763 1         18 $self->{lastline} = $_;
1764 1         24 $self->{lastline_no} = $.;
1765             }
1766              
1767             sub PopFile {
1768 10     10 0 38 my $self = shift;
1769              
1770 10 100       88 return 0 unless $self->{XSStack}->[-1]{type} eq 'file';
1771              
1772 2         6 my $data = pop @{ $self->{XSStack} };
  2         11  
1773 2         14 my $ThisFile = $self->{filename};
1774 2         13 my $isPipe = $data->{IsPipe};
1775              
1776             --$self->{IncludedFiles}->{$self->{filename}}
1777 2 100       21 unless $isPipe;
1778              
1779 2         71 close $self->{FH};
1780              
1781 2         39 $self->{FH} = $data->{Handle};
1782             # $filename is the leafname, which for some reason is used for diagnostic
1783             # messages, whereas $filepathname is the full pathname, and is used for
1784             # #line directives.
1785 2         9 $self->{filename} = $data->{Filename};
1786 2         6 $self->{filepathname} = $data->{Filepathname};
1787 2         7 $self->{lastline} = $data->{LastLine};
1788 2         24 $self->{lastline_no} = $data->{LastLineNo};
1789 2         7 @{ $self->{line} } = @{ $data->{Line} };
  2         12  
  2         9  
1790 2         5 @{ $self->{line_no} } = @{ $data->{LineNo} };
  2         11  
  2         8  
1791              
1792 2 50 66     30 if ($isPipe and $? ) {
1793 0         0 --$self->{lastline_no};
1794 0         0 print STDERR "Error reading from pipe '$ThisFile': $! in $self->{filename}, line $self->{lastline_no}\n" ;
1795 0         0 exit 1;
1796             }
1797              
1798 2         16 print Q(<<"EOF");
1799             #
1800             #/* INCLUDE: Returning to '$self->{filename}' from '$ThisFile' */
1801             #
1802             EOF
1803              
1804 2         30 return 1;
1805             }
1806              
1807             sub Q {
1808 439     439 0 930 my($text) = @_;
1809 439         2153 $text =~ s/^#//gm;
1810 439         987 $text =~ s/\[\[/{/g;
1811 439         785 $text =~ s/\]\]/}/g;
1812 439         1521 $text;
1813             }
1814              
1815             # Process "MODULE = Foo ..." lines and update global state accordingly
1816             sub _process_module_xs_line {
1817 8     8   81 my ($self, $module, $pkg, $prefix) = @_;
1818              
1819 8         50 ($self->{Module_cname} = $module) =~ s/\W/_/g;
1820              
1821 8 50       46 $self->{Package} = defined($pkg) ? $pkg : '';
1822 8 100       38 $self->{Prefix} = quotemeta( defined($prefix) ? $prefix : '' );
1823              
1824 8         36 ($self->{Packid} = $self->{Package}) =~ tr/:/_/;
1825              
1826 8         39 $self->{Packprefix} = $self->{Package};
1827 8 50       43 $self->{Packprefix} .= "::" if $self->{Packprefix} ne "";
1828              
1829 8         59 $self->{lastline} = "";
1830             }
1831              
1832             # Skip any embedded POD sections
1833             sub _maybe_skip_pod {
1834 572     572   926 my ($self) = @_;
1835              
1836 572         1352 while ($self->{lastline} =~ /^=/) {
1837 1         8 while ($self->{lastline} = readline($self->{FH})) {
1838 4 100       13 last if ($self->{lastline} =~ /^=cut\s*$/);
1839             }
1840 1 50       5 $self->death("Error: Unterminated pod") unless defined $self->{lastline};
1841 1         2 $self->{lastline} = readline($self->{FH});
1842 1         2 chomp $self->{lastline};
1843 1         4 $self->{lastline} =~ s/^\s+$//;
1844             }
1845             }
1846              
1847             # This chunk of code strips out (and parses) embedded TYPEMAP blocks
1848             # which support a HEREdoc-alike block syntax.
1849             sub _maybe_parse_typemap_block {
1850 572     572   857 my ($self) = @_;
1851              
1852             # This is special cased from the usual paragraph-handler logic
1853             # due to the HEREdoc-ish syntax.
1854 572 100       1191 if ($self->{lastline} =~ /^TYPEMAP\s*:\s*<<\s*(?:(["'])(.+?)\1|([^\s'"]+?))\s*;?\s*$/)
1855             {
1856 6 100       43 my $end_marker = quotemeta(defined($1) ? $2 : $3);
1857              
1858             # Scan until we find $end_marker alone on a line.
1859 6         11 my @tmaplines;
1860 6         17 while (1) {
1861 34         73 $self->{lastline} = readline($self->{FH});
1862 34 50       66 $self->death("Error: Unterminated TYPEMAP section") if not defined $self->{lastline};
1863 34 100       230 last if $self->{lastline} =~ /^$end_marker\s*$/;
1864 28         70 push @tmaplines, $self->{lastline};
1865             }
1866              
1867             my $tmap = ExtUtils::Typemaps->new(
1868             string => join("", @tmaplines),
1869             lineno_offset => 1 + ($self->current_line_number() || 0),
1870             fake_filename => $self->{filename},
1871 6   50     62 );
1872 6         27 $self->{typemap}->merge(typemap => $tmap, replace => 1);
1873              
1874 6         60 $self->{lastline} = "";
1875             }
1876             }
1877              
1878             # Read next xsub into @{ $self->{line} } from ($lastline, readline($self->{FH})).
1879             sub fetch_para {
1880 96     96 0 215 my $self = shift;
1881              
1882             # parse paragraph
1883             $self->death("Error: Unterminated '#if/#ifdef/#ifndef'")
1884 96 50 66     405 if !defined $self->{lastline} && $self->{XSStack}->[-1]{type} eq 'if';
1885 96         151 @{ $self->{line} } = ();
  96         246  
1886 96         200 @{ $self->{line_no} } = ();
  96         243  
1887 96 100       300 return $self->PopFile() if not defined $self->{lastline}; # EOF
1888              
1889 86 100       307 if ($self->{lastline} =~
1890             /^MODULE\s*=\s*([\w:]+)(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/)
1891             {
1892 8         96 $self->_process_module_xs_line($1, $2, $3);
1893             }
1894              
1895             # count how many #ifdef levels we see in this paragraph
1896             # decrementing when we see an endif. if we see an elsif
1897             # or endif without a corresponding #ifdef then we dont
1898             # consider it part of this paragraph.
1899 86         149 my $if_level = 0;
1900 86         149 for (;;) {
1901 572         1399 $self->_maybe_skip_pod;
1902              
1903 572         1212 $self->_maybe_parse_typemap_block;
1904              
1905 572         766 my $final;
1906 572 100 100     1394 if ($self->{lastline} !~ /^\s*#/ # not a CPP directive
1907             # CPP directives:
1908             # ANSI: if ifdef ifndef elif else endif define undef
1909             # line error pragma
1910             # gcc: warning include_next
1911             # obj-c: import
1912             # others: ident (gcc notes that some cpps have this one)
1913             || $self->{lastline} =~ /^\#[ \t]*
1914             (?:
1915             (?:if|ifn?def|elif|else|endif|elifn?def|
1916             define|undef|pragma|error|
1917             warning|line\s+\d+|ident)
1918             \b
1919             | (?:include(?:_next)?|import)
1920             \s* ["<] .* [>"]
1921             )
1922             /x
1923             )
1924             {
1925 569 100 100     1498 last if $self->{lastline} =~ /^\S/ && @{ $self->{line} } && $self->{line}->[-1] eq "";
  223   100     999  
1926 495 100       969 if ($self->{lastline}=~/^#[ \t]*(if|ifn?def|elif|else|endif|elifn?def)\b/) {
1927 3         22 my $type = $1; # highest defined capture buffer, "if" for any if like condition
1928 3 100       20 if ($type =~ /^if/) {
    100          
    50          
1929 1 50       6 if (@{$self->{line}}) {
  1         16  
1930             # increment level
1931 0         0 $if_level++;
1932             } else {
1933 1         4 $final = 1;
1934             }
1935             } elsif ($type eq "endif") {
1936 1 50       7 if ($if_level) { # are we in an if that was started in this paragraph?
1937 0         0 $if_level--; # yep- so decrement to end this if block
1938             } else {
1939 1         2 $final = 1;
1940             }
1941             } elsif (!$if_level) {
1942             # not in an #ifdef from this paragraph, thus
1943             # this directive should not be part of this paragraph.
1944 1         14 $final = 1;
1945             }
1946             }
1947 495 50 66     978 if ($final and @{$self->{line}}) {
  3         16  
1948 0         0 return 1;
1949             }
1950              
1951 495         664 push(@{ $self->{line} }, $self->{lastline});
  495         1108  
1952 495         682 push(@{ $self->{line_no} }, $self->{lastline_no});
  495         804  
1953             }
1954              
1955             # Read next line and continuation lines
1956 498 100       1572 last unless defined($self->{lastline} = readline($self->{FH}));
1957 488         871 $self->{lastline_no} = $.;
1958 488         635 my $tmp_line;
1959             $self->{lastline} .= $tmp_line
1960 488   33     1176 while ($self->{lastline} =~ /\\$/ && defined($tmp_line = readline($self->{FH})));
1961              
1962 488         740 chomp $self->{lastline};
1963 488         1129 $self->{lastline} =~ s/^\s+$//;
1964 488 100       911 if ($final) {
1965 2         7 last;
1966             }
1967             }
1968              
1969             # Nuke trailing "line" entries until there's one that's not empty
1970 101         190 pop(@{ $self->{line} }), pop(@{ $self->{line_no} })
  101         195  
1971 86   100     170 while @{ $self->{line} } && $self->{line}->[-1] eq "";
  187         668  
1972              
1973 86         204 return 1;
1974             }
1975              
1976             sub output_init {
1977 2     2 0 7 my $self = shift;
1978 2         5 my $argsref = shift;
1979              
1980             my ($type, $num, $var, $init, $printed_name)
1981 2         5 = @{$argsref}{qw(type num var init printed_name)};
  2         9  
1982              
1983             # local assign for efficiently passing in to eval_input_typemap_code
1984 2 100       18 local $argsref->{arg} = $num
1985             ? "ST(" . ($num-1) . ")"
1986             : "/* not a parameter */";
1987              
1988 2 50       12 if ( $init =~ /^=/ ) {
1989 2 50       9 if ($printed_name) {
1990 0         0 $self->eval_input_typemap_code(qq/print " $init\\n"/, $argsref);
1991             }
1992             else {
1993 2         19 $self->eval_input_typemap_code(qq/print "\\t$var $init\\n"/, $argsref);
1994             }
1995             }
1996             else {
1997 0 0 0     0 if ( $init =~ s/^\+// && $num ) {
    0          
1998 0         0 $self->generate_init( {
1999             type => $type,
2000             num => $num,
2001             var => $var,
2002             printed_name => $printed_name,
2003             } );
2004             }
2005             elsif ($printed_name) {
2006 0         0 print ";\n";
2007 0         0 $init =~ s/^;//;
2008             }
2009             else {
2010 0         0 $self->eval_input_typemap_code(qq/print "\\t$var;\\n"/, $argsref);
2011 0         0 $init =~ s/^;//;
2012             }
2013             $self->{deferred}
2014 0         0 .= $self->eval_input_typemap_code(qq/"\\n\\t$init\\n"/, $argsref);
2015             }
2016             }
2017              
2018             sub generate_init {
2019 55     55 0 98 my $self = shift;
2020 55         85 my $argsref = shift;
2021              
2022             my ($type, $num, $var, $printed_name)
2023 55         96 = @{$argsref}{qw(type num var printed_name)};
  55         163  
2024              
2025 55         99 my $argoff = $num - 1;
2026 55         119 my $arg = "ST($argoff)";
2027              
2028 55         114 my $typemaps = $self->{typemap};
2029              
2030 55         131 $type = ExtUtils::Typemaps::tidy_type($type);
2031 55 50       170 if (not $typemaps->get_typemap(ctype => $type)) {
2032 0         0 $self->report_typemap_failure($typemaps, $type);
2033 0         0 return;
2034             }
2035              
2036 55         237 (my $ntype = $type) =~ s/\s*\*/Ptr/g;
2037 55         302 (my $subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//;
2038              
2039 55         163 my $typem = $typemaps->get_typemap(ctype => $type);
2040 55         163 my $xstype = $typem->xstype;
2041             #this is an optimization from perl 5.0 alpha 6, class check is skipped
2042             #T_REF_IV_REF is missing since it has no untyped analog at the moment
2043             $xstype =~ s/OBJ$/REF/ || $xstype =~ s/^T_REF_IV_PTR$/T_PTRREF/
2044 55 50 0     165 if $self->{func_name} =~ /DESTROY$/;
2045 55 100 100     249 if ($xstype eq 'T_PV' and exists $self->{lengthof}->{$var}) {
2046 1 50       6 print "\t$var" unless $printed_name;
2047 1         15 print " = ($type)SvPV($arg, STRLEN_length_of_$var);\n";
2048             die "default value not supported with length(NAME) supplied"
2049 1 50       19 if defined $self->{defaults}->{$var};
2050 1         3 return;
2051             }
2052 54 50       163 $type =~ tr/:/_/ unless $self->{RetainCplusplusHierarchicalTypes};
2053              
2054 54         171 my $inputmap = $typemaps->get_inputmap(xstype => $xstype);
2055 54 100       120 if (not defined $inputmap) {
2056 1         10 $self->blurt("Error: No INPUT definition for type '$type', typekind '$xstype' found");
2057 1         4 return;
2058             }
2059              
2060 53         147 my $expr = $inputmap->cleaned_code;
2061             # Note: This gruesome bit either needs heavy rethinking or documentation. I vote for the former. --Steffen
2062 53 50       159 if ($expr =~ /DO_ARRAY_ELEM/) {
2063 0         0 my $subtypemap = $typemaps->get_typemap(ctype => $subtype);
2064 0 0       0 if (not $subtypemap) {
2065 0         0 $self->report_typemap_failure($typemaps, $subtype);
2066 0         0 return;
2067             }
2068              
2069 0         0 my $subinputmap = $typemaps->get_inputmap(xstype => $subtypemap->xstype);
2070 0 0       0 if (not $subinputmap) {
2071 0         0 $self->blurt("Error: No INPUT definition for type '$subtype', typekind '" . $subtypemap->xstype . "' found");
2072 0         0 return;
2073             }
2074              
2075 0         0 my $subexpr = $subinputmap->cleaned_code;
2076 0         0 $subexpr =~ s/\$type/\$subtype/g;
2077 0         0 $subexpr =~ s/ntype/subtype/g;
2078 0         0 $subexpr =~ s/\$arg/ST(ix_$var)/g;
2079 0         0 $subexpr =~ s/\n\t/\n\t\t/g;
2080 0         0 $subexpr =~ s/is not of (.*\")/[arg %d] is not of $1, ix_$var + 1/g;
2081 0         0 $subexpr =~ s/\$var/${var}\[ix_$var - $argoff]/;
2082 0         0 $expr =~ s/DO_ARRAY_ELEM/$subexpr/;
2083             }
2084 53 50       169 if ($expr =~ m#/\*.*scope.*\*/#i) { # "scope" in C comments
2085 0         0 $self->{ScopeThisXSUB} = 1;
2086             }
2087              
2088 53         382 my $eval_vars = {
2089             var => $var,
2090             printed_name => $printed_name,
2091             type => $type,
2092             ntype => $ntype,
2093             subtype => $subtype,
2094             num => $num,
2095             arg => $arg,
2096             argoff => $argoff,
2097             };
2098              
2099 53 100 66     528 if (defined($self->{defaults}->{$var})) {
    100          
2100 1         8 $expr =~ s/(\t+)/$1 /g;
2101 1         4 $expr =~ s/ /\t/g;
2102 1 50       4 if ($printed_name) {
2103 0         0 print ";\n";
2104             }
2105             else {
2106 1         12 $self->eval_input_typemap_code(qq/print "\\t$var;\\n"/, $eval_vars);
2107             }
2108 1 50       8 if ($self->{defaults}->{$var} eq 'NO_INIT') {
2109 0         0 $self->{deferred} .= $self->eval_input_typemap_code(
2110             qq/"\\n\\tif (items >= $num) {\\n$expr;\\n\\t}\\n"/,
2111             $eval_vars
2112             );
2113             }
2114             else {
2115 1         9 $self->{deferred} .= $self->eval_input_typemap_code(
2116             qq/"\\n\\tif (items < $num)\\n\\t $var = $self->{defaults}->{$var};\\n\\telse {\\n$expr;\\n\\t}\\n"/,
2117             $eval_vars
2118             );
2119             }
2120             }
2121             elsif ($self->{ScopeThisXSUB} or $expr !~ /^\s*\$var =/) {
2122 1 50       4 if ($printed_name) {
2123 0         0 print ";\n";
2124             }
2125             else {
2126 1         3 $self->eval_input_typemap_code(qq/print "\\t$var;\\n"/, $eval_vars);
2127             }
2128             $self->{deferred}
2129 1         7 .= $self->eval_input_typemap_code(qq/"\\n$expr;\\n"/, $eval_vars);
2130             }
2131             else {
2132 51 50       123 die "panic: do not know how to handle this branch for function pointers"
2133             if $printed_name;
2134 51         211 $self->eval_input_typemap_code(qq/print "$expr;\\n"/, $eval_vars);
2135             }
2136             }
2137              
2138             sub generate_output {
2139 17     17 0 34 my $self = shift;
2140 17         30 my $argsref = shift;
2141             my ($type, $num, $var, $do_setmagic, $do_push)
2142 17         29 = @{$argsref}{qw(type num var do_setmagic do_push)};
  17         62  
2143              
2144 17         53 my $arg = "ST(" . ($num - ($num != 0)) . ")";
2145              
2146 17         32 my $typemaps = $self->{typemap};
2147              
2148 17         48 $type = ExtUtils::Typemaps::tidy_type($type);
2149 17         53 local $argsref->{type} = $type;
2150              
2151 17 50       52 if ($type =~ /^array\(([^,]*),(.*)\)/) {
2152 0         0 print "\t$arg = sv_newmortal();\n";
2153 0         0 print "\tsv_setpvn($arg, (char *)$var, $2 * sizeof($1));\n";
2154 0 0       0 print "\tSvSETMAGIC($arg);\n" if $do_setmagic;
2155             }
2156             else {
2157 17         53 my $typemap = $typemaps->get_typemap(ctype => $type);
2158 17 50       56 if (not $typemap) {
2159 0         0 $self->report_typemap_failure($typemaps, $type);
2160 0         0 return;
2161             }
2162              
2163 17         57 my $outputmap = $typemaps->get_outputmap(xstype => $typemap->xstype);
2164 17 50       44 if (not $outputmap) {
2165 0         0 $self->blurt("Error: No OUTPUT definition for type '$type', typekind '" . $typemap->xstype . "' found");
2166 0         0 return;
2167             }
2168              
2169 17         54 (my $ntype = $type) =~ s/\s*\*/Ptr/g;
2170 17         35 $ntype =~ s/\(\)//g;
2171 17         96 (my $subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//;
2172 17 50       79 $type =~ tr/:/_/ unless $self->{RetainCplusplusHierarchicalTypes};
2173              
2174 17         153 my $eval_vars = {%$argsref, subtype => $subtype, ntype => $ntype, arg => $arg, type => $type };
2175 17         82 my $expr = $outputmap->cleaned_code;
2176 17 50       145 if ($expr =~ /DO_ARRAY_ELEM/) {
    100          
    100          
    50          
2177 0         0 my $subtypemap = $typemaps->get_typemap(ctype => $subtype);
2178 0 0       0 if (not $subtypemap) {
2179 0         0 $self->report_typemap_failure($typemaps, $subtype);
2180 0         0 return;
2181             }
2182              
2183 0         0 my $suboutputmap = $typemaps->get_outputmap(xstype => $subtypemap->xstype);
2184 0 0       0 if (not $suboutputmap) {
2185 0         0 $self->blurt("Error: No OUTPUT definition for type '$subtype', typekind '" . $subtypemap->xstype . "' found");
2186 0         0 return;
2187             }
2188              
2189 0         0 my $subexpr = $suboutputmap->cleaned_code;
2190 0         0 $subexpr =~ s/ntype/subtype/g;
2191 0         0 $subexpr =~ s/\$arg/ST(ix_$var)/g;
2192 0         0 $subexpr =~ s/\$var/${var}\[ix_$var]/g;
2193 0         0 $subexpr =~ s/\n\t/\n\t\t/g;
2194 0         0 $expr =~ s/DO_ARRAY_ELEM\n/$subexpr/;
2195 0         0 $self->eval_output_typemap_code("print qq\a$expr\a", $eval_vars);
2196 0 0       0 print "\t\tSvSETMAGIC(ST(ix_$var));\n" if $do_setmagic;
2197             }
2198             elsif ($var eq 'RETVAL') {
2199 5         11 my $orig_arg = $arg;
2200 5         11 my $indent;
2201 5         10 my $use_RETVALSV = 1;
2202 5         9 my $do_mortal = 0;
2203 5         12 my $do_copy_tmp = 1;
2204 5         6 my $pre_expr;
2205 5         18 local $eval_vars->{arg} = $arg = 'RETVALSV';
2206 5         23 my $evalexpr = $self->eval_output_typemap_code("qq\a$expr\a", $eval_vars);
2207              
2208 5 50       195 if ($expr =~ /^\t\Q$arg\E = new/) {
    50          
    0          
2209             # We expect that $arg has refcnt 1, so we need to
2210             # mortalize it.
2211 0         0 $do_mortal = 1;
2212             }
2213             # If RETVAL is immortal, don't mortalize it. This code is not perfect:
2214             # It won't detect a func or expression that only returns immortals, for
2215             # example, this RE must be tried before next elsif.
2216             elsif ($evalexpr =~ /^\t\Q$arg\E\s*=\s*(boolSV\(|(&PL_sv_yes|&PL_sv_no|&PL_sv_undef)\s*;)/) {
2217 5         15 $do_copy_tmp = 0; #$arg will be a ST(X), no SV* RETVAL, no RETVALSV
2218 5         8 $use_RETVALSV = 0;
2219             }
2220             elsif ($evalexpr =~ /^\s*\Q$arg\E\s*=/) {
2221             # We expect that $arg has refcnt >=1, so we need
2222             # to mortalize it!
2223 0 0       0 $use_RETVALSV = 0 if $ntype eq "SVPtr";#reuse SV* RETVAL vs open new block
2224 0         0 $do_mortal = 1;
2225             }
2226             else {
2227             # Just hope that the entry would safely write it
2228             # over an already mortalized value. By
2229             # coincidence, something like $arg = &PL_sv_undef
2230             # works too, but should be caught above.
2231 0         0 $pre_expr = "RETVALSV = sv_newmortal();\n";
2232             # new mortals don't have set magic
2233 0         0 $do_setmagic = 0;
2234             }
2235 5 50       25 if($use_RETVALSV) {
2236 0         0 print "\t{\n\t SV * RETVALSV;\n";
2237 0         0 $indent = "\t ";
2238             } else {
2239 5         11 $indent = "\t";
2240             }
2241 5 50       15 print $indent.$pre_expr if $pre_expr;
2242              
2243 5 50       15 if($use_RETVALSV) {
2244             #take control of 1 layer of indent, may or may not indent more
2245 0         0 $evalexpr =~ s/^(\t| )/$indent/gm;
2246             #"\t \t" doesn't draw right in some IDEs
2247             #break down all \t into spaces
2248 0         0 $evalexpr =~ s/\t/ /g;
2249             #rebuild back into \t'es, \t==8 spaces, indent==4 spaces
2250 0         0 $evalexpr =~ s/ /\t/g;
2251             }
2252             else {
2253 5 50 33     60 if($do_mortal || $do_setmagic) {
2254             #typemap entry evaled with RETVALSV, if we aren't using RETVALSV replace
2255 0         0 $evalexpr =~ s/RETVALSV/RETVAL/g; #all uses with RETVAL for prettier code
2256             }
2257             else { #if no extra boilerplate (no mortal, no set magic) is needed
2258             #after $evalexport, get rid of RETVALSV's visual cluter and change
2259 5         61 $evalexpr =~ s/RETVALSV/$orig_arg/g;#the lvalue to ST(X)
2260             }
2261             }
2262             #stop " RETVAL = RETVAL;" for SVPtr type
2263 5 50       38 print $evalexpr if $evalexpr !~ /^\s*RETVAL = RETVAL;$/;
2264 5 0       45 print $indent.'RETVAL'.($use_RETVALSV ? 'SV':'')
    0          
    50          
2265             .' = sv_2mortal(RETVAL'.($use_RETVALSV ? 'SV':'').");\n" if $do_mortal;
2266 5 0       15 print $indent.'SvSETMAGIC(RETVAL'.($use_RETVALSV ? 'SV':'').");\n" if $do_setmagic;
    50          
2267             #dont do "RETVALSV = boolSV(RETVAL); ST(0) = RETVALSV;", it is visual clutter
2268 5 0 33     65 print $indent."$orig_arg = RETVAL".($use_RETVALSV ? 'SV':'').";\n"
    50 33        
2269             if $do_mortal || $do_setmagic || $do_copy_tmp;
2270 5 50       43 print "\t}\n" if $use_RETVALSV;
2271             }
2272             elsif ($do_push) {
2273 4         13 print "\tPUSHs(sv_newmortal());\n";
2274 4         15 local $eval_vars->{arg} = "ST($num)";
2275 4         16 $self->eval_output_typemap_code("print qq\a$expr\a", $eval_vars);
2276 4 50       33 print "\tSvSETMAGIC($arg);\n" if $do_setmagic;
2277             }
2278             elsif ($arg =~ /^ST\(\d+\)$/) {
2279 8         36 $self->eval_output_typemap_code("print qq\a$expr\a", $eval_vars);
2280 8 50       64 print "\tSvSETMAGIC($arg);\n" if $do_setmagic;
2281             }
2282             }
2283             }
2284              
2285              
2286             # Just delegates to a clean package.
2287             # Shim to evaluate Perl code in the right variable context
2288             # for typemap code (having things such as $ALIAS set up).
2289             sub eval_output_typemap_code {
2290 71     71 0 183 my ($self, $code, $other) = @_;
2291 71         231 return ExtUtils::ParseXS::Eval::eval_output_typemap_code($self, $code, $other);
2292             }
2293              
2294             sub eval_input_typemap_code {
2295 57     57 0 127 my ($self, $code, $other) = @_;
2296 57         187 return ExtUtils::ParseXS::Eval::eval_input_typemap_code($self, $code, $other);
2297             }
2298              
2299             1;
2300              
2301             # vim: ts=2 sw=2 et: