File Coverage

blib/lib/ExtUtils/ParseXS/Node.pm
Criterion Covered Total %
statement 1794 1846 97.1
branch 714 808 88.3
condition 264 305 86.5
subroutine 171 173 98.8
pod 0 7 0.0
total 2943 3139 93.7


line stmt bran cond sub pod time code
1             package ExtUtils::ParseXS::Node;
2 28     28   156 use strict;
  28         39  
  28         929  
3 28     28   98 use warnings;
  28         40  
  28         978  
4 28     28   97 use Symbol;
  28         44  
  28         9071  
5              
6             our $VERSION = '3.63';
7              
8             =head1 NAME
9              
10             ExtUtils::ParseXS::Node - Classes for nodes of an Abstract Syntax Tree
11              
12             =head1 SYNOPSIS
13              
14             # Create a node to represent the Foo part of an XS file; then
15             # top-down parse it into a subtree; then top-down emit the
16             # contents of the subtree as C code.
17              
18             my $foo = ExtUtils::ParseXS::Node::Foo->new();
19             $foo->parse(...)
20             or die;
21             $foo->as_code(...);
22             print STDERR $foo->as_concise(1); # for debugging
23              
24             =head1 DESCRIPTION
25              
26             This API is currently private and subject to change.
27              
28             The C class, and its various subclasses, hold the
29             state for the nodes of an Abstract Syntax Tree (AST), which represents the
30             parsed state of an XS file.
31              
32             Each node is a hash of fields. Which field names are legal varies by the
33             node type. The hash keys and values can be accessed directly: there are no
34             getter/setter methods.
35              
36             Each node may have a C field which points to an array of all the
37             children of that node: this is what provides the tree structure. In
38             addition, some of those kids may also have direct links from fields for
39             quick access. For example, the C child object of an C
40             object can be accessed in either of these ways:
41              
42             $xsub_object->{kids}[0]
43             $xsub_object->{decl}
44              
45             Most object-valued node fields within a tree point only to their direct
46             children; however, both C and C have an
47             C field which points to the C object associated with
48             this line, which is located elsewhere in the tree.
49              
50             The various C nodes divide the parsing of the main body of an
51             XSUB into sections where different sets of keywords are allowable, and
52             where various bits of code can be conveniently emitted.
53              
54             =head2 Methods
55              
56             There are two main methods in addition to C, which are present in
57             all subclasses. First, C consumes lines from the source to
58             satisfy the construct being parsed. It may itself create objects of
59             lower-level constructs and call parse on them. For example,
60             C may create a C node and call
61             C on it, which will create C or C
62             nodes as appropriate, and so on.
63              
64             Secondly, C descends its sub-tree, outputting the tree as C
65             code.
66              
67             The C method returns a line-per-node string representation
68             of the node and any children. Most node classes just inherit this method
69             from the base C class. It is intended mainly for debugging.
70              
71             Some nodes also have an C method for adding any code to
72             the boot XSUB. This returns two array refs, one containing a list of code
73             lines to be inserted early into the boot XSUB, and a second for later
74             lines.
75              
76             Finally, in the IO_Param subclass, C is replaced with
77             C and C, since that node may need to
78             generate I sets of C code; one to assign a Perl argument to a C
79             variable, and the other to return the value of a variable to Perl.
80              
81             Note that parsing and code-generation are done as two separate phases;
82             C should only build a tree and never emit code.
83              
84             In addition to C<$self>, methods may commonly have some of these
85             parameters:
86              
87             =over
88              
89             =item C<$pxs>
90              
91             An C object which contains the overall processing
92             state. In particular, it has warning and croaking methods, and holds the
93             lines read in from the source file for the current paragraph.
94              
95             =item C<$xsub>
96              
97             For nodes related to parsing an XSUB, the current
98             C node being processed.
99              
100             =item C<$xbody>
101              
102             For nodes related to parsing an XSUB, the current
103             C node being processed. Note that in the
104             presence of a C keyword, an XSUB can have multiple bodies.
105              
106             =back
107              
108             The C and C methods for some subclasses may have
109             parameters in addition to those.
110              
111             Some subclasses may also have additional helper methods.
112              
113             =head2 Class Hierachy
114              
115             C and its sub-classes form the following inheritance hierarchy.
116             Various abstract classes are used by concrete subclasses where the
117             processing and/or fields are similar: for example, C, C etc
118             all consume a block of uninterpreted lines from the source file until the
119             next keyword, and emit that code, possibly wrapped in C<#line> directives.
120             This common behaviour is provided by the C class.
121              
122             Node
123             XS_file
124             preamble
125             C_part
126             C_part_POD
127             C_part_code
128             C_part_postamble
129             cpp_scope
130             global_cpp_line
131             BOOT
132             TYPEMAP
133             pre_boot
134             boot_xsub
135             xsub
136             xsub_decl
137             ReturnType
138             Param
139             IO_Param
140             Params
141             xbody
142             input_part
143             init_part
144             code_part
145             output_part
146             cleanup_part
147             autocall
148             oneline
149             MODULE
150             REQUIRE
151             FALLBACK
152             include
153             INCLUDE
154             INCLUDE_COMMAND
155             NOT_IMPLEMENTED_YET
156             CASE
157             enable
158             EXPORT_XSUB_SYMBOLS
159             PROTOTYPES
160             SCOPE
161             VERSIONCHECK
162             multiline
163             multiline_merged
164             C_ARGS
165             INTERFACE
166             INTERFACE_MACRO
167             OVERLOAD
168             ATTRS
169             PROTOTYPE
170             codeblock
171             CODE
172             CLEANUP
173             INIT
174             POSTCALL
175             PPCODE
176             PREINIT
177             keylines
178             ALIAS
179             INPUT
180             OUTPUT
181             keyline
182             ALIAS_line
183             INPUT_line
184             OUTPUT_line
185              
186              
187             =head2 Abstract Syntax Tree structure
188              
189             A typical XS file might compile to a tree with a node structure similar to
190             the following. Note that this is unrelated to the inheritance hierarchy
191             shown above. In this example, the XS file includes another file, and has a
192             couple of XSUBs within a C<#if/#else/#endif>. Note that a C
193             node is the parent of all the nodes within the same branch of an C<#if>,
194             or in the absence of C<#if>, within the same file.
195              
196             XS_file
197             preamble
198             C_part
199             C_part_POD
200             C_part_code
201             C_part_postamble
202             cpp_scope: type="main"
203             MODULE
204             PROTOTYPES
205             BOOT
206             TYPEMAP
207             INCLUDE
208             cpp_scope: type="include"
209             xsub
210             ...
211             global_cpp_line: directive="ifdef"
212             cpp_scope: type="if"
213             xsub
214             ...
215             global_cpp_line: directive="else"
216             cpp_scope: type="if"
217             xsub
218             ...
219             global_cpp_line: directive="endif"
220             xsub
221             ...
222             pre_boot
223             boot_xsub
224              
225             A typical XSUB might compile to a tree with a structure similar to the
226             following.
227              
228             xsub
229             xsub_decl
230             ReturnType
231             Params
232             Param
233             Param
234             ...
235             CASE # for when a CASE keyword being present implies multiple
236             # bodies; otherwise, just a bare xbody node.
237             xbody
238             # per-body copy of declaration Params, augmented by
239             # data from INPUT and OUTPUT sections
240             Params
241             IO_Param
242             IO_Param
243             ...
244             input_part
245             INPUT
246             INPUT_line
247             INPUT_line
248             ...
249             PREINIT
250             init_part
251             INIT
252             code_part
253             CODE
254             output_part
255             OUTPUT
256             OUTPUT_line
257             OUTPUT_line
258             ...
259             POSTCALL
260             cleanup_part
261             CLEANUP
262             CASE
263             xbody
264             ...
265              
266             =cut
267              
268             # store these in variables to hide them from brace-matching text editors
269             my $open_brace = '{';
270             my $close_brace = '}';
271              
272             # values for parse_keywords() flags
273             # (Can't assume 'constant.pm' is present yet)
274              
275             my $keywords_flag_MODULE = 1;
276             my $keywords_flag_NOT_IMPLEMENTED_YET = 2;
277              
278             # Utility sub to handle all the boilerplate of declaring a Node subclass,
279             # including setting up @INC and @FIELDS. Intended to be called from within
280             # BEGIN. (Created as a lexical sub ref to make it easily accessible to
281             # all subclasses in this file.)
282             #
283             # The first two args can optionally be ('-parent', 'Foo'), in which case
284             # the parent of this subclass will be ExtUtils::ParseXS::Node::Foo.
285             # If not specified, the parent will be ExtUtils::ParseXS::Node.
286             #
287             # Any remaining args are the names of fields. It also inherits the fields
288             # of its parent.
289              
290             my $USING_FIELDS;
291              
292             my $build_subclass;
293             BEGIN {
294             $build_subclass = sub {
295 1736         5089 my (@fields) = @_;
296              
297 1736         2444 my $parent = 'ExtUtils::ParseXS::Node';
298 1736 100 100     7103 if (@fields and $fields[0] eq '-parent') {
299 952         1299 shift @fields;
300 952         1426 my $p = shift @fields;
301 952         2495 $parent .= "::$p";
302             }
303              
304 1736         7645 my @bad = grep !/^\w+$/, @fields;
305 1736 50       2991 die "Internal error: bad field name(s) in build_subclass: (@bad)\n"
306             if @bad;
307              
308 28     28   155 no strict 'refs';
  28         45  
  28         3278  
309              
310 1736         3270 my $class = caller(0);
311 1736         1943 @fields = (@{"${parent}::FIELDS"}, @fields);
  1736         8232  
312 1736         2218 @{"${class}::ISA"} = $parent;
  1736         26713  
313 1736         2728 @{"${class}::FIELDS"} = @fields;
  1736         7768  
314              
315 1736 50       3227 if ($USING_FIELDS) {
316 1736 50       117057 eval qq{package $class; fields->import(\@fields); 1;}
317             or die $@;
318             }
319 28     28   2075 };
320             };
321              
322              
323             # ======================================================================
324              
325             package ExtUtils::ParseXS::Node;
326              
327             # Base class for all the other node types.
328             #
329             # The 'use fields' enables compile-time or run-time errors if code
330             # attempts to use a key which isn't listed here.
331              
332             BEGIN {
333 28     28   105 our @FIELDS = (
334             'line_no', # line number and ...
335             'file', # ... filename where this node appeared in src
336             'kids', # child nodes, if any
337             );
338              
339             # do 'use fields', except: fields needs Hash::Util which is XS, which
340             # needs us. So only 'use fields' on systems where Hash::Util has already
341             # been built.
342 28 50       1877 if (eval 'require Hash::Util; 1;') {
343 28         10960 require fields;
344 28         37294 $USING_FIELDS = 1;
345 28         127 fields->import(@FIELDS);
346             }
347             }
348              
349              
350             # new(): takes one optional arg, $args, which is a hash ref of key/value
351             # pairs to initialise the object with.
352              
353             sub new {
354 12278     12278 0 23806 my ($class, $args) = @_;
355 12278 100       25059 $args = {} unless defined $args;
356              
357 12278         15711 my __PACKAGE__ $self = shift;
358              
359 12278 50       19120 if ($USING_FIELDS) {
360 12278         26881 $self = fields::new($class);
361 12278         1206508 %$self = %$args;
362             }
363             else {
364 0         0 $self = bless { %$args } => $class;
365              
366             }
367 12278         27462 return $self;
368             }
369              
370              
371             # A very generic parse method that just notes the current file/line no.
372             # Typically called first as a SUPER by the parse() method of real nodes.
373              
374             sub parse {
375 8982     8982 0 11378 my __PACKAGE__ $self = shift;
376 8982         10872 my ExtUtils::ParseXS $pxs = shift;
377              
378 8982         16742 $self->{file} = $pxs->{in_pathname};
379             # account for the line array getting shifted
380             # as input lines are consumed, while line_no
381             # array isn't ever shifted
382             $self->{line_no} = $pxs->{line_no}->[
383 8982         12349 @{$pxs->{line_no}} - @{$pxs->{line}}
  8982         12867  
  8982         17960  
384             ];
385 8982         12637 1;
386             }
387              
388              
389             # Repeatedly look for keywords matching the pattern. For each found
390             # keyword, parse the text following them, and add any resultant nodes
391             # as kids to the current node. Returns a list of the successfully parsed
392             # and added kids.
393             # If $max is defined, it specifies the maximum number of keywords to
394             # process. This value is typically passed as undef (unlimited) or 1
395             # (just grab the next keyword).
396             # $flags can contain $keywords_flag_MODULE or
397             # keywords_flag_NOT_IMPLEMENTED_YET to indicate to match one of those
398             # keywords too (whose syntax is slightly different from 'KEY:' and
399             # so need special handling
400              
401             sub parse_keywords {
402 4817     4817 0 6653 my __PACKAGE__ $self = shift;
403 4817         5840 my ExtUtils::ParseXS $pxs = shift;
404 4817         5848 my $xsub = shift;
405 4817         5773 my $xbody = shift;
406 4817         6027 my $max = shift; # max number of keywords to process
407 4817         7419 my $pat = shift;
408 4817         6011 my $flags = shift;
409              
410 4817 100       8798 $flags = 0 unless defined $flags;
411              
412 4817         6102 my $n = 0;
413 4817         5760 my @kids;
414 4817         6197 while (@{$pxs->{line}}) {
  6051         12425  
415 2563         3299 my $line = shift @{$pxs->{line}};
  2563         4596  
416 2563 100       9300 next unless $line =~ /\S/;
417              
418             # extract/delete recognised keyword and any following text
419 2562         3403 my $keyword;
420              
421 2562 100 100     86046 if ( ($flags & $keywords_flag_MODULE)
    100 100        
      66        
422             && ExtUtils::ParseXS::Utilities::looks_like_MODULE_line($line)
423             )
424             {
425 440         1063 $keyword = 'MODULE';
426             }
427             elsif ( $line =~ s/^(\s*)($pat)\s*:\s*(?:#.*)?/$1/s
428             or ( ($flags & $keywords_flag_NOT_IMPLEMENTED_YET)
429             && $line =~ s/^(\s*)(NOT_IMPLEMENTED_YET)/$1/
430             )
431             )
432             {
433 982         4312 $keyword = $2
434             }
435             else {
436             # stop at unrecognised line
437 1140         2123 unshift @{$pxs->{line}}, $line;
  1140         2613  
438 1140         2190 last;
439             }
440              
441 1422         2749 unshift @{$pxs->{line}}, $line;
  1422         3553  
442             # create a node for the keyword and parse any lines associated
443             # with it.
444 1422         2531 my $class = "ExtUtils::ParseXS::Node::$keyword";
445 1422         17443 my $node = $class->new();
446 1422 50       10846 if ($node->parse($pxs, $xsub, $xbody)) {
447 1385         1920 push @{$self->{kids}}, $node;
  1385         3315  
448 1385         2436 push @kids, $node;
449             }
450              
451 1385         1948 $n++;
452 1385 100 66     4779 last if defined $max and $max >= $n;
453             }
454              
455 4780         10501 return @kids;
456             }
457              
458       1458 0   sub as_code { }
459              
460             # Most node types inherit this: just continue walking the tree
461             # looking for any nodes which provide some boot code.
462             # It returns two array refs; one for lines of code to be injected early
463             # into the boot XSUB, the second for later code.
464              
465             sub as_boot_code {
466 3219     3219 0 3583 my __PACKAGE__ $self = shift;
467 3219         3528 my ExtUtils::ParseXS $pxs = shift;
468              
469 3219         4775 my ($early, $later) = ([], []);
470 3219         4898 my $kids = $self->{kids};
471 3219 100       5008 if ($kids) {
472 1140         1843 for (@$kids) {
473 3656         9892 my ($e, $l) = $_->as_boot_code($pxs);
474 3656         5026 push @$early, @$e;
475 3656         5517 push @$later, @$l;
476             }
477             }
478 3219         5306 return $early, $later;
479             }
480              
481              
482             # as_concise(): for debugging:
483             #
484             # Return a string representing a concise line-per-node representation
485             # of the node and any children, in the spirit of 'perl -MO=Concise'.
486             # Intended to be human- rather than machine-readable.
487             #
488             # The single optional parameter, depth, is for indentation purposes
489              
490             sub as_concise {
491 0     0 0 0 my __PACKAGE__ $self = shift;
492 0         0 my $depth = shift;
493 0 0       0 $depth = 0 unless defined $depth;
494              
495 0         0 my $f = $self->{file};
496 0 0       0 $f = '??' unless defined $f;
497 0         0 $f =~ s{^.*/}{};
498 0 0       0 substr($f,0,10) = '' if length($f) > 10;
499              
500 0         0 my $l = $self->{line_no};
501 0 0       0 $l = defined $l ? sprintf("%-3d", $l) : '?? ';
502              
503 0         0 my $s = sprintf "%-15s", "$f:$l";
504 0         0 $s .= (' ' x $depth);
505              
506 0         0 my $class = ref $self;
507 0         0 $class =~ s/^.*:://g;
508 0         0 $s .= "${class}: ";
509              
510 0         0 my @kv;
511              
512 0         0 for my $key (sort grep !/^(file|line_no|kids)$/, keys %$self) {
513 0         0 my $v = $self->{$key};
514              
515             # some basic pretty-printing
516              
517 0 0       0 if (!defined $v) {
    0          
    0          
518 0         0 $v = '-';
519             }
520             elsif (ref $v) {
521 0         0 $v = "[ref]";
522             }
523             elsif ($v =~ /^-?\d+(\.\d+)?$/) {
524             # leave as-is
525             }
526             else {
527 0         0 $v = "$v";
528 0         0 $v =~ s/"/\\"/g;
529 0         0 my $max = 20;
530 0 0       0 substr($v, $max) = '...' if length($v) > $max;
531 0         0 $v = qq("$v");
532             }
533              
534 0         0 push @kv, "$key=$v";
535             }
536              
537 0         0 $s .= join '; ', @kv;
538 0         0 $s .= "\n";
539              
540 0 0       0 if ($self->{kids}) {
541 0         0 $s .= $_->as_concise($depth+1) for @{$self->{kids}};
  0         0  
542             }
543              
544 0         0 $s;
545             }
546              
547              
548             # Simple method wrapper for ExtUtils::ParseXS::Q
549              
550             sub Q {
551 3750     3750 0 4858 my __PACKAGE__ $self = shift;
552 3750         7071 my $text = shift;
553 3750         8858 return ExtUtils::ParseXS::Q($text);
554             }
555              
556              
557             # ======================================================================
558              
559             package ExtUtils::ParseXS::Node::XS_file;
560              
561             # Top-level AST node representing an entire XS file
562              
563 28     28   32754 BEGIN { $build_subclass->(
564             'preamble', # Node::preamble object which emits preamble C code
565             'C_part', # the C part of the XS file, before the first MODULE
566             'C_part_postamble',# Node::C_part_postamble object which emits
567             # boilerplate code following the C code
568             'cpp_scope', # node holding all the XS part of the main file
569             'pre_boot', # node holding code after user XSUBs but before boot XSUB
570             'boot_xsub', # node holding code which generates the boot XSUB
571             )};
572              
573             sub parse {
574 433     433   1148 my __PACKAGE__ $self = shift;
575 433         973 my ExtUtils::ParseXS $pxs = shift;
576              
577 433         1176 $self->{line_no} = 1;
578 433         1279 $self->{file} = $pxs->{in_pathname};
579              
580             # Hash of package name => package C name
581 433         1075 $pxs->{map_overloaded_package_to_C_package} = {};
582              
583             # Hashref of package name => fallback setting
584 433         1124 $pxs->{map_package_to_fallback_string} = {};
585              
586 433         1291 $pxs->{error_count} = 0;
587              
588             # Initialise the sequence of guard defines used by cpp_scope
589 433         1751 $pxs->{cpp_next_tmp_define} = 'XSubPPtmpAAAA';
590              
591             # "Parse" the start of the file. Doesn't actually consume any lines:
592             # just a placeholder for emitting preamble later
593              
594 433         3999 my $preamble = ExtUtils::ParseXS::Node::preamble->new();
595 433         1021 $self->{preamble} = $preamble;
596 433 50       1547 $preamble->parse($pxs, $self)
597             or return;
598 433         821 push @{$self->{kids}}, $preamble;
  433         1467  
599              
600              
601             # Process the first (C language) half of the XS file, up until the first
602             # MODULE: line
603              
604 433         3093 my $C_part = ExtUtils::ParseXS::Node::C_part->new();
605 433         945 $self->{C_part} = $C_part;
606 433         3673 my $c_part_result = $C_part->parse($pxs, $self);
607 433         857 push @{$self->{kids}}, $C_part;
  433         1143  
608              
609             # A failure when parsing the C part means that there wasn't a MODULE
610             # line. Don't try to parse the missing XS part, but still return
611             # success, passing through the lines from the C part.
612 433 100       1300 return 1 unless $c_part_result;
613              
614             # "Parse" the bit following any C code. Doesn't actually consume any
615             # lines: just a placeholder for emitting postamble code.
616              
617 432         4070 my $C_part_postamble = ExtUtils::ParseXS::Node::C_part_postamble->new();
618 432         1033 $self->{C_part_postamble} = $C_part_postamble;
619 432 50       2773 $C_part_postamble->parse($pxs, $self)
620             or return;
621 432         744 push @{$self->{kids}}, $C_part_postamble;
  432         997  
622              
623             # Parse the XS half of the file
624              
625 432         4944 my $cpp_scope = ExtUtils::ParseXS::Node::cpp_scope->new({type => 'main'});
626 432         1310 $self->{cpp_scope} = $cpp_scope;
627 432 50       3424 $cpp_scope->parse($pxs)
628             or return;
629 370         559 push @{$self->{kids}}, $cpp_scope;
  370         911  
630              
631             # Now at EOF: all paragraphs (and thus XSUBs) have now been read in
632             # and processed. Do any final post-processing.
633              
634             # "Parse" the bit following any C code. Doesn't actually consume any
635             # lines: just a placeholder for emitting any code which should follow
636             # user XSUBs but which comes before the boot XSUB
637              
638 370         3503 my $pre_boot = ExtUtils::ParseXS::Node::pre_boot->new();
639 370         1032 $self->{pre_boot} = $pre_boot;
640 370         613 push @{$self->{kids}}, $pre_boot;
  370         943  
641 370 50       1781 $pre_boot->parse($pxs)
642             or return;
643              
644             # Emit the boot XSUB initialization routine
645              
646 370         2988 my $boot_xsub = ExtUtils::ParseXS::Node::boot_xsub->new();
647 370         833 $self->{boot_xsub} = $boot_xsub;
648 370         587 push @{$self->{kids}}, $boot_xsub;
  370         1160  
649 370 50       1323 $boot_xsub->parse($pxs)
650             or return;
651              
652             warn( "Please specify prototyping behavior for "
653             . "$pxs->{in_filename} (see perlxs manual)\n")
654 370 50       1083 unless $pxs->{proto_behaviour_specified};
655              
656 370         1342 1;
657             }
658              
659              
660             sub as_code {
661 371     371   536 my __PACKAGE__ $self = shift;
662 371         559 my ExtUtils::ParseXS $pxs = shift;
663              
664 371         551 $_->as_code($pxs, $self) for @{$self->{kids}};
  371         1720  
665              
666             }
667             # ======================================================================
668              
669             package ExtUtils::ParseXS::Node::preamble;
670              
671             # AST node representing the boilerplate C code preamble at the start of
672             # the file. Parsing doesn't actually consume any lines; it exists just for
673             # its as_code() method which emits the preamble into the C file.
674              
675 28     28   130 BEGIN { $build_subclass->(
676             )};
677              
678             sub parse {
679 433     433   814 my __PACKAGE__ $self = shift;
680 433         774 my ExtUtils::ParseXS $pxs = shift;
681              
682 433         949 $self->{line_no} = 1;
683 433         989 $self->{file} = $pxs->{in_pathname};
684 433         1461 1;
685             }
686              
687             sub as_code {
688 371     371   568 my __PACKAGE__ $self = shift;
689 371         551 my ExtUtils::ParseXS $pxs = shift;
690              
691             # Emit preamble at start of C file, including the
692             # version it was generated by.
693              
694 371         2470 print $self->Q(<<"EOM");
695             |/*
696             | * This file was generated automatically by ExtUtils::ParseXS version $ExtUtils::ParseXS::VERSION from the
697             | * contents of $pxs->{in_filename}. Do not edit this file, edit $pxs->{in_filename} instead.
698             | *
699             | * ANY CHANGES MADE HERE WILL BE LOST!
700             | *
701             | */
702             |
703             EOM
704              
705             print("#line 1 \"" .
706             ExtUtils::ParseXS::Utilities::escape_file_for_line_directive(
707             $self->{file}) . "\"\n")
708 371 100       5084 if $pxs->{config_WantLineNumbers};
709             }
710              
711              
712             # ======================================================================
713              
714             package ExtUtils::ParseXS::Node::C_part;
715              
716             # A node representing the C part of the XS file - i.e. everything
717             # before the first MODULE line
718              
719 28     28   115 BEGIN { $build_subclass->(
720             )};
721              
722             sub parse {
723 433     433   879 my __PACKAGE__ $self = shift;
724 433         821 my ExtUtils::ParseXS $pxs = shift;
725              
726 433         1006 $self->{line_no} = 1;
727 433         1124 $self->{file} = $pxs->{in_pathname};
728              
729             # Read in lines until the first MODULE line, creating a list of
730             # Node::C_part_code and Node::C_part_POD nodes as children.
731             # Returns with $pxs->{lastline} holding the next line (i.e. the MODULE
732             # line) or errors out if not found
733              
734 433         3114 $pxs->{lastline} = readline($pxs->{in_fh});
735 433         3539 $pxs->{lastline_no} = $.;
736              
737 433         1579 while (defined $pxs->{lastline}) {
738 441 100       4079 if (ExtUtils::ParseXS::Utilities::looks_like_MODULE_line(
739             $pxs->{lastline}))
740             {
741             # the fetch_para() regime in place in the XS part of the file
742             # expects this to have been chomped
743 432         1159 chomp $pxs->{lastline};
744 432         1293 return 1;
745             }
746              
747             my $node =
748 9 100       146 $pxs->{lastline} =~ /^=/
749             ? ExtUtils::ParseXS::Node::C_part_POD->new()
750             : ExtUtils::ParseXS::Node::C_part_code->new();
751              
752             # Read in next block of code or POD lines
753 9 50       35 $node->parse($pxs)
754             or return;
755 9         18 push @{$self->{kids}}, $node;
  9         27  
756             }
757              
758 1         8 warn "Warning: no MODULE line found in XS file $pxs->{in_filename}\n";
759 1         5 return;
760             }
761              
762              
763             sub as_code {
764 371     371   3001 my __PACKAGE__ $self = shift;
765 371         562 my ExtUtils::ParseXS $pxs = shift;
766              
767 371         576 $_->as_code($pxs, $self) for @{$self->{kids}};
  371         1136  
768              
769             print 'ExtUtils::ParseXS::CountLines'->end_marker, "\n"
770 371 100       3641 if $pxs->{config_WantLineNumbers};
771             }
772              
773              
774             # ======================================================================
775              
776             package ExtUtils::ParseXS::Node::C_part_POD;
777              
778             # A node representing a section of POD within the C part of the XS file
779              
780 28     28   116 BEGIN { $build_subclass->(
781             'pod_lines', # array of lines containing pod, including start and end
782             # '=foo' lines
783             )};
784              
785             sub parse {
786 1     1   2 my __PACKAGE__ $self = shift;
787 1         2 my ExtUtils::ParseXS $pxs = shift;
788              
789 1         3 $self->{line_no} = $pxs->{lastline_no};
790 1         2 $self->{file} = $pxs->{in_pathname};
791              
792             # This method is called with $pxs->{lastline} holding the first line
793             # of POD and returns with $pxs->{lastline} holding the (unprocessed)
794             # next line following the =cut line
795              
796 1         1 my $cut;
797 1         2 while (1) {
798 5         4 push @{$self->{pod_lines}}, $pxs->{lastline};
  5         9  
799 5         18 $pxs->{lastline} = readline($pxs->{in_fh});
800 5         6 $pxs->{lastline_no} = $.;
801 5 100       10 return 1 if $cut;
802 4 50       5 last unless defined $pxs->{lastline};
803 4         13 $cut = $pxs->{lastline} =~ /^=cut\s*$/;
804             }
805              
806             # At this point $. is at end of file so die won't state the start
807             # of the problem, and as we haven't yet read any lines &death won't
808             # show the correct line in the message either.
809 0         0 die ( "Error: Unterminated pod in $pxs->{in_filename}, "
810             . "line $self->{line_no}\n");
811             }
812              
813              
814             sub as_code {
815 1     1   5 my __PACKAGE__ $self = shift;
816 1         2 my ExtUtils::ParseXS $pxs = shift;
817              
818             # Emit something in the C file to indicate that a section of POD has
819             # been elided, while maintaining the correct lines numbers using
820             # #line.
821             #
822             # We can't just write out a /* */ comment, as our embedded POD might
823             # itself be in a comment. We can't put a /**/ comment inside #if 0, as
824             # the C standard says that the source file is decomposed into
825             # preprocessing characters in the stage before preprocessing commands
826             # are executed.
827             #
828             # I don't want to leave the text as barewords, because the spec isn't
829             # clear whether macros are expanded before or after preprocessing
830             # commands are executed, and someone pathological may just have
831             # defined one of the 3 words as a macro that does something strange.
832             # Multiline strings are illegal in C, so the "" we write must be a
833             # string literal. And they aren't concatenated until 2 steps later, so
834             # we are safe.
835             # - Nicholas Clark
836              
837 1         7 print $self->Q(<<"EOF");
838             |#if 0
839             | "Skipped embedded POD."
840             |#endif
841             EOF
842              
843             printf("#line %d \"%s\"\n",
844 1         10 $self->{line_no} + @{$self->{pod_lines}},
845             ExtUtils::ParseXS::Utilities::escape_file_for_line_directive(
846             $pxs->{in_pathname}))
847 1 50       5 if $pxs->{config_WantLineNumbers};
848             }
849              
850              
851             # ======================================================================
852              
853             package ExtUtils::ParseXS::Node::C_part_code;
854              
855             # A node representing a section of C code within the C part of the XS file
856              
857 28     28   112 BEGIN { $build_subclass->(
858             'code_lines', # array of lines containing C code
859             )};
860              
861             sub parse {
862 8     8   23 my __PACKAGE__ $self = shift;
863 8         15 my ExtUtils::ParseXS $pxs = shift;
864              
865 8         20 $self->{line_no} = $pxs->{lastline_no};
866 8         19 $self->{file} = $pxs->{in_pathname};
867              
868             # This method is called with $pxs->{lastline} holding the first line
869             # of (possibly) C code and returns with $pxs->{lastline} holding the
870             # first (unprocessed) line which isn't C code (i.e. its the start of
871             # POD or a MODULE line)
872              
873 8         13 my $cut;
874 8         13 while (1) {
875             return 1 if ExtUtils::ParseXS::Utilities::looks_like_MODULE_line(
876 186 100       235 $pxs->{lastline});
877 180 100       280 return 1 if $pxs->{lastline} =~ /^=/;
878 179         166 push @{$self->{code_lines}}, $pxs->{lastline};
  179         264  
879 179         243 $pxs->{lastline} = readline($pxs->{in_fh});
880 179         198 $pxs->{lastline_no} = $.;
881 179 100       235 last unless defined $pxs->{lastline};
882             }
883              
884 1         3 1;
885             }
886              
887             sub as_code {
888 8     8   14 my __PACKAGE__ $self = shift;
889 8         13 my ExtUtils::ParseXS $pxs = shift;
890              
891 8         12 print @{$self->{code_lines}};
  8         30  
892             }
893              
894              
895              
896             # ======================================================================
897              
898             package ExtUtils::ParseXS::Node::C_part_postamble;
899              
900             # AST node representing the boilerplate C code postamble following any
901             # initial C code contained within the C part of the XS file.
902             # This node's parse() method doesn't actually consume any lines; the node
903             # exists just for its as_code() method to emit the postamble into the C
904             # file.
905              
906 28     28   97 BEGIN { $build_subclass->(
907             )};
908              
909             sub parse {
910 432     432   1268 my __PACKAGE__ $self = shift;
911 432         791 my ExtUtils::ParseXS $pxs = shift;
912              
913 432         1121 $self->{line_no} = $pxs->{lastline_no};
914 432         958 $self->{file} = $pxs->{in_pathname};
915 432         1345 1;
916             }
917              
918             sub as_code {
919 370     370   2726 my __PACKAGE__ $self = shift;
920 370         538 my ExtUtils::ParseXS $pxs = shift;
921              
922             # Emit boilerplate postamble following any code passed through from
923             # the 'C' part of the XS file
924              
925 370         965 print $self->Q(<<'EOF');
926             |#ifndef PERL_UNUSED_VAR
927             |# define PERL_UNUSED_VAR(var) if (0) var = var
928             |#endif
929             |
930             |#ifndef dVAR
931             |# define dVAR dNOOP
932             |#endif
933             |
934             |
935             |/* This stuff is not part of the API! You have been warned. */
936             |#ifndef PERL_VERSION_DECIMAL
937             |# define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
938             |#endif
939             |#ifndef PERL_DECIMAL_VERSION
940             |# define PERL_DECIMAL_VERSION \
941             | PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
942             |#endif
943             |#ifndef PERL_VERSION_GE
944             |# define PERL_VERSION_GE(r,v,s) \
945             | (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
946             |#endif
947             |#ifndef PERL_VERSION_LE
948             |# define PERL_VERSION_LE(r,v,s) \
949             | (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
950             |#endif
951             |
952             |/* XS_INTERNAL is the explicit static-linkage variant of the default
953             | * XS macro.
954             | *
955             | * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
956             | * "static", ie. it exports XSUB symbols. You probably don't want that
957             | * for anything but the BOOT XSUB.
958             | *
959             | * See XSUB.h in core!
960             | */
961             |
962             |
963             |/* TODO: This might be compatible further back than 5.10.0. */
964             |#if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
965             |# undef XS_EXTERNAL
966             |# undef XS_INTERNAL
967             |# if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
968             |# define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
969             |# define XS_INTERNAL(name) static XSPROTO(name)
970             |# endif
971             |# if defined(__SYMBIAN32__)
972             |# define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
973             |# define XS_INTERNAL(name) EXPORT_C static XSPROTO(name)
974             |# endif
975             |# ifndef XS_EXTERNAL
976             |# if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
977             |# define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
978             |# define XS_INTERNAL(name) static void name(pTHX_ CV* cv __attribute__unused__)
979             |# else
980             |# ifdef __cplusplus
981             |# define XS_EXTERNAL(name) extern "C" XSPROTO(name)
982             |# define XS_INTERNAL(name) static XSPROTO(name)
983             |# else
984             |# define XS_EXTERNAL(name) XSPROTO(name)
985             |# define XS_INTERNAL(name) static XSPROTO(name)
986             |# endif
987             |# endif
988             |# endif
989             |#endif
990             |
991             |/* perl >= 5.10.0 && perl <= 5.15.1 */
992             |
993             |
994             |/* The XS_EXTERNAL macro is used for functions that must not be static
995             | * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
996             | * macro defined, the best we can do is assume XS is the same.
997             | * Dito for XS_INTERNAL.
998             | */
999             |#ifndef XS_EXTERNAL
1000             |# define XS_EXTERNAL(name) XS(name)
1001             |#endif
1002             |#ifndef XS_INTERNAL
1003             |# define XS_INTERNAL(name) XS(name)
1004             |#endif
1005             |
1006             |/* Now, finally, after all this mess, we want an ExtUtils::ParseXS
1007             | * internal macro that we're free to redefine for varying linkage due
1008             | * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
1009             | * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
1010             | */
1011             |
1012             |#undef XS_EUPXS
1013             |#if defined(PERL_EUPXS_ALWAYS_EXPORT)
1014             |# define XS_EUPXS(name) XS_EXTERNAL(name)
1015             |#else
1016             | /* default to internal */
1017             |# define XS_EUPXS(name) XS_INTERNAL(name)
1018             |#endif
1019             |
1020             |#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
1021             |#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)
1022             |
1023             |/* prototype to pass -Wmissing-prototypes */
1024             |static void
1025             |S_croak_xs_usage(const CV *const cv, const char *const params);
1026             |
1027             |static void
1028             |S_croak_xs_usage(const CV *const cv, const char *const params)
1029             |{
1030             | const GV *const gv = CvGV(cv);
1031             |
1032             | PERL_ARGS_ASSERT_CROAK_XS_USAGE;
1033             |
1034             | if (gv) {
1035             | const char *const gvname = GvNAME(gv);
1036             | const HV *const stash = GvSTASH(gv);
1037             | const char *const hvname = stash ? HvNAME(stash) : NULL;
1038             |
1039             | if (hvname)
1040             | Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
1041             | else
1042             | Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
1043             | } else {
1044             | /* Pants. I don't think that it should be possible to get here. */
1045             | Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
1046             | }
1047             |}
1048             |#undef PERL_ARGS_ASSERT_CROAK_XS_USAGE
1049             |
1050             |#define croak_xs_usage S_croak_xs_usage
1051             |
1052             |#endif
1053             |
1054             |/* NOTE: the prototype of newXSproto() is different in versions of perls,
1055             | * so we define a portable version of newXSproto()
1056             | */
1057             |#ifdef newXS_flags
1058             |#define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
1059             |#else
1060             |#define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
1061             |#endif /* !defined(newXS_flags) */
1062             |
1063             |#if PERL_VERSION_LE(5, 21, 5)
1064             |# define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file)
1065             |#else
1066             |# define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
1067             |#endif
1068             |
1069             |/* simple backcompat versions of the TARGx() macros with no optimisation */
1070             |#ifndef TARGi
1071             |# define TARGi(iv, do_taint) sv_setiv_mg(TARG, iv)
1072             |# define TARGu(uv, do_taint) sv_setuv_mg(TARG, uv)
1073             |# define TARGn(nv, do_taint) sv_setnv_mg(TARG, nv)
1074             |#endif
1075             |
1076             EOF
1077              
1078             # Fix up line number reckoning
1079              
1080             print 'ExtUtils::ParseXS::CountLines'->end_marker, "\n"
1081 370 100       3921 if $pxs->{config_WantLineNumbers};
1082             }
1083              
1084              
1085             # ======================================================================
1086              
1087             package ExtUtils::ParseXS::Node::cpp_scope;
1088              
1089             # Node representing a part of an XS file which is all in the same C
1090             # preprocessor scope as regards C preprocessor (CPP) conditionals, i.e.
1091             # #if/#elsif/#else/#endif etc.
1092             #
1093             # Note that this only considers file-scoped C preprocessor directives;
1094             # ones within a code block such as CODE or BOOT don't contribute to the
1095             # state maintained here.
1096             #
1097             # Initially the whole XS part of the main XS file is considered a single
1098             # scope, so the single main cpp_scope node would have, as children, all
1099             # the file-scoped nodes such as Node::PROTOTYPES and any Node::xsub's.
1100             #
1101             # After an INCLUDE, the new XS file is considered as being in a separate
1102             # scope, and gets its own child cpp_scope node.
1103             #
1104             # Once an XS file starts having file-scope CPP conditionals, then each
1105             # branch of the conditional is considered a separate scope and gets its
1106             # own cpp_scope node. Nested conditionals cause nested cpp_scope objects
1107             # in the AST.
1108             #
1109             # The main reason for this node type is to separate out the AST into
1110             # separate sections which can each have the same named XSUB without a
1111             # 'duplicate XSUB' warning, and where newXS()-type calls can be added to
1112             # to the boot code for *both* XSUBs, guarded by suitable #ifdef's.
1113             #
1114             # This node is the main high-level node where file-scoped parsing takes
1115             # place: its parse() method contains a fetch_para() loop which does all
1116             # the looking for file-scoped keywords, CPP directives, and XSUB
1117             # declarations. It implements a recursive-decent parser by creating child
1118             # cpp_scope nodes and recursing into that child's parse() method (which
1119             # does its own fetch_para() calls).
1120              
1121 28     28   107 BEGIN { $build_subclass->(
1122             'type', # Str: what sort of scope: 'main', 'include' or 'if'
1123             'is_cmd', # Bool: for include type, it's INCLUDE_COMMAND
1124             'guard_name', # Str: the name of the XSubPPtmpAAAA guard define
1125             'seen_xsubs', # Hash: the names of any XSUBs seen in this scope
1126             )};
1127              
1128             sub parse {
1129 461     461   874 my __PACKAGE__ $self = shift;
1130 461         954 my ExtUtils::ParseXS $pxs = shift;
1131              
1132             # Main loop: for each iteration, parse the next 'thing' in the current
1133             # paragraph, such as a C preprocessor directive, a contiguous block of
1134             # file-scoped keywords, or an XSUB. When the current paragraph runs
1135             # out, read in another one. XSUBs, TYPEMAP and BOOT will consume
1136             # all lines until the end of the current paragraph.
1137             #
1138             # C preprocessor conditionals such as #if may trigger recursive
1139             # calls to process each branch until the matching #endif. These may
1140             # cross paragraph boundaries.
1141              
1142 461   100     6426 while ( ($pxs->{line} && @{$pxs->{line}}) || $pxs->fetch_para())
  1624   100     7591  
1143             {
1144 1677 100       2333 next unless @{$pxs->{line}}; # fetch_para() can return zero lines
  1677         3852  
1145              
1146 1591 100 66     6400 if ( !defined($self->{line_no})
1147             && defined $pxs->{line_no}[0]
1148             ) {
1149             # set file/line_no after line number info is available:
1150             # typically after the first call to fetch_para()
1151 460         2438 $self->SUPER::parse($pxs);
1152             }
1153              
1154             # skip blank line
1155 1591 50       6823 shift @{$pxs->{line}}, next if $pxs->{line}[0] !~ /\S/;
  0         0  
1156              
1157             # Process a C-preprocessor line. Note that any non-CPP lines
1158             # starting with '#' will already have been filtered out by
1159             # fetch_para().
1160             #
1161             # If its a #if or similar, then recursively process each branch
1162             # as a separate cpp_scope object until the matching #endif is
1163             # reached.
1164              
1165 1591 100       4520 if ($pxs->{line}[0] =~ /^#/) {
1166 46         249 my $node = ExtUtils::ParseXS::Node::global_cpp_line->new();
1167 46 50       226 $node->parse($pxs)
1168             or next;
1169 46         76 push @{$self->{kids}}, $node;
  46         115  
1170              
1171 46 100       135 next unless $node->{is_cond};
1172              
1173             # Parse branches of a CPP conditionals within a nested scope
1174              
1175 40 100       89 if (not $node->{is_if}) {
1176             $pxs->death("Error: '#". $node->{directive}
1177             . "' with no matching '#if'")
1178 23 100       78 if $self->{type} ne 'if';
1179              
1180             # we should already be within a nested scope; this
1181             # CPP condition keyword just ends that scope. Our
1182             # (recursive) caller will handle processing any further
1183             # branches if it's an elif/else rather than endif
1184              
1185 22         80 return 1
1186             }
1187              
1188             # So it's an 'if'/'ifdef' etc node. Start a new
1189             # Node::cpp_scope sub-parse to handle that branch and then any
1190             # other branches of the same conditional.
1191              
1192 17         28 while (1) {
1193             # For each iteration, parse the next branch in a new scope
1194 23         82 my $scope = ExtUtils::ParseXS::Node::cpp_scope->new(
1195             {type => 'if'});
1196 23 50       102 $scope->parse($pxs)
1197             or next;
1198              
1199             # Sub-parsing of that branch should have terminated
1200             # at an elif/endif line rather than falling off the
1201             # end of the file
1202 23         63 my $last = $scope->{kids}[-1];
1203 23 50 66     383 unless (
      66        
      33        
1204             defined $last
1205             && $last->isa(
1206             'ExtUtils::ParseXS::Node::global_cpp_line')
1207             && $last->{is_cond}
1208             && !$last->{is_if}
1209             ) {
1210 1         16 $pxs->death( "Error: Unterminated '#$node->{directive}'"
1211             . " from line $node->{line_no}")
1212             }
1213              
1214             # Move the CPP line which terminated the branch from
1215             # the end of the inner scope to the current scope
1216 22         32 pop @{$scope->{kids}};
  22         40  
1217 22         29 push @{$self->{kids}}, $scope, $last;
  22         71  
1218              
1219 22 100       30 if (grep { ref($_) !~ /::global_cpp_line$/ }
  33         109  
1220 22         45 @{$scope->{kids}} )
1221             {
1222             # the inner scope has some content, so needs
1223             # a '#define XSubPPtmpAAAA 1'-style guard
1224 20         59 $scope->{guard_name} = $pxs->{cpp_next_tmp_define}++;
1225             }
1226              
1227             # any more branches to process of current if?
1228 22 100       72 last if $last->{is_endif};
1229             } # while 1
1230              
1231 16         40 next;
1232             }
1233              
1234 1545         3330 my $file_scoped_keywords =
1235             "BOOT|REQUIRE|PROTOTYPES|EXPORT_XSUB_SYMBOLS|FALLBACK"
1236             . "|VERSIONCHECK|INCLUDE|INCLUDE_COMMAND|SCOPE|TYPEMAP";
1237              
1238             # Die if the next line is indented: all file-scoped things (CPP,
1239             # keywords, XSUB starts) are supposed to start on column 1
1240             # (although see the comment below about multiple parse_keywords()
1241             # iterations sneaking in indented keywords).
1242             #
1243              
1244 1545 100       4996 if ($pxs->{line}[0] =~ /^\s/) {
1245             # Try to customise the error message based around why this
1246             # line is indented, to better hint to the user what the
1247             # problem is.
1248              
1249 3 100       281 if ($pxs->{line}[0] =~ /^\s+($file_scoped_keywords)\s*:/) {
1250 1         11 $pxs->death(
1251             "Error: file-scoped keywords should not be indented");
1252             }
1253              
1254             # The text of the error message is based around a common reason
1255             # for an indented line to appear in file scope: this is due to an
1256             # XSUB being prematurely truncated by fetch_para(). For example in
1257             # the code below, the coder wants the foo and bar lines to both be
1258             # part of the same CODE block. But the XS parser sees the blank
1259             # line followed by the '#ifdef' on column 1 as terminating the
1260             # current XSUB. So the bar() line is treated as being in file
1261             # scope and dies because it is indented.
1262             #
1263             # |int f()
1264             # | CODE:
1265             # | foo();
1266             # |
1267             # |#ifdef USE_BAR
1268             # | bar();
1269             # |#endif
1270              
1271             $pxs->deathHint(
1272 2         49 "Error: file-scoped directives must not be indented",
1273             $self->Q(<
1274             |If this line is supposed to be part of an XSUB rather than being
1275             |file-scoped, then it is possible that your XSUB has a blank line
1276             |followed by a line starting at column 1 which is being misinterpreted
1277             |as the end of the current XSUB.
1278             EOF
1279             }
1280              
1281             # The SCOPE keyword can appear both in file scope (just before an
1282             # XSUB) and as an XSUB keyword. This field maintains the state of the
1283             # former: reset it at the start of processing any file-scoped
1284             # keywords just before the XSUB (i.e. without any blank lines, e.g.
1285             # SCOPE: ENABLE
1286             # int
1287             # foo(...)
1288             # These semantics may not be particularly sensible, but they maintain
1289             # backwards compatibility for now.
1290              
1291 1542         2619 $pxs->{file_SCOPE_enabled} = 0;
1292              
1293             # Process file-scoped keywords
1294             #
1295             # This loop repeatedly: skips any blank lines and then calls
1296             # the relevant Node::FOO::parse() method if it finds any of the
1297             # file-scoped keywords in the passed pattern.
1298             #
1299             # Note: due to the looping within parse_keywords() rather than
1300             # looping here, only the first keyword in a contiguous block
1301             # gets the 'start at column 1' check above enforced.
1302             # This is a bug, maintained for backwards compatibility: see the
1303             # comments below referring to SCOPE for other bits of code needed
1304             # to enforce this compatibility.
1305              
1306 1542         6014 $self->parse_keywords(
1307             $pxs,
1308             undef, undef, # xsub and xbody: not needed for non XSUB keywords
1309             undef, # implies process as many keywords as possible
1310             $file_scoped_keywords,
1311             $keywords_flag_MODULE,
1312             );
1313             # XXX we could have an 'or next' here if not for SCOPE backcompat
1314             # and also delete the following 'skip blank line' and 'next unless
1315             # @line' lines
1316              
1317             # skip blank lines
1318 1511   66     1993 shift @{$pxs->{line}} while @{$pxs->{line}} && $pxs->{line}[0] !~ /\S/;
  1511         7337  
  0         0  
1319              
1320 1511 100       1960 next unless @{$pxs->{line}};
  1511         5121  
1321              
1322             # Parse an XSUB
1323              
1324 462         4099 my $xsub = ExtUtils::ParseXS::Node::xsub->new();
1325 462 100       3953 $xsub->parse($pxs)
1326             or next;
1327 434         702 push @{$self->{kids}}, $xsub;
  434         1398  
1328              
1329             # Check for a duplicate function definition in this scope
1330             {
1331 434         634 my $name = $xsub->{decl}{full_C_name};
  434         888  
1332 434 100       1267 if ($self->{seen_xsubs}{$name}) {
1333 4         83 (my $short = $name) =~ s/^$pxs->{PACKAGE_C_name}_//;
1334 4         65 $pxs->Warn( "Warning: duplicate function definition "
1335             . "'$short' detected");
1336             }
1337 434         1362 $self->{seen_xsubs}{$name} = 1;
1338             }
1339              
1340             # xsub->parse() should have consumed all the remaining
1341             # lines in the current paragraph.
1342             die "Internal error: unexpectedly not at EOF\n"
1343 434 50       582 if @{$pxs->{line}};
  434         1132  
1344              
1345 434         1634 $pxs->{seen_an_XSUB} = 1; # encountered at least one XSUB
1346              
1347             } # END main 'while' loop
1348              
1349 376         1165 1;
1350             }
1351              
1352              
1353             sub as_code {
1354 396     396   5231 my __PACKAGE__ $self = shift;
1355 396         694 my ExtUtils::ParseXS $pxs = shift;
1356              
1357 396         1140 my $g = $self->{guard_name};
1358 396 100       964 print "#define $g 1\n\n" if defined $g;
1359 396         628 $_->as_code($pxs, $self) for @{$self->{kids}};
  396         2403  
1360             }
1361              
1362              
1363             sub as_boot_code {
1364 396     396   613 my __PACKAGE__ $self = shift;
1365 396         576 my ExtUtils::ParseXS $pxs = shift;
1366              
1367             # accumulate all the newXS()'s in $early and the BOOT blocks in $later,
1368 396         1097 my ($early, $later) = $self->SUPER::as_boot_code($pxs);
1369              
1370             # then wrap them all within '#if XSubPPtmpAAAA' guards
1371 396         914 my $g = $self->{guard_name};
1372 396 100       1045 if (defined $g) {
1373 20         47 unshift @$early, "#if $g\n";
1374 20         38 unshift @$later, "#if $g\n";
1375 20         65 push @$early, "#endif\n";
1376 20         32 push @$later, "#endif\n";
1377             }
1378              
1379 396         766 return $early, $later;
1380             }
1381              
1382              
1383             # ======================================================================
1384              
1385             package ExtUtils::ParseXS::Node::global_cpp_line;
1386              
1387             # AST node representing a single C-preprocessor line in file (global)
1388             # scope. (A "single" line can actually include embedded "\\\n"'s from line
1389             # continuations).
1390              
1391 28     28   1616 BEGIN { $build_subclass->(
1392             'cpp_line', # Str: the full text of the "# foo" CPP line
1393             'directive', # Str: one of 'define', 'endif' etc
1394             'rest', # Str: the rest of the line following the directive
1395             'is_cond', # Bool: it's an ifdef/else/endif etc
1396             'is_if', # Bool: it's an if/ifdef/ifndef
1397             'is_endif' # Bool: it's an endif
1398             )};
1399              
1400             sub parse {
1401 46     46   79 my __PACKAGE__ $self = shift;
1402 46         94 my ExtUtils::ParseXS $pxs = shift;
1403              
1404 46         125 $self->SUPER::parse($pxs); # set file/line_no
1405              
1406 46         61 my $line = shift @{$pxs->{line}};
  46         78  
1407              
1408 46 50       358 my ($directive, $rest) = $line =~ /^ \# \s* (\w+) (?:\s+ (.*) \s* $)?/sx
1409             or $pxs->death("Internal error: can't parse CPP line: $line\n");
1410 46 100       129 $rest = '' unless defined $rest;
1411 46         190 my $is_cond = $directive =~ /^(if|ifdef|ifndef|elif|else|endif)$/;
1412 46         150 my $is_if = $directive =~ /^(if|ifdef|ifndef)$/;
1413 46         89 my $is_endif = $directive =~ /^endif$/;
1414 46         173 @$self{qw(cpp_line directive rest is_cond is_if is_endif)}
1415             = ($line, $directive, $rest, $is_cond, $is_if, $is_endif);
1416              
1417 46         121 1;
1418             }
1419              
1420              
1421             sub as_code {
1422 42     42   177 my __PACKAGE__ $self = shift;
1423 42         54 my ExtUtils::ParseXS $pxs = shift;
1424              
1425 42         84 print $self->{cpp_line}, "\n";
1426             }
1427              
1428              
1429             # ======================================================================
1430              
1431             package ExtUtils::ParseXS::Node::BOOT;
1432              
1433             # Store the code lines associated with the BOOT keyword
1434             #
1435             # Note that unlike other codeblock-like Node classes, BOOT consumes
1436             # *all* lines remaining in the current paragraph, rather than stopping
1437             # at the next keyword, if any.
1438             # It's also file-scoped rather than XSUB-scoped.
1439              
1440 28     28   114 BEGIN { $build_subclass->(
1441             'lines', # Array ref of all code lines making up the BOOT
1442             )};
1443              
1444              
1445             # Consume all the remaining lines and store in @$lines.
1446              
1447             sub parse {
1448 4     4   4089 my __PACKAGE__ $self = shift;
1449 4         7175 my ExtUtils::ParseXS $pxs = shift;
1450              
1451 4         60 $self->SUPER::parse($pxs); # set file/line_no
1452              
1453             # Check all the @{$pxs->{line}} lines for balance: all the
1454             # #if, #else, #endif etc within the BOOT should balance out.
1455 4         40 ExtUtils::ParseXS::Utilities::check_conditional_preprocessor_statements();
1456              
1457             # Suck in all remaining lines
1458              
1459 4         12 $self->{lines} = [ @{$pxs->{line}} ];
  4         28  
1460 4         10 @{$pxs->{line}} = ();
  4         15  
1461              
1462             # Text following the keyword is ignored rather than being treated
1463             # as the first line of code.
1464 4         16 my $line0 = shift @{$self->{lines}};
  4         15  
1465 4 100 66     122 $pxs->Warn("Warning: text after keyword ignored: '$line0'")
1466             if defined $line0 && $line0 =~ /\S/;
1467              
1468 4         12 1;
1469             }
1470              
1471              
1472             sub as_boot_code {
1473 4     4   7 my __PACKAGE__ $self = shift;
1474 4         20 my ExtUtils::ParseXS $pxs = shift;
1475              
1476 4         16 my @lines;
1477              
1478             # Prepend a '#line' directive if not already present
1479 4 50 33     32 if ( $pxs->{config_WantLineNumbers}
      33        
1480 4         58 && @{$self->{lines}}
1481             && $self->{lines}[0] !~ /^\s*#\s*line\b/
1482             )
1483             {
1484             push @lines,
1485             sprintf "#line %d \"%s\"\n",
1486             $self->{line_no} + 1,
1487             ExtUtils::ParseXS::Utilities::escape_file_for_line_directive(
1488 4         24 $self->{file});
1489             }
1490              
1491             # Save all the BOOT lines (plus trailing empty line) to be emitted
1492             # later.
1493 4         9 push @lines, "$_\n" for @{$self->{lines}}, "";
  4         24  
1494              
1495 4         12 return [], \@lines;
1496             }
1497              
1498             # ======================================================================
1499              
1500             package ExtUtils::ParseXS::Node::TYPEMAP;
1501              
1502             # Process the lines associated with the TYPEMAP keyword
1503             #
1504             # fetch_para() will have already processed the <
1505             # and read all the lines up to, but not including, the EOF line.
1506              
1507 28     28   128 BEGIN { $build_subclass->(
1508             'lines', # Array ref of all lines making up the TYPEMAP section
1509             )};
1510              
1511              
1512             # Feed all the lines to ExtUtils::Typemaps.
1513              
1514             sub parse {
1515 167     167   595 my __PACKAGE__ $self = shift;
1516 167         339 my ExtUtils::ParseXS $pxs = shift;
1517              
1518 167         803 $self->SUPER::parse($pxs); # set file/line_no
1519              
1520 167         278 shift @{$pxs->{line}}; # skip the 'TYPEMAP:' line
  167         366  
1521              
1522             # Suck in all remaining lines
1523 167         466 $self->{lines} = $pxs->{line};
1524 167         440 $pxs->{line} = [];
1525              
1526             my $tmap = ExtUtils::Typemaps->new(
1527 167         2655 string => join("", map "$_\n", @{$self->{lines}}),
1528             lineno_offset => 1 + ($pxs->current_line_number() || 0),
1529             fake_filename => $pxs->{in_filename},
1530 167   50     377 );
1531              
1532 167         1426 $pxs->{typemaps_object}->merge(typemap => $tmap, replace => 1);
1533              
1534 167         1625 1;
1535             }
1536              
1537              
1538             # ======================================================================
1539              
1540             package ExtUtils::ParseXS::Node::pre_boot;
1541              
1542             # AST node representing C code that is emitted after all user-defined
1543             # XSUBs but before the boot XSUB. (This currently consists of
1544             # 'Foo::Bar::()' XSUBs for any packages which have overloading.)
1545             #
1546             # This node's parse() method doesn't actually consume any lines; the node
1547             # exists just for its as_code() method.
1548              
1549 28     28   113 BEGIN { $build_subclass->(
1550             )};
1551              
1552             sub parse {
1553 370     370   1102 my __PACKAGE__ $self = shift;
1554 370         651 my ExtUtils::ParseXS $pxs = shift;
1555              
1556 370         1135 $self->SUPER::parse($pxs); # set file/line_no
1557 370         879 1;
1558             }
1559              
1560             sub as_code {
1561 370     370   3430 my __PACKAGE__ $self = shift;
1562 370         614 my ExtUtils::ParseXS $pxs = shift;
1563              
1564             # For each package FOO which has had at least one overloaded method
1565             # specified:
1566             # - create a stub XSUB in that package called nil;
1567             # - generate code to be added to the boot XSUB which links that XSUB
1568             # to the symbol table entry *{"FOO::()"}. This mimics the action in
1569             # overload::import() which creates the stub method as a quick way to
1570             # check whether an object is overloaded (including via inheritance),
1571             # by doing $self->can('()').
1572             # - Further down, we add a ${"FOO:()"} scalar containing the value of
1573             # 'fallback' (or undef if not specified).
1574             #
1575             # XXX In 5.18.0, this arrangement was changed in overload.pm, but hasn't
1576             # been updated here. The *() glob was being used for two different
1577             # purposes: a sub to do a quick check of overloadability, and a scalar
1578             # to indicate what 'fallback' value was specified (even if it wasn't
1579             # specified). The commits:
1580             # v5.16.0-87-g50853fa94f
1581             # v5.16.0-190-g3866ea3be5
1582             # v5.17.1-219-g79c9643d87
1583             # changed this so that overloadability is checked by &((, while fallback
1584             # is checked by $() (and not present unless specified by 'fallback'
1585             # as opposed to the always being present, but sometimes undef).
1586             # Except that, in the presence of fallback, &() is added too for
1587             # backcompat reasons (which I don't fully understand - DAPM).
1588             # See overload.pm's import() and OVERLOAD() methods for more detail.
1589             #
1590             # So this code (and the code in as_boot_code) needs updating to match.
1591              
1592 370         616 for my $package (sort keys %{$pxs->{map_overloaded_package_to_C_package}})
  370         3623  
1593             {
1594             # make them findable with fetchmethod
1595 11         44 my $packid = $pxs->{map_overloaded_package_to_C_package}{$package};
1596 11         104 print $self->Q(<<"EOF");
1597             |XS_EUPXS(XS_${packid}_nil); /* prototype to pass -Wmissing-prototypes */
1598             |XS_EUPXS(XS_${packid}_nil)
1599             |{
1600             | dXSARGS;
1601             | PERL_UNUSED_VAR(items);
1602             | XSRETURN_EMPTY;
1603             |}
1604             |
1605             EOF
1606             }
1607             }
1608              
1609             sub as_boot_code {
1610 370     370   562 my __PACKAGE__ $self = shift;
1611 370         566 my ExtUtils::ParseXS $pxs = shift;
1612              
1613 370         557 my @early;
1614 370         578 for my $package (sort keys %{$pxs->{map_overloaded_package_to_C_package}})
  370         1718  
1615             {
1616 11         35 my $packid = $pxs->{map_overloaded_package_to_C_package}{$package};
1617 11         51 push @early, $self->Q(<<"EOF");
1618             | /* Making a sub named "${package}::()" allows the package */
1619             | /* to be findable via fetchmethod(), and causes */
1620             | /* overload::Overloaded("$package") to return true. */
1621             | (void)newXS_deffile("${package}::()", XS_${packid}_nil);
1622             EOF
1623             }
1624 370         786 return \@early, [];
1625             }
1626              
1627              
1628             # ======================================================================
1629              
1630             package ExtUtils::ParseXS::Node::boot_xsub;
1631              
1632             # AST node representing C code that is emitted to create the boo XSUB.
1633             #
1634             # This node's parse() method doesn't actually consume any lines; the node
1635             # exists just for its as_code() method.
1636              
1637 28     28   123 BEGIN { $build_subclass->(
1638             )};
1639              
1640             sub parse {
1641 370     370   630 my __PACKAGE__ $self = shift;
1642 370         807 my ExtUtils::ParseXS $pxs = shift;
1643              
1644 370         1150 $self->SUPER::parse($pxs); # set file/line_no
1645 370         831 1;
1646             }
1647              
1648             sub as_code {
1649 370     370   767 my __PACKAGE__ $self = shift;
1650 370         591 my ExtUtils::ParseXS $pxs = shift;
1651              
1652             # Walk the AST accumulating any boot code generated by
1653             # the various nodes' as_boot_code() methods.
1654 370         2036 my ($early, $later) = $pxs->{AST}->as_boot_code($pxs);
1655              
1656             # Emit the boot_Foo__Bar() C function / XSUB
1657              
1658 370         1293 print $self->Q(<<"EOF");
1659             |#ifdef __cplusplus
1660             |extern "C" $open_brace
1661             |#endif
1662             |XS_EXTERNAL(boot_$pxs->{MODULE_cname}); /* prototype to pass -Wmissing-prototypes */
1663             |XS_EXTERNAL(boot_$pxs->{MODULE_cname})
1664             |$open_brace
1665             |#if PERL_VERSION_LE(5, 21, 5)
1666             | dVAR; dXSARGS;
1667             |#else
1668 370 100       2596 | dVAR; ${\($pxs->{VERSIONCHECK_value} ? 'dXSBOOTARGSXSAPIVERCHK;' : 'dXSBOOTARGSAPIVERCHK;')}
1669             |#endif
1670             EOF
1671              
1672             # Declare a 'file' var for passing to newXS() and variants.
1673             #
1674             # If there is no $pxs->{seen_an_XSUB} then there are no xsubs
1675             # in this .xs so 'file' is unused, so silence warnings.
1676             #
1677             # 'file' can also be unused in other circumstances: in particular,
1678             # newXS_deffile() doesn't take a file parameter. So suppress any
1679             # 'unused var' warning always.
1680             #
1681             # Give it the correct 'const'ness: Under 5.8.x and lower, newXS() is
1682             # declared in proto.h as expecting a non-const file name argument. If
1683             # the wrong qualifier is used, it causes breakage with C++ compilers and
1684             # warnings with recent gcc.
1685              
1686 370 100       3271 print $self->Q(<<"EOF") if $pxs->{seen_an_XSUB};
1687             |#if PERL_VERSION_LE(5, 8, 999) /* PERL_VERSION_LT is 5.33+ */
1688             | char* file = __FILE__;
1689             |#else
1690             | const char* file = __FILE__;
1691             |#endif
1692             |
1693             | PERL_UNUSED_VAR(file);
1694             EOF
1695              
1696             # Emit assorted declarations
1697              
1698 370         2416 print $self->Q(<<"EOF");
1699             |
1700             | PERL_UNUSED_VAR(cv); /* -W */
1701             | PERL_UNUSED_VAR(items); /* -W */
1702             EOF
1703              
1704 370 100       2338 if ($pxs->{VERSIONCHECK_value}) {
1705 369         888 print $self->Q(<<"EOF");
1706             |#if PERL_VERSION_LE(5, 21, 5)
1707             | XS_VERSION_BOOTCHECK;
1708             |# ifdef XS_APIVERSION_BOOTCHECK
1709             | XS_APIVERSION_BOOTCHECK;
1710             |# endif
1711             |#endif
1712             |
1713             EOF
1714             }
1715             else {
1716 1         4 print $self->Q(<<"EOF") ;
1717             |#if PERL_VERSION_LE(5, 21, 5) && defined(XS_APIVERSION_BOOTCHECK)
1718             | XS_APIVERSION_BOOTCHECK;
1719             |#endif
1720             |
1721             EOF
1722             }
1723              
1724             # Declare a 'cv' variable within a scope small enough to be visible
1725             # just to newXS() calls which need to do further processing of the cv:
1726             # in particular, when emitting one of:
1727             # XSANY.any_i32 = $value;
1728             # XSINTERFACE_FUNC_SET(cv, $value);
1729              
1730 370 100       2743 if ($pxs->{need_boot_cv}) {
1731 35         131 print $self->Q(<<"EOF");
1732             | $open_brace
1733             | CV * cv;
1734             |
1735             EOF
1736             }
1737              
1738             # More overload stuff
1739              
1740 370 100       673 if (keys %{ $pxs->{map_overloaded_package_to_C_package} }) {
  370         1240  
1741             # Emit just once if any overloads:
1742             # Before 5.10, PL_amagic_generation used to need setting to at
1743             # least a non-zero value to tell perl that any overloading was
1744             # present.
1745 10         34 print $self->Q(<<"EOF");
1746             | /* register the overloading (type 'A') magic */
1747             |#if PERL_VERSION_LE(5, 8, 999) /* PERL_VERSION_LT is 5.33+ */
1748             | PL_amagic_generation++;
1749             |#endif
1750             EOF
1751              
1752 10         65 for my $package (
1753 10         43 sort keys %{ $pxs->{map_overloaded_package_to_C_package} })
1754             {
1755             # Emit once for each package with overloads:
1756             # Set ${'Foo::()'} to the fallback value for each overloaded
1757             # package 'Foo' (or undef if not specified).
1758             # But see the 'XXX' comments above about fallback and $().
1759              
1760 11         32 my $fallback = $pxs->{map_package_to_fallback_string}{$package};
1761 11 100       79 $fallback = 'UNDEF' unless defined $fallback;
1762 11 100       66 $fallback = $fallback eq 'TRUE' ? '&PL_sv_yes'
    100          
1763             : $fallback eq 'FALSE' ? '&PL_sv_no'
1764             : '&PL_sv_undef';
1765              
1766 11         82 print $self->Q(<<"EOF");
1767             | /* The magic for overload gets a GV* via gv_fetchmeth as */
1768             | /* mentioned above, and looks in the SV* slot of it for */
1769             | /* the "fallback" status. */
1770             | sv_setsv(
1771             | get_sv( "${package}::()", TRUE ),
1772             | $fallback
1773             | );
1774             EOF
1775             }
1776             }
1777              
1778             # Emit any boot code associated with newXS().
1779              
1780 370         919 print @$early;
1781              
1782             # Emit closing scope for the 'CV *cv' declaration
1783              
1784 370 100       2509 if ($pxs->{need_boot_cv}) {
1785 35         130 print $self->Q(<<"EOF");
1786             | $close_brace
1787             EOF
1788             }
1789              
1790             # Emit any lines derived from BOOT: sections
1791              
1792 370 100       1039 if (@$later) {
1793 14         50 print $self->Q(<<"EOF");
1794             |
1795             | /* Initialisation Section */
1796             |
1797             EOF
1798              
1799 14         62 print @$later;
1800              
1801             print 'ExtUtils::ParseXS::CountLines'->end_marker, "\n"
1802 14 50       120 if $pxs->{config_WantLineNumbers};
1803              
1804 14         128 print $self->Q(<<"EOF");
1805             |
1806             | /* End of Initialisation Section */
1807             |
1808             EOF
1809             }
1810              
1811             # Emit code to call any UNITCHECK blocks and return true.
1812             # Since 5.22, this is been put into a separate function.
1813              
1814 370         1742 print $self->Q(<<"EOF");
1815             |#if PERL_VERSION_LE(5, 21, 5)
1816             |# if PERL_VERSION_GE(5, 9, 0)
1817             | if (PL_unitcheckav)
1818             | call_list(PL_scopestack_ix, PL_unitcheckav);
1819             |# endif
1820             | XSRETURN_YES;
1821             |#else
1822             | Perl_xs_boot_epilog(aTHX_ ax);
1823             |#endif
1824             |$close_brace
1825             |
1826             |#ifdef __cplusplus
1827             |$close_brace
1828             |#endif
1829             EOF
1830             }
1831              
1832              
1833             # ======================================================================
1834              
1835             package ExtUtils::ParseXS::Node::xsub;
1836              
1837             # Process an entire XSUB definition
1838              
1839 28     28   169 BEGIN { $build_subclass->(
1840             'decl', # Node::xsub_decl object holding this XSUB's declaration
1841              
1842             # Boolean flags: they indicate that at least one of each specified
1843             # keyword has been seen in this XSUB
1844             'seen_ALIAS',
1845             'seen_INTERFACE',
1846             'seen_INTERFACE_MACRO',
1847             'seen_PPCODE',
1848             'seen_PROTOTYPE',
1849             'seen_SCOPE',
1850              
1851             # These three fields indicate how many SVs are returned to the caller,
1852             # and so influence the emitting of 'EXTEND(n)', 'XSRETURN(n)', and
1853             # potentially, the value of n in 'ST(n) = ...'.
1854             #
1855             # XSRETURN_count_basic is 0 or 1 and indicates whether a basic return
1856             # value is pushed onto the stack. It is usually directly related to
1857             # whether the XSUB is declared void, but NO_RETURN and CODE_sets_ST0
1858             # can alter that.
1859             #
1860             # XSRETURN_count_extra indicates how many SVs will be returned in
1861             # addition the basic 0 or 1. These will be params declared as OUTLIST.
1862             #
1863             # CODE_sets_ST0 is a flag indicating that something within a CODE
1864             # block is doing 'ST(0) = ..' or similar. This is a workaround for
1865             # a bug: see the code comments "Horrible 'void' return arg count hack"
1866             # in Node::CODE::parse() for more details.
1867             'CODE_sets_ST0', # Bool
1868             'XSRETURN_count_basic', # Int
1869             'XSRETURN_count_extra', # Int
1870              
1871             # These maintain the alias parsing state across potentially multiple
1872             # ALIAS keywords and or lines:
1873              
1874             'map_alias_name_to_value', # Hash: maps seen alias names to their value
1875              
1876             'map_alias_value_to_name_seen_hash', # Hash of Hash of Bools:
1877             # indicates which alias names have been
1878             # used for each value.
1879              
1880             'alias_clash_hinted', # Bool: an ALIAS warn-hint has been emitted.
1881              
1882             # Maintain the INTERFACE parsing state across potentially multiple
1883             # INTERFACE keywords and/or lines:
1884              
1885             'map_interface_name_short_to_original', # Hash: for each INTERFACE
1886             # name, map the short (PREFIX removed) name
1887             # to the original name.
1888              
1889             # Maintain the OVERLOAD parsing state across potentially multiple
1890             # OVERLOAD keywords and/or lines:
1891              
1892             'overload_name_seen', # Hash of Bools: indicates overload method
1893             # names (such as '<=>') which have been
1894             # listed by OVERLOAD (for newXS boot code
1895             # emitting).
1896              
1897             # Maintain the ATTRS parsing state across potentially multiple
1898             # ATTRS keywords and or lines:
1899              
1900             'attributes', # Array of Strs: all ATTRIBUTE keywords
1901             # (possibly multiple space-separated
1902             # keywords per string).
1903              
1904             # INTERFACE_MACRO state
1905              
1906             'interface_macro', # Str: value of interface extraction macro.
1907             'interface_macro_set', # Str: value of interface setting macro.
1908              
1909             # PROTOTYPE value
1910              
1911             'prototype', # Str: is set to either the global PROTOTYPES
1912             # values (0 or 1), or to what's been
1913             # overridden for this XSUB with PROTOTYPE
1914             # "0": DISABLE
1915             # "1": ENABLE
1916             # "2": empty prototype
1917             # other: a specific prototype.
1918              
1919             # Misc
1920              
1921             'SCOPE_enabled', # Bool: "SCOPE: ENABLE" seen, in either the
1922             # file or XSUB part of the XS file
1923              
1924             'PACKAGE_name', # value of $pxs->{PACKAGE_name} at parse time
1925             'PACKAGE_C_name', # value of $pxs->{PACKAGE_C_name} at parse time
1926              
1927             )};
1928              
1929              
1930             sub parse {
1931 462     462   1423 my __PACKAGE__ $self = shift;
1932 462         832 my ExtUtils::ParseXS $pxs = shift;
1933              
1934 462         1700 $self->SUPER::parse($pxs); # set file/line_no
1935              
1936             # record what package we're in
1937 462         1170 $self->{PACKAGE_name} = $pxs->{PACKAGE_name};
1938 462         976 $self->{PACKAGE_C_name} = $pxs->{PACKAGE_C_name};
1939              
1940             # Initially inherit the prototype behaviour for the XSUB from the
1941             # global PROTOTYPES default
1942 462         995 $self->{prototype} = $pxs->{PROTOTYPES_value};
1943              
1944             # inherit any SCOPE: value that immediately preceded the XSUB
1945             # declaration
1946 462         926 $self->{SCOPE_enabled} = $pxs->{file_SCOPE_enabled};
1947              
1948             # Parse the XSUB's declaration (return type, name, parameters)
1949              
1950 462         3486 my $decl = ExtUtils::ParseXS::Node::xsub_decl->new();
1951 462         1064 $self->{decl} = $decl;
1952 462 100       2492 $decl->parse($pxs, $self)
1953             or return;
1954 457         738 push @{$self->{kids}}, $decl;
  457         1239  
1955              
1956             # Check all the @{ $pxs->{line}} lines for balance: all the
1957             # #if, #else, #endif etc within the XSUB should balance out.
1958 457         2221 ExtUtils::ParseXS::Utilities::check_conditional_preprocessor_statements();
1959              
1960             # ----------------------------------------------------------------
1961             # Each iteration of this loop will process 1 optional CASE: line,
1962             # followed by all the other blocks. In the absence of a CASE: line,
1963             # this loop is only iterated once.
1964             # ----------------------------------------------------------------
1965              
1966 457         803 my $num = 0; # the number of CASE+bodies seen
1967 457         715 my $seen_bare_xbody = 0; # seen a previous body without a CASE
1968 457         949 my $case_had_cond = 1; # the previous CASE had a condition
1969              
1970             # Repeatedly look for CASE or XSUB body.
1971 457         681 while (1) {
1972             # Parse a CASE statement if present.
1973 925         2838 my ($case) =
1974             $self->parse_keywords(
1975             $pxs, $self, undef, # xbody not yet present so use undef
1976             1, # process maximum of one keyword
1977             "CASE",
1978             );
1979              
1980 925 100       1944 if (defined $case) {
1981 41         108 $case->{num} = ++$num;
1982              
1983 41 100       124 if ($seen_bare_xbody) {
1984 2         21 $pxs->blurt("Error: no 'CASE:' at top of function");
1985 2         7 $seen_bare_xbody = 0;
1986             }
1987              
1988 41 100       90 unless ($case_had_cond) {
1989 1         19 $pxs->blurt("Error: 'CASE:' after unconditional 'CASE:'");
1990             }
1991 41         67 $case_had_cond = length $case->{cond};
1992             }
1993             else {
1994 884         1257 $seen_bare_xbody = 1;
1995 884 100       1868 if ($num++) {
1996             # After the first CASE+body, we should only encounter
1997             # further CASE+bodies or end-of-paragraph
1998 444 100       597 last unless @{$pxs->{line}};
  444         1531  
1999 10         35 my $l = $pxs->{line}[0];
2000 10 100       412 $pxs->death(
2001             $l =~ /^$ExtUtils::ParseXS::BLOCK_regexp/o
2002             ? "Error: misplaced '$1:'"
2003             : qq{Error: junk at end of function: "$l"}
2004             );
2005             }
2006             }
2007              
2008             # Parse the XSUB's body
2009              
2010 481         3765 my $xbody = ExtUtils::ParseXS::Node::xbody->new();
2011 481 50       2544 $xbody->parse($pxs, $self)
2012             or return;
2013              
2014 468 100       1023 if (defined $case) {
2015             # make the xbody a child of the CASE
2016 41         63 push @{$case->{kids}}, $xbody;
  41         95  
2017 41         69 $xbody = $case;
2018             }
2019             else {
2020 427         616 push @{$self->{kids}}, $xbody;
  427         1027  
2021             }
2022             } # end while (@{ $pxs->{line} })
2023              
2024             # If any aliases have been declared, make the main sub name ix 0
2025             # if not specified.
2026              
2027 434 50 66     1486 if ( $self->{map_alias_name_to_value}
2028 20         74 and keys %{ $self->{map_alias_name_to_value} })
2029             {
2030 20         47 my $pname = $self->{decl}{full_perl_name};
2031             $self->{map_alias_name_to_value}{$pname} = 0
2032 20 100       88 unless defined $self->{map_alias_name_to_value}{$pname};
2033             }
2034              
2035             # per-XSUB sanity checks
2036              
2037 434 100 100     1162 if ( $self->{map_interface_name_short_to_original}
2038             && $self->{map_alias_name_to_value})
2039             {
2040 1         23 $pxs->blurt("Error: only one of ALIAS and INTERFACE can be used per XSUB");
2041             }
2042              
2043 434         1264 1;
2044             }
2045              
2046              
2047             sub as_code {
2048 433     433   924 my __PACKAGE__ $self = shift;
2049 433         695 my ExtUtils::ParseXS $pxs = shift;
2050              
2051             # ----------------------------------------------------------------
2052             # Emit initial C code for the XSUB
2053             # ----------------------------------------------------------------
2054              
2055             {
2056 433         626 my $extern = $self->{decl}{return_type}{extern_C}
2057 433 100       2462 ? qq[extern "C"] : "";
2058 433         1176 my $cname = $self->{decl}{full_C_name};
2059              
2060             # Emit function header
2061 433         1779 print $self->Q(<<"EOF");
2062             |$extern
2063             |XS_EUPXS(XS_$cname); /* prototype to pass -Wmissing-prototypes */
2064             |XS_EUPXS(XS_$cname)
2065             |$open_brace
2066             | dVAR; dXSARGS;
2067             EOF
2068             }
2069              
2070 433 100       2859 print $self->Q(<<"EOF") if $self->{seen_ALIAS};
2071             | dXSI32;
2072             EOF
2073              
2074 433 100       1268 if ($self->{seen_INTERFACE}) {
2075 16         49 my $type = $self->{decl}{return_type}{type};
2076             $type =~ tr/:/_/
2077 16 50       77 unless $pxs->{config_RetainCplusplusHierarchicalTypes};
2078 16 50       98 print $self->Q(<<"EOF") if $self->{seen_INTERFACE};
2079             | dXSFUNCTION($type);
2080             EOF
2081             }
2082              
2083              
2084             {
2085 433         642 my $params = $self->{decl}{params};
  433         1111  
2086             # the code to emit to determine whether the correct number of argument
2087             # have been passed
2088             my $condition_code =
2089             ExtUtils::ParseXS::set_cond($params->{seen_ellipsis},
2090             $params->{min_args},
2091 433         4209 $params->{nargs});
2092              
2093             # "-except" cmd line switch
2094 433 50       1535 print $self->Q(<<"EOF") if $pxs->{config_allow_exceptions};
2095             | char errbuf[1024];
2096             | *errbuf = '\\0';
2097             EOF
2098              
2099 433 100       1156 if ($condition_code) {
2100 429         1683 my $p = $params->usage_string();
2101 429         938 $p =~ s/"/\\"/g;
2102 429         1510 print $self->Q(<<"EOF");
2103             | if ($condition_code)
2104             | croak_xs_usage(cv, "$p");
2105             EOF
2106             }
2107             else {
2108             # cv and items likely to be unused
2109 4         19 print $self->Q(<<"EOF");
2110             | PERL_UNUSED_VAR(cv); /* -W */
2111             | PERL_UNUSED_VAR(items); /* -W */
2112             EOF
2113             }
2114             }
2115              
2116             # gcc -Wall: if an XSUB has PPCODE, it is possible that none of ST,
2117             # XSRETURN or XSprePUSH macros are used. Hence 'ax' (setup by
2118             # dXSARGS) is unused.
2119             # XXX: could breakup the dXSARGS; into dSP;dMARK;dITEMS
2120             # but such a move could break third-party extensions
2121 433 100       2730 print $self->Q(<<"EOF") if $self->{seen_PPCODE};
2122             | PERL_UNUSED_VAR(ax); /* -Wall */
2123             EOF
2124              
2125 433 100       1124 print $self->Q(<<"EOF") if $self->{seen_PPCODE};
2126             | SP -= items;
2127             EOF
2128              
2129             # ----------------------------------------------------------------
2130             # Emit the main body of the XSUB (all the CASE statements + bodies
2131             # or a single body)
2132             # ----------------------------------------------------------------
2133              
2134 433         705 $_->as_code($pxs, $self) for @{$self->{kids}};
  433         1719  
2135              
2136             # ----------------------------------------------------------------
2137             # All of the body of the XSUB (including all CASE variants) has now
2138             # been processed. Now emit any XSRETURN or similar, plus any closing
2139             # bracket.
2140             # ----------------------------------------------------------------
2141              
2142 433 50       1445 print $self->Q(<<"EOF") if $pxs->{config_allow_exceptions};
2143             | if (errbuf[0])
2144             | Perl_croak(aTHX_ errbuf);
2145             EOF
2146              
2147             # Emit XSRETURN(N) or XSRETURN_EMPTY. It's possible that the user's
2148             # CODE section rolled its own return, so this code may be
2149             # unreachable. So suppress any compiler warnings.
2150             # XXX Currently this is just for HP. Make more generic??
2151              
2152             # Suppress "statement is unreachable" warning on HPUX
2153 433 50       8267 print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
2154             "#pragma diag_suppress 2128\n",
2155             "#endif\n"
2156             if $^O eq "hpux";
2157              
2158 433 100       1131 unless ($self->{seen_PPCODE}) {
2159             my $nret = $self->{XSRETURN_count_basic}
2160 425         944 + $self->{XSRETURN_count_extra};
2161              
2162 425 100       1535 print $nret ? " XSRETURN($nret);\n"
2163             : " XSRETURN_EMPTY;\n";
2164             }
2165              
2166             # Suppress "statement is unreachable" warning on HPUX
2167 433 50       2825 print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
2168             "#pragma diag_default 2128\n",
2169             "#endif\n"
2170             if $^O eq "hpux";
2171              
2172             # Emit final closing bracket for the XSUB.
2173 433         1268 print "$close_brace\n\n";
2174             }
2175              
2176              
2177             # Return a list of boot code strings for the XSUB, including newXS()
2178             # call(s) plus any additional boot stuff like handling attributes or
2179             # storing an alias index in the XSUB's CV.
2180              
2181             sub as_boot_code {
2182 433     433   728 my __PACKAGE__ $self = shift;
2183 433         611 my ExtUtils::ParseXS $pxs = shift;
2184              
2185             # Depending on whether the XSUB has a prototype, work out how to
2186             # invoke one of the newXS() function variants. Set these:
2187             #
2188 433         1392 my $newXS; # the newXS() variant to be called in the boot section
2189             my $file_arg; # an extra ', file' arg to be passed to newXS call
2190 433         0 my $proto_arg; # an extra e.g. ', "$@"' arg to be passed to newXS call
2191              
2192 433         0 my @code; # boot code for each alias etc
2193              
2194 433         827 $proto_arg = "";
2195              
2196 433 100       1173 unless($self->{prototype}) {
2197             # no prototype
2198 391         730 $newXS = "newXS_deffile";
2199 391         1364 $file_arg = "";
2200             }
2201             else {
2202             # needs prototype
2203 42         104 $newXS = "newXSproto_portable";
2204 42         58 $file_arg = ", file";
2205              
2206 42 100       180 if ($self->{prototype} eq 2) {
    100          
2207             # User has specified an empty prototype
2208             }
2209             elsif ($self->{prototype} eq 1) {
2210             # Protoype enabled, but to be auto-generated by us
2211 35         138 $proto_arg = $self->{decl}{params}->proto_string();
2212 35         68 $proto_arg =~ s{\\}{\\\\}g; # escape backslashes
2213             }
2214             else {
2215             # User has manually specified a prototype
2216 6         11 $proto_arg = $self->{prototype};
2217             }
2218              
2219 42         70 $proto_arg = qq{, "$proto_arg"};
2220             }
2221              
2222             # Now use those values to append suitable newXS() and other code
2223             # into @code, for later insertion into the boot sub.
2224              
2225 433         1352 my $pname = $self->{decl}{full_perl_name};
2226 433         1334 my $cname = $self->{decl}{full_C_name};
2227              
2228 433 100 66     9236 if ( $self->{map_alias_name_to_value}
    100 66        
    100          
    100          
2229 20         78 and keys %{ $self->{map_alias_name_to_value} })
2230             {
2231             # For the main XSUB and for each alias name, generate a newXS() call
2232             # and 'XSANY.any_i32 = ix' line.
2233              
2234 20         31 foreach my $xname (sort keys
2235 20         125 %{ $self->{map_alias_name_to_value} })
2236             {
2237 66         115 my $value = $self->{map_alias_name_to_value}{$xname};
2238 66         187 push(@code, $self->Q(<<"EOF"));
2239             | cv = $newXS(\"$xname\", XS_$cname$file_arg$proto_arg);
2240             | XSANY.any_i32 = $value;
2241             EOF
2242 66         123 $pxs->{need_boot_cv} = 1;
2243             }
2244             }
2245             elsif ($self->{attributes}) {
2246             # Generate a standard newXS() call, plus a single call to
2247             # apply_attrs_string() call with the string of attributes.
2248 4         13 my $attrs = "@{$self->{attributes}}";
  4         14  
2249 4         25 push(@code, $self->Q(<<"EOF"));
2250             | cv = $newXS(\"$pname\", XS_$cname$file_arg$proto_arg);
2251             | apply_attrs_string("$self->{PACKAGE_name}", cv, "$attrs", 0);
2252             EOF
2253 4         11 $pxs->{need_boot_cv} = 1;
2254             }
2255             elsif ( $self->{seen_INTERFACE}
2256             or $self->{seen_INTERFACE_MACRO})
2257             {
2258             # For each interface name, generate both a newXS() and
2259             # XSINTERFACE_FUNC_SET() call.
2260 15         29 foreach my $yname (sort keys
2261 15         91 %{ $self->{map_interface_name_short_to_original} })
2262             {
2263 19         43 my $value = $self->{map_interface_name_short_to_original}{$yname};
2264 19 100       89 $yname = "$self->{PACKAGE_name}\::$yname" unless $yname =~ /::/;
2265              
2266 19         37 my $macro = $self->{interface_macro_set};
2267 19 100       88 $macro = 'XSINTERFACE_FUNC_SET' unless defined $macro;
2268 19         84 push(@code, $self->Q(<<"EOF"));
2269             | cv = $newXS(\"$yname\", XS_$cname$file_arg$proto_arg);
2270             | $macro(cv,$value);
2271             EOF
2272 19         59 $pxs->{need_boot_cv} = 1;
2273             }
2274             }
2275             elsif ($newXS eq 'newXS_deffile'){
2276             # Modified default: generate a standard newXS() call; but
2277             # work around the CPAN 'P5NCI' distribution doing:
2278             # #undef newXS
2279             # #define newXS ;
2280             # by omitting the initial (void).
2281             # XXX DAPM 2024:
2282             # this branch was originally: "elsif ($newXS eq 'newXS')"
2283             # but when the standard name for the newXS variant changed in
2284             # xsubpp, it was changed here too. So this branch no longer actually
2285             # handles a workaround for '#define newXS ;'. I also don't
2286             # understand how just omitting the '(void)' fixed the problem.
2287 356         1433 push(@code,
2288             " $newXS(\"$pname\", XS_$cname$file_arg$proto_arg);\n");
2289             }
2290             else {
2291             # Default: generate a standard newXS() call
2292 38         113 push(@code,
2293             " (void)$newXS(\"$pname\", XS_$cname$file_arg$proto_arg);\n");
2294             }
2295              
2296             # For every overload operator, generate an additional newXS()
2297             # call to add an alias such as "Foo::(<=>" for this XSUB.
2298              
2299 433         896 for my $operator (sort keys %{ $self->{overload_name_seen} })
  433         2181  
2300             {
2301 91         125 my $overload = "$self->{PACKAGE_name}\::($operator";
2302 91         187 push(@code,
2303             " (void)$newXS(\"$overload\", XS_$cname$file_arg$proto_arg);\n");
2304             }
2305              
2306 433         1382 return \@code, [];
2307             }
2308              
2309              
2310             # ======================================================================
2311              
2312             package ExtUtils::ParseXS::Node::xsub_decl;
2313              
2314             # Parse and store the complete declaration part of an XSUB, including
2315             # its parameters, name and return type.
2316              
2317 28     28   151 BEGIN { $build_subclass->(
2318             'return_type', # ReturnType object representing e.g "NO_OUTPUT char *"
2319             'params', # Params object representing e.g "a, int b, c=0"
2320             'class', # Str: the 'Foo::Bar' part of an XSUB's name;
2321             # - if defined, this is a C++ method
2322             'name', # Str: the 'foo' XSUB name
2323             'full_perl_name', # Str: the 'Foo::Bar::foo' perl XSUB name
2324             'full_C_name', # Str: the 'Foo__Bar__foo' C XSUB name
2325             'is_const', # Bool: declaration had postfix C++ 'const' modifier
2326             )};
2327              
2328              
2329             # Parse the XSUB's declaration - i.e. return type, name and parameters.
2330              
2331             sub parse {
2332 462     462   834 my __PACKAGE__ $self = shift;
2333 462         1258 my ExtUtils::ParseXS $pxs = shift;
2334 462         660 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
2335              
2336              
2337 462         1425 $self->SUPER::parse($pxs); # set file/line_no
2338              
2339             # Parse return type
2340              
2341 462         3266 my $return_type = ExtUtils::ParseXS::Node::ReturnType->new();
2342              
2343 462 50       2311 $return_type->parse($pxs, $xsub)
2344             or return;
2345              
2346 460         1151 $self->{return_type} = $return_type;
2347 460         706 push @{$self->{kids}}, $return_type;
  460         1309  
2348              
2349             # Decompose the function declaration: match a line like
2350             # Some::Class::foo_bar( args ) const ;
2351             # ----------- ------- ---- ----- --
2352             # $1 $2 $3 $4 $5
2353             #
2354             # where everything except $2 and $3 are optional and the 'const'
2355             # is for C++ functions.
2356              
2357 460         736 my $func_header = shift(@{ $pxs->{line} });
  460         1116  
2358 460 100       5797 $pxs->blurt("Error: cannot parse function definition from '$func_header'"),
2359             return
2360             unless $func_header =~
2361             /^(?:([\w:]*)::)?(\w+)\s*\(\s*(.*?)\s*\)\s*(const)?\s*(;\s*)?$/s;
2362              
2363 458         5176 my ($class, $name, $params_text, $const) = ($1, $2, $3, $4);
2364              
2365 458 100 100     1382 if (defined $const and !defined $class) {
2366 1         21 $pxs->blurt(
2367             "Error: const modifier only allowed on XSUBs which are C++ methods");
2368 1         3 undef $const;
2369             }
2370              
2371 458 100 100     1494 if ($return_type->{static} and !defined $class)
2372             {
2373 2         25 $pxs->Warn( "Warning: ignoring 'static' type modifier:"
2374             . " only valid with an XSUB name which includes a class");
2375 2         6 $return_type->{static} = 0;
2376             }
2377              
2378 458         5077 (my $full_pname = $name) =~
2379             s/^($pxs->{PREFIX_pattern})?/$pxs->{PACKAGE_class}/;
2380              
2381 458         2793 (my $clean_func_name = $name) =~ s/^$pxs->{PREFIX_pattern}//;
2382              
2383 458         1348 my $full_cname = "$pxs->{PACKAGE_C_name}_$clean_func_name";
2384 458 50       1103 $full_cname = $ExtUtils::ParseXS::VMS_SymSet->addsym($full_cname)
2385             if $ExtUtils::ParseXS::Is_VMS;
2386              
2387 458         987 $self->{class} = $class;
2388 458         1049 $self->{is_const} = defined $const;
2389 458         877 $self->{name} = $name;
2390 458         947 $self->{full_perl_name} = $full_pname;
2391 458         928 $self->{full_C_name} = $full_cname;
2392              
2393             # At this point, supposing that the input so far was:
2394             #
2395             # MODULE = ... PACKAGE = BAR::BAZ PREFIX = foo_
2396             # int
2397             # Some::Class::foo_bar(param1, param2, param3) const ;
2398             #
2399             # we should have:
2400             #
2401             # $self->{return_type} an object holding "int"
2402             # $self->{class} "Some::Class"
2403             # $self->{is_const} TRUE
2404             # $self->{name} "foo_bar"
2405             # $self->{full_perl_name} "BAR::BAZ::bar"
2406             # $self->{full_C_name} "BAR__BAZ_bar"
2407             # $params_text "param1, param2, param3"
2408              
2409             # ----------------------------------------------------------------
2410             # Process the XSUB's signature.
2411             #
2412             # Split $params_text into parameters, parse them, and store them as
2413             # Node::Param objects within the Node::Params object.
2414              
2415 458         3801 my $params = $self->{params} = ExtUtils::ParseXS::Node::Params->new();
2416              
2417 458 50       3215 $params->parse($pxs, $xsub, $params_text)
2418             or return;
2419 457         963 $self->{params} = $params;
2420 457         675 push @{$self->{kids}}, $params;
  457         993  
2421              
2422             # How many OUTLIST SVs get returned in addition to RETVAL
2423             $xsub->{XSRETURN_count_extra} =
2424             grep { defined $_->{in_out}
2425 756 100       2817 && $_->{in_out} =~ /OUTLIST$/
2426             }
2427 457         668 @{$self->{params}{kids}};
  457         1224  
2428 457         1602 1;
2429             }
2430              
2431              
2432             # ======================================================================
2433              
2434             package ExtUtils::ParseXS::Node::ReturnType;
2435              
2436             # Handle the 'return type' line at the start of an XSUB.
2437             # It mainly consists of the return type, but there are also
2438             # extra keywords to process, such as NO_RETURN.
2439              
2440 28     28   182 BEGIN { $build_subclass->(
2441             'type', # Str: the XSUB's C return type
2442             'no_output', # Bool: saw 'NO_OUTPUT'
2443             'extern_C', # Bool: saw 'extern C'
2444             'static', # Bool: saw 'static'
2445             'use_early_targ', # Bool: emit an early dTARG for backcompat
2446             )};
2447              
2448              
2449             # Extract out the return type declaration from the start of an XSUB.
2450             # If the declaration and function name are on the same line, delete the
2451             # type part; else pop the first line.
2452              
2453             sub parse {
2454 462     462   771 my __PACKAGE__ $self = shift;
2455 462         777 my ExtUtils::ParseXS $pxs = shift;
2456 462         667 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
2457              
2458 462         1306 $self->SUPER::parse($pxs); # set file/line_no
2459              
2460             # Whitespace-tidy the line containing the return type, plus possibly
2461             # the function name and arguments too.
2462             # XXX Tidying the latter was probably an unintended side-effect of
2463             # later allowing the return type and function to be on the same line.
2464              
2465 462         662 my $line = shift @{$pxs->{line}};
  462         1107  
2466 462         1697 $line = ExtUtils::Typemaps::tidy_type($line);
2467 462         956 my $type = $line;
2468              
2469 462 100       1605 $self->{no_output} = 1 if $type =~ s/^NO_OUTPUT\s+//;
2470              
2471             # Allow one-line declarations. This splits a single line like:
2472             # int foo(....)
2473             # into the two lines:
2474             # int
2475             # foo(...)
2476             #
2477             # Note that this splits both K&R-style 'foo(a, b)' and ANSI-style
2478             # 'foo(int a, int b)'. I don't know whether the former was intentional.
2479             # As of 5.40.0, the docs don't suggest that a 1-line K&R is legal. Was
2480             # added by 11416672a16, first appeared in 5.6.0.
2481             #
2482             # NB: $pxs->{config_allow_argtypes} is false if xsubpp was invoked
2483             # with -noargtypes
2484              
2485 67         277 unshift @{$pxs->{line}}, $2
2486             if $pxs->{config_allow_argtypes}
2487 462 100 100     5126 and $type =~ s/^(.*?\w.*?) \s* \b (\w+\s*\(.*)/$1/sx;
2488              
2489             # a function definition needs at least 2 lines
2490 462 100       783 unless (@{$pxs->{line}}) {
  462         1373  
2491 2 100       25 if ($line =~ /^([A-Z][A-Z_]+):/) {
2492             # It's possibly a mistyped keyword: give a more specific
2493             # error message:
2494 1         14 $pxs->death("Error: unrecognised keyword '$1'");
2495 0         0 return;
2496             }
2497             # Generic error message:
2498 1         117 $pxs->deathHint("Error: unrecognised line: '$line'",
2499             "possible start of a truncated XSUB definition?");
2500 0         0 return;
2501             }
2502              
2503 460 100       1174 $self->{extern_C} = 1 if $type =~ s/^extern "C"\s+//;
2504 460 100       1112 $self->{static} = 1 if $type =~ s/^static\s+//;
2505 460         953 $self->{type} = $type;
2506              
2507 460 100       1375 if ($type ne "void") {
2508             # Set a flag indicating that, for backwards-compatibility reasons,
2509             # early dXSTARG should be emitted.
2510             # Recent code emits a dXSTARG in a tighter scope and under
2511             # additional circumstances, but some XS code relies on TARG
2512             # having been declared. So continue to declare it early under
2513             # the original circumstances.
2514 252         1542 my $outputmap = $pxs->{typemaps_object}->get_outputmap(ctype => $type);
2515              
2516 252 100 66     2621 if ( $pxs->{config_optimize}
      100        
2517             and $outputmap
2518             and $outputmap->targetable_legacy)
2519             {
2520 213         590 $self->{use_early_targ} = 1;
2521             }
2522             }
2523              
2524 460         1469 1;
2525             }
2526              
2527              
2528             # ======================================================================
2529              
2530             package ExtUtils::ParseXS::Node::Param;
2531              
2532             # Node subclass which holds the state of one XSUB parameter, based on the
2533             # just the XSUB's signature. See also the Node::IO_Param subclass, which
2534             # augments the parameter declaration with info from INPUT and OUTPUT
2535             # lines.
2536              
2537 28     28   116 BEGIN { $build_subclass->(
2538             # values derived from the XSUB's signature
2539             'in_out', # Str: The IN/OUT/OUTLIST etc value (if any)
2540             'var', # Str: the name of the parameter
2541             'arg_num', # Int The arg number (starting at 1) mapped to this param
2542             'default', # Str: default value (if any)
2543             'default_usage', # Str: how to report default value in "usage:..." error
2544             'is_ansi', # Bool: param's type was specified in signature
2545             'is_length', # Bool: param is declared as 'length(foo)' in signature
2546             'length_param', # Obj: 'foo' param's matching 'length(foo)' parameter
2547             # node object, if any
2548             'len_name' , # Str: the 'foo' in 'length(foo)' in signature
2549             'is_synthetic', # Bool: var like 'THIS': we pretend it was in the sig
2550              
2551             # values derived from both the XSUB's signature and/or INPUT line
2552             'type', # Str: The C type of the parameter
2553             'no_init', # Bool: don't initialise the parameter
2554              
2555             # derived values calculated later
2556             'proto', # Str: overridden prototype char(s) (if any) from typemap
2557             )};
2558              
2559              
2560             # Parse a parameter. A parameter is of the general form:
2561             #
2562             # OUT char* foo = expression
2563             #
2564             # where:
2565             # IN/OUT/OUTLIST etc are only allowed under
2566             # $pxs->{config_allow_inout}
2567             #
2568             # a C type is only allowed under
2569             # $pxs->{config_allow_argtypes}
2570             #
2571             # foo can be a plain C variable name, or can be
2572             # length(foo) but only under $pxs->{config_allow_argtypes}
2573             #
2574             # = default default value - only allowed under
2575             # $pxs->{config_allow_argtypes}
2576              
2577             sub parse {
2578 514     514   814 my __PACKAGE__ $self = shift;
2579 514         767 my ExtUtils::ParseXS $pxs = shift;
2580 514         691 my $params = shift; # parent Params
2581 514         832 my $param_text = shift;
2582              
2583 514         1634 $self->SUPER::parse($pxs); # set file/line_no
2584              
2585             # Decompose parameter into its components.
2586             # Note that $name can be either 'foo' or 'length(foo)'
2587              
2588 514         6098 my ($out_type, $type, $name, $sp1, $sp2, $default) =
2589             $param_text =~
2590             /^
2591             (?:
2592             (IN|IN_OUT|IN_OUTLIST|OUT|OUTLIST)
2593             \b\s*
2594             )?
2595             (.*?) # optional type
2596             \s*
2597             \b
2598             ( \w+ # var
2599             | length\( \s*\w+\s* \) # length(var)
2600             )
2601             (?:
2602             (\s*) = (\s*) ( .*?) # default expr
2603             )?
2604             \s*
2605             $
2606             /x;
2607              
2608 514 100       1613 unless (defined $name) {
2609 7 100       52 if ($param_text =~ /^ SV \s* \* $/x) {
2610             # special-case SV* as a placeholder for backwards
2611             # compatibility.
2612 4         27 $self->{var} = 'SV *';
2613 4         19 return 1;
2614             }
2615 3         25 $pxs->blurt("Error: unparseable XSUB parameter: '$param_text'");
2616 3         32 return;
2617             }
2618              
2619 507 100 66     3413 undef $type unless length($type) && $type =~ /\S/;
2620 507         1104 $self->{var} = $name;
2621              
2622             # Check for duplicates
2623              
2624 507         1246 my $old_param = $params->{names}{$name};
2625 507 100       1254 if ($old_param) {
2626             # Normally a dup parameter is an error, but we allow RETVAL as
2627             # a real parameter, which overrides the synthetic one which
2628             # was added earlier if the return value isn't void.
2629 29 100 100     301 if ( $name eq 'RETVAL'
      100        
2630             and $old_param->{is_synthetic}
2631             and !defined $old_param->{arg_num})
2632             {
2633             # RETVAL is currently fully synthetic. Now that it has
2634             # been declared as a parameter too, override any implicit
2635             # RETVAL declaration. Delete the original param from the
2636             # param list and later re-add it as a parameter in its
2637             # correct position.
2638 16         45 @{$params->{kids}} = grep $_ != $old_param, @{$params->{kids}};
  16         36  
  16         66  
2639             # If the param declaration includes a type, it becomes a
2640             # real parameter. Otherwise the param is kept as
2641             # 'semi-real' (synthetic, but with an arg_num) until such
2642             # time as it gets a type set in INPUT, which would remove
2643             # the synthetic/no_init.
2644 16 100       109 %$self = %$old_param unless defined $type;
2645             }
2646             else {
2647 13         137 $pxs->blurt(
2648             "Error: duplicate definition of parameter '$name' ignored");
2649 13         130 return;
2650             }
2651             }
2652              
2653             # Process optional IN/OUT etc modifier
2654              
2655 494         822 my $orig_out_type = $out_type;
2656 494 100       1173 if (defined $out_type) {
2657             $pxs->blurt(
2658             "Error: parameter IN/OUT modifier not allowed under -noinout")
2659 72 100       424 unless $pxs->{config_allow_inout};
2660              
2661 72 100       351 $out_type = $out_type eq 'IN' ? '' : $out_type;
2662             }
2663             else {
2664 422         912 $out_type = '';
2665             }
2666              
2667             # Process optional type
2668              
2669 494 100 100     2499 if (defined($type) && !$pxs->{config_allow_argtypes}) {
2670 2         26 $pxs->blurt("Error: parameter type not allowed under -noargtypes");
2671 2         7 undef $type;
2672             }
2673              
2674             # Process 'length(foo)' pseudo-parameter
2675              
2676 494         1055 my $len_name;
2677              
2678 494 100       1316 if ($name =~ /^length\( \s* (\w+) \s* \)\z/x) {
2679             $pxs->blurt( "Error: length() pseudo-parameter not allowed "
2680             . "under -noargtypes")
2681 34 100       185 unless $pxs->{config_allow_argtypes};
2682              
2683 34         141 $len_name = $1;
2684              
2685 34 100       149 if (defined $default) {
2686 2         51 $pxs->blurt( "Error: default value not allowed on "
2687             . "length() parameter '$len_name'");
2688 2         7 undef $default;
2689             }
2690 34 100       109 unless (defined $type) {
2691 2         29 $pxs->blurt(
2692             "Error: length($len_name) doesn't have a type specified");
2693 2         14 $type = 'STRLEN'; # stop cascading problems while
2694             # blurting the rest of the file
2695             }
2696              
2697 34 100       104 if (defined $orig_out_type) {
2698             # Ban IN_OUT etc with length().
2699 5         66 $pxs->blurt( "Error: '$orig_out_type' modifier can't be used"
2700             . " with length($len_name)");
2701 5         10 $out_type = ''; # avoid cascading errors
2702             }
2703              
2704 34         96 $self->{no_init} = 1;
2705 34         93 $self->{is_length} = 1;
2706 34         82 $self->{len_name} = $len_name;
2707             # This is the C variable which will have it's
2708             # value set to the length of the string,
2709             # then used as an arg in an autocall:
2710 34         80 $self->{var} = "XSauto_length_of_$len_name";
2711              
2712             # Note that cross-checking with the foo parameter associated with
2713             # length(foo) is done near the end of Node::Params::parse(), after
2714             # all params have been parsed.
2715             }
2716              
2717             # Mark ANSI params: those which have a type (including 'length(s)')
2718             # and which thus don't need a matching INPUT line.
2719              
2720 494 100       1242 if (defined $type) { # 'int foo' or 'int length(foo)'
2721 353         662 $self->{type} = $type;
2722 353         659 $self->{is_ansi} = 1;
2723             }
2724              
2725 494 100       1185 $self->{in_out} = $out_type if length $out_type;
2726 494 100       1399 $self->{no_init} = 1 if $out_type =~ /^OUT/;
2727              
2728             # Process the default expression, including making the text
2729             # to be used in "usage: ..." error messages.
2730              
2731 494         984 my $report_def = '';
2732 494 100       1010 if (defined $default) {
2733 37 100       226 $pxs->death("Error: missing default value expression for '$name'")
2734             unless $default =~ /\S/;
2735              
2736             # The default expression for reporting usage. For backcompat,
2737             # sometimes preserve the spaces either side of the '='
2738 36 100       162 $report_def = ($self->{is_ansi} ? '' : $sp1)
2739             . "=$sp2$default";
2740 36         71 $self->{default_usage} = $report_def;
2741 36         88 $self->{default} = $default;
2742             }
2743              
2744 493         1582 1;
2745             }
2746              
2747              
2748             # Set the 'proto' field of the param. This is based on the value, if any,
2749             # of the proto method of the typemap for that param's type. It will
2750             # typically be a single character like '$'.
2751             #
2752             # Note that params can have different types (and thus different proto
2753             # chars) in different CASE branches.
2754              
2755             sub set_proto {
2756 784     784   1145 my __PACKAGE__ $self = shift;
2757 784         1009 my ExtUtils::ParseXS $pxs = shift;
2758              
2759             # only needed for real args that the caller may pass.
2760 784 100       1759 return unless $self->{arg_num};
2761 456         916 my $type = $self->{type};
2762 456 100       936 return unless defined $type;
2763 420         1152 my $typemap = $pxs->{typemaps_object}->get_typemap(ctype => $type);
2764 420 100       892 return unless defined $typemap;
2765 413         1214 my $p = $typemap->proto;
2766 413 100 66     2180 return unless defined $p && length $p;
2767 4         14 $self->{proto} = $p;
2768             }
2769              
2770              
2771             # ======================================================================
2772              
2773             package ExtUtils::ParseXS::Node::IO_Param;
2774              
2775             # Subclass of Node::Param which holds the state of one XSUB parameter,
2776             # based on the XSUB's signature, but also augmented by info from INPUT or
2777             # OUTPUT lines
2778              
2779 28     28   155 BEGIN { $build_subclass->(-parent => 'Param',
2780             # values derived from the XSUB's INPUT line
2781              
2782             'init_op', # Str: initialisation type: one of =/+/;
2783             'init', # Str: initialisation template code
2784             'is_addr', # Bool: INPUT var declared as '&foo'
2785             'is_alien', # Bool: var declared in INPUT line, but not in signature
2786             'in_input', # Bool: the parameter has appeared in an INPUT statement
2787             'defer', # Str: deferred initialisation template code
2788              
2789             # values derived from the XSUB's OUTPUT line
2790             #
2791             'in_output', # Bool: the parameter has appeared in an OUTPUT statement
2792             'do_setmagic', # Bool: 'SETMAGIC: ENABLE' was active for this parameter
2793             'output_code', # Str: the optional setting-code for this parameter
2794              
2795             # ArrayRefs: results of looking up typemaps (which are done in the
2796             # parse phase, as the typemap definitions can in theory change
2797             # further down in the XS file). For now these just store
2798             # uninterpreted, the list returned by the call to
2799             # lookup_input_typemap() etc, for later use by the as_input_code()
2800             # etc methods.
2801             #
2802             'input_typemap_vals', # result of lookup_input_typemap()
2803             'output_typemap_vals', # result of lookup_output_typemap(...)
2804             'output_typemap_vals_outlist', # result of lookup_output_typemap(..., n)
2805             )};
2806              
2807              
2808             # Given a param with known type etc, extract its typemap INPUT template
2809             # and also create a hash of vars that can be used to eval that template.
2810             # An undef returned hash ref signifies that the returned template string
2811             # doesn't need to be evalled.
2812             #
2813             # Returns ($expr, $eval_vars, $is_template)
2814             # or empty list on failure.
2815             #
2816             # $expr: text like '$var = SvIV($arg)'
2817             # $eval_vars: hash ref like { var => 'foo', arg => 'ST(0)', ... }
2818             # $is_template: $expr has '$arg' etc and needs evalling
2819              
2820             sub lookup_input_typemap {
2821 750     750   1059 my __PACKAGE__ $self = shift;
2822 750         1069 my ExtUtils::ParseXS $pxs = shift;
2823 750         1086 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
2824 750         924 my $xbody = shift;
2825              
2826             my ($type, $arg_num, $var, $init, $no_init, $default)
2827 750         1274 = @{$self}{qw(type arg_num var init no_init default)};
  750         3152  
2828 750         2935 my $arg = $pxs->ST($arg_num);
2829              
2830             # whitespace-tidy the type
2831 750         1968 $type = ExtUtils::Typemaps::tidy_type($type);
2832              
2833             # Specify the environment for when the initialiser template is evaled.
2834             # Only the common ones are specified here. Other fields may be added
2835             # later.
2836             my $eval_vars = {
2837             type => $type,
2838             var => $var,
2839             num => $arg_num,
2840             arg => $arg,
2841             alias => $xsub->{seen_ALIAS},
2842             func_name => $xsub->{decl}{name},
2843             full_perl_name => $xsub->{decl}{full_perl_name},
2844             full_C_name => $xsub->{decl}{full_C_name},
2845             Package => $xsub->{PACKAGE_name},
2846 750         8827 };
2847              
2848             # The type looked up in the eval is Foo__Bar rather than Foo::Bar
2849             $eval_vars->{type} =~ tr/:/_/
2850 750 50       2681 unless $pxs->{config_RetainCplusplusHierarchicalTypes};
2851              
2852 750         1349 my $init_template;
2853              
2854 750 100       1987 if (defined $init) {
    100          
2855             # Use the supplied code template rather than getting it from the
2856             # typemap
2857              
2858 13 50       62 $pxs->death(
2859             "Internal error: ExtUtils::ParseXS::Node::Param::as_code(): "
2860             . "both init and no_init supplied")
2861             if $no_init;
2862              
2863 13         37 $eval_vars->{init} = $init;
2864 13         44 $init_template = "\$var = $init";
2865             }
2866             elsif ($no_init) {
2867             # don't add initialiser
2868 337         853 $init_template = "";
2869             }
2870             else {
2871             # Get the initialiser template from the typemap
2872              
2873 400         839 my $typemaps = $pxs->{typemaps_object};
2874              
2875             # Normalised type ('Foo *' becomes 'FooPtr): one of the valid vars
2876             # which can appear within a typemap template.
2877 400         1387 (my $ntype = $type) =~ s/\s*\*/Ptr/g;
2878              
2879             # $subtype is really just for the T_ARRAY / DO_ARRAY_ELEM code below,
2880             # where it's the type of each array element. But it's also passed to
2881             # the typemap template (although undocumented and virtually unused).
2882 400         2820 (my $subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//;
2883              
2884             # look up the TYPEMAP entry for this C type and grab the corresponding
2885             # XS type name (e.g. $type of 'char *' gives $xstype of 'T_PV'
2886 400         1341 my $typemap = $typemaps->get_typemap(ctype => $type);
2887 400 100       946 if (not $typemap) {
2888 3         40 $pxs->report_typemap_failure($typemaps, $type);
2889 3         24 return;
2890             }
2891 397         1202 my $xstype = $typemap->xstype;
2892              
2893             # An optimisation: for the typemaps which check that the dereferenced
2894             # item is blessed into the right class, skip the test for DESTROY()
2895             # methods, as more or less by definition, DESTROY() will be called
2896             # on an object of the right class. Basically, for T_foo_OBJ, use
2897             # T_foo_REF instead. T_REF_IV_PTR was added in v5.22.0.
2898             $xstype =~ s/OBJ$/REF/ || $xstype =~ s/^T_REF_IV_PTR$/T_PTRREF/
2899 397 100 33     1367 if $xsub->{decl}{name} =~ /DESTROY$/;
2900              
2901             # Get the ExtUtils::Typemaps::InputMap object associated with the
2902             # xstype. This contains the template of the code to be embedded,
2903             # e.g. 'SvPV_nolen($arg)'
2904 397         1186 my $inputmap = $typemaps->get_inputmap(xstype => $xstype);
2905 397 100       899 if (not defined $inputmap) {
2906 3         31 $pxs->blurt("Error: no INPUT definition for type '$type', typekind '$xstype' found");
2907 3         25 return;
2908             }
2909              
2910             # Get the text of the template, with a few transformations to make it
2911             # work better with fussy C compilers. In particular, strip trailing
2912             # semicolons and remove any leading white space before a '#'.
2913 394         1272 my $expr = $inputmap->cleaned_code;
2914              
2915 394         726 my $argoff = $arg_num - 1;
2916              
2917             # Process DO_ARRAY_ELEM. This is an undocumented hack that makes the
2918             # horrible T_ARRAY typemap work. "DO_ARRAY_ELEM" appears as a token
2919             # in the INPUT and OUTPUT code for for T_ARRAY, within a "for each
2920             # element" loop, and the purpose of this branch is to substitute the
2921             # token for some real code which will process each element, based
2922             # on the type of the array elements (the $subtype).
2923             #
2924             # Note: This gruesome bit either needs heavy rethinking or
2925             # documentation. I vote for the former. --Steffen, 2011
2926             # Seconded, DAPM 2024.
2927 394 100       1224 if ($expr =~ /\bDO_ARRAY_ELEM\b/) {
2928 6         34 my $subtypemap = $typemaps->get_typemap(ctype => $subtype);
2929 6 100       39 if (not $subtypemap) {
2930 1         23 $pxs->report_typemap_failure($typemaps, $subtype);
2931 1         17 return;
2932             }
2933              
2934 5         25 my $subinputmap =
2935             $typemaps->get_inputmap(xstype => $subtypemap->xstype);
2936 5 100       25 if (not $subinputmap) {
2937 1         12 $pxs->blurt("Error: no INPUT definition for subtype "
2938             . "'$subtype', typekind '"
2939             . $subtypemap->xstype . "' found");
2940 1         10 return;
2941             }
2942              
2943 4         14 my $subexpr = $subinputmap->cleaned_code;
2944 4         18 $subexpr =~ s/\$type/\$subtype/g;
2945 4         30 $subexpr =~ s/ntype/subtype/g;
2946 4         30 $subexpr =~ s/\$arg/ST(ix_$var)/g;
2947 4         11 $subexpr =~ s/\n\t/\n\t\t/g;
2948 4         12 $subexpr =~ s/is not of (.*\")/[arg %d] is not of $1, ix_$var + 1/g;
2949 4         34 $subexpr =~ s/\$var/${var}\[ix_$var - $argoff]/;
2950 4         39 $expr =~ s/\bDO_ARRAY_ELEM\b/$subexpr/;
2951             }
2952              
2953 392 100       1333 if ($expr =~ m#/\*.*scope.*\*/#i) { # "scope" in C comments
2954 1         8 $xsub->{SCOPE_enabled} = 1;
2955             }
2956              
2957             # Specify additional environment for when a template derived from a
2958             # *typemap* is evalled.
2959 392         2710 @$eval_vars{qw(ntype subtype argoff)} = ($ntype, $subtype, $argoff);
2960 392         731 $init_template = $expr;
2961              
2962             # For a parameter foo, if length(foo) was also declared as a
2963             # pseudo-parameter, then try to modify the normal typemap, which
2964             # we would expect to contain SvPV_nolen(...) or similar, into this
2965             # form instead: SvPV(..., STRLEN_length_of_foo).
2966             # Croak if this isn't possible.
2967             # Just accept the typemap as-is if it already contains the correct
2968             # STRLEN_length_of_ entry.
2969              
2970 392 100       1041 if ($self->{length_param}) {
2971 29 100       109 if ($expr =~ /\bSTRLEN_length_of_\$var\b/) {
2972             # leave as-is
2973             }
2974             else {
2975 28 100       375 unless ($expr =~
2976             s{ \b
2977             (SvPV\w*)_nolen(\w*)
2978             \(
2979             \s*\$arg\s*
2980             \)
2981             }
2982             {$1$2(\$arg, STRLEN_length_of_\$var)}x
2983             ) {
2984 2         32 $pxs->deathHint(
2985             "Error: can't modify input typemap for"
2986             . " length($self->{var})",
2987             <
2988             The parameter '$self->{var}' has an associated length($self->{var})
2989             pseudo-parameter. In cases like this, the XS parser attempts to modify
2990             a typemap entry such as
2991              
2992             \$var = (\$type)SvPV_nolen(\$arg)
2993              
2994             into a similar one which also sets a length, such as
2995              
2996             \$var = (\$type)SvPV(\$arg, STRLEN_length_of_\$var)
2997              
2998             In this case, the following typemap did not contain a recognised
2999             SVPV_nolen() variant:
3000              
3001             $expr
3002             EOF
3003             }
3004             }
3005             }
3006              
3007 390         848 $init_template = $expr;
3008             }
3009              
3010 740         3267 return ($init_template, $eval_vars, 1);
3011             }
3012              
3013              
3014              
3015             # Given a param with known type etc, extract its typemap OUTPUT template
3016             # and also create a hash of vars that can be used to eval that template.
3017             # An undef returned hash ref signifies that the returned template string
3018             # doesn't need to be evalled.
3019             # $out_num, if defined, signifies that this lookup is for an OUTLIST param
3020             #
3021             # Returns ($expr, $eval_vars, $is_template, $saw_DAE)
3022             # or empty list on failure.
3023             #
3024             # $expr: text like 'sv_setiv($arg, $var)'
3025             # $eval_vars: hash ref like { var => 'foo', arg => 'ST(0)', ... }
3026             # $is_template: $expr has '$arg' etc and needs evalling
3027             # $saw_DAE: DO_ARRAY_ELEM was encountered
3028             #
3029              
3030             sub lookup_output_typemap {
3031 317     317   547 my __PACKAGE__ $self = shift;
3032 317         535 my ExtUtils::ParseXS $pxs = shift;
3033 317         458 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
3034 317         546 my $xbody = shift;
3035 317         474 my $out_num = shift;
3036              
3037             my ($type, $num, $var, $do_setmagic, $output_code)
3038 317         597 = @{$self}{qw(type arg_num var do_setmagic output_code)};
  317         1271  
3039              
3040             # values to return
3041 317         788 my ($expr, $eval_vars, $is_template, $saw_DAE);
3042 317         476 $is_template = 1;
3043              
3044 317 100       910 if ($var eq 'RETVAL') {
3045             # Do some preliminary RETVAL-specific checks and settings.
3046              
3047             # Only OUT/OUTPUT vars (which update one of the passed args) should be
3048             # calling set magic; RETVAL and OUTLIST should be setting the value of
3049             # a fresh mortal or TARG. Note that a param can be both OUTPUT and
3050             # OUTLIST - the value of $do_setmagic only applies to its use as an
3051             # OUTPUT (updating) value.
3052              
3053 229 50       477 $pxs->death("Internal error: do set magic requested on RETVAL")
3054             if $do_setmagic;
3055              
3056             # RETVAL normally has an undefined arg_num, although it can be
3057             # set to a real index if RETVAL is also declared as a parameter.
3058             # But when returning its value, it's always stored at ST(0).
3059 229         323 $num = 1;
3060              
3061             # It is possible for RETVAL to have multiple types, e.g.
3062             # int
3063             # foo(long RETVAL)
3064             #
3065             # In the above, 'long' is used for the RETVAL C var's declaration,
3066             # while 'int' is used to generate the return code (for backwards
3067             # compatibility).
3068 229         539 $type = $xsub->{decl}{return_type}{type};
3069             }
3070              
3071             # ------------------------------------------------------------------
3072             # Do initial processing of $type, including creating various derived
3073             # values
3074              
3075 317 100       666 unless (defined $type) {
3076 3         47 $pxs->blurt("Error: can't determine output type for '$var'");
3077 3         21 return;
3078             }
3079              
3080             # $ntype: normalised type ('Foo *' becomes 'FooPtr' etc): one of the
3081             # valid vars which can appear within a typemap template.
3082 314         1366 (my $ntype = $type) =~ s/\s*\*/Ptr/g;
3083 314         644 $ntype =~ s/\(\)//g;
3084              
3085             # $subtype is really just for the T_ARRAY / DO_ARRAY_ELEM code below,
3086             # where it's the type of each array element. But it's also passed to
3087             # the typemap template (although undocumented and virtually unused).
3088             # Basically for a type like FooArray or FooArrayPtr, the subtype is Foo.
3089 314         2259 (my $subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//;
3090              
3091             # whitespace-tidy the type
3092 314         988 $type = ExtUtils::Typemaps::tidy_type($type);
3093              
3094             # The type as supplied to the eval is Foo__Bar rather than Foo::Bar
3095 314         574 my $eval_type = $type;
3096             $eval_type =~ tr/:/_/
3097 314 50       957 unless $pxs->{config_RetainCplusplusHierarchicalTypes};
3098              
3099             # We can be called twice for the same variable: once to update the
3100             # original arg (via an entry in OUTPUT) and once to push the param's
3101             # value (via OUTLIST). When doing the latter, any override code on an
3102             # OUTPUT line should not be used.
3103 314 100       752 undef $output_code if defined $out_num;
3104              
3105             # ------------------------------------------------------------------
3106             # Find the template code (pre any eval) and store it in $expr.
3107             # This is typically obtained via a typemap lookup, but can be
3108             # overridden. Also set vars ready for evalling the typemap template.
3109              
3110 314         435 my $outputmap;
3111 314         562 my $typemaps = $pxs->{typemaps_object};
3112              
3113 314 100       911 if (defined $output_code) {
    100          
3114             # An override on an OUTPUT line: use that instead of the typemap.
3115             # Note that we don't set $expr here, because $expr holds a template
3116             # string pre-eval, while OUTPUT override code is *not*
3117             # template-expanded, so $output_code is effectively post-eval code.
3118 11         35 $is_template = 0;
3119 11         23 $expr = $output_code;
3120             }
3121             elsif ($type =~ /^array\(([^,]*),(.*)\)/) {
3122             # Specially handle the implicit array return type, "array(type, nlelem)"
3123             # rather than using a typemap entry. It returns a string SV whose
3124             # buffer is a copy of $var, which it assumes is a C array of
3125             # type 'type' with 'nelem' elements.
3126              
3127 4         28 my ($atype, $nitems) = ($1, $2);
3128              
3129 4 100       18 if ($var ne 'RETVAL') {
3130             # This special type is intended for use only as the return type of
3131             # an XSUB
3132 2 100       35 $pxs->blurt( "Error: can't use array(type,nitems) type for "
3133             . (defined $out_num ? "OUTLIST" : "OUT")
3134             . " parameter");
3135 2         21 return;
3136             }
3137              
3138             $expr =
3139 2         7 "\tsv_setpvn(\$arg, (char *)\$var, $nitems * sizeof($atype));\n";
3140             }
3141             else {
3142             # Handle a normal return type via a typemap.
3143              
3144             # Get the output map entry for this type; complain if not found.
3145 299         905 my $typemap = $typemaps->get_typemap(ctype => $type);
3146 299 100       665 if (not $typemap) {
3147 2         24 $pxs->report_typemap_failure($typemaps, $type);
3148 2         12 return;
3149             }
3150              
3151 297         955 $outputmap = $typemaps->get_outputmap(xstype => $typemap->xstype);
3152 297 100       690 if (not $outputmap) {
3153 3         24 $pxs->blurt( "Error: no OUTPUT definition for type '$type', "
3154             . "typekind '" . $typemap->xstype . "' found");
3155 3         16 return;
3156             }
3157              
3158             # Get the text of the typemap template, with a few transformations to
3159             # make it work better with fussy C compilers. In particular, strip
3160             # trailing semicolons and remove any leading white space before a '#'.
3161              
3162 294         932 $expr = $outputmap->cleaned_code;
3163             }
3164              
3165 307 100       1373 my $arg = $pxs->ST(defined $out_num ? $out_num + 1 : $num);
3166              
3167             # Specify the environment for if/when the code template is evalled.
3168             $eval_vars =
3169             {
3170             num => $num,
3171             var => $var,
3172             do_setmagic => $do_setmagic,
3173             subtype => $subtype,
3174             ntype => $ntype,
3175             arg => $arg,
3176             type => $eval_type,
3177             alias => $xsub->{seen_ALIAS},
3178             func_name => $xsub->{decl}{name},
3179             full_perl_name => $xsub->{decl}{full_perl_name},
3180             full_C_name => $xsub->{decl}{full_C_name},
3181             Package => $xsub->{PACKAGE_name},
3182 307         3817 };
3183              
3184              
3185             # ------------------------------------------------------------------
3186             # Handle DO_ARRAY_ELEM token as a very special case
3187              
3188 307 100 100     2179 if (!defined $output_code and $expr =~ /\bDO_ARRAY_ELEM\b/) {
3189             # See the comments in ExtUtils::ParseXS::Node::Param::as_code() that
3190             # explain the similar code for the DO_ARRAY_ELEM hack there.
3191              
3192 8 100       38 if ($var ne 'RETVAL') {
3193             # Typemap templates containing DO_ARRAY_ELEM are assumed to
3194             # contain a loop which explicitly stores a new mortal SV at
3195             # each of the locations ST(0) .. ST(n-1), and which then uses
3196             # the code from the typemap for the underlying array element
3197             # to set each SV's value.
3198             #
3199             # This is a horrible hack for RETVAL, which would probably
3200             # fail with OUTLIST due to stack offsets being wrong, and
3201             # definitely would fail with OUT, which is supposed to be
3202             # updating parameter SVs, not pushing anything on the stack.
3203             # So forbid all except RETVAL.
3204 2 100       34 $pxs->blurt("Error: can't use typemap containing DO_ARRAY_ELEM for "
3205             . (defined $out_num ? "OUTLIST" : "OUT")
3206             . " parameter");
3207 2         17 return;
3208             }
3209              
3210 6         37 my $subtypemap = $typemaps->get_typemap(ctype => $subtype);
3211 6 100       26 if (not $subtypemap) {
3212 1         14 $pxs->report_typemap_failure($typemaps, $subtype);
3213 1         10 return;
3214             }
3215              
3216 5         30 my $suboutputmap =
3217             $typemaps->get_outputmap(xstype => $subtypemap->xstype);
3218              
3219 5 100       26 if (not $suboutputmap) {
3220 1         8 $pxs->blurt( "Error: no OUTPUT definition for subtype '$subtype', "
3221             . "typekind '" . $subtypemap->xstype . "' found");
3222 1         10 return;
3223             }
3224              
3225 4         15 my $subexpr = $suboutputmap->cleaned_code;
3226 4         19 $subexpr =~ s/ntype/subtype/g;
3227 4         62 $subexpr =~ s/\$arg/ST(ix_$var)/g;
3228 4         29 $subexpr =~ s/\$var/${var}\[ix_$var]/g;
3229 4         16 $subexpr =~ s/\n\t/\n\t\t/g;
3230 4         29 $expr =~ s/\bDO_ARRAY_ELEM\b/$subexpr/;
3231              
3232 4         17 $saw_DAE = 1;
3233             }
3234              
3235 303         1586 return $expr, $eval_vars, $is_template, $saw_DAE;
3236             }
3237              
3238              
3239             # $self->as_input_code():
3240             #
3241             # Emit the param object as C code which declares and initialise the variable.
3242             # See also the as_output_code() method, which emits code to return the value
3243             # of that local var.
3244              
3245             sub as_input_code {
3246 736     736   1230 my __PACKAGE__ $self = shift;
3247 736         1038 my ExtUtils::ParseXS $pxs = shift;
3248 736         969 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
3249 736         1005 my $xbody = shift;
3250              
3251             my ($type, $arg_num, $var, $init, $no_init, $defer, $default)
3252 736         1220 = @{$self}{qw(type arg_num var init no_init defer default)};
  736         3493  
3253              
3254 736         2174 my $arg = $pxs->ST($arg_num);
3255              
3256              
3257             # For this construct: 'foo(char *s, int length(s))', ...
3258              
3259 736 100       2573 if ($self->{is_length}) {
    100          
3260             # ... the call for the 'length(s)' pseudo-parameter should
3261             # emit nothing ...
3262 32         87 return;
3263             }
3264             elsif ($self->{length_param}) {
3265             # ... while the call for the 's' parameter should emit a (possibly
3266             # modified) declaration and init as normal, but also some extra
3267             # lines. In total this parameter should emit code something like:
3268             #
3269             # STRLEN STRLEN_length_of_s;
3270             # int XSauto_length_of_s;
3271             # char * s = (char *)SvPV(ST(0), STRLEN_length_of_s);
3272             #
3273             # XSauto_length_of_s = STRLEN_length_of_s;
3274              
3275 29         72 my $lenp = $self->{length_param};
3276 29         87 my $xsauto_var = $lenp->{var};
3277 29         108 print "\tSTRLEN\tSTRLEN_length_of_$var;\n";
3278 29         248 print "\t$lenp->{type}\t$xsauto_var;\n";
3279              
3280             # The "var = SvPV()" line will be emitted by the main body of this
3281             # function. Note that the T_PV typemap entry will have already
3282             # been overridden in lookup_input_typemap() during parse time
3283             # to change SvPV_nolen() to SvPV() or similar.
3284             #
3285             # The final assign should be deferred to come after all
3286             # declarations.
3287             $xbody->{input_part}{deferred_code_lines} .=
3288 29         212 "\n\t$xsauto_var = STRLEN_length_of_$var;\n";
3289             }
3290              
3291             # Emit the variable's type and name.
3292             #
3293             # Includes special handling for function pointer types. An INPUT line
3294             # always has the C type followed by the variable name. The C code
3295             # which is emitted normally follows the same pattern. However for
3296             # function pointers, the code is different: the variable name has to
3297             # be embedded *within* the type. For example, these two INPUT lines:
3298             #
3299             # char * s
3300             # int (*)(int) fn_ptr
3301             #
3302             # cause the following lines of C to be emitted;
3303             #
3304             # char * s = [something from a typemap]
3305             # int (* fn_ptr)(int) = [something from a typemap]
3306             #
3307             # So handle specially the specific case of a type containing '(*)' by
3308             # embedding the variable name *within* rather than *after* the type.
3309              
3310              
3311 704 100       2121 if ($type =~ / \( \s* \* \s* \) /x) {
3312             # for a fn ptr type, embed the var name in the type declaration
3313 3         32 print "\t" . $pxs->map_type($type, $var);
3314             }
3315             else {
3316             print "\t",
3317 701 100 100     4533 ((defined($xsub->{decl}{class}) && $var eq 'CLASS')
3318             ? $type
3319             : $pxs->map_type($type, undef)),
3320             "\t$var";
3321             }
3322              
3323             # Result of parse-phase lookup of INPUT typemap for this param's type.
3324 704         1542 my $lookup = $self->{input_typemap_vals};
3325 704 50       1385 $pxs->death( "Internal error: parameter '$var' "
3326             . "doesn't have input_typemap_vals")
3327             unless $lookup;
3328              
3329 704         1729 my ($init_template, $eval_vars, $is_template) = @$lookup;
3330              
3331 704 100       1455 return unless defined $init_template; # an error occurred
3332              
3333 696 50       1380 unless ($is_template) {
3334             # template already expanded
3335 0         0 print " = $init_template\n";
3336 0         0 return;
3337             }
3338              
3339             # whitespace-tidy the type
3340 696         1869 $type = ExtUtils::Typemaps::tidy_type($type);
3341              
3342             # Now finally, emit the actual variable declaration and initialisation
3343             # line(s). The variable type and name will already have been emitted.
3344              
3345 696 100       3031 my $init_code =
3346             length $init_template
3347             ? $pxs->eval_input_typemap_code("qq\a$init_template\a", $eval_vars)
3348             : "";
3349              
3350              
3351 696 100 100     26130 if (defined $default
    100 100        
      100        
3352             # XXX for now, for backcompat, ignore default if the
3353             # param has a typemap override
3354             && !(defined $init)
3355             # XXX for now, for backcompat, ignore default if the
3356             # param wouldn't otherwise get initialised
3357             && !$no_init
3358             ) {
3359             # Has a default value. Just terminate the variable declaration, and
3360             # defer the initialisation.
3361              
3362 28         136 print ";\n";
3363              
3364             # indent the code 1 step further
3365 28         415 $init_code =~ s/(\t+)/$1 /g;
3366 28         84 $init_code =~ s/ /\t/g;
3367              
3368 28 100       83 if ($default eq 'NO_INIT') {
3369             # for foo(a, b = NO_INIT), add code to initialise later only if
3370             # an arg was supplied.
3371             $xbody->{input_part}{deferred_code_lines}
3372 1         8 .= sprintf "\n\tif (items >= %d) {\n%s;\n\t}\n",
3373             $arg_num, $init_code;
3374             }
3375             else {
3376             # for foo(a, b = default), add code to initialise later to either
3377             # the arg or default value
3378 27 50       234 my $else = $init_code =~ /\S/
3379             ? "\telse {\n$init_code;\n\t}\n"
3380             : "";
3381              
3382 27         67 $default =~ s/"/\\"/g; # escape double quotes
3383             $xbody->{input_part}{deferred_code_lines}
3384 27         126 .= sprintf "\n\tif (items < %d)\n\t %s = %s;\n%s",
3385             $arg_num,
3386             $var,
3387             $pxs->eval_input_typemap_code("qq\a$default\a",
3388             $eval_vars),
3389             $else;
3390             }
3391             }
3392             elsif ($xsub->{SCOPE_enabled} or $init_code !~ /^\s*\Q$var\E =/) {
3393             # The template is likely a full block rather than a '$var = ...'
3394             # expression. Just terminate the variable declaration, and defer the
3395             # initialisation.
3396             # Note that /\Q$var\E/ matches the string containing whatever $var
3397             # was expanded to in the eval.
3398              
3399 304         999 print ";\n";
3400              
3401             $xbody->{input_part}{deferred_code_lines}
3402 304 100       2337 .= sprintf "\n%s;\n", $init_code
3403             if $init_code =~ /\S/;
3404             }
3405             else {
3406             # The template starts with '$var = ...'. The variable name has already
3407             # been emitted, so remove it from the typemap before evalling it,
3408              
3409 364 50       13965 $init_code =~ s/^\s*\Q$var\E(\s*=\s*)/$1/
3410             # we just checked above that it starts with var=, so this
3411             # should never happen
3412             or $pxs->death(
3413             "Internal error: typemap doesn't start with '\$var='\n");
3414              
3415 364         1912 printf "%s;\n", $init_code;
3416             }
3417              
3418 696 100       4807 if (defined $defer) {
3419             $xbody->{input_part}{deferred_code_lines}
3420 6         36 .= $pxs->eval_input_typemap_code("qq\a$defer\a", $eval_vars)
3421             . "\n";
3422             }
3423             }
3424              
3425              
3426             # $param->as_output_code($ParseXS_object, $out_num])
3427             #
3428             # Emit code to: possibly create, then set the value of, and possibly
3429             # push, an output SV, based on the values in the $param object.
3430             #
3431             # $out_num is optional and its presence indicates that an OUTLIST var is
3432             # being pushed: it indicates the position on the stack of that SV.
3433             #
3434             # This function emits code such as "sv_setiv(ST(0), (IV)foo)", based on
3435             # the typemap OUTPUT entry associated with $type. It passes the typemap
3436             # code through a double-quotish context eval first to expand variables
3437             # such as $arg and $var. It also tries to optimise the emitted code in
3438             # various ways, such as using TARG where available rather than calling
3439             # sv_newmortal() to obtain an SV to set to the return value.
3440             #
3441             # It expects to handle three categories of variable, with these general
3442             # actions:
3443             #
3444             # RETVAL, i.e. the return value
3445             #
3446             # Create a new SV; use the typemap to set its value to RETVAL; then
3447             # store it at ST(0).
3448             #
3449             # OUTLIST foo
3450             #
3451             # Create a new SV; use the typemap to set its value to foo; then store
3452             # it at ST($out_num-1).
3453             #
3454             # OUTPUT: foo / OUT foo
3455             #
3456             # Update the value of the passed arg ST($num-1), using the typemap to
3457             # set its value
3458             #
3459             # Note that it's possible for this function to be called *twice* for the
3460             # same variable: once for OUTLIST, and once for an 'OUTPUT:' entry.
3461             #
3462             # It treats output typemaps as falling into two basic categories,
3463             # exemplified by:
3464             #
3465             # sv_setFoo($arg, (Foo)$var));
3466             #
3467             # $arg = newFoo($var);
3468             #
3469             # The first form is the most general and can be used to set the SV value
3470             # for all of the three variable categories above. For the first two
3471             # categories it typically uses a new mortal, while for the last, it just
3472             # uses the passed arg SV.
3473             #
3474             # The assign form of the typemap can be considered an optimisation of
3475             # sv_setsv($arg, newFoo($var)), and is applicable when newFOO() is known
3476             # to return a new SV. So rather than copying it to yet another new SV,
3477             # just return as-is, possibly after mortalising it,
3478             #
3479             # Some typemaps evaluate to different code depending on whether the var is
3480             # RETVAL, e.g T_BOOL is currently defined as:
3481             #
3482             # ${"$var" eq "RETVAL" ? \"$arg = boolSV($var);"
3483             # : \"sv_setsv($arg, boolSV($var));"}
3484             #
3485             # So we examine the typemap *after* evaluation to determine whether it's
3486             # of the form '$arg = ' or not.
3487             #
3488             # Note that *currently* we generally end up with the pessimised option for
3489             # OUTLIST vars, since the typmaps onlt check for RETVAL.
3490             #
3491             # Currently RETVAL and 'OUTLIST var' mostly share the same code paths
3492             # below, so they both benefit from optimisations such as using TARG
3493             # instead of creating a new mortal, and using the RETVALSV C var to keep
3494             # track of the temp SV, rather than repeatedly retrieving it from ST(0)
3495             # etc. Note that RETVALSV is private and shouldn't be referenced within XS
3496             # code or typemaps.
3497              
3498             sub as_output_code {
3499 307     307   500 my __PACKAGE__ $self = shift;
3500 307         472 my ExtUtils::ParseXS $pxs = shift;
3501 307         449 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
3502 307         418 my $xbody = shift;
3503 307         448 my $out_num = shift;
3504              
3505             my ($type, $var, $do_setmagic, $output_code)
3506 307         537 = @{$self}{qw(type var do_setmagic output_code)};
  307         1138  
3507              
3508 307 100       767 if ($var eq 'RETVAL') {
3509             # It is possible for RETVAL to have multiple types, e.g.
3510             # int
3511             # foo(long RETVAL)
3512             #
3513             # In the above, 'long' is used for the RETVAL C var's declaration,
3514             # while 'int' is used to generate the return code (for backwards
3515             # compatibility).
3516 219         481 $type = $xsub->{decl}{return_type}{type};
3517             }
3518              
3519             # whitespace-tidy the type
3520 307         821 $type = ExtUtils::Typemaps::tidy_type($type);
3521              
3522             # We can be called twice for the same variable: once to update the
3523             # original arg (via an entry in OUTPUT) and once to push the param's
3524             # value (via OUTLIST). When doing the latter, any override code on an
3525             # OUTPUT line should not be used.
3526 307 100       770 undef $output_code if defined $out_num;
3527              
3528             # Result of parse-phase lookup of OUTPUT typemap for this param's type.
3529             my $lookup = defined $out_num
3530             ? $self->{output_typemap_vals_outlist}
3531 307 100       807 : $self->{output_typemap_vals};
3532 307 50       688 $pxs->death( "Internal error: parameter '$var' "
3533             . "doesn't have output_typemap_vals")
3534             unless $lookup;
3535              
3536 307         731 my ($expr, $eval_vars, $is_template, $saw_DAE) = @$lookup;
3537              
3538 307 100       736 return unless defined $expr; # error
3539              
3540 293 100       1006 if ($saw_DAE) {
    100          
3541             # We do our own code emitting and return here (rather than control
3542             # passing on to normal RETVAL processing) since that processing is
3543             # expecting to push a single temp onto the stack, while our code
3544             # pushes several temps.
3545 4         59 print $pxs->eval_output_typemap_code("qq\a$expr\a", $eval_vars);
3546 4         48 return;
3547             }
3548             elsif (!$is_template) {
3549             # $expr doesn't need evalling - use as-is
3550 11         22 $output_code = $expr;
3551             }
3552              
3553 289         706 my $ntype = $eval_vars->{ntype};
3554 289         493 my $num = $eval_vars->{num};
3555 289         536 my $arg = $eval_vars->{arg};
3556              
3557             # ------------------------------------------------------------------
3558             # Now emit code for the three types of return value:
3559             #
3560             # RETVAL - The usual case: store an SV at ST(0) which is set
3561             # to the value of RETVAL. This is typically a new
3562             # mortal, but may be optimised to use TARG.
3563             #
3564             # OUTLIST param - if $out_num is defined (and will be >= 0) Push
3565             # after any RETVAL, new mortal(s) containing the
3566             # current values of the local var set from that
3567             # parameter. (May also use TARG if not already used
3568             # by RETVAL).
3569             #
3570             # OUT/OUTPUT param - update passed arg SV at ST($num-1) (which
3571             # corresponds to param) with the current value of
3572             # the local var set from that parameter.
3573              
3574 289 100 100     1036 if ($var ne 'RETVAL' and not defined $out_num) {
3575             # This is a normal OUTPUT var: i.e. a named parameter whose
3576             # corresponding arg on the stack should be updated with the
3577             # parameter's current value by using the code contained in the
3578             # output typemap.
3579             #
3580             # Note that for args being *updated* (as opposed to replaced), this
3581             # branch relies on the typemap to Do The Right Thing. For example,
3582             # T_BOOL currently has this typemap entry:
3583             #
3584             # ${"$var" eq "RETVAL" ? \"$arg = boolSV($var);"
3585             # : \"sv_setsv($arg, boolSV($var));"}
3586             #
3587             # which means that if we hit this branch, $evalexpr will have been
3588             # expanded to something like "sv_setsv(ST(2), boolSV(foo))".
3589              
3590 35 50       82 unless (defined $num) {
3591 0         0 $pxs->blurt(
3592             "Internal error: OUT parameter has undefined argument number");
3593 0         0 return;
3594             }
3595              
3596             # Use the code on the OUTPUT line if specified, otherwise use the
3597             # typemap
3598 35 100       178 my $code = defined $output_code
3599             ? "\t$output_code\n"
3600             : $pxs->eval_output_typemap_code("qq\a$expr\a", $eval_vars);
3601 35         108 print $code;
3602              
3603             # For parameters in the OUTPUT section, honour the SETMAGIC in force
3604             # at the time. For parameters instead being output because of an OUT
3605             # keyword in the signature, assume set magic always.
3606 35 100 100     400 print "\tSvSETMAGIC($arg);\n" if !$self->{in_output} || $do_setmagic;
3607 35         239 return;
3608             }
3609              
3610             # ------------------------------------------------------------------
3611             # The rest of this main body handles RETVAL or "OUTLIST foo".
3612              
3613 254 100 66     708 if (defined $output_code and !defined $out_num) {
3614             # Handle this (just emit overridden code as-is):
3615             # OUTPUT:
3616             # RETVAL output_code
3617 8         42 print "\t$output_code\n";
3618 8 50       76 print "\t++SP;\n" if $xbody->{output_part}{stack_was_reset};
3619 8         40 return;
3620             }
3621              
3622             # Emit a standard RETVAL/OUTLIST return
3623              
3624             # ------------------------------------------------------------------
3625             # First, evaluate the typemap, expanding any vars like $var and $arg,
3626             # for example,
3627             #
3628             # $arg = newFoo($var);
3629             # or
3630             # sv_setFoo($arg, $var);
3631             #
3632             # However, rather than using the actual destination (such as ST(0))
3633             # for the value of $arg, we instead set it initially to RETVALSV. This
3634             # is because often the SV will be used in more than one statement,
3635             # and so it is more efficient to temporarily store it in a C auto var.
3636             # So we normally emit code such as:
3637             #
3638             # {
3639             # SV *RETVALSV;
3640             # RETVALSV = newFoo(RETVAL);
3641             # RETVALSV = sv_2mortal(RETVALSV);
3642             # ST(0) = RETVALSV;
3643             # }
3644             #
3645             # Rather than
3646             #
3647             # ST(0) = newFoo(RETVAL);
3648             # sv_2mortal(ST(0));
3649             #
3650             # Later we sometimes modify the evalled typemap to change 'RETVALSV'
3651             # to some other value:
3652             # - back to e.g. 'ST(0)' if there is no other use of the SV;
3653             # - to TARG when we are using the OP_ENTERSUB's targ;
3654             # - to $var when then return type is SV* (and thus ntype is SVPtr)
3655             # and so the variable will already have been declared as type 'SV*'
3656             # and thus there is no need for a RETVALSV too.
3657             #
3658             # Note that we evaluate the typemap early here so that the various
3659             # regexes below such as /^\s*\Q$arg\E\s*=/ can be matched against
3660             # the *evalled* result of typemap entries such as
3661             #
3662             # ${ "$var" eq "RETVAL" ? \"$arg = $var;" : \"sv_setsv_mg($arg, $var);" }
3663             #
3664             # which may eval to something like "RETVALSV = RETVAL" and
3665             # subsequently match /^\s*\Q$arg\E =/ (where $arg is "RETVAL"), but
3666             # couldn't have matched against the original typemap.
3667             # This is why we *always* set $arg to 'RETVALSV' first and then modify
3668             # the typemap later - we don't know what final value we want for $arg
3669             # until after we've examined the evalled result.
3670              
3671 246         514 my $orig_arg = $arg;
3672 246         544 $eval_vars->{arg} = $arg = 'RETVALSV';
3673 246         1245 my $evalexpr = $pxs->eval_output_typemap_code("qq\a$expr\a", $eval_vars);
3674              
3675             # ------------------------------------------------------------------
3676             # Examine the just-evalled typemap code to determine what optimisations
3677             # etc can be performed and what sort of code needs emitting. The two
3678             # halves of this following if/else examine the two forms of evalled
3679             # typemap:
3680             #
3681             # RETVALSV = newFoo((Foo)RETVAL);
3682             # and
3683             # sv_setFoo(RETVALSV, (Foo)RETVAL);
3684             #
3685             # In particular, the first form is assumed to be returning an SV which
3686             # the function has generated itself (e.g. newSVREF()) and which may
3687             # just need mortalising; while the second form generally needs a call
3688             # to sv_newmortal() first to create an SV which the function can then
3689             # set the value of.
3690              
3691 246         418 my $do_mortalize = 0; # Emit an sv_2mortal()
3692 246         378 my $want_newmortal = 0; # Emit an sv_newmortal()
3693 246         672 my $retvar = 'RETVALSV'; # The name of the C var which holds the SV
3694             # (likely tmp) to set to the value of the var
3695              
3696 246 100       2700 if ($evalexpr =~ /^\s*\Q$arg\E\s*=/) {
3697             # Handle this form: RETVALSV = newFoo((Foo)RETVAL);
3698             # newFoo creates its own SV: we just need to mortalise and return it
3699              
3700             # Is the SV one of the immortal SVs?
3701 9 100       386 if ($evalexpr =~
3702             /^\s*
3703             \Q$arg\E
3704             \s*=\s*
3705             ( boolSV\(.*\)
3706             | &PL_sv_yes
3707             | &PL_sv_no
3708             | &PL_sv_undef
3709             | &PL_sv_zero
3710             )
3711             \s*;\s*$
3712             /x)
3713             {
3714             # If so, we can skip mortalising it to stop it leaking.
3715 6         24 $retvar = $orig_arg; # just assign to ST(N) directly
3716             }
3717             else {
3718             # general '$arg = newFOO()' typemap
3719 3         11 $do_mortalize = 1;
3720              
3721             # If $var is already of type SV*, then use that instead of
3722             # declaring 'SV* RETVALSV' as an intermediate var.
3723 3 100       16 $retvar = $var if $ntype eq "SVPtr";
3724             }
3725             }
3726             else {
3727             # Handle this (eval-expanded) form of typemap:
3728             # sv_setFoo(RETVALSV, (Foo)var);
3729             # We generally need to supply a mortal SV for the typemap code to
3730             # set, and then return it on the stack,
3731              
3732             # First, see if we can use the targ (if any) attached to the current
3733             # OP_ENTERSUB, to avoid having to create a new mortal.
3734             #
3735             # The targetable() OutputMap class method looks at whether the code
3736             # snippet is of a form suitable for using TARG as the destination.
3737             # It looks for one of a known list of well-behaved setting function
3738             # calls, like sv_setiv() which will set the TARG to a value that
3739             # doesn't include magic, tieing, being a reference (which would leak
3740             # as the TARG is never freed), etc. If so, emit dXSTARG and replace
3741             # RETVALSV with TARG.
3742             #
3743             # For backwards-compatibility, dXSTARG may have already been emitted
3744             # early in the XSUB body, when a more restrictive set of targ-
3745             # compatible typemap entries were checked for. Note that dXSTARG is
3746             # defined as something like:
3747             #
3748             # SV * targ = (PL_op->op_private & OPpENTERSUB_HASTARG)
3749             # ? PAD_SV(PL_op->op_targ) : sv_newmortal()
3750              
3751 237 100 66     2512 if ( $pxs->{config_optimize}
      100        
3752             && ExtUtils::Typemaps::OutputMap->targetable($evalexpr)
3753             && !$xbody->{output_part}{targ_used})
3754             {
3755             # So TARG is available for use.
3756 200         455 $retvar = 'TARG';
3757             # can only use TARG to return one value
3758 200         397 $xbody->{output_part}{targ_used} = 1;
3759              
3760             # Since we're using TARG for the return SV, see if we can use
3761             # the TARG[iun] macros as appropriate to speed up setting it.
3762             # If so, convert "sv_setiv(RETVALSV, val)" to "TARGi(val,1)"
3763             # and similarly for uv and nv. These macros skip a function
3764             # call for the common case where TARG is already a simple
3765             # IV/UV/NV. Convert the _mg forms too: since we're setting the
3766             # TARG, there shouldn't be set magic on it, so the _mg action
3767             # can be safely ignored.
3768              
3769 200         3159 $evalexpr =~ s{
3770             ^
3771             (\s*)
3772             sv_set([iun])v(?:_mg)?
3773             \(
3774             \s* RETVALSV \s* ,
3775             \s* (.*)
3776             \)
3777             ( \s* ; \s*)
3778             $
3779             }
3780             {$1TARG$2($3, 1)$4}x;
3781             }
3782             else {
3783             # general typemap: give it a fresh SV to set the value of.
3784 37         71 $want_newmortal = 1;
3785             }
3786             }
3787              
3788             # ------------------------------------------------------------------
3789             # Now emit the return C code, based on the various flags and values
3790             # determined above.
3791              
3792 246         586 my $do_scope; # wrap code in a {} block
3793             my @lines; # Lines of code to eventually emit
3794              
3795             # Do any declarations first
3796              
3797 246 100 100     1887 if ($retvar eq 'TARG' && !$xsub->{decl}{return_type}{use_early_targ}) {
    100          
3798 21         86 push @lines, "\tdXSTARG;\n";
3799 21         47 $do_scope = 1;
3800             }
3801             elsif ($retvar eq 'RETVALSV') {
3802 39         143 push @lines, "\tSV * $retvar;\n";
3803 39         81 $do_scope = 1;
3804             }
3805              
3806 246 100       641 push @lines, "\tRETVALSV = sv_newmortal();\n" if $want_newmortal;
3807              
3808             # Emit the typemap, while changing the name of the destination SV back
3809             # from RETVALSV to one of the other forms (varname/TARG/ST(N)) if was
3810             # determined earlier to be necessary.
3811             # Skip emitting it if it's of the trivial form "var = var", which is
3812             # generated when the typemap is of the form '$arg = $var' and the SVPtr
3813             # optimisation is using $var for the destination.
3814              
3815 246 100       879 $evalexpr =~ s/\bRETVALSV\b/$retvar/g if $retvar ne 'RETVALSV';
3816              
3817 246 100       6067 unless ($evalexpr =~ /^\s*\Q$var\E\s*=\s*\Q$var\E\s*;\s*$/) {
3818 245         742 push @lines, split /^/, $evalexpr
3819             }
3820              
3821             # Emit mortalisation on the result SV if needed
3822 246 100       682 push @lines, "\t$retvar = sv_2mortal($retvar);\n" if $do_mortalize;
3823              
3824             # Emit the final 'ST(n) = RETVALSV' or similar, unless ST(n)
3825             # was already assigned to earlier directly by the typemap.
3826 246 100       859 push @lines, "\t$orig_arg = $retvar;\n" unless $retvar eq $orig_arg;
3827              
3828 246 100       534 if ($do_scope) {
3829             # Add an extra 4-indent, then wrap the output code in a new block
3830 60         151 for (@lines) {
3831 219         579 s/\t/ /g; # break down all tabs into spaces
3832 219         528 s/^/ /; # add 4-space extra indent
3833 219         640 s/ /\t/g; # convert 8 spaces back to tabs
3834             }
3835 60         188 unshift @lines, "\t{\n";
3836 60         149 push @lines, "\t}\n";
3837             }
3838              
3839 246         979 print @lines;
3840 246 100       2106 print "\t++SP;\n" if $xbody->{output_part}{stack_was_reset};
3841             }
3842              
3843              
3844             # ======================================================================
3845              
3846             package ExtUtils::ParseXS::Node::Params;
3847              
3848             # A Node subclass which holds a list of the parameters for an XSUB.
3849             # It is a mainly a list of Node::Param or Node::IO_Param kids, and is
3850             # used in two contexts.
3851             #
3852             # First, as a field of an xsub_decl node, where it holds a list of Param
3853             # objects which represent the individual parameters found within an XSUB's
3854             # signature, plus possibly extra synthetic ones such as THIS and RETVAL.
3855             #
3856             # Second, as a field of an xbody node, where it contains a copy of the
3857             # signature's Params object (and Param children), but where the children
3858             # are in fact IO_param objects and hold augmented information provided by
3859             # any INPUT and OUTPUT blocks within that XSUB body (of which there can be
3860             # more than one in the presence of CASE).
3861              
3862 28     28   138 BEGIN { $build_subclass->(
3863              
3864             'names', # Hash ref mapping variable names to Node::Param
3865             # or Node::IO_Param objects
3866              
3867             'params_text', # Str: The original text of the sig, e.g.
3868             # "param1, int param2 = 0"
3869              
3870             'seen_ellipsis', # Bool: XSUB signature has ( ,...)
3871              
3872             'nargs', # Int: The number of args expected from caller
3873             'min_args', # Int: The minimum number of args allowed from caller
3874              
3875             'auto_function_sig_override', # Str: the C_ARGS value, if any
3876             )};
3877              
3878              
3879             # ----------------------------------------------------------------
3880             # Parse the parameter list of an XSUB's signature.
3881             #
3882             # Split the XSUB's parameter list on commas into parameters, while
3883             # allowing for things like '(a = ",", b)'.
3884             #
3885             # Then for each parameter, parse its various fields and store in a
3886             # ExtUtils::ParseXS::Node::Param object. Store those Param objects within
3887             # the Params object, plus any other state deduced from the signature, such
3888             # as min/max permitted number of args.
3889             #
3890             # A typical signature might look like:
3891             #
3892             # OUT char *s, \
3893             # int length(s), \
3894             # OUTLIST int size = 10)
3895             #
3896             # ----------------------------------------------------------------
3897              
3898             my ($C_group_rex, $C_arg);
3899              
3900             # Group in C (no support for comments or literals)
3901             #
3902             # DAPM 2024: I'm not entirely clear what this is supposed to match.
3903             # It appears to match balanced and possibly nested [], {} etc, with
3904             # similar but possibly unbalanced punctuation within. But the balancing
3905             # brackets don't have to correspond: so [} is just as valid as [] or {},
3906             # as is [{{{{] or even [}}}}}
3907              
3908             $C_group_rex = qr/ [({\[]
3909             (?: (?> [^()\[\]{}]+ ) | (??{ $C_group_rex }) )*
3910             [)}\]] /x;
3911              
3912             # $C_arg: match a chunk in C without comma at toplevel (no comments),
3913             # i.e. a single arg within an XS signature, such as
3914             # foo = ','
3915             #
3916             # DAPM 2024. This appears to match zero, one or more of:
3917             # a random collection of non-bracket/quote/comma chars (e.g, a word or
3918             # number or 'int *foo' etc), or
3919             # a balanced(ish) nested brackets, or
3920             # a "string literal", or
3921             # a 'c' char literal
3922             # So (I guess), it captures the next item in a function signature
3923              
3924             $C_arg = qr/ (?: (?> [^()\[\]{},"']+ )
3925             | (??{ $C_group_rex })
3926             | " (?: (?> [^\\"]+ )
3927             | \\.
3928             )* " # String literal
3929             | ' (?: (?> [^\\']+ ) | \\. )* ' # Char literal
3930             )* /xs;
3931              
3932              
3933             sub parse {
3934 458     458   845 my __PACKAGE__ $self = shift;
3935 458         676 my ExtUtils::ParseXS $pxs = shift;
3936 458         678 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
3937 458         738 my $params_text = shift;
3938              
3939 458         1470 $self->SUPER::parse($pxs); # set file/line_no
3940              
3941             # remove line continuation chars (\)
3942 458         1815 $params_text =~ s/\\\s*/ /g;
3943 458         1115 $self->{params_text} = $params_text;
3944              
3945 458         704 my @param_texts;
3946 458         1042 my $opt_args = 0; # how many params with default values seen
3947 458         699 my $nargs = 0; # how many args are expected
3948              
3949             # First, split signature into separate parameters
3950              
3951 458 100       2253 if ($params_text =~ /\S/) {
3952 307         968 my $sig_c = "$params_text ,";
3953 28     28   258 use re 'eval'; # needed for 5.16.0 and earlier
  28         64  
  28         2705  
3954 307         1777 my $can_use_regex = ($sig_c =~ /^( (??{ $C_arg }) , )* $ /x);
3955 28     28   151 no re 'eval';
  28         41  
  28         1062  
3956              
3957 307 100       913 if ($can_use_regex) {
3958             # If the parameters are capable of being split by using the
3959             # fancy regex, do so. This splits the params on commas, but
3960             # can handle things like foo(a = ",", b)
3961 28     28   107 use re 'eval';
  28         45  
  28         35101  
3962 306         1396 @param_texts = ($sig_c =~ /\G ( (??{ $C_arg }) ) , /xg);
3963             }
3964             else {
3965             # This is the fallback parameter-splitting path for when the
3966             # $C_arg regex doesn't work. This code path should ideally
3967             # never be reached, and indicates a design weakness in $C_arg.
3968 1         13 @param_texts = split(/\s*,\s*/, $params_text);
3969 1         10 $pxs->Warn( "Warning: cannot parse parameter list "
3970             . "'$params_text', fallback to split");
3971             }
3972             }
3973             else {
3974 151         335 @param_texts = ();
3975             }
3976              
3977             # C++ methods get a fake object/class param at the start.
3978             # This affects arg numbering.
3979 458 100       1800 if (defined($xsub->{decl}{class})) {
3980             my ($var, $type) =
3981             ( $xsub->{decl}{return_type}{static}
3982             or $xsub->{decl}{name} eq 'new'
3983             )
3984             ? ('CLASS', "char *")
3985 25 100 100     452 : ('THIS', ($xsub->{decl}{is_const} ? "const " : "")
    100          
3986             . "$xsub->{decl}{class} *");
3987              
3988 25         355 my ExtUtils::ParseXS::Node::Param $param
3989             = ExtUtils::ParseXS::Node::Param->new( {
3990             var => $var,
3991             type => $type,
3992             is_synthetic => 1,
3993             arg_num => ++$nargs,
3994             });
3995 25         83 push @{$self->{kids}}, $param;
  25         94  
3996 25         181 $self->{names}{$var} = $param;
3997             }
3998              
3999             # For non-void return types, add a fake RETVAL parameter. This triggers
4000             # the emitting of an 'int RETVAL;' declaration or similar, and (e.g. if
4001             # later flagged as in_output), triggers the emitting of code to return
4002             # RETVAL's value.
4003             #
4004             # Note that a RETVAL param can be in three main states:
4005             #
4006             # fully-synthetic What is being created here. RETVAL hasn't appeared
4007             # in a signature or INPUT.
4008             #
4009             # semi-real Same as fully-synthetic, but with a defined arg_num,
4010             # and with an updated position within
4011             # @{$self->{kids}}. A RETVAL has appeared in the
4012             # signature, but without a type yet specified, so it
4013             # continues to use $xsub->{decl}{return_type}{type}.
4014             #
4015             # real is_synthetic, no_init flags turned off. Its type
4016             # comes from the sig or INPUT line. This is just a
4017             # normal parameter now.
4018              
4019 458 100       1799 if ($xsub->{decl}{return_type}{type} ne 'void') {
4020             my ExtUtils::ParseXS::Node::Param $param =
4021             ExtUtils::ParseXS::Node::Param->new( {
4022             var => 'RETVAL',
4023             type => $xsub->{decl}{return_type}{type},
4024 250         3293 no_init => 1, # just declare the var, don't initialise it
4025             is_synthetic => 1,
4026             } );
4027              
4028 250         809 push @{$self->{kids}}, $param;
  250         800  
4029 250         1564 $self->{names}{RETVAL} = $param;
4030             }
4031              
4032 458         1700 for my $param_text (@param_texts) {
4033             # Parse each parameter.
4034              
4035 528         1832 $param_text =~ s/^\s+//;
4036 528         1980 $param_text =~ s/\s+$//;
4037              
4038             # Process ellipsis (...)
4039              
4040             $pxs->blurt("Error: further XSUB parameter seen after ellipsis (...)")
4041 528 100       1476 if $self->{seen_ellipsis};
4042              
4043 528 100       1269 if ($param_text eq '...') {
4044 14         25 $self->{seen_ellipsis} = 1;
4045 14         27 next;
4046             }
4047              
4048 514         1955 my $param = ExtUtils::ParseXS::Node::Param->new();
4049 514 100       2325 $param->parse($pxs, $self, $param_text)
4050             or next;
4051              
4052 497         705 push @{$self->{kids}}, $param;
  497         1131  
4053 497 100       2728 $self->{names}{$param->{var}} = $param unless $param->{var} eq 'SV *';
4054 497 100       1358 $opt_args++ if defined $param->{default};
4055             # Give the param a number if it will consume one of the passed args
4056             $param->{arg_num} = ++$nargs
4057             unless ( defined $param->{in_out} && $param->{in_out} eq "OUTLIST"
4058             or $param->{is_length})
4059              
4060 497 100 100     3773 } # for (@param_texts)
      100        
4061              
4062 457         992 $self->{nargs} = $nargs;
4063 457         1270 $self->{min_args} = $nargs - $opt_args;
4064              
4065             # for each parameter of the form 'length(foo)', set 'length_param' in
4066             # the corresponding 'foo' parameter to point to that length parameter
4067             # object, or error out if foo not found.
4068 457         678 for my $param (@{$self->{kids}}) {
  457         993  
4069 756 100       1731 next unless $param->{is_length};
4070 34         73 my $name = $param->{len_name};
4071 34 100       94 if (exists $self->{names}{$name}) {
4072 33         79 $self->{names}{$name}{length_param} = $param;
4073              
4074             $pxs->blurt("Error: length() on placeholder parameter '$name'")
4075 33 100       120 unless defined $self->{names}{$name}{type};
4076              
4077             $pxs->blurt( "Error: default value for $name not allowed"
4078             . " when length($name) also present")
4079 33 100       140 if defined $self->{names}{$name}{default};
4080              
4081 33         67 my $in_out = $self->{names}{$name}{in_out};
4082 33 100 100     190 $pxs->blurt( "Error: '$in_out' modifier on '$name'"
4083             . " can't be used with length()")
4084             if defined $in_out and $in_out !~ /^IN/;
4085             }
4086             else {
4087 1         14 $pxs->blurt("Error: length() on non-parameter '$name'");
4088             }
4089             }
4090              
4091 457         1465 1;
4092             }
4093              
4094              
4095             # Return a string to be used in "usage: .." error messages.
4096              
4097             sub usage_string {
4098 429     429   848 my __PACKAGE__ $self = shift;
4099              
4100             my @args = map {
4101             $_->{var}
4102             . (defined $_->{default_usage}
4103             ?$_->{default_usage}
4104 436 100       2067 : ''
4105             )
4106             }
4107             grep {
4108             defined $_->{arg_num},
4109 725         2003 }
4110 429         751 @{$self->{kids}};
  429         1240  
4111              
4112 429 100       1279 push @args, '...' if $self->{seen_ellipsis};
4113 429         1285 return join ', ', @args;
4114             }
4115              
4116              
4117             # $self->C_func_signature():
4118             #
4119             # return two arrays
4120             # the first contains the arguments to pass to an autocall C
4121             # function, e.g. ['a', '&b', 'c'];
4122             # the second contains the types of those args, for use in declaring
4123             # a function pointer type, e.g. ['int', 'char*', 'long'].
4124              
4125             sub C_func_signature {
4126 339     339   604 my __PACKAGE__ $self = shift;
4127 339         461 my ExtUtils::ParseXS $pxs = shift;
4128              
4129 339         567 my @args;
4130             my @types;
4131 339         479 for my $param (@{$self->{kids}}) {
  339         1354  
4132             next if $param->{is_synthetic} # THIS/CLASS/RETVAL
4133             # if a synthetic RETVAL has acquired an arg_num, then
4134             # it's appeared in the signature (although without a
4135             # type) and has become semi-real.
4136 550 100 100     2827 && !($param->{var} eq 'RETVAL' && defined($param->{arg_num}));
      100        
4137              
4138 349 100       915 if ($param->{var} eq 'SV *') {
4139             #backcompat placeholder
4140 1         14 $pxs->blurt("Error: parameter 'SV *' not valid as a C argument");
4141 1         6 next;
4142             }
4143              
4144 348         594 my $io = $param->{in_out};
4145 348 100       862 $io = '' unless defined $io;
4146              
4147             # Ignore fake/alien stuff, except an OUTLIST arg, which
4148             # isn't passed from perl (so no arg_num), but *is* passed to
4149             # the C function and then back to perl.
4150             next unless defined $param->{arg_num}
4151             or $io eq 'OUTLIST'
4152 348 100 100     1303 or $param->{is_length};
      100        
4153              
4154 333         558 my $a = $param->{var};
4155 333 100 100     1623 $a = "&$a" if $param->{is_addr} or $io =~ /OUT/;
4156 333         723 push @args, $a;
4157 333         568 my $t = $param->{type};
4158 333 100       965 push @types, defined $t ? $t : 'void*';
4159             }
4160              
4161 339         1111 return \@args, \@types;
4162             }
4163              
4164              
4165             # $self->proto_string():
4166             #
4167             # return a string containing the perl prototype string for this XSUB,
4168             # e.g. '$$;$$@'.
4169              
4170             sub proto_string {
4171 35     35   58 my __PACKAGE__ $self = shift;
4172              
4173             # Generate a prototype entry for each param that's bound to a real
4174             # arg. Use '$' unless the typemap for that param has specified an
4175             # overridden entry.
4176             my @p = map defined $_->{proto} ? $_->{proto} : '$',
4177             grep defined $_->{arg_num} && $_->{arg_num} > 0,
4178 35 100 66     63 @{$self->{kids}};
  35         336  
4179              
4180 35         71 my @sep = (';'); # separator between required and optional args
4181 35         53 my $min = $self->{min_args};
4182 35 100       86 if ($min < $self->{nargs}) {
4183             # has some default vals
4184 8         21 splice (@p, $min, 0, ';');
4185 8         25 @sep = (); # separator already added
4186             }
4187 35 100       87 push @p, @sep, '@' if $self->{seen_ellipsis}; # '...'
4188 35         98 return join '', @p;
4189             }
4190              
4191              
4192             # ======================================================================
4193              
4194             package ExtUtils::ParseXS::Node::xbody;
4195              
4196             # This node holds all the foo_part nodes which make up the body of an
4197             # XSUB. Note that in the presence of CASE: keywords, an XSUB may have
4198             # multiple xbodys, one per CASE.
4199             # This node doesn't contain the signature, and nor is it responsible
4200             # for emitting the code for the closing part of an XSUB e.g. the
4201             # XSRETURN(N); there is only one of those per XSUB, so is handled by a
4202             # higher-level node.
4203              
4204 28     28   139 BEGIN { $build_subclass->(
4205             'ioparams', # Params object: per-body copy of params which accumulate
4206             # extra info from any INPUT and OUTPUT sections (which can
4207             # vary between different CASEs)
4208              
4209             # Node objects representing the various parts of an xbody. These
4210             # are aliases of the same objects in @{$self->{kids}} for easier
4211             # access.
4212             'input_part',
4213             'init_part',
4214             'code_part',
4215             'output_part',
4216             'cleanup_part',
4217              
4218             # Misc parse state
4219              
4220             'seen_RETVAL_in_CODE', # Bool: have seen 'RETVAL' within a CODE block
4221             'seen_autocall', # Bool: this xbody has an autocall node
4222             'OUTPUT_SETMAGIC_state', # Bool: most recent value of SETMAGIC in an
4223             # OUTPUT section.
4224              
4225             )};
4226              
4227              
4228             sub parse {
4229 481     481   837 my __PACKAGE__ $self = shift;
4230 481         783 my ExtUtils::ParseXS $pxs = shift;
4231 481         691 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4232              
4233 481         1516 $self->SUPER::parse($pxs); # set file/line_no
4234              
4235             {
4236             # Make a per-xbody copy of the Params object, which will
4237             # accumulate any extra info from (per-CASE) INPUT and OUTPUT
4238             # sections.
4239              
4240 481         695 my $orig = $xsub->{decl}{params};
  481         1022  
4241              
4242             # make a shallow copy
4243 481         1296 my $ioparams = ExtUtils::ParseXS::Node::Params->new($orig);
4244              
4245             # now duplicate (deep copy) any Param objects and regenerate a new
4246             # names-mapping hash
4247              
4248 481         1216 $ioparams->{kids} = [];
4249 481         916 $ioparams->{names} = {};
4250              
4251 481         875 for my $op (@{$orig->{kids}}) {
  481         2520  
4252 789         3742 my $p = ExtUtils::ParseXS::Node::IO_Param->new($op);
4253             # don't copy the current proto state (from the most recent
4254             # CASE) into the new CASE.
4255 789         1509 undef $p->{proto};
4256 789         1185 push @{$ioparams->{kids}}, $p;
  789         1771  
4257 789         2514 $ioparams->{names}{$p->{var}} = $p;
4258             }
4259              
4260 481         1126 $self->{ioparams} = $ioparams;
4261             }
4262              
4263             # by default, OUTPUT entries have SETMAGIC: ENABLE
4264 481         1007 $self->{OUTPUT_SETMAGIC_state} = 1;
4265              
4266 481         1067 for my $part (qw(input_part init_part code_part output_part cleanup_part)) {
4267 2355         22468 my $kid = "ExtUtils::ParseXS::Node::$part"->new();
4268 2355 50       8074 if ($kid->parse($pxs, $xsub, $self)) {
4269 2342         2970 push @{$self->{kids}}, $kid;
  2342         4510  
4270 2342         5523 $self->{$part} = $kid;
4271             }
4272             }
4273              
4274 468         1302 1;
4275             }
4276              
4277              
4278             sub as_code {
4279 457     457   746 my __PACKAGE__ $self = shift;
4280 457         677 my ExtUtils::ParseXS $pxs = shift;
4281 457         655 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4282              
4283             # Emit opening brace. With cmd-line switch "-except", prefix it with 'TRY'
4284 457 50       2582 print +($pxs->{config_allow_exceptions} ? ' TRY' : '')
4285             . " $open_brace\n";
4286              
4287 457 50       2687 if ($self->{kids}) {
4288 457         987 $_->as_code($pxs, $xsub, $self) for @{$self->{kids}};
  457         2139  
4289             }
4290              
4291             # ----------------------------------------------------------------
4292             # Emit trailers for the body of the XSUB
4293             # ----------------------------------------------------------------
4294              
4295 457 100       1359 if ($xsub->{SCOPE_enabled}) {
4296             # the matching opens were emitted in input_part->as_code()
4297 4         16 print " $close_brace\n";
4298             # PPCODE->as_code emits its own LEAVE and return, so this
4299             # line would never be reached.
4300 4 50       40 print " LEAVE;\n" unless $xsub->{seen_PPCODE};
4301             }
4302              
4303             # matches the $open_brace at the start of this function
4304 457         1691 print " $close_brace\n";
4305              
4306 457 50       3407 print $self->Q(<<"EOF") if $pxs->{config_allow_exceptions};
4307             | BEGHANDLERS
4308             | CATCHALL
4309             | sprintf(errbuf, "%s: %s\\tpropagated", Xname, Xreason);
4310             | ENDHANDLERS
4311             EOF
4312              
4313             }
4314              
4315              
4316             # ======================================================================
4317              
4318             package ExtUtils::ParseXS::Node::input_part;
4319              
4320 28     28   188 BEGIN { $build_subclass->(
4321              
4322             # Str: used during code generation:
4323             # a multi-line string containing lines of code to be emitted *after*
4324             # all INPUT and PREINIT keywords have been processed.
4325             'deferred_code_lines',
4326             )};
4327              
4328              
4329             sub parse {
4330 481     481   806 my __PACKAGE__ $self = shift;
4331 481         834 my ExtUtils::ParseXS $pxs = shift;
4332 481         694 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4333 481         715 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4334              
4335 481         1498 $self->SUPER::parse($pxs); # set file/line_no
4336              
4337             # Process any implicit INPUT section.
4338             {
4339 481         734 my $input = ExtUtils::ParseXS::Node::INPUT->new();
  481         4079  
4340 481 100 66     3850 if ( $input->parse($pxs, $xsub, $xbody)
      66        
4341             && $input->{kids}
4342 99         284 && @{$input->{kids}})
4343             {
4344 99         175 $input->{implicit} = 1;
4345 99         133 push @{$self->{kids}}, $input;
  99         240  
4346             }
4347             }
4348              
4349             # Repeatedly look for INPUT or similar or generic keywords,
4350             # parse the text following them, and add any resultant nodes
4351             # as kids to the current node.
4352             $self->parse_keywords(
4353 476         2247 $pxs, $xsub, $xbody,
4354             undef, # implies process as many keywords as possible
4355              
4356             "C_ARGS|INPUT|INTERFACE_MACRO|PREINIT|SCOPE|"
4357             . $ExtUtils::ParseXS::Constants::generic_xsub_keywords_alt,
4358             );
4359              
4360             # For each param, look up its INPUT typemap information now (at parse
4361             # time) and save the results for use later in as_input_code().
4362              
4363 471         836 for my $ioparam (@{$xbody->{ioparams}{kids}}) {
  471         2455  
4364             # might be placeholder param which doesn't get emitted
4365 787 100       2100 next unless defined $ioparam->{type};
4366             $ioparam->{input_typemap_vals} =
4367 750         3127 [ $ioparam->lookup_input_typemap($pxs, $xsub, $xbody) ];
4368             }
4369              
4370             # Now that the type of each param is finalised, calculate its
4371             # overridden prototype character, if any.
4372             #
4373             # Note that the type of a param can change during parsing, so when to
4374             # call this method is significant. In particular:
4375             # - THIS's type may be set provisionally based on the XSUB's package,
4376             # then updated if it appears as a parameter or on an INPUT line.
4377             # - typemaps can be overridden using the TYPEMAP keyword, so
4378             # it's possible the typemap->proto() method will return something
4379             # different by the time the proto field is used to emit boot code.
4380             # - params can have different types (and thus typemap entries and
4381             # proto chars) per CASE branch.
4382             # So we calculate the per-case/xbody params' proto values here, and
4383             # also use that value to update the per-XSUB value, warning if the
4384             # value changes.
4385              
4386 469         818 for my $ioparam (@{$xbody->{ioparams}{kids}}) {
  469         1180  
4387 784         2365 $ioparam->set_proto($pxs);
4388 784         1333 my $ioproto = $ioparam->{proto};
4389 784         1312 my $name = $ioparam->{var};
4390 784 50       1423 next unless defined $name;
4391 784 100       1804 next unless $ioparam->{arg_num};
4392              
4393 456         1180 my $param = $$xsub{decl}{params}{names}{$name};
4394 456         744 my $proto = $param->{proto};
4395 456 100       1274 $ioproto = '$' unless defined $ioproto;
4396 456 100 100     1146 if (defined $proto and $proto ne $ioproto) {
4397 2         33 $pxs->Warn("Warning: prototype for '$name' varies: '$proto' versus '$ioproto'");
4398             }
4399 456         1090 $param->{proto} = $ioproto;
4400             }
4401              
4402 469         1320 1;
4403             }
4404              
4405              
4406             sub as_code {
4407 457     457   740 my __PACKAGE__ $self = shift;
4408 457         686 my ExtUtils::ParseXS $pxs = shift;
4409 457         808 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4410 457         611 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4411              
4412 457         804 my $ioparams = $xbody->{ioparams};
4413              
4414             # Lines to be emitted after PREINIT/INPUT. This may get populated
4415             # by the as_code() methods we call of our kids.
4416 457         1778 $self->{deferred_code_lines} = "";
4417              
4418 457 100       1210 if ($self->{kids}) {
4419 153         219 $_->as_code($pxs, $xsub, $xbody) for @{$self->{kids}};
  153         938  
4420             }
4421              
4422             # The matching closes will be emitted in xbody->as_code()
4423 457 100       1352 print $self->Q(<<"EOF") if $xsub->{SCOPE_enabled};
4424             | ENTER;
4425             | $open_brace
4426             EOF
4427              
4428             # Emit any 'char * CLASS' or 'Foo::Bar *THIS' declaration if needed
4429              
4430 457         744 for my $ioparam (grep $_->{is_synthetic}, @{$ioparams->{kids}}) {
  457         2409  
4431 261         1341 $ioparam->as_input_code($pxs, $xsub, $xbody);
4432             }
4433              
4434             # Recent code emits a dXSTARG in a tighter scope and under
4435             # additional circumstances, but some XS code relies on TARG
4436             # having been declared. So continue to declare it early under
4437             # the original circumstances.
4438 457 100       1707 if ($xsub->{decl}{return_type}{use_early_targ}) {
4439 214         448 print "\tdXSTARG;\n";
4440             }
4441              
4442             # Emit declaration/init code for any parameters which were
4443             # declared with a type in the signature (rather than in INPUT).
4444              
4445 457         1825 for my $ioparam (grep $_->{is_ansi}, @{$ioparams->{kids}}) {
  457         1632  
4446 352         1250 $ioparam->as_input_code($pxs, $xsub, $xbody);
4447             }
4448              
4449             # ----------------------------------------------------------------
4450             # All C variable declarations have now been emitted. It's now time
4451             # to emit any code which goes before the main body (i.e. the CODE:
4452             # etc or the implicit call to the wrapped function).
4453             # ----------------------------------------------------------------
4454              
4455             # Emit any code which has been deferred until all declarations
4456             # have been done. This is typically INPUT typemaps which don't
4457             # start with a simple '$var =' and so would not have been emitted
4458             # at the variable declaration stage.
4459 457         1237 print $self->{deferred_code_lines};
4460             }
4461              
4462              
4463             # ======================================================================
4464              
4465             package ExtUtils::ParseXS::Node::init_part;
4466              
4467 28     28   128 BEGIN { $build_subclass->(
4468             )};
4469              
4470              
4471             sub parse {
4472 469     469   792 my __PACKAGE__ $self = shift;
4473 469         701 my ExtUtils::ParseXS $pxs = shift;
4474 469         661 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4475 469         684 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4476              
4477 469         1439 $self->SUPER::parse($pxs); # set file/line_no
4478              
4479             # Repeatedly look for INIT or generic keywords,
4480             # parse the text following them, and add any resultant nodes
4481             # as kids to the current node.
4482 469         1858 $self->parse_keywords(
4483             $pxs, $xsub, $xbody,
4484             undef, # implies process as many keywords as possible
4485              
4486             "C_ARGS|INIT|INTERFACE|INTERFACE_MACRO|"
4487             . $ExtUtils::ParseXS::Constants::generic_xsub_keywords_alt,
4488             );
4489              
4490 469         996 1;
4491             }
4492              
4493              
4494             sub as_code {
4495 457     457   1218 my __PACKAGE__ $self = shift;
4496 457         652 my ExtUtils::ParseXS $pxs = shift;
4497 457         648 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4498 457         654 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4499              
4500 457 100       1892 if ($self->{kids}) {
4501 22         42 $_->as_code($pxs, $xsub, $xbody) for @{$self->{kids}};
  22         155  
4502             }
4503             }
4504              
4505              
4506             # ======================================================================
4507              
4508             package ExtUtils::ParseXS::Node::code_part;
4509              
4510 28     28   104 BEGIN { $build_subclass->(
4511             )};
4512              
4513              
4514             sub parse {
4515 469     469   807 my __PACKAGE__ $self = shift;
4516 469         769 my ExtUtils::ParseXS $pxs = shift;
4517 469         718 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4518 469         765 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4519              
4520 469         1283 $self->SUPER::parse($pxs); # set file/line_no
4521              
4522             # Look for a CODE/PPCODE/NOT_IMPLEMENTED_YET keyword; if found, add
4523             # the kid to the current node.
4524 469 100       1538 return 1 if $self->parse_keywords(
4525             $pxs, $xsub, $xbody,
4526             1, # match at most one keyword
4527             "CODE|PPCODE",
4528             $keywords_flag_NOT_IMPLEMENTED_YET,
4529             );
4530              
4531             # Didn't find a CODE keyword or similar, so auto-generate a call
4532             # to the same-named C library function.
4533              
4534 357         2666 my $autocall = ExtUtils::ParseXS::Node::autocall->new();
4535             # mainly a NOOP, but sets line number etc and flags that autocall seen
4536 357 50       2084 $autocall->parse($pxs, $xsub, $xbody)
4537             or return;
4538 357         557 push @{$self->{kids}}, $autocall;
  357         895  
4539              
4540 357         807 1;
4541             }
4542              
4543              
4544             sub as_code {
4545 457     457   779 my __PACKAGE__ $self = shift;
4546 457         635 my ExtUtils::ParseXS $pxs = shift;
4547 457         717 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4548 457         643 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4549              
4550 457 50       1064 if ($self->{kids}) {
4551 457         651 $_->as_code($pxs, $xsub, $xbody) for @{$self->{kids}};
  457         2679  
4552             }
4553             }
4554              
4555              
4556             # ======================================================================
4557              
4558             package ExtUtils::ParseXS::Node::output_part;
4559              
4560 28     28   106 BEGIN { $build_subclass->(
4561              
4562             # State during code emitting
4563              
4564             'targ_used', # Bool: the TARG has been allocated for this body,
4565             # so is no longer available for use.
4566              
4567             'stack_was_reset', # Bool: An XSprePUSH was emitted, so return values
4568             # should be PUSHed rather than just set.
4569             )};
4570              
4571              
4572             sub parse {
4573 468     468   879 my __PACKAGE__ $self = shift;
4574 468         691 my ExtUtils::ParseXS $pxs = shift;
4575 468         714 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4576 468         712 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4577              
4578 468         1414 $self->SUPER::parse($pxs); # set file/line_no
4579              
4580             # Repeatedly look for POSTCALL, OUTPUT or generic keywords,
4581             # parse the text following them, and add any resultant nodes
4582             # as kids to the current node.
4583             # XXX POSTCALL is documented to precede OUTPUT, but here we allow
4584             # them in any order and multiplicity.
4585 468         2053 $self->parse_keywords(
4586             $pxs, $xsub, $xbody,
4587             undef, # implies process as many keywords as possible
4588             "POSTCALL|OUTPUT|"
4589             . $ExtUtils::ParseXS::Constants::generic_xsub_keywords_alt,
4590             );
4591              
4592             # Work out whether a RETVAL SV will be returned. Note that this should
4593             # be consistent across CASEs; we warn elsewhere if CODE_sets_ST0 isn't
4594             # consistent.
4595              
4596             $xsub->{XSRETURN_count_basic} =
4597             ( $xsub->{CODE_sets_ST0}
4598             or ( $xsub->{decl}{return_type}{type} ne "void"
4599             && !$xsub->{decl}{return_type}{no_output})
4600 468 100 100     4893 )
4601             ? 1 : 0;
4602              
4603             # For each param, look up its OUTPUT typemap information now (at parse
4604             # time) and save the results for use later in as_output_code_().
4605              
4606 468         851 for my $ioparam (@{$xbody->{ioparams}{kids}}) {
  468         2287  
4607             # might be placeholder param which doesn't get emitted
4608             # XXXX next unless defined $ioparam->{type};
4609              
4610             next unless
4611             # XXX simplify all this
4612             ( defined $ioparam->{in_out}
4613             && $ioparam->{in_out} =~ /OUT$/
4614             && !$ioparam->{in_output}
4615             )
4616             ||
4617              
4618             (
4619             $ioparam->{var} eq "RETVAL"
4620             && ( $ioparam->{in_output}
4621             or ( $xbody->{seen_autocall}
4622             && $xsub->{decl}{return_type}{type} ne "void"
4623             && !$xsub->{decl}{return_type}{no_output}
4624             )
4625             )
4626             )
4627             ||
4628             (
4629             $ioparam->{in_output}
4630 783 100 100     8373 && $ioparam->{var} ne 'RETVAL'
      66        
      100        
      100        
      100        
      66        
      100        
4631             )
4632             ;
4633              
4634             $ioparam->{output_typemap_vals} =
4635 269         1207 [ $ioparam->lookup_output_typemap($pxs, $xsub, $xbody) ];
4636             }
4637              
4638 468         942 my $out_num = $xsub->{XSRETURN_count_basic};
4639              
4640 468         715 for my $ioparam (@{$xbody->{ioparams}{kids}}) {
  468         1124  
4641             next unless defined $ioparam->{in_out}
4642 783 100 100     2275 && $ioparam->{in_out} =~ /OUTLIST$/;
4643             $ioparam->{output_typemap_vals_outlist} =
4644 48         288 [ $ioparam->lookup_output_typemap($pxs, $xsub, $xbody, $out_num++) ];
4645             }
4646              
4647 468         1107 1;
4648             }
4649              
4650              
4651             sub as_code {
4652 457     457   3974 my __PACKAGE__ $self = shift;
4653 457         908 my ExtUtils::ParseXS $pxs = shift;
4654 457         625 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4655 457         591 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4656              
4657             # TARG is available for use within this body.
4658 457         1093 $self->{targ_used} = 0;
4659              
4660             # SP still pointing at top arg
4661 457         933 $self->{stack_was_reset} = 0;
4662              
4663 457 100       1188 if ($self->{kids}) {
4664 70         96 $_->as_code($pxs, $xsub, $xbody) for @{$self->{kids}};
  70         404  
4665             }
4666              
4667 457         1247 my $ioparams = $xbody->{ioparams};
4668              
4669 457         1068 my $retval = $ioparams->{names}{RETVAL};
4670              
4671             # A CODE section using RETVAL must also have an OUTPUT entry
4672 457 100 100     1938 if ( $xbody->{seen_RETVAL_in_CODE}
      100        
      100        
4673             and not ($retval && $retval->{in_output})
4674             and $xsub->{decl}{return_type}{type} ne 'void')
4675             {
4676 3         37 $pxs->Warn( "Warning: found a 'CODE' section which seems to be "
4677             . "using 'RETVAL' but no 'OUTPUT' section.");
4678             }
4679              
4680             # Process any OUT vars: i.e. vars that are declared OUT in
4681             # the XSUB's signature rather than in an OUTPUT section.
4682              
4683 457         736 for my $param (
4684             grep {
4685             defined $_->{in_out}
4686             && $_->{in_out} =~ /OUT$/
4687             && !$_->{in_output}
4688 772 100 100     3571 }
4689 457         1117 @{$ioparams->{kids}})
4690             {
4691 17         75 $param->as_output_code($pxs, $xsub, $xbody);
4692             }
4693              
4694 457         961 my $basic = $xsub->{XSRETURN_count_basic};
4695 457         878 my $extra = $xsub->{XSRETURN_count_extra};
4696              
4697 457 100       1045 if ($extra) {
4698             # If there are any OUTLIST vars to be returned, we reset SP to
4699             # the base of the stack frame and then PUSH any return values.
4700 39         135 print "\tXSprePUSH;\n";
4701 39         280 $self->{stack_was_reset} = 1;
4702             }
4703              
4704             # Extend the stack if we're going to return more values than were
4705             # passed to us: which would consist of the GV or CV on the stack
4706             # plus at least min_args at the time ENTERSUB was called.
4707              
4708 457         905 my $n = $basic + $extra;
4709             print "\tEXTEND(SP,$n);\n"
4710 457 100       1304 if $n > $ioparams->{min_args} + 1;
4711              
4712             # All OUTPUT done; now handle an implicit or deferred RETVAL:
4713             # - OUTPUT_line::as_code() will have skipped/deferred any RETVAL line,
4714             # - non-void CODE-less XSUBs have an implicit 'OUTPUT: RETVAL'
4715              
4716 457 100 100     5334 if ( ($retval && $retval->{in_output})
      100        
      100        
      100        
4717             or ( $xbody->{seen_autocall}
4718             && $xsub->{decl}{return_type}{type} ne "void"
4719             && !$xsub->{decl}{return_type}{no_output}
4720             )
4721             )
4722             {
4723             # emit a deferred RETVAL from OUTPUT or implicit RETVAL
4724 219         931 $retval->as_output_code($pxs, $xsub, $xbody);
4725             }
4726              
4727             # Now that RETVAL is on the stack, also push any OUTLIST vars too
4728 457         897 for my $param (grep { defined $_->{in_out}
4729 772 100       3589 && $_->{in_out} =~ /OUTLIST$/
4730             }
4731 457         1241 @{$ioparams->{kids}}
4732             ) {
4733 48         248 $param->as_output_code($pxs, $xsub, $xbody, $basic++);
4734             }
4735             }
4736              
4737              
4738             # ======================================================================
4739              
4740             package ExtUtils::ParseXS::Node::cleanup_part;
4741              
4742 28     28   125 BEGIN { $build_subclass->(
4743             )};
4744              
4745              
4746             sub parse {
4747 468     468   761 my __PACKAGE__ $self = shift;
4748 468         728 my ExtUtils::ParseXS $pxs = shift;
4749 468         778 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4750 468         695 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4751              
4752 468         1484 $self->SUPER::parse($pxs); # set file/line_no
4753              
4754             # Repeatedly look for CLEANUP or generic keywords,
4755             # parse the text following them, and add any resultant nodes
4756             # as kids to the current node.
4757 468         2107 $self->parse_keywords(
4758             $pxs, $xsub, $xbody,
4759             undef, # implies process as many keywords as possible
4760             "CLEANUP|"
4761             . $ExtUtils::ParseXS::Constants::generic_xsub_keywords_alt,
4762             );
4763              
4764 468         1030 1;
4765             }
4766              
4767              
4768             sub as_code {
4769 457     457   1119 my __PACKAGE__ $self = shift;
4770 457         678 my ExtUtils::ParseXS $pxs = shift;
4771 457         770 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4772 457         589 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4773              
4774 457 100       1405 if ($self->{kids}) {
4775 4         13 $_->as_code($pxs, $xsub, $xbody) for @{$self->{kids}};
  4         34  
4776             }
4777             }
4778              
4779              
4780             # ======================================================================
4781              
4782             package ExtUtils::ParseXS::Node::oneline;
4783              
4784             # Generic base class for keyword Nodes which consume only a single source
4785             # line, such as 'SCOPE: ENABLE'.
4786             # On entry, $self->lines[0] will be any text (on the same line) which
4787             # follows the keyword.
4788              
4789 28     28   117 BEGIN { $build_subclass->(
4790             'text', # Str: any text following the keyword
4791             )};
4792              
4793              
4794             sub parse {
4795 963     963   2022 my __PACKAGE__ $self = shift;
4796 963         1440 my ExtUtils::ParseXS $pxs = shift;
4797              
4798 963         2523 $self->SUPER::parse($pxs); # set file/line_no
4799 963         1247 my $s = shift @{$pxs->{line}};
  963         1919  
4800 963         3915 ExtUtils::ParseXS::Utilities::trim_whitespace($s);
4801 963         2121 $self->{text} = $s;
4802 963         1450 1;
4803             }
4804              
4805              
4806             # ======================================================================
4807              
4808             package ExtUtils::ParseXS::Node::MODULE;
4809              
4810             # Process a MODULE keyword, e.g.
4811             #
4812             # MODULE = Foo PACKAGE = Foo::Bar PREFIX = foo_
4813              
4814 28     28   132 BEGIN { $build_subclass->(-parent => 'oneline',
4815             'module', # Str
4816             'package', # Str: may be ''
4817             'prefix', # Str: may be ''
4818             )};
4819              
4820              
4821             sub parse {
4822 440     440   876 my __PACKAGE__ $self = shift;
4823 440         771 my ExtUtils::ParseXS $pxs = shift;
4824              
4825 440         2867 $self->SUPER::parse($pxs); # set file/line_no
4826              
4827 440         960 my $line = $self->{text};
4828 440 100       7338 my ($module, $pkg, $prefix) = $line =~
4829             /^
4830             MODULE \s* = \s* ([\w:]+)
4831             (?: \s+ PACKAGE \s* = \s* ([\w:]+))?
4832             (?: \s+ PREFIX \s* = \s* (\S+))?
4833             \s*
4834             $/x
4835             or $pxs->death("Error: unparseable MODULE line: '$line'");
4836              
4837 436         1283 $self->{module} = $module;
4838 436         1766 ($pxs->{MODULE_cname} = $module) =~ s/\W/_/g;
4839              
4840 436 50       1846 $self->{package} = $pxs->{PACKAGE_name} = defined($pkg) ? $pkg : '';
4841              
4842 436 100       2282 $self->{prefix} = $prefix = defined($prefix) ? $prefix : '';
4843 436         1434 $pxs->{PREFIX_pattern} = quotemeta($prefix);
4844              
4845 436         1796 ($pxs->{PACKAGE_C_name} = $pxs->{PACKAGE_name}) =~ tr/:/_/;
4846              
4847 436         1166 $pxs->{PACKAGE_class} = $pxs->{PACKAGE_name};
4848 436 50       1789 $pxs->{PACKAGE_class} .= "::" if $pxs->{PACKAGE_class} ne "";
4849              
4850 436         1249 1;
4851             }
4852              
4853              
4854             # ======================================================================
4855              
4856             package ExtUtils::ParseXS::Node::NOT_IMPLEMENTED_YET;
4857              
4858             # Handle NOT_IMPLEMENTED_YET pseudo-keyword
4859              
4860 28     28   129 BEGIN { $build_subclass->(-parent => 'oneline',
4861             )};
4862              
4863             sub as_code {
4864 2     2   6 my __PACKAGE__ $self = shift;
4865 2         3 my ExtUtils::ParseXS $pxs = shift;
4866 2         7 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4867              
4868 2         7 print "\n"
4869             . "\tPerl_croak(aTHX_ \"$xsub->{decl}{full_perl_name}: "
4870             . "not implemented yet\");\n";
4871             }
4872              
4873              
4874             # ======================================================================
4875              
4876             package ExtUtils::ParseXS::Node::CASE;
4877              
4878             # Process the 'CASE:' keyword
4879              
4880 28     28   125 BEGIN { $build_subclass->(-parent => 'oneline',
4881             'cond', # Str: the C code of the condition for the CASE, or ''
4882             'num', # Int: which CASE number this is (starting at 1)
4883             )};
4884              
4885              
4886             sub parse {
4887 41     41   86 my __PACKAGE__ $self = shift;
4888 41         85 my ExtUtils::ParseXS $pxs = shift;
4889              
4890 41         162 $self->SUPER::parse($pxs); # set file/line_no/text
4891 41         91 $self->{cond} = $self->{text};
4892             # Note that setting num, and consistency checking (like "else"
4893             # without "if") is done by the caller, Node::xsub.
4894 41         99 1;
4895             }
4896              
4897              
4898             sub as_code {
4899 40     40   64 my __PACKAGE__ $self = shift;
4900 40         53 my ExtUtils::ParseXS $pxs = shift;
4901 40         61 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4902              
4903 40         80 my $cond = $self->{cond};
4904 40 100       4762 $cond = " if ($cond)" if length $cond;
4905 40 100       155 print " ", ($self->{num} > 1 ? " else" : ""), $cond, "\n";
4906 40         220 $_->as_code($pxs, $xsub) for @{$self->{kids}};
  40         141  
4907             }
4908              
4909              
4910             # ======================================================================
4911              
4912             package ExtUtils::ParseXS::Node::autocall;
4913              
4914             # Handle an empty XSUB body (i.e. no CODE or PPCODE)
4915             # by auto-generating a call to a C library function of the same
4916             # name
4917              
4918 28     28   116 BEGIN { $build_subclass->(
4919             'args', # Str: text to use for auto function call arguments
4920             'types', # Str: text to use for auto function type declaration
4921             )};
4922              
4923              
4924             sub parse {
4925 357     357   895 my __PACKAGE__ $self = shift;
4926 357         570 my ExtUtils::ParseXS $pxs = shift;
4927 357         472 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4928 357         536 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4929              
4930 357         1101 $self->SUPER::parse($pxs); # set file/line_no
4931              
4932 357         812 $xbody->{seen_autocall} = 1;
4933              
4934 357         840 my $ioparams = $xbody->{ioparams};
4935 357         574 my ($args, $types);
4936 357         704 $args = $ioparams->{auto_function_sig_override}; # C_ARGS
4937 357 100       858 if (defined $args) {
4938             # Try to determine the C_ARGS types; for example, with
4939             #
4940             # foo(short s, int i, long l)
4941             # C_ARGS: s, l
4942             #
4943             # set $types to ['short', 'long']. May give the wrong results if
4944             # C_ARGS isn't just a simple list of parameter names
4945 18         129 for my $var (split /,/, $args) {
4946 37         147 $var =~ s/^\s+//;
4947 37         76 $var =~ s/\s+$//;
4948 37         70 my $param = $ioparams->{names}{$var};
4949             # 'void*' is a desperate guess if no such parameter
4950             push @$types, ($param && defined $param->{type})
4951 37 100 66     216 ? $param->{type} : 'void*';
4952             }
4953 18         59 $self->{args} = $args;
4954             }
4955             else {
4956 339         1319 ($args, $types) = $ioparams->C_func_signature($pxs);
4957 339         1467 $self->{args} = join ', ', @$args;
4958             }
4959              
4960 357 50       939 unless ($pxs->{config_RetainCplusplusHierarchicalTypes}) {
4961 357         1317 s/:/_/g for @$types;
4962             }
4963 357         1012 $self->{types} = join ', ', @$types;
4964              
4965 357         1156 1;
4966             }
4967              
4968              
4969             sub as_code {
4970 347     347   723 my __PACKAGE__ $self = shift;
4971 347         493 my ExtUtils::ParseXS $pxs = shift;
4972 347         458 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
4973 347         635 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
4974              
4975 347         897 my $class = $xsub->{decl}{class};
4976 347         746 my $name = $xsub->{decl}{name};
4977              
4978 347 100 100     1283 if ( defined $class
4979             and $name eq "DESTROY")
4980             {
4981             # Emit a default body for a C++ DESTROY method: "delete THIS;"
4982 1         5 print "\n\t";
4983 1         10 print "delete THIS;\n";
4984              
4985             }
4986             else {
4987             # Emit a default body: this will be a call to the function being
4988             # wrapped. Typically:
4989             # RETVAL = foo(args);
4990             # with the function name being appropriately modified when it's
4991             # a C++ new() method etc.
4992              
4993 346         770 print "\n\t";
4994              
4995 346         2614 my $ret_type = $xsub->{decl}{return_type}{type};
4996 346 100       1139 if ($ret_type ne "void") {
4997 183         359 print "RETVAL = ";
4998             }
4999              
5000 346 100       756 if (defined $class) {
5001 26 100       78 if ($xsub->{decl}{return_type}{static}) {
5002             # it has a return type of 'static foo'
5003 4 100       19 if ($name eq 'new') {
5004 2         10 $name = "$class";
5005             }
5006             else {
5007 2         15 print "${class}::";
5008             }
5009             }
5010             else {
5011 22 100       66 if ($name eq 'new') {
5012 7         17 $name .= " $class";
5013             }
5014             else {
5015 15         51 print "THIS->";
5016             }
5017             }
5018             }
5019              
5020             # Handle "xsubpp -s=strip_prefix" hack
5021 346         713 my $strip = $pxs->{config_strip_c_func_prefix};
5022 346 50       845 $name =~ s/^\Q$strip//
5023             if defined $strip;
5024              
5025 346 100 66     2854 if ( $xsub->{seen_INTERFACE}
5026             or $xsub->{seen_INTERFACE_MACRO})
5027             {
5028             $ret_type =~ s/:/_/g
5029 16 50       117 unless $pxs->{config_RetainCplusplusHierarchicalTypes};
5030 16         46 $name = "(($ret_type (*)($self->{types}))(XSFUNCTION))";
5031             }
5032              
5033 346         1571 print "$name($self->{args});\n";
5034              
5035             }
5036             }
5037              
5038              
5039             # ======================================================================
5040              
5041             package ExtUtils::ParseXS::Node::FALLBACK;
5042              
5043             # Process the 'FALLBACK' keyword.
5044             # Its main effect is to update $pxs->{map_package_to_fallback_string} with
5045             # the fallback value for the current package. That is later used to plant
5046             # boot code to set ${package}::() to a true/false/undef value.
5047              
5048 28     28   154 BEGIN { $build_subclass->(-parent => 'oneline',
5049             'value', # Str: TRUE, FALSE or UNDEF
5050             )};
5051              
5052              
5053             sub parse {
5054 9     9   23 my __PACKAGE__ $self = shift;
5055 9         16 my ExtUtils::ParseXS $pxs = shift;
5056              
5057 9         38 $self->SUPER::parse($pxs); # set file/line_no/text
5058              
5059             # The rest of the current line should contain either TRUE,
5060             # FALSE or UNDEF, but we also secretly allow 0 or 1 and lower/mixed
5061             # case.
5062              
5063 9         23 my $s = $self->{text};
5064              
5065 9 50       27 $s = 'TRUE' if $s eq '1';
5066 9 50       25 $s = 'FALSE' if $s eq '0';
5067 9         23 $s = uc($s);
5068              
5069 9 100       87 $pxs->death("Error: FALLBACK: invalid value '$s' (should be TRUE/FALSE/UNDEF)")
5070             unless $s =~ /^(TRUE|FALSE|UNDEF)$/;
5071              
5072 8         23 $self->{value} = $s;
5073              
5074             # Only one FALLBACK allowed per package
5075              
5076             $pxs->Warn("Warning: duplicate FALLBACK: entry")
5077 8 100       42 if exists $pxs->{map_package_to_fallback_string}{$pxs->{PACKAGE_name}};
5078              
5079 8         32 $pxs->{map_package_to_fallback_string}{$pxs->{PACKAGE_name}} = $s;
5080              
5081 8         18 1;
5082             }
5083              
5084              
5085             # ======================================================================
5086              
5087             package ExtUtils::ParseXS::Node::REQUIRE;
5088              
5089             # Process the 'REQUIRE' keyword.
5090              
5091 28     28   147 BEGIN { $build_subclass->(-parent => 'oneline',
5092             'version', # Str: the minimum version allowed, e.g.'1.23'
5093             )};
5094              
5095              
5096             sub parse {
5097 7     7   18 my __PACKAGE__ $self = shift;
5098 7         18 my ExtUtils::ParseXS $pxs = shift;
5099              
5100 7         31 $self->SUPER::parse($pxs); # set file/line_no/text
5101              
5102 7         14 my $ver = $self->{text};
5103              
5104 7 100       33 $pxs->death("Error: REQUIRE expects a version number")
5105             unless length $ver;
5106              
5107             # check that the version number is of the form n.n
5108 6 100       70 $pxs->death("Error: REQUIRE: expected a MMM(.NNN) number, got '$ver'")
5109             unless $ver =~ /^\d+(\.\d*)?$/;
5110              
5111 4         31 my $got = $ExtUtils::ParseXS::VERSION;
5112 4 100       51 $pxs->death("Error: xsubpp $ver (or better) required--this is only $got.")
5113             unless $got >= $ver;
5114              
5115 3         6 $self->{version} = $ver;
5116              
5117 3         12 1;
5118             }
5119              
5120              
5121             # ======================================================================
5122              
5123             package ExtUtils::ParseXS::Node::include;
5124              
5125             # Common base class for the 'INCLUDE' and 'INCLUDE_COMMAND' keywords
5126              
5127 28     28   250 BEGIN { $build_subclass->(-parent => 'oneline',
5128             'is_cmd', # Bool: is INCLUDE_COMMAND
5129             'inc_filename', # Str: the file/command to be included
5130             'old_filename', # Str: the previous file
5131             )};
5132              
5133              
5134             sub parse {
5135 13     13   35 my __PACKAGE__ $self = shift;
5136 13         39 my ExtUtils::ParseXS $pxs = shift;
5137              
5138 13         52 $self->SUPER::parse($pxs); # set file/line_no/text
5139              
5140 13         28 my $f = $self->{text};
5141 13         37 my $is_cmd = $self->{is_cmd};
5142 13 100       55 my $key = $is_cmd ? 'INCLUDE_COMMAND' : 'INCLUDE';
5143              
5144 13 100       38 if ($is_cmd) {
5145 6 50       61 $f = $self->QuoteArgs($f) if $^O eq 'VMS';
5146              
5147 6 100       35 $pxs->death("Error: INCLUDE_COMMAND: command missing")
5148             unless length $f;
5149              
5150 5 100 100     86 $pxs->death("Error: INCLUDE_COMMAND: pipes are illegal")
5151             if $f =~ /^\s*\|/ or $f =~ /\|\s*$/;
5152             }
5153             else {
5154 7 100       39 $pxs->death("Error: INCLUDE: filename missing")
5155             unless length $f;
5156              
5157 6 100       40 $pxs->death("Error: INCLUDE: output pipe is illegal")
5158             if $f =~ /^\s*\|/;
5159              
5160             # simple minded recursion detector
5161             $pxs->death("Error: INCLUDE: loop detected")
5162 5 100       31 if $pxs->{IncludedFiles}{$f};
5163              
5164 4 50       28 ++$pxs->{IncludedFiles}->{$f} unless $f =~ /\|\s*$/;
5165              
5166 4 50 33     19 if ($f =~ /\|\s*$/ && $f =~ /^\s*perl\s/) {
5167 0         0 $pxs->WarnHint(
5168             "Note: the INCLUDE directive with a command is discouraged",
5169             <<'HINT');
5170             Use INCLUDE_COMMAND instead! In particular, using 'perl' in an
5171             'INCLUDE: ... |' directive is not guaranteed to pick up the correct perl.
5172             The INCLUDE_COMMAND directive allows the use of $^X as the currently
5173             running perl, see 'perldoc perlxs' for details.
5174             HINT
5175             }
5176             }
5177              
5178             # Save the current file context.
5179              
5180 7         61 my @save_keys = qw(in_fh in_filename in_pathname
5181             lastline lastline_no line line_no);
5182 7         35 my @saved = @$pxs{@save_keys};
5183              
5184 7   66     49 my $isPipe = $is_cmd || $pxs->{in_filename} =~ /\|\s*$/;
5185              
5186 7         23 $pxs->{line} = [];
5187 7         13 $pxs->{line_no} = [];
5188              
5189             # Open the new file / pipe
5190              
5191 7         67 $pxs->{in_fh} = Symbol::gensym();
5192              
5193 7 100       222 if ($is_cmd) {
5194             # Expand the special token '$^X' into the full path of the
5195             # currently running perl interpreter
5196 3         23 my $X = $pxs->_safe_quote($^X); # quotes if has spaces
5197 3         38 $f =~ s/^\s*\$\^X/$X/;
5198              
5199 3 50       15548 open ($pxs->{in_fh}, "-|", $f)
5200             or $pxs->death(
5201             "Error: INCLUDE_COMMAND: cannot run command '$f' to include its output: $!");
5202             }
5203             else {
5204 4 100       364 open($pxs->{in_fh}, $f)
5205             or $pxs->death("Error: INCLUDE: cannot open '$f': $!");
5206             }
5207              
5208 6         98 $self->{old_filename} = $pxs->{in_filename};
5209 6         88 $self->{inc_filename} = $f;
5210 6         51 $pxs->{in_filename} = $f;
5211              
5212 6         53 my $path = $f;
5213 6 100       68 if ($is_cmd) {
5214             #$path =~ s/\"/\\"/g; # Fails? See CPAN RT #53938: MinGW Broken after 2.21
5215 3         44 $path =~ s/\\/\\\\/g; # Works according to reporter of #53938
5216             }
5217             else {
5218             $path = ($^O =~ /^mswin/i)
5219             # See CPAN RT #61908: gcc doesn't like
5220             # backslashes on win32?
5221             ? "$pxs->{dir}/$path"
5222 3 50       6652 : File::Spec->catfile($pxs->{dir}, $path);
5223             }
5224 6         71 $pxs->{in_pathname} = $self->{file} = $path;
5225              
5226             # Prime the pump by reading the first non-blank line
5227 6         876220 while (readline($pxs->{in_fh})) {
5228 9 100       179 last unless /^\s*$/;
5229             }
5230              
5231 6         42 $pxs->{lastline} = $_;
5232 6 100       54 chomp $pxs->{lastline} if defined $pxs->{lastline};
5233 6         74 $pxs->{lastline_no} = $self->{line_no} = $.;
5234              
5235             # Parse included file
5236              
5237             my $cpp_scope = ExtUtils::ParseXS::Node::cpp_scope->new({
5238             type => 'include',
5239             is_cmd => $self->{is_cmd},
5240 6         305 });
5241 6 50       99 $cpp_scope->parse($pxs)
5242             or return;
5243 5         15 push @{$self->{kids}}, $cpp_scope;
  5         34  
5244              
5245             --$pxs->{IncludedFiles}->{$pxs->{in_filename}}
5246 5 100       69 unless $isPipe;
5247              
5248 5         284 close $pxs->{in_fh};
5249              
5250             # Restore the current file context.
5251              
5252 5         66 @$pxs{@save_keys} = @saved;
5253              
5254 5 100 100     115 if ($isPipe and $?) {
5255             $pxs->death(sprintf
5256             "Error: %s: got return code 0x%04x when reading from pipe '%s'",
5257             $key, $?, $self->{inc_filename}
5258 1         44 );
5259             }
5260              
5261 4         46 1;
5262             }
5263              
5264              
5265             sub as_code {
5266 4     4   8 my __PACKAGE__ $self = shift;
5267 4         9 my ExtUtils::ParseXS $pxs = shift;
5268              
5269             my $comment = $self->{is_cmd}
5270 4 100       33 ? "INCLUDE_COMMAND: Including output of"
5271             : "INCLUDE: Including";
5272              
5273 4         15 $comment .= " '$self->{inc_filename}' from '$self->{old_filename}'";
5274              
5275 4         45 print $self->Q(<<"EOF");
5276             |
5277             |/* $comment */
5278             |
5279             EOF
5280              
5281 4         19 $_->as_code($pxs) for @{$self->{kids}};
  4         24  
5282              
5283 4         28 print $self->Q(<<"EOF");
5284             |
5285             |/* INCLUDE: Returning to '$self->{old_filename}' from '$self->{inc_filename}' */
5286             |
5287             EOF
5288              
5289             }
5290              
5291              
5292             # ======================================================================
5293              
5294             package ExtUtils::ParseXS::Node::INCLUDE;
5295              
5296             # Process the 'INCLUDE' keyword. Most processing is actually done by the
5297             # parent 'include' class which handles INCLUDE_COMMAND too.
5298              
5299 28     28   185 BEGIN { $build_subclass->(-parent => 'include',
5300             )};
5301              
5302              
5303             sub parse {
5304 7     7   24 my __PACKAGE__ $self = shift;
5305 7         15 my ExtUtils::ParseXS $pxs = shift;
5306              
5307 7         19 $self->{is_cmd} = 0;
5308 7         69 $self->SUPER::parse($pxs); # main parsing done by Node::include
5309 2         9 1;
5310             }
5311              
5312              
5313             # ======================================================================
5314              
5315             package ExtUtils::ParseXS::Node::INCLUDE_COMMAND;
5316              
5317             # Process the 'INCLUDE_COMMAND' keyword. Most processing is actually done
5318             # by the parent 'include' class which handles INCLUDE too.
5319              
5320 28     28   103 BEGIN { $build_subclass->(-parent => 'include',
5321             )};
5322              
5323              
5324             sub parse {
5325 6     6   24 my __PACKAGE__ $self = shift;
5326 6         18 my ExtUtils::ParseXS $pxs = shift;
5327              
5328 6         35 $self->{is_cmd} = 1;
5329 6         65 $self->SUPER::parse($pxs); # main parsing done by Node::include
5330 2         16 1;
5331             }
5332              
5333              
5334             # ======================================================================
5335              
5336             package ExtUtils::ParseXS::Node::enable;
5337              
5338             # Base class for keywords which accept ENABLE/DISABLE as an argument
5339              
5340 28     28   102 BEGIN { $build_subclass->(-parent => 'oneline',
5341             'enable', # Bool
5342             )};
5343              
5344              
5345             sub parse {
5346 451     451   810 my __PACKAGE__ $self = shift;
5347 451         1015 my ExtUtils::ParseXS $pxs = shift;
5348              
5349 451         1437 $self->SUPER::parse($pxs); # set file/line_no, self->{text}
5350 451         1028 my $s = $self->{text};
5351              
5352 451         6109 my ($keyword) = ($self =~ /(\w+)=/); # final component of class name
5353              
5354 451 100       1507 if ($keyword eq 'PROTOTYPES') {
5355             # For backwards compatibility, parsing the PROTOTYPES
5356             # keyword's value is very lax: in particular, anything that
5357             # didn't match 'ENABLE' (such as 'Enabled' or 'ENABLED') used to
5358             # be treated as valid but false. Continue to use this
5359             # interpretation for backcomp, but warn.
5360              
5361 431 100       3888 unless ($s =~ /^ ((ENABLE|DISABLE) D? ;?) \s* $ /xi) {
5362 3         39 $pxs->death("Error: $keyword: invalid value '$s' (should be ENABLE/DISABLE)")
5363             }
5364 428         1576 my ($value, $en_dis) = ($1, $2);
5365 428 100       1399 $self->{enable} = $en_dis eq 'ENABLE' ? 1 : 0;
5366 428 100       2550 unless ($value =~ /^(ENABLE|DISABLE)$/) {
5367             $pxs->Warn("Warning: invalid PROTOTYPES value '$value' interpreted as "
5368 4 100       48 . ($self->{enable} ? 'ENABLE' : 'DISABLE'));
5369             }
5370             }
5371             else {
5372             # SCOPE / VERSIONCHECK / EXPORT_XSUB_SYMBOLS
5373 20 100       319 $s =~ /^(ENABLE|DISABLE)\s*$/
5374             or $pxs->death(
5375             "Error: $keyword: invalid value '$s' (should be ENABLE/DISABLE)"
5376             );
5377 7 100       35 $self->{enable} = $1 eq 'ENABLE' ? 1 : 0;
5378             }
5379              
5380 435         808 1;
5381             }
5382              
5383              
5384             # ======================================================================
5385              
5386             package ExtUtils::ParseXS::Node::EXPORT_XSUB_SYMBOLS;
5387              
5388             # Handle EXPORT_XSUB_SYMBOLS keyword
5389             #
5390             # Note that this keyword can appear both inside of and outside of an
5391             # XSUB; for the latter, it it is currently created as a temporary
5392             # object where as_code() is called immediately after parse() and then
5393             # the object is discarded.
5394              
5395 28     28   158 BEGIN { $build_subclass->(-parent => 'enable',
5396             )};
5397              
5398              
5399             sub parse {
5400 3     3   13 my __PACKAGE__ $self = shift;
5401 3         6 my ExtUtils::ParseXS $pxs = shift;
5402              
5403 3         16 $self->SUPER::parse($pxs); # set file/line_no, self->{enable}
5404 0         0 1;
5405             }
5406              
5407              
5408             sub as_code {
5409 0     0   0 my __PACKAGE__ $self = shift;
5410 0         0 my ExtUtils::ParseXS $pxs = shift;
5411 0         0 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5412 0         0 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5413              
5414 0 0       0 my $xs_impl = $self->{enable} ? 'XS_EXTERNAL' : 'XS_INTERNAL';
5415              
5416             # Change the definition of XS_EUPXS, so that any subsequent
5417             # XS_EUPXS(fXS_Foo_foo) XSUB declarations will expand to
5418             # XS_EXTERNAL/XS_INTERNAL as appropriate
5419              
5420 0         0 print $self->Q(<<"EOF");
5421             |#undef XS_EUPXS
5422             |#if defined(PERL_EUPXS_ALWAYS_EXPORT)
5423             |# define XS_EUPXS(name) XS_EXTERNAL(name)
5424             |#elif defined(PERL_EUPXS_NEVER_EXPORT)
5425             |# define XS_EUPXS(name) XS_INTERNAL(name)
5426             |#else
5427             |# define XS_EUPXS(name) $xs_impl(name)
5428             |#endif
5429             EOF
5430             }
5431              
5432              
5433             # ======================================================================
5434              
5435             package ExtUtils::ParseXS::Node::PROTOTYPES;
5436              
5437             # Handle PROTOTYPES keyword
5438             #
5439             # Note that this keyword can appear both inside of and outside of an XSUB.
5440              
5441 28     28   111 BEGIN { $build_subclass->(-parent => 'enable',
5442             )};
5443              
5444              
5445             sub parse {
5446 431     431   906 my __PACKAGE__ $self = shift;
5447 431         895 my ExtUtils::ParseXS $pxs = shift;
5448              
5449 431         2198 $self->SUPER::parse($pxs); # set file/line_no, self->{enable}
5450 428         1117 $pxs->{PROTOTYPES_value} = $self->{enable};
5451 428         1190 $pxs->{proto_behaviour_specified} = 1;
5452 428         1054 1;
5453             }
5454              
5455              
5456             # ======================================================================
5457              
5458             package ExtUtils::ParseXS::Node::SCOPE;
5459              
5460             # Handle SCOPE keyword
5461             #
5462             # Note that this keyword can appear both inside of and outside of an XSUB.
5463              
5464 28     28   111 BEGIN { $build_subclass->(-parent => 'enable',
5465             )};
5466              
5467              
5468             sub parse {
5469 12     12   52 my __PACKAGE__ $self = shift;
5470 12         57 my ExtUtils::ParseXS $pxs = shift;
5471 12         50 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5472 12         43 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5473              
5474 12         103 $self->SUPER::parse($pxs); # set file/line_no, self->{enable}
5475              
5476             # $xsub not defined for file-scoped SCOPE
5477 6 100       21 if ($xsub) {
5478             $pxs->blurt("Error: only one SCOPE declaration allowed per XSUB")
5479 4 100       28 if $xsub->{seen_SCOPE};
5480 4         27 $xsub->{seen_SCOPE} = 1;
5481             }
5482              
5483             # Note that currently this parse method can be called either while
5484             # parsing an XSUB, or while processing file-scoped keywords
5485             # just before an XSUB declaration. So potentially set both types of
5486             # state.
5487 6 100       34 $xsub->{SCOPE_enabled} = $self->{enable} if $xsub;
5488 6         9 $pxs->{file_SCOPE_enabled} = $self->{enable};
5489 6         21 1;
5490             }
5491              
5492              
5493             # ======================================================================
5494              
5495             package ExtUtils::ParseXS::Node::VERSIONCHECK;
5496              
5497             # Handle VERSIONCHECK keyword
5498             #
5499             # Note that this keyword can appear both inside of and outside of an XSUB.
5500              
5501 28     28   117 BEGIN { $build_subclass->(-parent => 'enable',
5502             )};
5503              
5504              
5505             sub parse {
5506 5     5   22 my __PACKAGE__ $self = shift;
5507 5         15 my ExtUtils::ParseXS $pxs = shift;
5508              
5509 5         36 $self->SUPER::parse($pxs); # set file/line_no, self->{enable}
5510 1         1 $pxs->{VERSIONCHECK_value} = $self->{enable};
5511 1         3 1;
5512             }
5513              
5514              
5515             # ======================================================================
5516              
5517             package ExtUtils::ParseXS::Node::multiline;
5518              
5519             # Generic base class for keyword Nodes which can contain multiple lines,
5520             # e.g. C code or other data: so anything from ALIAS to PPCODE.
5521             # On entry, $self->lines[0] will be any text (on the same line) which
5522             # follows the keyword.
5523              
5524 28     28   88 BEGIN { $build_subclass->(
5525             'lines', # Array ref of all lines until the next keyword
5526             )};
5527              
5528              
5529             # Consume all the lines up until the next directive and store in @$lines.
5530              
5531             sub parse {
5532 196     196   445 my __PACKAGE__ $self = shift;
5533 196         309 my ExtUtils::ParseXS $pxs = shift;
5534              
5535 196         814 $self->SUPER::parse($pxs); # set file/line_no
5536              
5537 196         427 my @lines;
5538              
5539             # Consume lines until the next directive
5540 196   100     514 while( @{$pxs->{line}}
  569         4586  
5541             && $pxs->{line}[0] !~ /^$ExtUtils::ParseXS::BLOCK_regexp/o)
5542             {
5543 373         639 push @lines, shift @{$pxs->{line}};
  373         854  
5544             }
5545              
5546 196         495 $self->{lines} = \@lines;
5547 196         565 1;
5548             }
5549              
5550             # No as_code() method - we rely on the sub-classes for that
5551              
5552              
5553             # ======================================================================
5554              
5555             package ExtUtils::ParseXS::Node::multiline_merged;
5556              
5557             # Generic base class for keyword Nodes which can contain multiple lines.
5558             # It's the same is is parent class, :Node::multiline, except that in
5559             # addition, leading blank lines are skipped and the remainder concatenated
5560             # into a single line, 'text'.
5561              
5562 28     28   129 BEGIN { $build_subclass->(-parent => 'multiline',
5563             'text', # Str: singe string containing all concatenated lines
5564             )};
5565              
5566              
5567             # Consume all the lines up until the next directive and store in
5568             # @$lines, and in addition, concatenate and store in $text
5569              
5570             sub parse {
5571 48     48   123 my __PACKAGE__ $self = shift;
5572 48         113 my ExtUtils::ParseXS $pxs = shift;
5573              
5574 48         246 $self->SUPER::parse($pxs); # set file/line_no, read lines
5575              
5576 48         225 my @lines = @{$self->{lines}};
  48         137  
5577 48   100     527 shift @lines while @lines && $lines[0] !~ /\S/;
5578             # XXX ParseXS originally didn't include a trailing \n,
5579             # so we carry on doing the same.
5580 48         251 $self->{text} = join "\n", @lines;
5581 48         238 ExtUtils::ParseXS::Utilities::trim_whitespace($self->{text});
5582 48         100 1;
5583             }
5584              
5585             # No as_code() method - we rely on the sub-classes for that
5586              
5587              
5588             # ======================================================================
5589              
5590             package ExtUtils::ParseXS::Node::C_ARGS;
5591              
5592             # Handle C_ARGS keyword
5593              
5594 28     28   119 BEGIN { $build_subclass->(-parent => 'multiline_merged',
5595             )};
5596              
5597              
5598             sub parse {
5599 18     18   53 my __PACKAGE__ $self = shift;
5600 18         42 my ExtUtils::ParseXS $pxs = shift;
5601 18         48 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5602 18         39 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5603              
5604 18         90 $self->SUPER::parse($pxs); # set file/line_no, get lines, set text
5605 18         47 $xbody->{ioparams}{auto_function_sig_override} = $self->{text};
5606 18         53 1;
5607             }
5608              
5609              
5610             # ======================================================================
5611              
5612             package ExtUtils::ParseXS::Node::INTERFACE;
5613              
5614             # Handle INTERFACE keyword
5615              
5616 28     28   149 BEGIN { $build_subclass->(-parent => 'multiline_merged',
5617             )};
5618              
5619              
5620             sub parse {
5621 16     16   53 my __PACKAGE__ $self = shift;
5622 16         38 my ExtUtils::ParseXS $pxs = shift;
5623 16         30 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5624 16         59 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5625              
5626 16         110 $self->SUPER::parse($pxs); # set file/line_no, get lines, set text
5627 16         49 $xsub->{seen_INTERFACE} = 1;
5628              
5629 16         85 foreach (split /[\s,]+/, $self->{text}) {
5630 21         60 my $short = $_;
5631 21         166 $short =~ s/^$pxs->{PREFIX_pattern}//;
5632             $pxs->blurt("Error: duplicate INTERFACE name: '$short'")
5633 21 100       94 if exists $xsub->{map_interface_name_short_to_original}{$short};
5634              
5635 21         79 $xsub->{map_interface_name_short_to_original}{$short} = $_;
5636             }
5637              
5638 16         45 1;
5639             }
5640              
5641              
5642             sub as_code {
5643 16     16   49 my __PACKAGE__ $self = shift;
5644 16         30 my ExtUtils::ParseXS $pxs = shift;
5645 16         26 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5646 16         36 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5647              
5648 16         33 my $macro = $xsub->{interface_macro};
5649 16 100       80 $macro = 'XSINTERFACE_FUNC' unless defined $macro;
5650              
5651 16         46 my $type = $xsub->{decl}{return_type}{type};
5652             $type =~ tr/:/_/
5653 16 50       68 unless $pxs->{config_RetainCplusplusHierarchicalTypes};
5654 16         69 print <<"EOF";
5655             XSFUNCTION = $macro($type,cv,XSANY.any_dptr);
5656             EOF
5657             }
5658              
5659              
5660             # ======================================================================
5661              
5662             package ExtUtils::ParseXS::Node::INTERFACE_MACRO;
5663              
5664             # Handle INTERFACE_MACRO keyword
5665              
5666 28     28   149 BEGIN { $build_subclass->(-parent => 'multiline_merged',
5667             'get_macro', # Str: name of macro to get interface
5668             'set_macro', # Str: name of macro to set interface
5669             )};
5670              
5671              
5672             sub parse {
5673 2     2   10 my __PACKAGE__ $self = shift;
5674 2         8 my ExtUtils::ParseXS $pxs = shift;
5675 2         8 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5676 2         9 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5677              
5678 2         19 $self->SUPER::parse($pxs); # set file/line_no, get lines, set text
5679              
5680 2         7 $xsub->{seen_INTERFACE_MACRO} = 1;
5681              
5682 2         4 my $s = $self->{text};
5683 2         8 my ($m1, $m2);
5684 2 50       12 if ($s =~ /\s/) { # two macros
5685 2         10 ($m1, $m2) = split ' ', $s;
5686             }
5687             else {
5688             # XXX rather than using a fake macro name which will probably
5689             # give a compile error later, we should really warn/die here?
5690 0         0 ($m1, $m2) = ($s, 'UNKNOWN_CVT');
5691             }
5692              
5693 2         10 $self->{get_macro} = $xsub->{interface_macro} = $m1;
5694 2         6 $self->{set_macro} = $xsub->{interface_macro_set} = $m2;
5695              
5696 2         6 1;
5697             }
5698              
5699              
5700             # ======================================================================
5701              
5702             package ExtUtils::ParseXS::Node::OVERLOAD;
5703              
5704             # Handle OVERLOAD keyword
5705              
5706 28     28   130 BEGIN { $build_subclass->(-parent => 'multiline_merged',
5707             'ops', # Hash ref of seen overloaded op names
5708             )};
5709              
5710             # Add all overload method names, like 'cmp', '<=>', etc, (possibly
5711             # multiple ones per line) until the next keyword line, as 'seen' keys to
5712             # the $xsub->{overload_name_seen} hash.
5713              
5714             sub parse {
5715 12     12   48 my __PACKAGE__ $self = shift;
5716 12         58 my ExtUtils::ParseXS $pxs = shift;
5717 12         35 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5718 12         34 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5719              
5720 12         109 $self->SUPER::parse($pxs); # set file/line_no, get lines, set text
5721              
5722 12         41 my $s = $self->{text};
5723              
5724             # Note that this doesn't forbid invalid overload op names, to allow
5725             # for forwards compatibility. It does warn/skip ones which don't
5726             # seem to be even vaguely syntactically correct.
5727 12         84 for my $op (split ' ', $s) {
5728 93 100       268 if ($op !~ m{^
5729             ^
5730             ( [\w:"\\)+\-*/%<>.&|^!~{}=\@\$]+ )
5731             $
5732             }x)
5733              
5734             {
5735 1         25 $pxs->Warn("Warning: unrecognised OVERLOAD op name '$op' ignored");
5736 1         6 next;
5737             }
5738              
5739 92         256 $self->{ops}{$op} = 1;
5740             $pxs->Warn("Warning: duplicate OVERLOAD op name: '$op'")
5741 92 100       169 if exists $xsub->{overload_name_seen}{$op};
5742 92         134 $xsub->{overload_name_seen}{$op} = 1;
5743             }
5744              
5745             # Mark the current package as being overloaded
5746             $pxs->{map_overloaded_package_to_C_package}->{$xsub->{PACKAGE_name}}
5747 12         71 = $xsub->{PACKAGE_C_name};
5748              
5749 12         36 1;
5750             }
5751              
5752              
5753             # ======================================================================
5754              
5755             package ExtUtils::ParseXS::Node::ATTRS;
5756              
5757             # Handle ATTRS keyword
5758              
5759 28     28   122 BEGIN { $build_subclass->(-parent => 'multiline',
5760             )};
5761              
5762              
5763             # Read each lines's worth of attributes into a string that is pushed
5764             # to the $xsub->{attributes} array. Note that it doesn't matter that multiple
5765             # space-separated attributes on the same line are stored as a single
5766             # string; later, all the attribute lines are joined together into a single
5767             # string to pass to apply_attrs_string().
5768              
5769             sub parse {
5770 5     5   15 my __PACKAGE__ $self = shift;
5771 5         18 my ExtUtils::ParseXS $pxs = shift;
5772 5         10 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5773 5         16 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5774              
5775 5         38 $self->SUPER::parse($pxs); # set file/line_no, get lines
5776 5         9 for (@{$self->{lines}}) {
  5         15  
5777 6         26 ExtUtils::ParseXS::Utilities::trim_whitespace($_);
5778 6         9 push @{$xsub->{attributes}}, $_;
  6         21  
5779             }
5780 5         17 1;
5781             }
5782              
5783              
5784             # ======================================================================
5785              
5786             package ExtUtils::ParseXS::Node::PROTOTYPE;
5787              
5788             # Handle PROTOTYPE keyword
5789              
5790 28     28   106 BEGIN { $build_subclass->(-parent => 'multiline',
5791             'prototype', # Str: 0 (disable), 1 (enable), 2 ("") or "$$@" etc
5792             )};
5793              
5794              
5795             # PROTOTYPE: Process one or more lines of the form
5796             # DISABLE
5797             # ENABLE
5798             # $$@ # a literal prototype
5799             # # an empty prototype - equivalent to foo() { ...}
5800             #
5801             # The last line takes precedence.
5802             # XXX It's a design flaw that more than one line can be processed.
5803              
5804             sub parse {
5805 12     12   27 my __PACKAGE__ $self = shift;
5806 12         34 my ExtUtils::ParseXS $pxs = shift;
5807 12         25 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5808 12         23 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5809              
5810 12         52 $self->SUPER::parse($pxs); # set file/line_no, get lines
5811              
5812 12         20 my $proto;
5813              
5814             $pxs->death("Error: only one PROTOTYPE definition allowed per xsub")
5815 12 100       55 if $xsub->{seen_PROTOTYPE};
5816 11         25 $xsub->{seen_PROTOTYPE} = 1;
5817              
5818 11         20 for (@{$self->{lines}}) {
  11         32  
5819 18 100       56 next unless /\S/;
5820 12         61 ExtUtils::ParseXS::Utilities::trim_whitespace($_);
5821              
5822 12 100       49 if ($_ eq 'DISABLE') {
    100          
5823 2         10 $proto = 0;
5824             }
5825             elsif ($_ eq 'ENABLE') {
5826 1         9 $proto = 1;
5827             }
5828             else {
5829 9         32 s/\s+//g; # remove any whitespace
5830 9 100       43 $pxs->death("Error: invalid prototype '$_'")
5831             unless ExtUtils::ParseXS::Utilities::valid_proto_string($_);
5832 8         37 $proto = ExtUtils::ParseXS::Utilities::C_string($_);
5833             }
5834             }
5835              
5836             # If no prototype specified, then assume empty prototype ""
5837 10 100       30 $proto = 2 unless defined $proto;
5838              
5839 10         27 $self->{prototype} = $proto;
5840 10         17 $xsub->{prototype} = $proto;
5841              
5842 10         23 $pxs->{proto_behaviour_specified} = 1;
5843 10         24 1;
5844             }
5845              
5846              
5847             # ======================================================================
5848              
5849             package ExtUtils::ParseXS::Node::codeblock;
5850              
5851             # Base class for Nodes which contain lines of literal C code
5852             # (such as PREINIT: and CODE:)
5853              
5854 28     28   122 BEGIN { $build_subclass->(-parent => 'multiline',
5855             )};
5856              
5857             sub parse {
5858 131     131   234 my __PACKAGE__ $self = shift;
5859 131         358 my ExtUtils::ParseXS $pxs = shift;
5860 131         293 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5861 131         255 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5862              
5863 131         647 $self->SUPER::parse($pxs); # use multiline::parse()
5864              
5865             # Text following the keyword is ignored rather than being treated
5866             # as the first line of code.
5867 131         198 my $line0 = shift @{$self->{lines}};
  131         353  
5868 131 100 66     899 $pxs->Warn("Warning: text after keyword ignored: '$line0'")
5869             if defined $line0 && $line0 =~ /\S/;
5870 131         292 return 1;
5871             }
5872              
5873             # Emit the lines of code, skipping any initial blank lines,
5874             # and possibly wrapping in '#line' directives.
5875              
5876             sub as_code {
5877 129     129   256 my __PACKAGE__ $self = shift;
5878 129         208 my ExtUtils::ParseXS $pxs = shift;
5879 129         189 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5880 129         243 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5881              
5882 129         217 my @lines = map "$_\n", @{$self->{lines}};
  129         662  
5883              
5884 129         263 my $n = 1;
5885              
5886             # strip leading blank lines
5887 129   66     1231 $n++, shift @lines while @lines && $lines[0] !~ /\S/;
5888              
5889             # Add a leading '#line' if needed.
5890             # The XSubPPtmp test is a bit of a hack - it skips synthetic blocks
5891             # added to boot etc which may not have line numbers.
5892 129         260 my $line0 = $lines[0];
5893 129 100 66     1112 if ( $pxs->{config_WantLineNumbers}
      66        
5894             && ! ( defined $line0
5895             && ( $line0 =~ /^\s*#\s*line\b/
5896             || $line0 =~ /^#if XSubPPtmp/
5897             )
5898             )
5899             ) {
5900             unshift @lines,
5901             "#line "
5902             . ($self->{line_no} + $n)
5903             . " \""
5904             . ExtUtils::ParseXS::Utilities::escape_file_for_line_directive(
5905             $self->{file})
5906 115         578 . "\"\n";
5907             }
5908              
5909             # Add a final "restoring" '#line'
5910             push @lines, 'ExtUtils::ParseXS::CountLines'->end_marker . "\n"
5911 129 100       594 if $pxs->{config_WantLineNumbers};
5912              
5913 129         392 print for @lines;
5914             }
5915              
5916              
5917             # ======================================================================
5918              
5919             package ExtUtils::ParseXS::Node::CODE;
5920              
5921             # Store the code lines associated with the CODE keyword
5922              
5923 28     28   131 BEGIN { $build_subclass->(-parent => 'codeblock',
5924             )};
5925              
5926             sub parse {
5927 101     101   251 my __PACKAGE__ $self = shift;
5928 101         231 my ExtUtils::ParseXS $pxs = shift;
5929 101         197 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
5930 101         286 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
5931              
5932 101         529 $self->SUPER::parse($pxs); # set file/line_no/lines
5933              
5934             # Check if the code block includes "RETVAL". This check is for later
5935             # use to warn if RETVAL is used but no OUTPUT block is present.
5936             # Ignore if its only being used in an 'ignore this var' situation.
5937 101         184 my $code = join "\n", @{$self->{lines}};
  101         349  
5938             $xbody->{seen_RETVAL_in_CODE} =
5939 101   100     737 $code =~ /\bRETVAL\b/
5940             && $code !~ /\b\QPERL_UNUSED_VAR(RETVAL)/;
5941              
5942             # Horrible 'void' return arg count hack.
5943             #
5944             # Until about 1996, xsubpp always emitted 'XSRETURN(1)', even for a
5945             # void XSUB. This was fixed for CODE-less void XSUBs simply by
5946             # actually honouring the 'void' type and emitting 'XSRETURN_EMPTY'
5947             # instead. However, for CODE blocks, the documentation had already
5948             # endorsed a coding style along the lines of
5949             #
5950             # void
5951             # foo(...)
5952             # CODE:
5953             # ST(0) = sv_newmortal();
5954             #
5955             # i.e. the XSUB returns an SV even when the return type is 'void'.
5956             # In 2024 there is still lots of code of this style out in the wild,
5957             # even in the distros bundled with perl.
5958             #
5959             # So honouring the void type here breaks lots of existing code. Thus
5960             # this hack specifically looks for: void XSUBs with a CODE block that
5961             # appears to put stuff on the stack via 'ST(n)=' or 'XST_m()', and if
5962             # so, emits 'XSRETURN(1)' rather than the 'XSRETURN_EMPTY' implied by
5963             # the 'void' return type.
5964             #
5965             # So set a flag which indicates that a CODE block sets ST(0). This
5966             # will be used later when deciding how/whether to emit EXTEND(n) and
5967             # XSRETURN(n).
5968              
5969 101         654 my $st0 =
5970             $code =~ m{ ( \b ST \s* \( [^;]* = )
5971             | ( \b XST_m\w+\s* \( ) }x;
5972              
5973             $pxs->Warn("Warning: ST(0) isn't consistently set in every CASE's CODE block")
5974             if defined $xsub->{CODE_sets_ST0}
5975 101 100 100     499 && $xsub->{CODE_sets_ST0} ne $st0;
5976 101         259 $xsub->{CODE_sets_ST0} = $st0;
5977              
5978 101         294 1;
5979             }
5980              
5981              
5982             # ======================================================================
5983              
5984             package ExtUtils::ParseXS::Node::CLEANUP;
5985              
5986             # Store the code lines associated with the CLEANUP: keyword
5987              
5988 28     28   126 BEGIN { $build_subclass->(-parent => 'codeblock',
5989             )};
5990              
5991             # Currently all methods are just inherited.
5992              
5993              
5994             # ======================================================================
5995              
5996             package ExtUtils::ParseXS::Node::INIT;
5997              
5998             # Store the code lines associated with the INIT: keyword
5999              
6000 28     28   153 BEGIN { $build_subclass->(-parent => 'codeblock',
6001             )};
6002              
6003             # Currently all methods are just inherited.
6004              
6005              
6006             # ======================================================================
6007              
6008             package ExtUtils::ParseXS::Node::POSTCALL;
6009              
6010             # Store the code lines associated with the POSTCALL: keyword
6011              
6012 28     28   84 BEGIN { $build_subclass->(-parent => 'codeblock',
6013             )};
6014              
6015             # Currently all methods are just inherited.
6016              
6017              
6018             # ======================================================================
6019              
6020             package ExtUtils::ParseXS::Node::PPCODE;
6021              
6022             # Store the code lines associated with the PPCODE keyword
6023              
6024 28     28   87 BEGIN { $build_subclass->(-parent => 'codeblock',
6025             )};
6026              
6027             sub parse {
6028 9     9   67 my __PACKAGE__ $self = shift;
6029 9         22 my ExtUtils::ParseXS $pxs = shift;
6030 9         23 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6031 9         19 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6032              
6033 9         107 $self->SUPER::parse($pxs); # set file/line_no/lines
6034 9         20 $xsub->{seen_PPCODE} = 1;
6035 9 100       19 $pxs->death("Error: PPCODE must be the last thing") if @{$pxs->{line}};
  9         83  
6036 8         22 1;
6037             }
6038              
6039              
6040             sub as_code {
6041 8     8   13 my __PACKAGE__ $self = shift;
6042 8         12 my ExtUtils::ParseXS $pxs = shift;
6043 8         12 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6044 8         32 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6045              
6046             # Just emit the code block and then code to do PUTBACK and return.
6047             # The # user of PPCODE is supposed to have done all the return stack
6048             # manipulation themselves.
6049             # Note that PPCODE blocks often include a XSRETURN(1) or
6050             # similar, so any final code we emit after that is in danger of
6051             # triggering a "statement is unreachable" warning.
6052              
6053 8         43 $self->SUPER::as_code($pxs, $xsub, $xbody); # emit code block
6054              
6055 8 50       66 print "\tLEAVE;\n" if $xsub->{SCOPE_enabled};
6056              
6057             # Suppress "statement is unreachable" warning on HPUX
6058 8 50       64 print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
6059             "#pragma diag_suppress 2111\n",
6060             "#endif\n"
6061             if $^O eq "hpux";
6062              
6063 8         20 print "\tPUTBACK;\n\treturn;\n";
6064              
6065             # Suppress "statement is unreachable" warning on HPUX
6066 8 50       71 print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
6067             "#pragma diag_default 2111\n",
6068             "#endif\n"
6069             if $^O eq "hpux";
6070             }
6071              
6072              
6073             # ======================================================================
6074              
6075             package ExtUtils::ParseXS::Node::PREINIT;
6076              
6077             # Store the code lines associated with the PREINIT: keyword
6078              
6079 28     28   133 BEGIN { $build_subclass->(-parent => 'codeblock',
6080             )};
6081              
6082             # Currently all methods are just inherited.
6083              
6084              
6085             # ======================================================================
6086              
6087             package ExtUtils::ParseXS::Node::keylines;
6088              
6089             # Base class for keyword FOO nodes which have a FOO_line kid node for
6090             # each line making up the keyword - such as OUTPUT etc.
6091              
6092 28     28   105 BEGIN { $build_subclass->(
6093             'lines', # Array ref of all lines until the next keyword
6094             )};
6095              
6096              
6097             # Process each line on and following the keyword line.
6098             # For each line, create a FOO_line kid and call its parse() method.
6099              
6100             sub parse {
6101 573     573   1466 my __PACKAGE__ $self = shift;
6102 573         842 my ExtUtils::ParseXS $pxs = shift;
6103 573         867 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6104 573         787 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6105 573         880 my $do_notimplemented = shift;
6106              
6107 573         1722 $self->SUPER::parse($pxs); # set file/line_no
6108              
6109             # Consume and process lines until the next directive.
6110 573   100     851 while( @{$pxs->{line}}
  919         7938  
6111             && $pxs->{line}[0] !~ /^$ExtUtils::ParseXS::BLOCK_regexp/o)
6112             {
6113 353 100       763 if ($do_notimplemented) {
6114             # treat NOT_IMPLEMENTED_YET as another block separator, in
6115             # addition to $BLOCK_regexp.
6116 153 100       575 last if $pxs->{line}[0] =~ /^\s*NOT_IMPLEMENTED_YET/;
6117             }
6118              
6119 351 100       1579 unless ($pxs->{line}[0] =~ /\S/) { # skip blank lines
6120 69         147 shift @{$pxs->{line}};
  69         169  
6121 69         171 next;
6122             }
6123              
6124 282         408 push @{$self->{lines}}, $pxs->{line}[0];
  282         735  
6125              
6126 282         589 my $class = ref($self) . '_line';
6127 282         1475 my $kid = $class->new();
6128             # Keep the current line in $self->{lines} for now so that the
6129             # parse() method below sees the right line number. We rely on that
6130             # method to actually pop the line.
6131 282 100       1163 if ($kid->parse($pxs, $xsub, $xbody, $self)) {
6132 252         368 push @{$self->{kids}}, $kid;
  252         708  
6133             }
6134             }
6135              
6136 568         1097 1;
6137             }
6138              
6139              
6140             # call as_code() on any kids which have that method
6141              
6142             sub as_code {
6143 191     191   303 my __PACKAGE__ $self = shift;
6144 191         283 my ExtUtils::ParseXS $pxs = shift;
6145 191         298 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6146 191         239 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6147              
6148 191 100       565 return unless $self->{kids};
6149 183         263 $_->as_code($pxs, $xsub, $xbody) for @{$self->{kids}};
  183         703  
6150             }
6151              
6152              
6153             # ======================================================================
6154              
6155             package ExtUtils::ParseXS::Node::keyline;
6156              
6157             # Base class for FOO_line nodes which have a FOO node as
6158             # their parent.
6159              
6160 28     28   117 BEGIN { $build_subclass->(
6161             'line', # Str: text of current line
6162             )};
6163              
6164              
6165             # The two jobs of this parse method are to grab the next line, and also to
6166             # set the right line number for any warning or error messages triggered by
6167             # the current line. It is called as a SUPER by the parse() methods of its
6168             # concrete subclasses.
6169              
6170             sub parse {
6171 282     282   369 my __PACKAGE__ $self = shift;
6172 282         335 my ExtUtils::ParseXS $pxs = shift;
6173              
6174 282         659 $self->SUPER::parse($pxs); # set file/line_no
6175             # By shifting *now*, the line above gets the correct line number of
6176             # this src line, while subsequent processing gives the right line
6177             # number for warnings etc, since the warn/err methods assume the line
6178             # being processed has already been popped.
6179 282         376 my $line = shift @{$pxs->{line}}; # line of text to be processed
  282         508  
6180 282         549 $self->{line} = $line;
6181 282         434 1;
6182             }
6183              
6184              
6185             # ======================================================================
6186              
6187             package ExtUtils::ParseXS::Node::ALIAS;
6188              
6189             # Handle ALIAS keyword
6190              
6191 28     28   103 BEGIN { $build_subclass->(-parent => 'keylines',
6192             'aliases', # hashref of all alias => value pairs.
6193             # Populated by ALIAS_line::parse()
6194             )};
6195              
6196             sub parse {
6197 23     23   38 my __PACKAGE__ $self = shift;
6198 23         35 my ExtUtils::ParseXS $pxs = shift;
6199 23         38 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6200 23         36 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6201              
6202 23         87 $xsub->{seen_ALIAS} = 1;
6203 23         68 $self->SUPER::parse($pxs, $xsub, $xbody);
6204             }
6205              
6206              
6207             # ======================================================================
6208              
6209             package ExtUtils::ParseXS::Node::ALIAS_line;
6210              
6211             # Handle one line from an ALIAS keyword block
6212              
6213 28     28   107 BEGIN { $build_subclass->(-parent => 'keyline',
6214             )};
6215              
6216              
6217             # Parse one line from an ALIAS block
6218             #
6219             # Each line can have zero or more definitions, separated by white space.
6220             # Each definition is of one of the two forms:
6221             #
6222             # name = value
6223             # name => other_name
6224             #
6225             # where 'value' is a positive integer (or C macro) and the names are
6226             # simple or qualified perl function names. E.g.
6227             #
6228             # foo = 1 Bar::foo = 2 Bar::baz => Bar::foo
6229             #
6230             # The RHS of a '=>' is the name of an existing alias
6231             #
6232             # The results are added to a hash in the parent ALIAS node, as well as
6233             # to a couple of per-xsub hashes which accumulate the results across
6234             # possibly multiple ALIAS keywords.
6235             #
6236             # Updates:
6237             # $parent->{aliases}{$alias} = $value;
6238             # $xsub->{map_alias_name_to_value}{$alias} = $value;
6239             # $xsub->{map_alias_value_to_name_seen_hash}{$value}{$alias}++;
6240              
6241              
6242             sub parse {
6243 53     53   71 my __PACKAGE__ $self = shift;
6244 53         66 my ExtUtils::ParseXS $pxs = shift;
6245 53         94 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6246 53         58 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6247 53         89 my ExtUtils::ParseXS::Node::ALIAS $parent = shift; # parent ALIAS node
6248              
6249 53         129 $self->SUPER::parse($pxs); # set file/line_no/line
6250 53         92 my $line = $self->{line}; # line of text to be processed
6251              
6252 53         134 ExtUtils::ParseXS::Utilities::trim_whitespace($line);
6253              
6254 53         82 my $orig = $line; # keep full line for error messages
6255              
6256             # we use this later for symbolic aliases
6257 53         128 my $fname = $pxs->{PACKAGE_class} . $xsub->{decl}{name};
6258              
6259             # chop out and process one alias entry from $line
6260              
6261 53         267 while ($line =~ s/^\s*([\w:]+)\s*=(>?)\s*([\w:]+)\s*//) {
6262 53         171 my ($alias, $is_symbolic, $value) = ($1, $2, $3);
6263 53         69 my $orig_alias = $alias;
6264              
6265 53 100 100     245 $pxs->blurt( "Error: in alias definition for '$alias' the value "
6266             . "may not contain ':' unless it is symbolic.")
6267             if !$is_symbolic and $value=~/:/;
6268              
6269             # check for optional package definition in the alias
6270 53 100       162 $alias = $pxs->{PACKAGE_class} . $alias if $alias !~ /::/;
6271              
6272 53 100       95 if ($is_symbolic) {
6273 7         10 my $orig_value = $value;
6274 7 100       27 $value = $pxs->{PACKAGE_class} . $value if $value !~ /::/;
6275 7 100       20 if (defined $xsub->{map_alias_name_to_value}{$value}) {
    50          
6276 6         10 $value = $xsub->{map_alias_name_to_value}{$value};
6277             } elsif ($value eq $fname) {
6278 0         0 $value = 0;
6279             } else {
6280 1         18 $pxs->blurt( "Error: unknown alias '$value' in "
6281             . "symbolic definition for '$orig_alias'");
6282             }
6283             }
6284              
6285             # check for duplicate alias name & duplicate value
6286 53         112 my $prev_value = $xsub->{map_alias_name_to_value}{$alias};
6287 53 100       95 if (defined $prev_value) {
6288 3 100       17 if ($prev_value eq $value) {
6289 1         15 $pxs->Warn("Warning: ignoring duplicate alias '$orig_alias'")
6290             } else {
6291 2         27 $pxs->Warn( "Warning: conflicting duplicate alias "
6292             . "'$orig_alias' changes definition "
6293             . "from '$prev_value' to '$value'");
6294             delete $xsub->{map_alias_value_to_name_seen_hash}
6295 2         10 ->{$prev_value}{$alias};
6296             }
6297             }
6298              
6299             # Check and see if this alias results in two aliases having the same
6300             # value, we only check non-symbolic definitions as the whole point of
6301             # symbolic definitions is to say we want to duplicate the value and
6302             # it is NOT a mistake.
6303 53 100       94 unless ($is_symbolic) {
6304 46         56 my @keys= sort keys %{$xsub->
6305 46 100       231 {map_alias_value_to_name_seen_hash}->{$value}||{}};
6306             # deal with an alias of 0, which might not be in the aliases
6307             # dataset yet as 0 is the default for the base function ($fname)
6308             push @keys, $fname
6309             if $value eq "0" and
6310 46 100 100     143 !defined $xsub->{map_alias_name_to_value}{$fname};
6311 46 100 100     158 if (@keys and $pxs->{config_author_warnings}) {
6312             # We do not warn about value collisions unless author_warnings
6313             # are enabled. They aren't helpful to a module consumer, only
6314             # the module author.
6315 13         27 @keys= map { "'$_'" }
6316 8         18 map { my $copy= $_;
  13         19  
6317 13         57 $copy=~s/^$pxs->{PACKAGE_class}//;
6318 13         28 $copy
6319             } @keys;
6320             $pxs->WarnHint(
6321             "Warning: aliases '$orig_alias' and "
6322             . join(", ", @keys)
6323             . " have identical values of $value"
6324             . ( $value eq "0"
6325             ? " - the base function"
6326             : "" ),
6327 8 100       99 !$xsub->{alias_clash_hinted}++
    100          
6328             ? "If this is deliberate use a "
6329             . "symbolic alias instead."
6330             : undef
6331             );
6332             }
6333             }
6334              
6335 53         142 $parent->{aliases}{$alias} = $value;
6336 53         97 $xsub->{map_alias_name_to_value}->{$alias} = $value;
6337 53         222 $xsub->{map_alias_value_to_name_seen_hash}{$value}{$alias}++;
6338             }
6339              
6340 53 100       142 $pxs->blurt("Error: cannot parse ALIAS definitions from '$orig'")
6341             if $line =~ /\S/;
6342              
6343 53         118 1;
6344             }
6345              
6346              
6347             # ======================================================================
6348              
6349             package ExtUtils::ParseXS::Node::INPUT;
6350              
6351             # Handle an explicit INPUT: block, or any implicit INPUT
6352             # block which can follow an xsub signature or CASE keyword.
6353              
6354 28     28   135 BEGIN { $build_subclass->(-parent => 'keylines',
6355             'implicit', # Bool: this is an INPUT section at the start of the
6356             # XSUB/CASE, without an explicit 'INPUT' keyword
6357             )};
6358              
6359             # The inherited parse() method will call INPUT_line->parse() for each line
6360              
6361              
6362             sub parse {
6363 484     484   846 my __PACKAGE__ $self = shift;
6364 484         1552 my ExtUtils::ParseXS $pxs = shift;
6365 484         720 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6366 484         710 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6367              
6368             # Call the SUPER parse method, which will call INPUT_line->parse()
6369             # for each INPUT line. The '1' bool arg indicates to treat
6370             # NOT_IMPLEMENTED_YET as another block separator, in addition to
6371             # $BLOCK_regexp.
6372 484         2918 $self->SUPER::parse($pxs, $xsub, $xbody, 1);
6373              
6374 479         5406 1;
6375             }
6376              
6377              
6378             # ======================================================================
6379              
6380             package ExtUtils::ParseXS::Node::INPUT_line;
6381              
6382             # Handle one line from an INPUT keyword block
6383              
6384 28     28   102 BEGIN { $build_subclass->(-parent => 'keyline',
6385             'ioparam', # The IO_Param object associated with this INPUT line.
6386              
6387             # The parsed components of this INPUT line:
6388             'type', # Str: char *
6389             'is_addr', # Bool: &
6390             'name', # Str: foo
6391             'init_op', # Str: =
6392             'init', # Str: SvIv($arg)
6393             )};
6394              
6395              
6396             # Parse one line in an INPUT block. This method does two main things:
6397             #
6398             # It parses the line and stores its components in the fields of the
6399             # INPUT_line object (which aren't further used for parsing or code
6400             # generation)
6401             #
6402             # It also uses those values to create/update the IO_Param object
6403             # associated with this variable. For example with
6404             #
6405             # void
6406             # foo(a = 0)
6407             # int a
6408             #
6409             # a IO_Param object will already have been created with the name 'a' and
6410             # default value '0' when the signature was parsed. Parsing the 'int a'
6411             # line will set the INPUT_line object's fields to (type => 'int',
6412             # name => 'a'), while the IO_Param object will have its type field set to
6413             # 'int'. The INPUT_line object also stores a ref to the IO_Param object.
6414             #
6415              
6416             sub parse {
6417 146     146   241 my __PACKAGE__ $self = shift;
6418 146         200 my ExtUtils::ParseXS $pxs = shift;
6419 146         207 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6420 146         217 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6421 146         238 my ExtUtils::ParseXS::Node::INPUT $parent = shift; # parent INPUT node
6422              
6423 146         459 $self->SUPER::parse($pxs); # set file/line_no/line
6424 146         251 my $line = $self->{line}; # line of text to be processed
6425              
6426 146         494 ExtUtils::ParseXS::Utilities::trim_whitespace($line);
6427              
6428             # remove any trailing semicolon, except for initialisations
6429 146 100       753 $line =~ s/\s*;$//g unless $line =~ /[=;+].*\S/;
6430              
6431             # Extract optional initialisation code (which overrides the
6432             # normal typemap), such as 'int foo = ($type)SvIV($arg)'
6433 146         348 my $var_init = '';
6434 146         214 my $init_op;
6435 146 100       808 if ($line =~ s/\s* ([=;+]) \s* (.*) $//xs) {
6436 26         101 ($init_op, $var_init) = ($1, $2);
6437 26 100 100     384 $pxs->death("Error: missing '$init_op' initialiser value")
6438             unless $var_init =~ /\S/ && $var_init !~ /^\s*;\s*$/;
6439             }
6440              
6441 141         557 $line =~ s/\s+/ /g;
6442              
6443             # Split 'char * &foo' into ('char *', '&', 'foo')
6444             # skip to next INPUT line if not valid.
6445             #
6446             # Note that this pattern has a very liberal sense of what is "valid",
6447             # since we don't fully parse C types. For example:
6448             #
6449             # int foo(a)
6450             # int a XYZ
6451             #
6452             # would be interpreted as an "alien" (i.e. not in the signature)
6453             # variable called "XYZ", with a type of "int a". And because it's
6454             # alien the initialiser is skipped, so 'int a' is never looked up in
6455             # a typemap, so we don't detect anything wrong. Later on, the C
6456             # compiler is likely to trip over on the emitted declaration
6457             # however:
6458             # int a XYZ;
6459              
6460             my ($var_type, $var_addr, $var_name) =
6461             $line =~ /^
6462             ( .*? [^&\s] ) # type
6463             \s*
6464             (\&?) # addr
6465             \s* \b
6466             (\w+ | length\(\w+\)) # name or length(name)
6467             $
6468             /xs
6469 141 100       1420 or do {
6470 1         8 $pxs->blurt("Error: invalid parameter declaration '$self->{line}'");
6471 1         10 return;
6472             };
6473              
6474             # length(s) is only allowed in the XSUB's signature.
6475 140 100       441 if ($var_name =~ /^length\((\w+)\)$/) {
6476 2         20 $pxs->blurt("Error: length() not permitted in INPUT section");
6477 2         31 return;
6478             }
6479              
6480 138         300 my ($var_num, $is_alien);
6481              
6482 138         257 my $ioparams = $xbody->{ioparams};
6483              
6484             my ExtUtils::ParseXS::Node::IO_Param $ioparam =
6485 138         334 $ioparams->{names}{$var_name};
6486              
6487 138 100       316 if (defined $ioparam) {
6488             # The var appeared in the signature too.
6489              
6490             # Check for duplicate definitions of a particular parameter name.
6491             # This can be either because it has appeared in multiple INPUT
6492             # lines, or because the type was already defined in the signature,
6493             # and thus shouldn't be defined again. The exception to this are
6494             # synthetic params like THIS, which are assigned a provisional type
6495             # which can be overridden.
6496 128 100 100     923 if ( $ioparam->{in_input}
      100        
6497             or (!$ioparam->{is_synthetic} and defined $ioparam->{type})
6498             ) {
6499 7         53 $pxs->blurt(
6500             "Error: duplicate definition of parameter '$var_name' ignored");
6501 7         69 return;
6502             }
6503              
6504 121 100 100     431 if ($var_name eq 'RETVAL' and $ioparam->{is_synthetic}) {
6505             # Convert a synthetic RETVAL into a real parameter
6506 11         38 delete $ioparam->{is_synthetic};
6507 11         38 delete $ioparam->{no_init};
6508 11 100       53 if (! defined $ioparam->{arg_num}) {
6509             # if has arg_num, RETVAL has appeared in signature but with no
6510             # type, and has already been moved to the correct position;
6511             # otherwise, it's an alien var that didn't appear in the
6512             # signature; move to the correct position.
6513 6         22 @{$ioparams->{kids}} =
6514 6         19 grep $_ != $ioparam, @{$ioparams->{kids}};
  6         32  
6515 6         8 push @{$ioparams->{kids}}, $ioparam;
  6         14  
6516 6         12 $is_alien = 1;
6517 6         12 $ioparam->{is_alien} = 1;
6518             }
6519             }
6520              
6521 121         231 $ioparam->{in_input} = 1;
6522 121         188 $var_num = $ioparam->{arg_num};
6523             }
6524             else {
6525             # The var is in an INPUT line, but not in signature. Treat it as a
6526             # general var declaration (which really should have been in a
6527             # PREINIT section). Legal but nasty: flag is as 'alien'
6528 10         38 $is_alien = 1;
6529 10         77 $ioparam = ExtUtils::ParseXS::Node::IO_Param->new({
6530             var => $var_name,
6531             is_alien => 1,
6532             });
6533              
6534 10         37 push @{$ioparams->{kids}}, $ioparam;
  10         34  
6535 10         36 $ioparams->{names}{$var_name} = $ioparam;
6536             }
6537              
6538             # Parse the initialisation part of the INPUT line (if any)
6539              
6540 131         184 my ($init, $defer);
6541 131         229 my $no_init = $ioparam->{no_init}; # may have had OUT in signature
6542              
6543 131 100 100     604 if (!$no_init && defined $init_op) {
6544             # Use the init code based on overridden $var_init, which was
6545             # preceded by /[=;+]/ which has been extracted into $init_op
6546              
6547 20 100 100     203 if ( $init_op =~ /^[=;]$/
    100          
6548             and $var_init =~ /^NO_INIT\s*;?\s*$/
6549             ) {
6550             # NO_INIT: skip initialisation
6551 1         5 $no_init = 1;
6552             }
6553             elsif ($init_op eq '=') {
6554             # Overridden typemap, such as '= ($type)SvUV($arg)'
6555 13         84 $var_init =~ s/;\s*$//;
6556 13         39 $init = $var_init,
6557             }
6558             else {
6559             # "; extra code" or "+ extra code" :
6560             # append the extra code (after passing through eval) after all the
6561             # INPUT and PREINIT blocks have been processed, indirectly using
6562             # the $input_part->{deferred_code_lines} mechanism.
6563             # In addition, for '+', also generate the normal initialisation
6564             # code from the standard typemap - assuming that it's a real
6565             # parameter that appears in the signature as well as the INPUT
6566             # line.
6567 6   66     41 $no_init = !($init_op eq '+' && !$is_alien);
6568             # But in either case, add the deferred code
6569 6         15 $defer = $var_init;
6570             }
6571             }
6572             else {
6573             # no initialiser: emit var and init code based on typemap entry,
6574             # unless: it's alien (so no stack arg to bind to it)
6575 111 100       223 $no_init = 1 if $is_alien;
6576             }
6577              
6578             # Save the basic information parsed from this line
6579              
6580             $self->{type} = $var_type,
6581             $self->{is_addr} = !!$var_addr,
6582             $self->{name} = $var_name,
6583             $self->{init_op} = $init_op,
6584             $self->{init} = $var_init,
6585 131         598 $self->{ioparam} = $ioparam;
6586              
6587             # and also update the ioparam object using that information
6588              
6589 131         1154 %$ioparam = (
6590             %$ioparam,
6591             type => $var_type,
6592             arg_num => $var_num,
6593             var => $var_name,
6594             defer => $defer,
6595             init => $init,
6596             init_op => $init_op,
6597             no_init => $no_init,
6598             is_addr => !!$var_addr,
6599             );
6600              
6601 131         515 1;
6602             }
6603              
6604              
6605             sub as_code {
6606 131     131   178 my __PACKAGE__ $self = shift;
6607 131         179 my ExtUtils::ParseXS $pxs = shift;
6608 131         178 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6609 131         159 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6610              
6611             # Emit "type var" declaration and possibly various forms of
6612             # initialiser code.
6613              
6614 131         209 my $ioparam = $self->{ioparam};
6615              
6616             # Synthetic params like THIS will be emitted later - they
6617             # are treated like ANSI params, except the type can overridden
6618             # within an INPUT statement
6619 131 100       353 return if $ioparam->{is_synthetic};
6620              
6621             # The ioparam object contains data from both the INPUT line and
6622             # the XSUB signature.
6623 123         536 $ioparam->as_input_code($pxs, $xsub, $xbody);
6624             }
6625              
6626              
6627             # ======================================================================
6628              
6629             package ExtUtils::ParseXS::Node::OUTPUT;
6630              
6631             # Handle an OUTPUT: block
6632              
6633 28     28   139 BEGIN { $build_subclass->(-parent => 'keylines',
6634             )};
6635              
6636             # The inherited parse() method will call OUTPUT_line->parse() for each line
6637              
6638              
6639             # ======================================================================
6640              
6641             package ExtUtils::ParseXS::Node::OUTPUT_line;
6642              
6643             # Handle one line from an OUTPUT keyword block
6644              
6645 28     28   95 BEGIN { $build_subclass->(-parent => 'keyline',
6646             'ioparam', # the IO_Param object associated with this OUTPUT line.
6647             'is_setmagic', # Bool: the line is a SETMAGIC: line
6648             'do_setmagic', # Bool: the current SETMAGIC state
6649             'name', # Str: name of the parameter to output
6650             'code', # Str: optional setting code
6651             )};
6652              
6653              
6654             # Parse one line from an OUTPUT block
6655              
6656             sub parse {
6657 83     83   183 my __PACKAGE__ $self = shift;
6658 83         194 my ExtUtils::ParseXS $pxs = shift;
6659 83         145 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6660 83         126 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6661 83         151 my ExtUtils::ParseXS::Node::OUTPUT $parent = shift; # parent OUTPUT node
6662              
6663 83         302 $self->SUPER::parse($pxs); # set file/line_no/line
6664 83         158 my $line = $self->{line}; # line of text to be processed
6665              
6666 83 50       494 return unless $line =~ /\S/; # skip blank lines
6667              
6668             # set some sane default values in case we do one of the early returns
6669             # below
6670              
6671 83         211 $self->{do_setmagic} = $xbody->{OUTPUT_SETMAGIC_state};
6672 83         165 $self->{is_setmagic} = 0;
6673              
6674 83 100       432 if ($line =~ /^\s*SETMAGIC\s*:\s*(.*?)\s*$/) {
6675 7         25 my $arg = $1;
6676 7 100       47 unless ($arg =~ /^(ENABLE|DISABLE)$/) {
6677 1         19 $pxs->blurt("Error: SETMAGIC: invalid value '$arg' (should be ENABLE/DISABLE)");
6678 1         14 return;
6679             }
6680 6 100       18 $xbody->{OUTPUT_SETMAGIC_state} = ($arg eq "ENABLE" ? 1 : 0);
6681 6         11 $self->{do_setmagic} = $xbody->{OUTPUT_SETMAGIC_state};
6682 6         8 $self->{is_setmagic} = 1;
6683 6         29 return;
6684             }
6685              
6686             # Expect lines of the two forms
6687             # SomeVar
6688             # SomeVar sv_setsv(....);
6689             #
6690 76         505 my ($outarg, $outcode) = $line =~ /^\s*(\S+)\s*(.*?)\s*$/s;
6691              
6692 76         215 $self->{name} = $outarg;
6693              
6694             my ExtUtils::ParseXS::Node::IO_Param $ioparam =
6695 76         214 $xbody->{ioparams}{names}{$outarg};
6696 76         153 $self->{ioparam} = $ioparam;
6697              
6698 76 100 100     473 if ($ioparam && $ioparam->{in_output}) {
6699 2         29 $pxs->blurt("Error: duplicate OUTPUT parameter '$outarg' ignored");
6700 2         21 return;
6701             }
6702              
6703 74 100 100     530 if ( $outarg eq "RETVAL"
6704             and $xsub->{decl}{return_type}{no_output})
6705             {
6706 3         30 $pxs->blurt( "Error: can't use RETVAL in OUTPUT "
6707             . "when NO_OUTPUT declared");
6708 3         22 return;
6709             }
6710              
6711 71 100 66     459 if ( !$ioparam # no such param or, for RETVAL, RETVAL was void;
      66        
6712             # not bound to an arg which can be updated
6713             or $outarg ne "RETVAL" && !$ioparam->{arg_num})
6714             {
6715 3         31 $pxs->blurt("Error: OUTPUT $outarg not a parameter");
6716 3         23 return;
6717             }
6718              
6719 68         209 $ioparam->{in_output} = 1;
6720             $ioparam->{do_setmagic} = $outarg eq 'RETVAL'
6721             ? 0 # RETVAL never needs magic setting
6722 68 100       197 : $xbody->{OUTPUT_SETMAGIC_state};
6723 68 100       172 $self->{code} = $ioparam->{output_code} = $outcode if length $outcode;
6724              
6725 68         191 1;
6726             }
6727              
6728              
6729             sub as_code {
6730 68     68   99 my __PACKAGE__ $self = shift;
6731 68         132 my ExtUtils::ParseXS $pxs = shift;
6732 68         91 my ExtUtils::ParseXS::Node::xsub $xsub = shift;
6733 68         95 my ExtUtils::ParseXS::Node::xbody $xbody = shift;
6734              
6735             # An OUTPUT: line serves two logically distinct purposes. First, any
6736             # parameters listed are updated; i.e. the perl equivalent of
6737             #
6738             # my $foo = $_[0];
6739             # # maybe $foo's value gets changed here
6740             # $_[0] = $foo; # update caller's arg with current value
6741             #
6742             # The code for updating such OUTPUT vars is emitted here, in the
6743             # same order they appear in OUTPUT lines, and preserving the order
6744             # of any intermixed POSTCALL etc blocks.
6745             #
6746             # Second, it can be used to indicate that an SV should be created,
6747             # set to the current value of RETVAL, and pushed on the stack; i.e
6748             # the perl equivalent of
6749             #
6750             # my $RETVAL;
6751             # # maybe $RETVAL's value gets set here
6752             # return $RETVAL;
6753             #
6754             # The code to return RETVAL is emitted later, after all other
6755             # processing for XSUB is complete apart from any final CLEANUP block.
6756             # It is done at the same time as any emitting for params declared as
6757             # OUT or OUTLIST in the signature.
6758             #
6759             # There isn't any particularly strong reason to do things in this
6760             # exact order; but the ordering was the result of how xsubpp was
6761             # originally written and subsequently modified, and changing things
6762             # now might break existing XS code which has come to rely on the
6763             # ordering.
6764              
6765 68 100       249 return if $self->{name} eq 'RETVAL';
6766              
6767 23         46 my $ioparam = $self->{ioparam};
6768 23 50       83 return unless $ioparam; # might be an ENABLE line with no param to emit
6769              
6770 23         86 $ioparam->as_output_code($pxs);
6771             }
6772              
6773              
6774             # ======================================================================
6775              
6776              
6777             1;
6778              
6779             # vim: ts=4 sts=4 sw=4: et: