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