1#!/usr/bin/perl -w 2# 3# Regenerate (overwriting only if changed): 4# 5# embed.h 6# embedvar.h 7# perlapi.c 8# perlapi.h 9# proto.h 10# 11# from information stored in 12# 13# embed.fnc 14# intrpvar.h 15# perlvars.h 16# regen/opcodes 17# 18# Accepts the standard regen_lib -q and -v args. 19# 20# This script is normally invoked from regen.pl. 21 22require 5.004; # keep this compatible, an old perl is all we may have before 23 # we build the new one 24 25use strict; 26 27BEGIN { 28 # Get function prototypes 29 require './regen/regen_lib.pl'; 30 require './regen/embed_lib.pl'; 31} 32 33my $unflagged_pointers; 34 35# 36# See database of global and static function prototypes in embed.fnc 37# This is used to generate prototype headers under various configurations, 38# export symbols lists for different platforms, and macros to provide an 39# implicit interpreter context argument. 40# 41 42my $error_count = 0; 43sub die_at_end ($) { # Keeps going for now, but makes sure the regen doesn't 44 # succeed. 45 warn shift; 46 $error_count++; 47} 48 49sub full_name ($$) { # Returns the function name with potentially the 50 # prefixes 'S_' or 'Perl_' 51 my ($func, $flags) = @_; 52 53 return "Perl_$func" if $flags =~ /p/; 54 return "S_$func" if $flags =~ /[SIi]/; 55 return $func; 56} 57 58sub open_print_header { 59 my ($file, $quote) = @_; 60 61 return open_new($file, '>', 62 { file => $file, style => '*', by => 'regen/embed.pl', 63 from => ['data in embed.fnc', 'regen/embed.pl', 64 'regen/opcodes', 'intrpvar.h', 'perlvars.h'], 65 final => "\nEdit those files and run 'make regen_headers' to effect changes.\n", 66 copyright => [1993 .. 2009], quote => $quote }); 67} 68 69my ($embed, $core, $ext, $api) = setup_embed(); 70 71# generate proto.h 72{ 73 my $pr = open_print_header("proto.h"); 74 print $pr "START_EXTERN_C\n"; 75 my $ret; 76 77 foreach (@$embed) { 78 if (@$_ == 1) { 79 print $pr "$_->[0]\n"; 80 next; 81 } 82 83 my ($flags,$retval,$plain_func,@args) = @$_; 84 if ($flags =~ / ( [^AabCDdEefFGhIiMmNnOoPpRrSsTUuWXx] ) /x) { 85 die_at_end "flag $1 is not legal (for function $plain_func)"; 86 } 87 my @nonnull; 88 my $args_assert_line = ( $flags !~ /G/ ); 89 my $has_depth = ( $flags =~ /W/ ); 90 my $has_context = ( $flags !~ /T/ ); 91 my $never_returns = ( $flags =~ /r/ ); 92 my $binarycompat = ( $flags =~ /b/ ); 93 my $commented_out = ( $flags =~ /m/ ); 94 my $is_malloc = ( $flags =~ /a/ ); 95 my $can_ignore = ( $flags !~ /R/ ) && ( $flags !~ /P/ ) && !$is_malloc; 96 my @names_of_nn; 97 my $func; 98 99 if (! $can_ignore && $retval eq 'void') { 100 warn "It is nonsensical to require the return value of a void function ($plain_func) to be checked"; 101 } 102 103 die_at_end "$plain_func: S and p flags are mutually exclusive" 104 if $flags =~ /S/ && $flags =~ /p/; 105 die_at_end "$plain_func: m and $1 flags are mutually exclusive" 106 if $flags =~ /m/ && $flags =~ /([pS])/; 107 108 die_at_end "$plain_func: u flag only usable with m" if $flags =~ /u/ 109 && $flags !~ /m/; 110 111 my $static_inline = 0; 112 if ($flags =~ /([SIi])/) { 113 my $type; 114 if ($never_returns) { 115 $type = { 116 'S' => 'PERL_STATIC_NO_RET', 117 'i' => 'PERL_STATIC_INLINE_NO_RET', 118 'I' => 'PERL_STATIC_FORCE_INLINE_NO_RET' 119 }->{$1}; 120 } 121 else { 122 $type = { 123 'S' => 'STATIC', 124 'i' => 'PERL_STATIC_INLINE', 125 'I' => 'PERL_STATIC_FORCE_INLINE' 126 }->{$1}; 127 } 128 $retval = "$type $retval"; 129 die_at_end "Don't declare static function '$plain_func' pure" if $flags =~ /P/; 130 $static_inline = $type =~ /^PERL_STATIC(?:_FORCE)?_INLINE/; 131 } 132 else { 133 if ($never_returns) { 134 $retval = "PERL_CALLCONV_NO_RET $retval"; 135 } 136 else { 137 $retval = "PERL_CALLCONV $retval"; 138 } 139 } 140 141 die_at_end "For '$plain_func', M flag requires p flag" 142 if $flags =~ /M/ && $flags !~ /p/; 143 die_at_end "For '$plain_func', C flag requires one of [pIimb] flags" 144 if $flags =~ /C/ && $flags !~ /[Iibmp]/; 145 die_at_end "For '$plain_func', X flag requires one of [Iip] flags" 146 if $flags =~ /X/ && $flags !~ /[Iip]/; 147 die_at_end "For '$plain_func', X and m flags are mutually exclusive" 148 if $flags =~ /X/ && $flags =~ /m/; 149 die_at_end "For '$plain_func', [Ii] with [ACX] requires p flag" 150 if $flags =~ /[Ii]/ && $flags =~ /[ACX]/ && $flags !~ /p/; 151 die_at_end "For '$plain_func', b and m flags are mutually exclusive" 152 . " (try M flag)" if $flags =~ /b/ && $flags =~ /m/; 153 die_at_end "For '$plain_func', b flag without M flag requires D flag" 154 if $flags =~ /b/ && $flags !~ /M/ && $flags !~ /D/; 155 die_at_end "For '$plain_func', I and i flags are mutually exclusive" 156 if $flags =~ /I/ && $flags =~ /i/; 157 158 $func = full_name($plain_func, $flags); 159 $ret = ""; 160 $ret .= "$retval\t$func("; 161 if ( $has_context ) { 162 $ret .= @args ? "pTHX_ " : "pTHX"; 163 } 164 if (@args) { 165 die_at_end "n flag is contradicted by having arguments" 166 if $flags =~ /n/; 167 my $n; 168 for my $arg ( @args ) { 169 ++$n; 170 if ( $arg =~ /\*/ && $arg !~ /\b(NN|NULLOK)\b/ ) { 171 warn "$func: $arg needs NN or NULLOK\n"; 172 ++$unflagged_pointers; 173 } 174 my $nn = ( $arg =~ s/\s*\bNN\b\s+// ); 175 push( @nonnull, $n ) if $nn; 176 177 my $nullok = ( $arg =~ s/\s*\bNULLOK\b\s+// ); # strip NULLOK with no effect 178 179 # Make sure each arg has at least a type and a var name. 180 # An arg of "int" is valid C, but want it to be "int foo". 181 my $temp_arg = $arg; 182 $temp_arg =~ s/\*//g; 183 $temp_arg =~ s/\s*\bstruct\b\s*/ /g; 184 if ( ($temp_arg ne "...") 185 && ($temp_arg !~ /\w+\s+(\w+)(?:\[\d+\])?\s*$/) ) { 186 die_at_end "$func: $arg ($n) doesn't have a name\n"; 187 } 188 if (defined $1 && $nn && !($commented_out && !$binarycompat)) { 189 push @names_of_nn, $1; 190 } 191 } 192 $ret .= join ", ", @args; 193 } 194 else { 195 $ret .= "void" if !$has_context; 196 } 197 $ret .= " _pDEPTH" if $has_depth; 198 $ret .= ")"; 199 my @attrs; 200 if ( $flags =~ /r/ ) { 201 push @attrs, "__attribute__noreturn__"; 202 } 203 if ( $flags =~ /D/ ) { 204 push @attrs, "__attribute__deprecated__"; 205 } 206 if ( $is_malloc ) { 207 push @attrs, "__attribute__malloc__"; 208 } 209 if ( !$can_ignore ) { 210 push @attrs, "__attribute__warn_unused_result__"; 211 } 212 if ( $flags =~ /P/ ) { 213 push @attrs, "__attribute__pure__"; 214 } 215 if ( $flags =~ /I/ ) { 216 push @attrs, "__attribute__always_inline__"; 217 } 218 if( $flags =~ /f/ ) { 219 my $prefix = $has_context ? 'pTHX_' : ''; 220 my ($args, $pat); 221 if ($args[-1] eq '...') { 222 $args = scalar @args; 223 $pat = $args - 1; 224 $args = $prefix . $args; 225 } 226 else { 227 # don't check args, and guess which arg is the pattern 228 # (one of 'fmt', 'pat', 'f'), 229 $args = 0; 230 my @fmts = grep $args[$_] =~ /\b(f|pat|fmt)$/, 0..$#args; 231 if (@fmts != 1) { 232 die "embed.pl: '$plain_func': can't determine pattern arg\n"; 233 } 234 $pat = $fmts[0] + 1; 235 } 236 my $macro = grep($_ == $pat, @nonnull) 237 ? '__attribute__format__' 238 : '__attribute__format__null_ok__'; 239 if ($plain_func =~ /strftime/) { 240 push @attrs, sprintf "%s(__strftime__,%s1,0)", $macro, $prefix; 241 } 242 else { 243 push @attrs, sprintf "%s(__printf__,%s%d,%s)", $macro, 244 $prefix, $pat, $args; 245 } 246 } 247 elsif ((grep { $_ eq '...' } @args) && $flags !~ /F/) { 248 die_at_end "$plain_func: Function with '...' arguments must have" 249 . " f or F flag"; 250 } 251 if ( @attrs ) { 252 $ret .= "\n"; 253 $ret .= join( "\n", map { "\t\t\t$_" } @attrs ); 254 } 255 $ret .= ";"; 256 $ret = "/* $ret */" if $commented_out; 257 258 $ret .= "\n#define PERL_ARGS_ASSERT_\U$plain_func\E" 259 if $args_assert_line || @names_of_nn; 260 $ret .= "\t\\\n\t" . join '; ', map "assert($_)", @names_of_nn 261 if @names_of_nn; 262 263 $ret = "#ifndef PERL_NO_INLINE_FUNCTIONS\n$ret\n#endif" if $static_inline; 264 $ret = "#ifndef NO_MATHOMS\n$ret\n#endif" if $binarycompat; 265 $ret .= @attrs ? "\n\n" : "\n"; 266 267 print $pr $ret; 268 } 269 270 print $pr <<'EOF'; 271#ifdef PERL_CORE 272# include "pp_proto.h" 273#endif 274END_EXTERN_C 275EOF 276 277 read_only_bottom_close_and_rename($pr) if ! $error_count; 278} 279 280die_at_end "$unflagged_pointers pointer arguments to clean up\n" if $unflagged_pointers; 281 282sub readvars { 283 my ($file, $pre) = @_; 284 local (*FILE, $_); 285 my %seen; 286 open(FILE, '<', $file) 287 or die "embed.pl: Can't open $file: $!\n"; 288 while (<FILE>) { 289 s/[ \t]*#.*//; # Delete comments. 290 if (/PERLVARA?I?C?\($pre,\s*(\w+)/) { 291 die_at_end "duplicate symbol $1 while processing $file line $.\n" 292 if $seen{$1}++; 293 } 294 } 295 close(FILE); 296 return sort keys %seen; 297} 298 299my @intrp = readvars 'intrpvar.h','I'; 300my @globvar = readvars 'perlvars.h','G'; 301 302sub hide { 303 my ($from, $to, $indent) = @_; 304 $indent = '' unless defined $indent; 305 my $t = int(length("$indent$from") / 8); 306 "#${indent}define $from" . "\t" x ($t < 3 ? 3 - $t : 1) . "$to\n"; 307} 308 309sub multon ($$$) { 310 my ($sym,$pre,$ptr) = @_; 311 hide("PL_$sym", "($ptr$pre$sym)"); 312} 313 314my $em = open_print_header('embed.h'); 315 316print $em <<'END'; 317/* (Doing namespace management portably in C is really gross.) */ 318 319/* By defining PERL_NO_SHORT_NAMES (not done by default) the short forms 320 * (like warn instead of Perl_warn) for the API are not defined. 321 * Not defining the short forms is a good thing for cleaner embedding. */ 322 323#ifndef PERL_NO_SHORT_NAMES 324 325/* Hide global symbols */ 326 327END 328 329my @az = ('a'..'z'); 330 331sub embed_h { 332 my ($guard, $funcs) = @_; 333 print $em "$guard\n" if $guard; 334 335 my $lines; 336 foreach (@$funcs) { 337 if (@$_ == 1) { 338 my $cond = $_->[0]; 339 # Indent the conditionals if we are wrapped in an #if/#endif pair. 340 $cond =~ s/#(.*)/# $1/ if $guard; 341 $lines .= "$cond\n"; 342 next; 343 } 344 my $ret = ""; 345 my ($flags,$retval,$func,@args) = @$_; 346 unless ($flags =~ /[omM]/) { 347 my $args = scalar @args; 348 if ($flags =~ /T/) { 349 my $full_name = full_name($func, $flags); 350 next if $full_name eq $func; # Don't output a no-op. 351 $ret = hide($func, $full_name); 352 } 353 elsif ($args and $args[$args-1] =~ /\.\.\./) { 354 if ($flags =~ /p/) { 355 # we're out of luck for varargs functions under CPP 356 # So we can only do these macros for no implicit context: 357 $ret = "#ifndef PERL_IMPLICIT_CONTEXT\n" 358 . hide($func, full_name($func, $flags)) . "#endif\n"; 359 } 360 } 361 else { 362 my $alist = join(",", @az[0..$args-1]); 363 $ret = "#define $func($alist)"; 364 my $t = int(length($ret) / 8); 365 $ret .= "\t" x ($t < 4 ? 4 - $t : 1); 366 $ret .= full_name($func, $flags) . "(aTHX"; 367 $ret .= "_ " if $alist; 368 $ret .= $alist; 369 if ($flags =~ /W/) { 370 if ($alist) { 371 $ret .= " _aDEPTH"; 372 } else { 373 die "Can't use W without other args (currently)"; 374 } 375 } 376 $ret .= ")\n"; 377 } 378 $ret = "#ifndef NO_MATHOMS\n$ret#endif\n" if $flags =~ /b/; 379 } 380 $lines .= $ret; 381 } 382 # Prune empty #if/#endif pairs. 383 while ($lines =~ s/#\s*if[^\n]+\n#\s*endif\n//) { 384 } 385 # Merge adjacent blocks. 386 while ($lines =~ s/(#ifndef PERL_IMPLICIT_CONTEXT 387[^\n]+ 388)#endif 389#ifndef PERL_IMPLICIT_CONTEXT 390/$1/) { 391 } 392 393 print $em $lines; 394 print $em "#endif\n" if $guard; 395} 396 397embed_h('', $api); 398embed_h('#if defined(PERL_CORE) || defined(PERL_EXT)', $ext); 399embed_h('#ifdef PERL_CORE', $core); 400 401print $em <<'END'; 402 403#endif /* #ifndef PERL_NO_SHORT_NAMES */ 404 405/* Compatibility stubs. Compile extensions with -DPERL_NOCOMPAT to 406 disable them. 407 */ 408 409#if !defined(PERL_CORE) 410# define sv_setptrobj(rv,ptr,name) sv_setref_iv(rv,name,PTR2IV(ptr)) 411# define sv_setptrref(rv,ptr) sv_setref_iv(rv,NULL,PTR2IV(ptr)) 412#endif 413 414#if !defined(PERL_CORE) && !defined(PERL_NOCOMPAT) 415 416/* Compatibility for various misnamed functions. All functions 417 in the API that begin with "perl_" (not "Perl_") take an explicit 418 interpreter context pointer. 419 The following are not like that, but since they had a "perl_" 420 prefix in previous versions, we provide compatibility macros. 421 */ 422# define perl_atexit(a,b) call_atexit(a,b) 423END 424 425foreach (@$embed) { 426 my ($flags, $retval, $func, @args) = @$_; 427 next unless $func; 428 next unless $flags =~ /O/; 429 430 my $alist = join ",", @az[0..$#args]; 431 my $ret = "# define perl_$func($alist)"; 432 my $t = (length $ret) >> 3; 433 $ret .= "\t" x ($t < 5 ? 5 - $t : 1); 434 print $em "$ret$func($alist)\n"; 435} 436 437my @nocontext; 438{ 439 my (%has_va, %has_nocontext); 440 foreach (@$embed) { 441 next unless @$_ > 1; 442 ++$has_va{$_->[2]} if $_->[-1] =~ /\.\.\./; 443 ++$has_nocontext{$1} if $_->[2] =~ /(.*)_nocontext/; 444 } 445 446 @nocontext = sort grep { 447 $has_nocontext{$_} 448 && !/printf/ # Not clear to me why these are skipped but they are. 449 } keys %has_va; 450} 451 452print $em <<'END'; 453 454/* varargs functions can't be handled with CPP macros. :-( 455 This provides a set of compatibility functions that don't take 456 an extra argument but grab the context pointer using the macro 457 dTHX. 458 */ 459#if defined(PERL_IMPLICIT_CONTEXT) && !defined(PERL_NO_SHORT_NAMES) 460END 461 462foreach (@nocontext) { 463 print $em hide($_, "Perl_${_}_nocontext", " "); 464} 465 466print $em <<'END'; 467#endif 468 469#endif /* !defined(PERL_CORE) && !defined(PERL_NOCOMPAT) */ 470 471#if !defined(PERL_IMPLICIT_CONTEXT) 472/* undefined symbols, point them back at the usual ones */ 473END 474 475foreach (@nocontext) { 476 print $em hide("Perl_${_}_nocontext", "Perl_$_", " "); 477} 478 479print $em <<'END'; 480#endif 481END 482 483read_only_bottom_close_and_rename($em) if ! $error_count; 484 485$em = open_print_header('embedvar.h'); 486 487print $em <<'END'; 488/* (Doing namespace management portably in C is really gross.) */ 489 490/* 491 The following combinations of MULTIPLICITY and PERL_IMPLICIT_CONTEXT 492 are supported: 493 1) none 494 2) MULTIPLICITY # supported for compatibility 495 3) MULTIPLICITY && PERL_IMPLICIT_CONTEXT 496 497 All other combinations of these flags are errors. 498 499 only #3 is supported directly, while #2 is a special 500 case of #3 (supported by redefining vTHX appropriately). 501*/ 502 503#if defined(MULTIPLICITY) 504/* cases 2 and 3 above */ 505 506# if defined(PERL_IMPLICIT_CONTEXT) 507# define vTHX aTHX 508# else 509# define vTHX PERL_GET_INTERP 510# endif 511 512END 513 514my $sym; 515 516for $sym (@intrp) { 517 if ($sym eq 'sawampersand') { 518 print $em "#ifndef PL_sawampersand\n"; 519 } 520 print $em multon($sym,'I','vTHX->'); 521 if ($sym eq 'sawampersand') { 522 print $em "#endif\n"; 523 } 524} 525 526print $em <<'END'; 527 528#endif /* MULTIPLICITY */ 529 530#if defined(PERL_GLOBAL_STRUCT) 531 532END 533 534for $sym (@globvar) { 535 print $em "#ifdef OS2\n" if $sym eq 'sh_path'; 536 print $em "#ifdef __VMS\n" if $sym eq 'perllib_sep'; 537 print $em multon($sym, 'G','my_vars->'); 538 print $em multon("G$sym",'', 'my_vars->'); 539 print $em "#endif\n" if $sym eq 'sh_path'; 540 print $em "#endif\n" if $sym eq 'perllib_sep'; 541} 542 543print $em <<'END'; 544 545#endif /* PERL_GLOBAL_STRUCT */ 546END 547 548read_only_bottom_close_and_rename($em) if ! $error_count; 549 550my $capih = open_print_header('perlapi.h'); 551 552print $capih <<'EOT'; 553/* declare accessor functions for Perl variables */ 554#ifndef __perlapi_h__ 555#define __perlapi_h__ 556 557#if defined (MULTIPLICITY) && defined (PERL_GLOBAL_STRUCT) 558 559START_EXTERN_C 560 561#undef PERLVAR 562#undef PERLVARA 563#undef PERLVARI 564#undef PERLVARIC 565#define PERLVAR(p,v,t) EXTERN_C t* Perl_##p##v##_ptr(pTHX); 566#define PERLVARA(p,v,n,t) typedef t PL_##v##_t[n]; \ 567 EXTERN_C PL_##v##_t* Perl_##p##v##_ptr(pTHX); 568#define PERLVARI(p,v,t,i) PERLVAR(p,v,t) 569#define PERLVARIC(p,v,t,i) PERLVAR(p,v, const t) 570 571#include "perlvars.h" 572 573#undef PERLVAR 574#undef PERLVARA 575#undef PERLVARI 576#undef PERLVARIC 577 578END_EXTERN_C 579 580#if defined(PERL_CORE) 581 582/* accessor functions for Perl "global" variables */ 583 584/* these need to be mentioned here, or most linkers won't put them in 585 the perl executable */ 586 587#ifndef PERL_NO_FORCE_LINK 588 589START_EXTERN_C 590 591#ifndef DOINIT 592EXTCONST void * const PL_force_link_funcs[]; 593#else 594EXTCONST void * const PL_force_link_funcs[] = { 595#undef PERLVAR 596#undef PERLVARA 597#undef PERLVARI 598#undef PERLVARIC 599#define PERLVAR(p,v,t) (void*)Perl_##p##v##_ptr, 600#define PERLVARA(p,v,n,t) PERLVAR(p,v,t) 601#define PERLVARI(p,v,t,i) PERLVAR(p,v,t) 602#define PERLVARIC(p,v,t,i) PERLVAR(p,v,t) 603 604/* In Tru64 (__DEC && __osf__) the cc option -std1 causes that one 605 * cannot cast between void pointers and function pointers without 606 * info level warnings. The PL_force_link_funcs[] would cause a few 607 * hundred of those warnings. In code one can circumnavigate this by using 608 * unions that overlay the different pointers, but in declarations one 609 * cannot use this trick. Therefore we just disable the warning here 610 * for the duration of the PL_force_link_funcs[] declaration. */ 611 612#if defined(__DECC) && defined(__osf__) 613#pragma message save 614#pragma message disable (nonstandcast) 615#endif 616 617#include "perlvars.h" 618 619#if defined(__DECC) && defined(__osf__) 620#pragma message restore 621#endif 622 623#undef PERLVAR 624#undef PERLVARA 625#undef PERLVARI 626#undef PERLVARIC 627}; 628#endif /* DOINIT */ 629 630END_EXTERN_C 631 632#endif /* PERL_NO_FORCE_LINK */ 633 634#else /* !PERL_CORE */ 635 636EOT 637 638foreach $sym (@globvar) { 639 print $capih 640 "#undef PL_$sym\n" . hide("PL_$sym", "(*Perl_G${sym}_ptr(NULL))"); 641} 642 643print $capih <<'EOT'; 644 645#endif /* !PERL_CORE */ 646#endif /* MULTIPLICITY && PERL_GLOBAL_STRUCT */ 647 648#endif /* __perlapi_h__ */ 649EOT 650 651read_only_bottom_close_and_rename($capih) if ! $error_count; 652 653my $capi = open_print_header('perlapi.c', <<'EOQ'); 654 * 655 * 656 * Up to the threshold of the door there mounted a flight of twenty-seven 657 * broad stairs, hewn by some unknown art of the same black stone. This 658 * was the only entrance to the tower; ... 659 * 660 * [p.577 of _The Lord of the Rings_, III/x: "The Voice of Saruman"] 661 * 662 */ 663EOQ 664 665print $capi <<'EOT'; 666#include "EXTERN.h" 667#include "perl.h" 668#include "perlapi.h" 669 670#if defined (MULTIPLICITY) && defined (PERL_GLOBAL_STRUCT) 671 672/* accessor functions for Perl "global" variables */ 673START_EXTERN_C 674 675#undef PERLVARI 676#define PERLVARI(p,v,t,i) PERLVAR(p,v,t) 677 678#undef PERLVAR 679#undef PERLVARA 680#define PERLVAR(p,v,t) t* Perl_##p##v##_ptr(pTHX) \ 681 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); } 682#define PERLVARA(p,v,n,t) PL_##v##_t* Perl_##p##v##_ptr(pTHX) \ 683 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); } 684#undef PERLVARIC 685#define PERLVARIC(p,v,t,i) \ 686 const t* Perl_##p##v##_ptr(pTHX) \ 687 { PERL_UNUSED_CONTEXT; return (const t *)&(PL_##v); } 688#include "perlvars.h" 689 690#undef PERLVAR 691#undef PERLVARA 692#undef PERLVARI 693#undef PERLVARIC 694 695END_EXTERN_C 696 697#endif /* MULTIPLICITY && PERL_GLOBAL_STRUCT */ 698EOT 699 700read_only_bottom_close_and_rename($capi) if ! $error_count; 701 702die "$error_count errors found" if $error_count; 703 704# ex: set ts=8 sts=4 sw=4 noet: 705