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_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 embed.pl from data in embed.fnc, embed.pl,
63 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);
112 @args = split /\s*\|\s*/, $_;
115 ++$has_va{$func} if $args[-1] =~ /\.\.\./;
116 ++$has_nocontext{$1} if $func =~ /(.*)_nocontext/;
122 open IN, 'pp.sym' or die $!;
127 s/[ \t]*#.*//; # Delete comments.
128 if (/^\s*(\S+)\s*$/) {
130 warn "duplicate symbol $sym while processing 'pp.sym' line $.\n"
135 foreach (sort keys %syms) {
138 # These are all indirectly referenced by globals.c.
139 # This is somewhat annoying.
140 push @embed, ['pR', 'OP *', $_, 'NN OP *o'];
143 push @embed, ['p', 'OP *', $_];
146 warn "Illegal symbol '$_' in pp.sym";
151 # walk table providing an array of components in each line to
152 # subroutine, printing the result
153 sub walk_table (&@) {
154 my ($function, $filename, $trailer) = @_;
156 if (ref $filename) { # filehandle
160 $F = safer_open("$filename-new");
161 print $F do_not_edit ($filename);
164 my @outs = &{$function}(@$_);
165 # $function->(@args) is not 5.003
168 print $F $trailer if $trailer;
169 unless (ref $filename) {
171 rename_if_different("$filename-new", $filename);
176 my $wrote_protected = 0;
185 my ($flags,$retval,$plain_func,@args) = @_;
187 my $has_context = ( $flags !~ /n/ );
188 my $never_returns = ( $flags =~ /r/ );
189 my $commented_out = ( $flags =~ /m/ );
190 my $binarycompat = ( $flags =~ /b/ );
191 my $is_malloc = ( $flags =~ /a/ );
192 my $can_ignore = ( $flags !~ /R/ ) && !$is_malloc;
196 my $splint_flags = "";
197 if ( $SPLINT && !$commented_out ) {
198 $splint_flags .= '/*@noreturn@*/ ' if $never_returns;
199 if ($can_ignore && ($retval ne 'void') && ($retval !~ /\*/)) {
200 $retval .= " /*\@alt void\@*/";
205 $retval = "STATIC $splint_flags$retval";
206 $func = "S_$plain_func";
209 $retval = "PERL_CALLCONV $splint_flags$retval";
210 if ($flags =~ /[bp]/) {
211 $func = "Perl_$plain_func";
216 $ret = "$retval\t$func(";
217 if ( $has_context ) {
218 $ret .= @args ? "pTHX_ " : "pTHX";
222 for my $arg ( @args ) {
224 if ( $arg =~ /\*/ && $arg !~ /\b(NN|NULLOK)\b/ ) {
225 warn "$func: $arg needs NN or NULLOK\n";
226 ++$unflagged_pointers;
228 my $nn = ( $arg =~ s/\s*\bNN\b\s+// );
229 push( @nonnull, $n ) if $nn;
231 my $nullok = ( $arg =~ s/\s*\bNULLOK\b\s+// ); # strip NULLOK with no effect
233 # Make sure each arg has at least a type and a var name.
234 # An arg of "int" is valid C, but want it to be "int foo".
236 $temp_arg =~ s/\*//g;
237 $temp_arg =~ s/\s*\bstruct\b\s*/ /g;
238 if ( ($temp_arg ne "...")
239 && ($temp_arg !~ /\w+\s+(\w+)(?:\[\d+\])?\s*$/) ) {
240 warn "$func: $arg ($n) doesn't have a name\n";
242 if ( $SPLINT && $nullok && !$commented_out ) {
243 $arg = '/*@null@*/ ' . $arg;
245 if (defined $1 && $nn && !($commented_out && !$binarycompat)) {
246 push @names_of_nn, $1;
249 $ret .= join ", ", @args;
252 $ret .= "void" if !$has_context;
256 if ( $flags =~ /r/ ) {
257 push @attrs, "__attribute__noreturn__";
259 if ( $flags =~ /D/ ) {
260 push @attrs, "__attribute__deprecated__";
263 push @attrs, "__attribute__malloc__";
265 if ( !$can_ignore ) {
266 push @attrs, "__attribute__warn_unused_result__";
268 if ( $flags =~ /P/ ) {
269 push @attrs, "__attribute__pure__";
271 if( $flags =~ /f/ ) {
272 my $prefix = $has_context ? 'pTHX_' : '';
273 my $args = scalar @args;
275 my $macro = @nonnull && $nonnull[-1] == $pat
276 ? '__attribute__format__'
277 : '__attribute__format__null_ok__';
278 push @attrs, sprintf "%s(__printf__,%s%d,%s%d)", $macro,
279 $prefix, $pat, $prefix, $args;
282 my @pos = map { $has_context ? "pTHX_$_" : $_ } @nonnull;
283 push @attrs, map { sprintf( "__attribute__nonnull__(%s)", $_ ) } @pos;
287 $ret .= join( "\n", map { "\t\t\t$_" } @attrs );
290 $ret = "/* $ret */" if $commented_out;
292 $ret .= "\n#define PERL_ARGS_ASSERT_\U$plain_func\E\t\\\n\t"
293 . join '; ', map "assert($_)", @names_of_nn;
295 $ret .= @attrs ? "\n\n" : "\n";
300 # generates global.sym (API export list)
303 sub write_global_sym {
305 my ($flags,$retval,$func,@args) = @_;
306 # If a function is defined twice, for example before and after an
307 # #else, only process the flags on the first instance for global.sym
308 return '' if $seen{$func}++;
309 if ($flags =~ /[AX]/ && $flags !~ /[xm]/
310 || $flags =~ /b/) { # public API, so export
311 $func = "Perl_$func" if $flags =~ /[pbX]/;
320 my $pr = safer_open('proto.h-new');
322 print $pr do_not_edit ("proto.h"), "\nSTART_EXTERN_C\n";
324 walk_table(\&write_protos, $pr);
326 print $pr "END_EXTERN_C\n/* ex: set ro: */\n";
329 rename_if_different('proto.h-new', 'proto.h');
332 warn "$unflagged_pointers pointer arguments to clean up\n" if $unflagged_pointers;
333 walk_table(\&write_global_sym, "global.sym", "# ex: set ro:\n");
335 sub readvars(\%$$@) {
336 my ($syms, $file,$pre,$keep_pre) = @_;
338 open(FILE, "< $file")
339 or die "embed.pl: Can't open $file: $!\n";
341 s/[ \t]*#.*//; # Delete comments.
342 if (/PERLVARA?I?S?C?\($pre(\w+)/) {
344 $sym = $pre . $sym if $keep_pre;
345 warn "duplicate symbol $sym while processing $file line $.\n"
346 if exists $$syms{$sym};
347 $$syms{$sym} = $pre || 1;
356 readvars %intrp, 'intrpvar.h','I';
357 readvars %globvar, 'perlvars.h','G';
367 my ($from, $to, $indent) = @_;
368 $indent = '' unless defined $indent;
369 my $t = int(length("$indent$from") / 8);
370 "#${indent}define $from" . "\t" x ($t < 3 ? 3 - $t : 1) . "$to\n";
373 sub bincompat_var ($$) {
374 my ($pfx, $sym) = @_;
375 my $arg = ($pfx eq 'G' ? 'NULL' : 'aTHX');
376 undefine("PL_$sym") . hide("PL_$sym", "(*Perl_${pfx}${sym}_ptr($arg))");
380 my ($sym,$pre,$ptr) = @_;
381 hide("PL_$sym", "($ptr$pre$sym)");
386 return hide("PL_$pre$sym", "PL_$sym");
389 my $em = safer_open('embed.h-new');
391 print $em do_not_edit ("embed.h"), <<'END';
393 /* (Doing namespace management portably in C is really gross.) */
395 /* By defining PERL_NO_SHORT_NAMES (not done by default) the short forms
396 * (like warn instead of Perl_warn) for the API are not defined.
397 * Not defining the short forms is a good thing for cleaner embedding. */
399 #ifndef PERL_NO_SHORT_NAMES
401 /* Hide global symbols */
405 # Try to elimiate lots of repeated
412 # by tracking state and merging foo and bar into one block.
413 my $ifdef_state = '';
419 my $new_ifdef_state = '';
422 $ret = "$arg\n" if $arg =~ /^#\s*(if|ifn?def|else|endif)\b/;
425 my ($flags,$retval,$func,@args) = @_;
426 unless ($flags =~ /[om]/) {
427 my $args = scalar @args;
430 $ret = hide($func,"S_$func");
432 elsif ($flags =~ /p/) {
433 $ret = hide($func,"Perl_$func");
436 elsif ($args and $args[$args-1] =~ /\.\.\./) {
438 # we're out of luck for varargs functions under CPP
439 # So we can only do these macros for no implicit context:
440 $ret = "#ifndef PERL_IMPLICIT_CONTEXT\n"
441 . hide($func,"Perl_$func") . "#endif\n";
445 my $alist = join(",", @az[0..$args-1]);
446 $ret = "#define $func($alist)";
447 my $t = int(length($ret) / 8);
448 $ret .= "\t" x ($t < 4 ? 4 - $t : 1);
450 $ret .= "S_$func(aTHX";
452 elsif ($flags =~ /p/) {
453 $ret .= "Perl_$func(aTHX";
455 $ret .= "_ " if $alist;
456 $ret .= $alist . ")\n";
459 unless ($flags =~ /A/) {
462 = "#if defined(PERL_CORE) || defined(PERL_EXT)\n";
465 $new_ifdef_state = "#ifdef PERL_CORE\n";
468 if ($new_ifdef_state ne $ifdef_state) {
469 $ret = $new_ifdef_state . $ret;
473 if ($ifdef_state && $new_ifdef_state ne $ifdef_state) {
474 # Close the old one ahead of opening the new one.
475 $ret = "#endif\n$ret";
477 # Remember the new state.
478 $ifdef_state = $new_ifdef_state;
483 print $em "#endif\n";
488 #endif /* #ifndef PERL_NO_SHORT_NAMES */
490 /* Compatibility stubs. Compile extensions with -DPERL_NOCOMPAT to
494 #if !defined(PERL_CORE)
495 # define sv_setptrobj(rv,ptr,name) sv_setref_iv(rv,name,PTR2IV(ptr))
496 # define sv_setptrref(rv,ptr) sv_setref_iv(rv,NULL,PTR2IV(ptr))
499 #if !defined(PERL_CORE) && !defined(PERL_NOCOMPAT)
501 /* Compatibility for various misnamed functions. All functions
502 in the API that begin with "perl_" (not "Perl_") take an explicit
503 interpreter context pointer.
504 The following are not like that, but since they had a "perl_"
505 prefix in previous versions, we provide compatibility macros.
507 # define perl_atexit(a,b) call_atexit(a,b)
511 my ($flags,$retval,$func,@args) = @_;
513 return unless $flags =~ /O/;
515 my $alist = join ",", @az[0..$#args];
516 my $ret = "# define perl_$func($alist)";
517 my $t = (length $ret) >> 3;
518 $ret .= "\t" x ($t < 5 ? 5 - $t : 1);
519 "$ret$func($alist)\n";
524 /* varargs functions can't be handled with CPP macros. :-(
525 This provides a set of compatibility functions that don't take
526 an extra argument but grab the context pointer using the macro
529 #if defined(PERL_IMPLICIT_CONTEXT) && !defined(PERL_NO_SHORT_NAMES)
532 foreach (sort keys %has_va) {
533 next unless $has_nocontext{$_};
534 next if /printf/; # Not clear to me why these are skipped but they are.
535 print $em hide($_, "Perl_${_}_nocontext", " ");
541 #endif /* !defined(PERL_CORE) && !defined(PERL_NOCOMPAT) */
543 #if !defined(PERL_IMPLICIT_CONTEXT)
544 /* undefined symbols, point them back at the usual ones */
547 foreach (sort keys %has_va) {
548 next unless $has_nocontext{$_};
549 next if /printf/; # Not clear to me why these are skipped but they are.
550 print $em hide("Perl_${_}_nocontext", "Perl_$_", " ");
560 rename_if_different('embed.h-new', 'embed.h');
562 $em = safer_open('embedvar.h-new');
564 print $em do_not_edit ("embedvar.h"), <<'END';
566 /* (Doing namespace management portably in C is really gross.) */
569 The following combinations of MULTIPLICITY and PERL_IMPLICIT_CONTEXT
572 2) MULTIPLICITY # supported for compatibility
573 3) MULTIPLICITY && PERL_IMPLICIT_CONTEXT
575 All other combinations of these flags are errors.
577 only #3 is supported directly, while #2 is a special
578 case of #3 (supported by redefining vTHX appropriately).
581 #if defined(MULTIPLICITY)
582 /* cases 2 and 3 above */
584 # if defined(PERL_IMPLICIT_CONTEXT)
587 # define vTHX PERL_GET_INTERP
592 for $sym (sort keys %intrp) {
593 print $em multon($sym,'I','vTHX->');
598 #else /* !MULTIPLICITY */
604 for $sym (sort keys %intrp) {
605 print $em multoff($sym,'I');
614 #endif /* MULTIPLICITY */
616 #if defined(PERL_GLOBAL_STRUCT)
620 for $sym (sort keys %globvar) {
621 print $em multon($sym, 'G','my_vars->');
622 print $em multon("G$sym",'', 'my_vars->');
627 #else /* !PERL_GLOBAL_STRUCT */
631 for $sym (sort keys %globvar) {
632 print $em multoff($sym,'G');
637 #endif /* PERL_GLOBAL_STRUCT */
643 rename_if_different('embedvar.h-new', 'embedvar.h');
645 my $capi = safer_open('perlapi.c-new');
646 my $capih = safer_open('perlapi.h-new');
648 print $capih do_not_edit ("perlapi.h"), <<'EOT';
650 /* declare accessor functions for Perl variables */
651 #ifndef __perlapi_h__
652 #define __perlapi_h__
654 #if defined (MULTIPLICITY) && defined (PERL_GLOBAL_STRUCT)
663 #define PERLVAR(v,t) EXTERN_C t* Perl_##v##_ptr(pTHX);
664 #define PERLVARA(v,n,t) typedef t PL_##v##_t[n]; \
665 EXTERN_C PL_##v##_t* Perl_##v##_ptr(pTHX);
666 #define PERLVARI(v,t,i) PERLVAR(v,t)
667 #define PERLVARIC(v,t,i) PERLVAR(v, const t)
668 #define PERLVARISC(v,i) typedef const char PL_##v##_t[sizeof(i)]; \
669 EXTERN_C PL_##v##_t* Perl_##v##_ptr(pTHX);
671 #include "perlvars.h"
681 #if defined(PERL_CORE)
683 /* accessor functions for Perl "global" variables */
685 /* these need to be mentioned here, or most linkers won't put them in
686 the perl executable */
688 #ifndef PERL_NO_FORCE_LINK
693 EXTCONST void * const PL_force_link_funcs[];
695 EXTCONST void * const PL_force_link_funcs[] = {
700 #define PERLVAR(v,t) (void*)Perl_##v##_ptr,
701 #define PERLVARA(v,n,t) PERLVAR(v,t)
702 #define PERLVARI(v,t,i) PERLVAR(v,t)
703 #define PERLVARIC(v,t,i) PERLVAR(v,t)
704 #define PERLVARISC(v,i) PERLVAR(v,char)
706 /* In Tru64 (__DEC && __osf__) the cc option -std1 causes that one
707 * cannot cast between void pointers and function pointers without
708 * info level warnings. The PL_force_link_funcs[] would cause a few
709 * hundred of those warnings. In code one can circumnavigate this by using
710 * unions that overlay the different pointers, but in declarations one
711 * cannot use this trick. Therefore we just disable the warning here
712 * for the duration of the PL_force_link_funcs[] declaration. */
714 #if defined(__DECC) && defined(__osf__)
716 #pragma message disable (nonstandcast)
719 #include "perlvars.h"
721 #if defined(__DECC) && defined(__osf__)
722 #pragma message restore
735 #endif /* PERL_NO_FORCE_LINK */
737 #else /* !PERL_CORE */
741 foreach $sym (sort keys %globvar) {
742 print $capih bincompat_var('G',$sym);
745 print $capih <<'EOT';
747 #endif /* !PERL_CORE */
748 #endif /* MULTIPLICITY && PERL_GLOBAL_STRUCT */
750 #endif /* __perlapi_h__ */
755 rename_if_different('perlapi.h-new', 'perlapi.h');
757 print $capi do_not_edit ("perlapi.c"), <<'EOT';
763 #if defined (MULTIPLICITY) && defined (PERL_GLOBAL_STRUCT)
765 /* accessor functions for Perl "global" variables */
769 #define PERLVARI(v,t,i) PERLVAR(v,t)
773 #define PERLVAR(v,t) t* Perl_##v##_ptr(pTHX) \
774 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
775 #define PERLVARA(v,n,t) PL_##v##_t* Perl_##v##_ptr(pTHX) \
776 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
779 #define PERLVARIC(v,t,i) \
780 const t* Perl_##v##_ptr(pTHX) \
781 { PERL_UNUSED_CONTEXT; return (const t *)&(PL_##v); }
782 #define PERLVARISC(v,i) PL_##v##_t* Perl_##v##_ptr(pTHX) \
783 { dVAR; PERL_UNUSED_CONTEXT; return &(PL_##v); }
784 #include "perlvars.h"
794 #endif /* MULTIPLICITY && PERL_GLOBAL_STRUCT */
800 rename_if_different('perlapi.c-new', 'perlapi.c');
802 # ex: set ts=8 sts=4 sw=4 noet: