File Coverage

blib/lib/ExtUtils/ParseXS.pm
Criterion Covered Total %
statement 893 1044 85.5
branch 356 564 63.1
condition 113 203 55.6
subroutine 54 57 94.7
pod 3 40 7.5
total 1419 1908 74.3


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