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