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