3 # Regenerate (overwriting only if changed):
12 # from information stored in
19 # Accepts the standard regen_lib -q and -v args.
21 # This script is normally invoked from regen.pl.
23 require 5.004; # keep this compatible, an old perl is all we may have before
24 # we build the new one
29 # Get function prototypes
30 require 'regen/regen_lib.pl';
33 my $SPLINT = 0; # Turn true for experimental splint support http://www.splint.org
34 my $unflagged_pointers;
37 # See database of global and static function prototypes in embed.fnc
38 # This is used to generate prototype headers under various configurations,
39 # export symbols lists for different platforms, and macros to provide an
40 # implicit interpreter context argument.
47 my $years = '1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009';
49 $years =~ s/1999,/1999,\n / if length $years > 40;
52 -*- buffer-read-only: t -*-
56 Copyright (C) $years, by Larry Wall and others
58 You may distribute under the terms of either the GNU General Public
59 License or the Artistic License, as specified in the README file.
61 !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
62 This file is built by regen/embed.pl from data in embed.fnc,
63 regen/embed.pl, regen/opcodes intrpvar.h, and perlvars.h.
64 Any changes made here will be lost!
66 Edit those files and run 'make regen_headers' to effect changes.
70 $warning .= <<EOW if $file eq 'perlapi.c';
72 Up to the threshold of the door there mounted a flight of twenty-seven
73 broad stairs, hewn by some unknown art of the same black stone. This
74 was the only entrance to the tower; ...
76 [p.577 of _The Lord of the Rings_, III/x: "The Voice of Saruman"]
81 if ($file =~ m:\.[ch]$:) {
82 $warning =~ s:^: * :gm;
83 $warning =~ s: +$::gm;
88 $warning =~ s:^:# :gm;
89 $warning =~ s: +$::gm;
94 open IN, "embed.fnc" or die $!;
97 my (%has_va, %has_nocontext);
113 @args = split /\s*\|\s*/, $_;
116 ++$has_va{$func} if $args[-1] =~ /\.\.\./;
117 ++$has_nocontext{$1} if $func =~ /(.*)_nocontext/;
120 if (@args == 1 && $args[0] !~ /^#\s*(?:if|ifdef|ifndef|else|endif)/) {
121 die "Illegal line $. '$args[0]' in embed.fnc";
126 open IN, 'regen/opcodes' or die $!;
134 my (undef, undef, $check) = split /\t+/, $_;
138 foreach (keys %syms) {
139 # These are all indirectly referenced by globals.c.
140 push @embed, ['pR', 'OP *', $_, 'NN OP *o'];
145 my (@core, @ext, @api);
147 # Cluster entries in embed.fnc that have the same #ifdef guards.
148 # Also, split out at the top level the three classes of functions.
157 $_->[0] =~ s/^#\s+/#/;
159 $_->[0] =~ s/^#ifdef\s+(\S+)/#if defined($1)/;
160 $_->[0] =~ s/^#ifndef\s+(\S+)/#if !defined($1)/;
161 if ($_->[0] =~ /^#if\s*(.*)/) {
163 } elsif ($_->[0] =~ /^#else\s*$/) {
164 die "Unmatched #else in embed.fnc" unless @state;
165 $state[-1] = "!($state[-1])";
166 } elsif ($_->[0] =~ m!^#endif\s*(?:/\*.*\*/)?$!) {
167 die "Unmatched #endif in embed.fnc" unless @state;
170 die "Unhandled pre-processor directive '$_->[0]' in embed.fnc";
173 # Nested #if blocks are effectively &&ed together
174 # For embed.fnc, ordering withing the && isn't relevant, so we can
175 # sort them to try to group more functions together.
176 my @sorted = sort @state;
177 while (my $directive = shift @sorted) {
178 $current->{$directive} ||= {};
179 $current = $current->{$directive};
181 $current->{''} ||= [];
182 $current = $current->{''};
186 my ($level, $indent, $wanted) = @_;
187 my $funcs = $level->{''};
190 if (!defined $wanted) {
194 if ($_->[0] =~ /A/) {
195 push @entries, $_ if $wanted eq 'A';
196 } elsif ($_->[0] =~ /E/) {
197 push @entries, $_ if $wanted eq 'E';
199 push @entries, $_ if $wanted eq '';
203 @entries = sort {$a->[2] cmp $b->[2]} @entries;
205 foreach (sort grep {length $_} keys %$level) {
206 my @conditional = add_level($level->{$_}, $indent . ' ', $wanted);
208 ["#${indent}if $_"], @conditional, ["#${indent}endif"]
213 @core = add_level(\%groups, '', '');
214 @ext = add_level(\%groups, '', 'E');
215 @api = add_level(\%groups, '', 'A');
217 @embed = add_level(\%groups, '');
220 # walk table providing an array of components in each line to
221 # subroutine, printing the result
222 sub walk_table (&@) {
223 my ($function, $filename, $trailer) = @_;
225 if (ref $filename) { # filehandle
229 $F = safer_open("$filename-new");
230 print $F do_not_edit ($filename);
233 my @outs = &{$function}(@$_);
234 # $function->(@args) is not 5.003
237 print $F $trailer if $trailer;
238 unless (ref $filename) {
240 rename_if_different("$filename-new", $filename);
246 my $pr = safer_open('proto.h-new');
247 print $pr do_not_edit ("proto.h"), "\nSTART_EXTERN_C\n";
252 print $pr "$_->[0]\n";
256 my ($flags,$retval,$plain_func,@args) = @$_;
258 my $has_context = ( $flags !~ /n/ );
259 my $never_returns = ( $flags =~ /r/ );
260 my $commented_out = ( $flags =~ /m/ );
261 my $binarycompat = ( $flags =~ /b/ );
262 my $is_malloc = ( $flags =~ /a/ );
263 my $can_ignore = ( $flags !~ /R/ ) && !$is_malloc;
267 my $splint_flags = "";
268 if ( $SPLINT && !$commented_out ) {
269 $splint_flags .= '/*@noreturn@*/ ' if $never_returns;
270 if ($can_ignore && ($retval ne 'void') && ($retval !~ /\*/)) {
271 $retval .= " /*\@alt void\@*/";
276 $retval = "STATIC $splint_flags$retval";
277 $func = "S_$plain_func";
280 $retval = "PERL_CALLCONV $splint_flags$retval";
281 if ($flags =~ /[bp]/) {
282 $func = "Perl_$plain_func";
287 $ret = "$retval\t$func(";
288 if ( $has_context ) {
289 $ret .= @args ? "pTHX_ " : "pTHX";
293 for my $arg ( @args ) {
295 if ( $arg =~ /\*/ && $arg !~ /\b(NN|NULLOK)\b/ ) {
296 warn "$func: $arg needs NN or NULLOK\n";
297 ++$unflagged_pointers;
299 my $nn = ( $arg =~ s/\s*\bNN\b\s+// );
300 push( @nonnull, $n ) if $nn;
302 my $nullok = ( $arg =~ s/\s*\bNULLOK\b\s+// ); # strip NULLOK with no effect
304 # Make sure each arg has at least a type and a var name.
305 # An arg of "int" is valid C, but want it to be "int foo".
307 $temp_arg =~ s/\*//g;
308 $temp_arg =~ s/\s*\bstruct\b\s*/ /g;
309 if ( ($temp_arg ne "...")
310 && ($temp_arg !~ /\w+\s+(\w+)(?:\[\d+\])?\s*$/) ) {
311 warn "$func: $arg ($n) doesn't have a name\n";
313 if ( $SPLINT && $nullok && !$commented_out ) {
314 $arg = '/*@null@*/ ' . $arg;
316 if (defined $1 && $nn && !($commented_out && !$binarycompat)) {
317 push @names_of_nn, $1;
320 $ret .= join ", ", @args;
323 $ret .= "void" if !$has_context;
327 if ( $flags =~ /r/ ) {
328 push @attrs, "__attribute__noreturn__";
330 if ( $flags =~ /D/ ) {
331 push @attrs, "__attribute__deprecated__";
334 push @attrs, "__attribute__malloc__";
336 if ( !$can_ignore ) {
337 push @attrs, "__attribute__warn_unused_result__";
339 if ( $flags =~ /P/ ) {
340 push @attrs, "__attribute__pure__";
342 if( $flags =~ /f/ ) {
343 my $prefix = $has_context ? 'pTHX_' : '';
344 my $args = scalar @args;
346 my $macro = @nonnull && $nonnull[-1] == $pat
347 ? '__attribute__format__'
348 : '__attribute__format__null_ok__';
349 push @attrs, sprintf "%s(__printf__,%s%d,%s%d)", $macro,
350 $prefix, $pat, $prefix, $args;
353 my @pos = map { $has_context ? "pTHX_$_" : $_ } @nonnull;
354 push @attrs, map { sprintf( "__attribute__nonnull__(%s)", $_ ) } @pos;
358 $ret .= join( "\n", map { "\t\t\t$_" } @attrs );
361 $ret = "/* $ret */" if $commented_out;
363 $ret .= "\n#define PERL_ARGS_ASSERT_\U$plain_func\E\t\\\n\t"
364 . join '; ', map "assert($_)", @names_of_nn;
366 $ret .= @attrs ? "\n\n" : "\n";
373 # include "pp_proto.h"
380 rename_if_different('proto.h-new', 'proto.h');
383 # generates global.sym (API export list)
386 sub write_global_sym {
388 my ($flags,$retval,$func,@args) = @_;
389 if ($flags =~ /[AX]/ && $flags !~ /[xm]/
390 || $flags =~ /b/) { # public API, so export
391 # If a function is defined twice, for example before and after
392 # an #else, only export its name once.
393 return '' if $seen{$func}++;
394 $func = "Perl_$func" if $flags =~ /[pbX]/;
402 warn "$unflagged_pointers pointer arguments to clean up\n" if $unflagged_pointers;
403 walk_table(\&write_global_sym, "global.sym", "# ex: set ro:\n");
405 sub readvars(\%$$@) {
406 my ($syms, $file,$pre,$keep_pre) = @_;
408 open(FILE, "< $file")
409 or die "embed.pl: Can't open $file: $!\n";
411 s/[ \t]*#.*//; # Delete comments.
412 if (/PERLVARA?I?S?C?\($pre(\w+)/) {
414 $sym = $pre . $sym if $keep_pre;
415 warn "duplicate symbol $sym while processing $file line $.\n"
416 if exists $$syms{$sym};
417 $$syms{$sym} = $pre || 1;
426 readvars %intrp, 'intrpvar.h','I';
427 readvars %globvar, 'perlvars.h','G';
437 my ($from, $to, $indent) = @_;
438 $indent = '' unless defined $indent;
439 my $t = int(length("$indent$from") / 8);
440 "#${indent}define $from" . "\t" x ($t < 3 ? 3 - $t : 1) . "$to\n";
443 sub bincompat_var ($$) {
444 my ($pfx, $sym) = @_;
445 my $arg = ($pfx eq 'G' ? 'NULL' : 'aTHX');
446 undefine("PL_$sym") . hide("PL_$sym", "(*Perl_${pfx}${sym}_ptr($arg))");
450 my ($sym,$pre,$ptr) = @_;
451 hide("PL_$sym", "($ptr$pre$sym)");
456 return hide("PL_$pre$sym", "PL_$sym");
459 my $em = safer_open('embed.h-new');
461 print $em do_not_edit ("embed.h"), <<'END';
463 /* (Doing namespace management portably in C is really gross.) */
465 /* By defining PERL_NO_SHORT_NAMES (not done by default) the short forms
466 * (like warn instead of Perl_warn) for the API are not defined.
467 * Not defining the short forms is a good thing for cleaner embedding. */
469 #ifndef PERL_NO_SHORT_NAMES
471 /* Hide global symbols */
478 my ($guard, $funcs) = @_;
479 print $em "$guard\n" if $guard;
485 # Indent the conditionals if we are wrapped in an #if/#endif pair.
486 $cond =~ s/#(.*)/# $1/ if $guard;
491 my ($flags,$retval,$func,@args) = @$_;
492 unless ($flags =~ /[om]/) {
493 my $args = scalar @args;
496 $ret = hide($func,"S_$func");
498 elsif ($flags =~ /p/) {
499 $ret = hide($func,"Perl_$func");
502 elsif ($args and $args[$args-1] =~ /\.\.\./) {
504 # we're out of luck for varargs functions under CPP
505 # So we can only do these macros for no implicit context:
506 $ret = "#ifndef PERL_IMPLICIT_CONTEXT\n"
507 . hide($func,"Perl_$func") . "#endif\n";
511 my $alist = join(",", @az[0..$args-1]);
512 $ret = "#define $func($alist)";
513 my $t = int(length($ret) / 8);
514 $ret .= "\t" x ($t < 4 ? 4 - $t : 1);
516 $ret .= "S_$func(aTHX";
518 elsif ($flags =~ /p/) {
519 $ret .= "Perl_$func(aTHX";
521 $ret .= "_ " if $alist;
522 $ret .= $alist . ")\n";
527 # Prune empty #if/#endif pairs.
528 while ($lines =~ s/#\s*if[^\n]+\n#\s*endif\n//) {
530 # Merge adjacent blocks.
531 while ($lines =~ s/(#ifndef PERL_IMPLICIT_CONTEXT
534 #ifndef PERL_IMPLICIT_CONTEXT
539 print $em "#endif\n" if $guard;
543 embed_h('#if defined(PERL_CORE) || defined(PERL_EXT)', \@ext);
544 embed_h('#ifdef PERL_CORE', \@core);
548 #endif /* #ifndef PERL_NO_SHORT_NAMES */
550 /* Compatibility stubs. Compile extensions with -DPERL_NOCOMPAT to
554 #if !defined(PERL_CORE)
555 # define sv_setptrobj(rv,ptr,name) sv_setref_iv(rv,name,PTR2IV(ptr))
556 # define sv_setptrref(rv,ptr) sv_setref_iv(rv,NULL,PTR2IV(ptr))
559 #if !defined(PERL_CORE) && !defined(PERL_NOCOMPAT)
561 /* Compatibility for various misnamed functions. All functions
562 in the API that begin with "perl_" (not "Perl_") take an explicit
563 interpreter context pointer.
564 The following are not like that, but since they had a "perl_"
565 prefix in previous versions, we provide compatibility macros.
567 # define perl_atexit(a,b) call_atexit(a,b)
571 my ($flags,$retval,$func,@args) = @_;
573 return unless $flags =~ /O/;
575 my $alist = join ",", @az[0..$#args];
576 my $ret = "# define perl_$func($alist)";
577 my $t = (length $ret) >> 3;
578 $ret .= "\t" x ($t < 5 ? 5 - $t : 1);
579 "$ret$func($alist)\n";
584 /* varargs functions can't be handled with CPP macros. :-(
585 This provides a set of compatibility functions that don't take
586 an extra argument but grab the context pointer using the macro
589 #if defined(PERL_IMPLICIT_CONTEXT) && !defined(PERL_NO_SHORT_NAMES)
592 foreach (sort keys %has_va) {
593 next unless $has_nocontext{$_};
594 next if /printf/; # Not clear to me why these are skipped but they are.
595 print $em hide($_, "Perl_${_}_nocontext", " ");
601 #endif /* !defined(PERL_CORE) && !defined(PERL_NOCOMPAT) */
603 #if !defined(PERL_IMPLICIT_CONTEXT)
604 /* undefined symbols, point them back at the usual ones */
607 foreach (sort keys %has_va) {
608 next unless $has_nocontext{$_};
609 next if /printf/; # Not clear to me why these are skipped but they are.
610 print $em hide("Perl_${_}_nocontext", "Perl_$_", " ");
620 rename_if_different('embed.h-new', 'embed.h');
622 $em = safer_open('embedvar.h-new');
624 print $em do_not_edit ("embedvar.h"), <<'END';
626 /* (Doing namespace management portably in C is really gross.) */
629 The following combinations of MULTIPLICITY and PERL_IMPLICIT_CONTEXT
632 2) MULTIPLICITY # supported for compatibility
633 3) MULTIPLICITY && PERL_IMPLICIT_CONTEXT
635 All other combinations of these flags are errors.
637 only #3 is supported directly, while #2 is a special
638 case of #3 (supported by redefining vTHX appropriately).
641 #if defined(MULTIPLICITY)
642 /* cases 2 and 3 above */
644 # if defined(PERL_IMPLICIT_CONTEXT)
647 # define vTHX PERL_GET_INTERP
652 for $sym (sort keys %intrp) {
653 print $em multon($sym,'I','vTHX->');
658 #else /* !MULTIPLICITY */
664 for $sym (sort keys %intrp) {
665 print $em multoff($sym,'I');
674 #endif /* MULTIPLICITY */
676 #if defined(PERL_GLOBAL_STRUCT)
680 for $sym (sort keys %globvar) {
681 print $em multon($sym, 'G','my_vars->');
682 print $em multon("G$sym",'', 'my_vars->');
687 #else /* !PERL_GLOBAL_STRUCT */
691 for $sym (sort keys %globvar) {
692 print $em multoff($sym,'G');
697 #endif /* PERL_GLOBAL_STRUCT */
703 rename_if_different('embedvar.h-new', 'embedvar.h');
705 my $capi = safer_open('perlapi.c-new');
706 my $capih = safer_open('perlapi.h-new');
708 print $capih do_not_edit ("perlapi.h"), <<'EOT';
710 /* declare accessor functions for Perl variables */
711 #ifndef __perlapi_h__
712 #define __perlapi_h__
714 #if defined (MULTIPLICITY) && defined (PERL_GLOBAL_STRUCT)
723 #define PERLVAR(v,t) EXTERN_C t* Perl_##v##_ptr(pTHX);
724 #define PERLVARA(v,n,t) typedef t PL_##v##_t[n]; \
725 EXTERN_C PL_##v##_t* Perl_##v##_ptr(pTHX);
726 #define PERLVARI(v,t,i) PERLVAR(v,t)
727 #define PERLVARIC(v,t,i) PERLVAR(v, const t)
728 #define PERLVARISC(v,i) typedef const char PL_##v##_t[sizeof(i)]; \
729 EXTERN_C PL_##v##_t* Perl_##v##_ptr(pTHX);
731 #include "perlvars.h"
741 #if defined(PERL_CORE)
743 /* accessor functions for Perl "global" variables */
745 /* these need to be mentioned here, or most linkers won't put them in
746 the perl executable */
748 #ifndef PERL_NO_FORCE_LINK
753 EXTCONST void * const PL_force_link_funcs[];
755 EXTCONST void * const PL_force_link_funcs[] = {
760 #define PERLVAR(v,t) (void*)Perl_##v##_ptr,
761 #define PERLVARA(v,n,t) PERLVAR(v,t)
762 #define PERLVARI(v,t,i) PERLVAR(v,t)
763 #define PERLVARIC(v,t,i) PERLVAR(v,t)
764 #define PERLVARISC(v,i) PERLVAR(v,char)
766 /* In Tru64 (__DEC && __osf__) the cc option -std1 causes that one
767 * cannot cast between void pointers and function pointers without
768 * info level warnings. The PL_force_link_funcs[] would cause a few
769 * hundred of those warnings. In code one can circumnavigate this by using
770 * unions that overlay the different pointers, but in declarations one
771 * cannot use this trick. Therefore we just disable the warning here
772 * for the duration of the PL_force_link_funcs[] declaration. */
774 #if defined(__DECC) && defined(__osf__)
776 #pragma message disable (nonstandcast)
779 #include "perlvars.h"
781 #if defined(__DECC) && defined(__osf__)
782 #pragma message restore
795 #endif /* PERL_NO_FORCE_LINK */
797 #else /* !PERL_CORE */
801 foreach $sym (sort keys %globvar) {
802 print $capih bincompat_var('G',$sym);
805 print $capih <<'EOT';
807 #endif /* !PERL_CORE */
808 #endif /* MULTIPLICITY && PERL_GLOBAL_STRUCT */
810 #endif /* __perlapi_h__ */
815 rename_if_different('perlapi.h-new', 'perlapi.h');
817 print $capi do_not_edit ("perlapi.c"), <<'EOT';
823 #if defined (MULTIPLICITY) && defined (PERL_GLOBAL_STRUCT)
825 /* accessor functions for Perl "global" variables */
829 #define PERLVARI(v,t,i) PERLVAR(v,t)
833 #define PERLVAR(v,t) t* Perl_##v##_ptr(pTHX) \
834 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
835 #define PERLVARA(v,n,t) PL_##v##_t* Perl_##v##_ptr(pTHX) \
836 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
839 #define PERLVARIC(v,t,i) \
840 const t* Perl_##v##_ptr(pTHX) \
841 { PERL_UNUSED_CONTEXT; return (const t *)&(PL_##v); }
842 #define PERLVARISC(v,i) PL_##v##_t* Perl_##v##_ptr(pTHX) \
843 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
844 #include "perlvars.h"
854 #endif /* MULTIPLICITY && PERL_GLOBAL_STRUCT */
860 rename_if_different('perlapi.c-new', 'perlapi.c');
862 # ex: set ts=8 sts=4 sw=4 noet: