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