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