3 # Regenerate (overwriting only if changed):
12 # from information stored in
17 # pp.sym (which has been generated by opcode.pl)
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, pp.sym, 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, 'pp.sym' or die $!;
131 s/[ \t]*#.*//; # Delete comments.
132 if (/^\s*(\S+)\s*$/) {
134 warn "duplicate symbol $sym while processing 'pp.sym' line $.\n"
139 foreach (sort keys %syms) {
142 # These are all indirectly referenced by globals.c.
143 # This is somewhat annoying.
144 push @embed, ['pR', 'OP *', $_, 'NN OP *o'];
147 push @embed, ['p', 'OP *', $_];
150 warn "Illegal symbol '$_' in pp.sym";
156 my (@core, @ext, @api);
158 # Cluster entries in embed.fnc that have the same #ifdef guards.
159 # Also, split out at the top level the three classes of functions.
168 $_->[0] =~ s/^#\s+/#/;
170 $_->[0] =~ s/^#ifdef\s+(\S+)/#if defined($1)/;
171 $_->[0] =~ s/^#ifndef\s+(\S+)/#if !defined($1)/;
172 if ($_->[0] =~ /^#if\s*(.*)/) {
174 } elsif ($_->[0] =~ /^#else\s*$/) {
175 die "Unmatched #else in embed.fnc" unless @state;
176 $state[-1] = "!($state[-1])";
177 } elsif ($_->[0] =~ m!^#endif\s*(?:/\*.*\*/)?$!) {
178 die "Unmatched #endif in embed.fnc" unless @state;
181 die "Unhandled pre-processor directive '$_->[0]' in embed.fnc";
184 # Nested #if blocks are effectively &&ed together
185 # For embed.fnc, ordering withing the && isn't relevant, so we can
186 # sort them to try to group more functions together.
187 my @sorted = sort @state;
188 while (my $directive = shift @sorted) {
189 $current->{$directive} ||= {};
190 $current = $current->{$directive};
192 $current->{''} ||= [];
193 $current = $current->{''};
197 my ($level, $indent, $wanted) = @_;
198 my $funcs = $level->{''};
201 if (!defined $wanted) {
205 if ($_->[0] =~ /A/) {
206 push @entries, $_ if $wanted eq 'A';
207 } elsif ($_->[0] =~ /E/) {
208 push @entries, $_ if $wanted eq 'E';
210 push @entries, $_ if $wanted eq '';
214 @entries = sort {$a->[2] cmp $b->[2]} @entries;
216 foreach (sort grep {length $_} keys %$level) {
217 my @conditional = add_level($level->{$_}, $indent . ' ', $wanted);
219 ["#${indent}if $_"], @conditional, ["#${indent}endif"]
224 @core = add_level(\%groups, '', '');
225 @ext = add_level(\%groups, '', 'E');
226 @api = add_level(\%groups, '', 'A');
228 @embed = add_level(\%groups, '');
231 # walk table providing an array of components in each line to
232 # subroutine, printing the result
233 sub walk_table (&@) {
234 my ($function, $filename, $trailer) = @_;
236 if (ref $filename) { # filehandle
240 $F = safer_open("$filename-new");
241 print $F do_not_edit ($filename);
244 my @outs = &{$function}(@$_);
245 # $function->(@args) is not 5.003
248 print $F $trailer if $trailer;
249 unless (ref $filename) {
251 rename_if_different("$filename-new", $filename);
257 my $pr = safer_open('proto.h-new');
258 print $pr do_not_edit ("proto.h"), "\nSTART_EXTERN_C\n";
263 print $pr "$_->[0]\n";
267 my ($flags,$retval,$plain_func,@args) = @$_;
269 my $has_context = ( $flags !~ /n/ );
270 my $never_returns = ( $flags =~ /r/ );
271 my $commented_out = ( $flags =~ /m/ );
272 my $binarycompat = ( $flags =~ /b/ );
273 my $is_malloc = ( $flags =~ /a/ );
274 my $can_ignore = ( $flags !~ /R/ ) && !$is_malloc;
278 my $splint_flags = "";
279 if ( $SPLINT && !$commented_out ) {
280 $splint_flags .= '/*@noreturn@*/ ' if $never_returns;
281 if ($can_ignore && ($retval ne 'void') && ($retval !~ /\*/)) {
282 $retval .= " /*\@alt void\@*/";
287 $retval = "STATIC $splint_flags$retval";
288 $func = "S_$plain_func";
291 $retval = "PERL_CALLCONV $splint_flags$retval";
292 if ($flags =~ /[bp]/) {
293 $func = "Perl_$plain_func";
298 $ret = "$retval\t$func(";
299 if ( $has_context ) {
300 $ret .= @args ? "pTHX_ " : "pTHX";
304 for my $arg ( @args ) {
306 if ( $arg =~ /\*/ && $arg !~ /\b(NN|NULLOK)\b/ ) {
307 warn "$func: $arg needs NN or NULLOK\n";
308 ++$unflagged_pointers;
310 my $nn = ( $arg =~ s/\s*\bNN\b\s+// );
311 push( @nonnull, $n ) if $nn;
313 my $nullok = ( $arg =~ s/\s*\bNULLOK\b\s+// ); # strip NULLOK with no effect
315 # Make sure each arg has at least a type and a var name.
316 # An arg of "int" is valid C, but want it to be "int foo".
318 $temp_arg =~ s/\*//g;
319 $temp_arg =~ s/\s*\bstruct\b\s*/ /g;
320 if ( ($temp_arg ne "...")
321 && ($temp_arg !~ /\w+\s+(\w+)(?:\[\d+\])?\s*$/) ) {
322 warn "$func: $arg ($n) doesn't have a name\n";
324 if ( $SPLINT && $nullok && !$commented_out ) {
325 $arg = '/*@null@*/ ' . $arg;
327 if (defined $1 && $nn && !($commented_out && !$binarycompat)) {
328 push @names_of_nn, $1;
331 $ret .= join ", ", @args;
334 $ret .= "void" if !$has_context;
338 if ( $flags =~ /r/ ) {
339 push @attrs, "__attribute__noreturn__";
341 if ( $flags =~ /D/ ) {
342 push @attrs, "__attribute__deprecated__";
345 push @attrs, "__attribute__malloc__";
347 if ( !$can_ignore ) {
348 push @attrs, "__attribute__warn_unused_result__";
350 if ( $flags =~ /P/ ) {
351 push @attrs, "__attribute__pure__";
353 if( $flags =~ /f/ ) {
354 my $prefix = $has_context ? 'pTHX_' : '';
355 my $args = scalar @args;
357 my $macro = @nonnull && $nonnull[-1] == $pat
358 ? '__attribute__format__'
359 : '__attribute__format__null_ok__';
360 push @attrs, sprintf "%s(__printf__,%s%d,%s%d)", $macro,
361 $prefix, $pat, $prefix, $args;
364 my @pos = map { $has_context ? "pTHX_$_" : $_ } @nonnull;
365 push @attrs, map { sprintf( "__attribute__nonnull__(%s)", $_ ) } @pos;
369 $ret .= join( "\n", map { "\t\t\t$_" } @attrs );
372 $ret = "/* $ret */" if $commented_out;
374 $ret .= "\n#define PERL_ARGS_ASSERT_\U$plain_func\E\t\\\n\t"
375 . join '; ', map "assert($_)", @names_of_nn;
377 $ret .= @attrs ? "\n\n" : "\n";
382 print $pr "END_EXTERN_C\n/* ex: set ro: */\n";
385 rename_if_different('proto.h-new', 'proto.h');
388 # generates global.sym (API export list)
391 sub write_global_sym {
393 my ($flags,$retval,$func,@args) = @_;
394 if ($flags =~ /[AX]/ && $flags !~ /[xm]/
395 || $flags =~ /b/) { # public API, so export
396 # If a function is defined twice, for example before and after
397 # an #else, only export its name once.
398 return '' if $seen{$func}++;
399 $func = "Perl_$func" if $flags =~ /[pbX]/;
407 warn "$unflagged_pointers pointer arguments to clean up\n" if $unflagged_pointers;
408 walk_table(\&write_global_sym, "global.sym", "# ex: set ro:\n");
410 sub readvars(\%$$@) {
411 my ($syms, $file,$pre,$keep_pre) = @_;
413 open(FILE, "< $file")
414 or die "embed.pl: Can't open $file: $!\n";
416 s/[ \t]*#.*//; # Delete comments.
417 if (/PERLVARA?I?S?C?\($pre(\w+)/) {
419 $sym = $pre . $sym if $keep_pre;
420 warn "duplicate symbol $sym while processing $file line $.\n"
421 if exists $$syms{$sym};
422 $$syms{$sym} = $pre || 1;
431 readvars %intrp, 'intrpvar.h','I';
432 readvars %globvar, 'perlvars.h','G';
442 my ($from, $to, $indent) = @_;
443 $indent = '' unless defined $indent;
444 my $t = int(length("$indent$from") / 8);
445 "#${indent}define $from" . "\t" x ($t < 3 ? 3 - $t : 1) . "$to\n";
448 sub bincompat_var ($$) {
449 my ($pfx, $sym) = @_;
450 my $arg = ($pfx eq 'G' ? 'NULL' : 'aTHX');
451 undefine("PL_$sym") . hide("PL_$sym", "(*Perl_${pfx}${sym}_ptr($arg))");
455 my ($sym,$pre,$ptr) = @_;
456 hide("PL_$sym", "($ptr$pre$sym)");
461 return hide("PL_$pre$sym", "PL_$sym");
464 my $em = safer_open('embed.h-new');
466 print $em do_not_edit ("embed.h"), <<'END';
468 /* (Doing namespace management portably in C is really gross.) */
470 /* By defining PERL_NO_SHORT_NAMES (not done by default) the short forms
471 * (like warn instead of Perl_warn) for the API are not defined.
472 * Not defining the short forms is a good thing for cleaner embedding. */
474 #ifndef PERL_NO_SHORT_NAMES
476 /* Hide global symbols */
483 my ($guard, $funcs) = @_;
484 print $em "$guard\n" if $guard;
490 # Indent the conditionals if we are wrapped in an #if/#endif pair.
491 $cond =~ s/#(.*)/# $1/ if $guard;
496 my ($flags,$retval,$func,@args) = @$_;
497 unless ($flags =~ /[om]/) {
498 my $args = scalar @args;
501 $ret = hide($func,"S_$func");
503 elsif ($flags =~ /p/) {
504 $ret = hide($func,"Perl_$func");
507 elsif ($args and $args[$args-1] =~ /\.\.\./) {
509 # we're out of luck for varargs functions under CPP
510 # So we can only do these macros for no implicit context:
511 $ret = "#ifndef PERL_IMPLICIT_CONTEXT\n"
512 . hide($func,"Perl_$func") . "#endif\n";
516 my $alist = join(",", @az[0..$args-1]);
517 $ret = "#define $func($alist)";
518 my $t = int(length($ret) / 8);
519 $ret .= "\t" x ($t < 4 ? 4 - $t : 1);
521 $ret .= "S_$func(aTHX";
523 elsif ($flags =~ /p/) {
524 $ret .= "Perl_$func(aTHX";
526 $ret .= "_ " if $alist;
527 $ret .= $alist . ")\n";
532 # Prune empty #if/#endif pairs.
533 while ($lines =~ s/#\s*if[^\n]+\n#\s*endif\n//) {
535 # Merge adjacent blocks.
536 while ($lines =~ s/(#ifndef PERL_IMPLICIT_CONTEXT
539 #ifndef PERL_IMPLICIT_CONTEXT
544 print $em "#endif\n" if $guard;
548 embed_h('#if defined(PERL_CORE) || defined(PERL_EXT)', \@ext);
549 embed_h('#ifdef PERL_CORE', \@core);
553 #endif /* #ifndef PERL_NO_SHORT_NAMES */
555 /* Compatibility stubs. Compile extensions with -DPERL_NOCOMPAT to
559 #if !defined(PERL_CORE)
560 # define sv_setptrobj(rv,ptr,name) sv_setref_iv(rv,name,PTR2IV(ptr))
561 # define sv_setptrref(rv,ptr) sv_setref_iv(rv,NULL,PTR2IV(ptr))
564 #if !defined(PERL_CORE) && !defined(PERL_NOCOMPAT)
566 /* Compatibility for various misnamed functions. All functions
567 in the API that begin with "perl_" (not "Perl_") take an explicit
568 interpreter context pointer.
569 The following are not like that, but since they had a "perl_"
570 prefix in previous versions, we provide compatibility macros.
572 # define perl_atexit(a,b) call_atexit(a,b)
576 my ($flags,$retval,$func,@args) = @_;
578 return unless $flags =~ /O/;
580 my $alist = join ",", @az[0..$#args];
581 my $ret = "# define perl_$func($alist)";
582 my $t = (length $ret) >> 3;
583 $ret .= "\t" x ($t < 5 ? 5 - $t : 1);
584 "$ret$func($alist)\n";
589 /* varargs functions can't be handled with CPP macros. :-(
590 This provides a set of compatibility functions that don't take
591 an extra argument but grab the context pointer using the macro
594 #if defined(PERL_IMPLICIT_CONTEXT) && !defined(PERL_NO_SHORT_NAMES)
597 foreach (sort keys %has_va) {
598 next unless $has_nocontext{$_};
599 next if /printf/; # Not clear to me why these are skipped but they are.
600 print $em hide($_, "Perl_${_}_nocontext", " ");
606 #endif /* !defined(PERL_CORE) && !defined(PERL_NOCOMPAT) */
608 #if !defined(PERL_IMPLICIT_CONTEXT)
609 /* undefined symbols, point them back at the usual ones */
612 foreach (sort keys %has_va) {
613 next unless $has_nocontext{$_};
614 next if /printf/; # Not clear to me why these are skipped but they are.
615 print $em hide("Perl_${_}_nocontext", "Perl_$_", " ");
625 rename_if_different('embed.h-new', 'embed.h');
627 $em = safer_open('embedvar.h-new');
629 print $em do_not_edit ("embedvar.h"), <<'END';
631 /* (Doing namespace management portably in C is really gross.) */
634 The following combinations of MULTIPLICITY and PERL_IMPLICIT_CONTEXT
637 2) MULTIPLICITY # supported for compatibility
638 3) MULTIPLICITY && PERL_IMPLICIT_CONTEXT
640 All other combinations of these flags are errors.
642 only #3 is supported directly, while #2 is a special
643 case of #3 (supported by redefining vTHX appropriately).
646 #if defined(MULTIPLICITY)
647 /* cases 2 and 3 above */
649 # if defined(PERL_IMPLICIT_CONTEXT)
652 # define vTHX PERL_GET_INTERP
657 for $sym (sort keys %intrp) {
658 print $em multon($sym,'I','vTHX->');
663 #else /* !MULTIPLICITY */
669 for $sym (sort keys %intrp) {
670 print $em multoff($sym,'I');
679 #endif /* MULTIPLICITY */
681 #if defined(PERL_GLOBAL_STRUCT)
685 for $sym (sort keys %globvar) {
686 print $em multon($sym, 'G','my_vars->');
687 print $em multon("G$sym",'', 'my_vars->');
692 #else /* !PERL_GLOBAL_STRUCT */
696 for $sym (sort keys %globvar) {
697 print $em multoff($sym,'G');
702 #endif /* PERL_GLOBAL_STRUCT */
708 rename_if_different('embedvar.h-new', 'embedvar.h');
710 my $capi = safer_open('perlapi.c-new');
711 my $capih = safer_open('perlapi.h-new');
713 print $capih do_not_edit ("perlapi.h"), <<'EOT';
715 /* declare accessor functions for Perl variables */
716 #ifndef __perlapi_h__
717 #define __perlapi_h__
719 #if defined (MULTIPLICITY) && defined (PERL_GLOBAL_STRUCT)
728 #define PERLVAR(v,t) EXTERN_C t* Perl_##v##_ptr(pTHX);
729 #define PERLVARA(v,n,t) typedef t PL_##v##_t[n]; \
730 EXTERN_C PL_##v##_t* Perl_##v##_ptr(pTHX);
731 #define PERLVARI(v,t,i) PERLVAR(v,t)
732 #define PERLVARIC(v,t,i) PERLVAR(v, const t)
733 #define PERLVARISC(v,i) typedef const char PL_##v##_t[sizeof(i)]; \
734 EXTERN_C PL_##v##_t* Perl_##v##_ptr(pTHX);
736 #include "perlvars.h"
746 #if defined(PERL_CORE)
748 /* accessor functions for Perl "global" variables */
750 /* these need to be mentioned here, or most linkers won't put them in
751 the perl executable */
753 #ifndef PERL_NO_FORCE_LINK
758 EXTCONST void * const PL_force_link_funcs[];
760 EXTCONST void * const PL_force_link_funcs[] = {
765 #define PERLVAR(v,t) (void*)Perl_##v##_ptr,
766 #define PERLVARA(v,n,t) PERLVAR(v,t)
767 #define PERLVARI(v,t,i) PERLVAR(v,t)
768 #define PERLVARIC(v,t,i) PERLVAR(v,t)
769 #define PERLVARISC(v,i) PERLVAR(v,char)
771 /* In Tru64 (__DEC && __osf__) the cc option -std1 causes that one
772 * cannot cast between void pointers and function pointers without
773 * info level warnings. The PL_force_link_funcs[] would cause a few
774 * hundred of those warnings. In code one can circumnavigate this by using
775 * unions that overlay the different pointers, but in declarations one
776 * cannot use this trick. Therefore we just disable the warning here
777 * for the duration of the PL_force_link_funcs[] declaration. */
779 #if defined(__DECC) && defined(__osf__)
781 #pragma message disable (nonstandcast)
784 #include "perlvars.h"
786 #if defined(__DECC) && defined(__osf__)
787 #pragma message restore
800 #endif /* PERL_NO_FORCE_LINK */
802 #else /* !PERL_CORE */
806 foreach $sym (sort keys %globvar) {
807 print $capih bincompat_var('G',$sym);
810 print $capih <<'EOT';
812 #endif /* !PERL_CORE */
813 #endif /* MULTIPLICITY && PERL_GLOBAL_STRUCT */
815 #endif /* __perlapi_h__ */
820 rename_if_different('perlapi.h-new', 'perlapi.h');
822 print $capi do_not_edit ("perlapi.c"), <<'EOT';
828 #if defined (MULTIPLICITY) && defined (PERL_GLOBAL_STRUCT)
830 /* accessor functions for Perl "global" variables */
834 #define PERLVARI(v,t,i) PERLVAR(v,t)
838 #define PERLVAR(v,t) t* Perl_##v##_ptr(pTHX) \
839 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
840 #define PERLVARA(v,n,t) PL_##v##_t* Perl_##v##_ptr(pTHX) \
841 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
844 #define PERLVARIC(v,t,i) \
845 const t* Perl_##v##_ptr(pTHX) \
846 { PERL_UNUSED_CONTEXT; return (const t *)&(PL_##v); }
847 #define PERLVARISC(v,i) PL_##v##_t* Perl_##v##_ptr(pTHX) \
848 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
849 #include "perlvars.h"
859 #endif /* MULTIPLICITY && PERL_GLOBAL_STRUCT */
865 rename_if_different('perlapi.c-new', 'perlapi.c');
867 # ex: set ts=8 sts=4 sw=4 noet: