=head1 NAME
Devel::PPPort - Perl/Pollution/Portability
=head1 SYNOPSIS
Devel::PPPort::WriteFile() ; # defaults to ./ppport.h
Devel::PPPort::WriteFile('someheader.h') ;
=head1 DESCRIPTION
Perl has changed over time, gaining new features, new functions,
increasing its flexibility, and reducing the impact on the C namespace
environment (reduced pollution). The header file, typicaly C<ppport.h>,
written by this module attempts to bring some of the newer Perl
features to older versions of Perl, so that you can worry less about
keeping track of old releases, but users can still reap the benefit.
Why you should use C<ppport.h> in modern code: so that your code will work
with the widest range of Perl interpreters possible, without significant
additional work.
Why you should attempt older code to fully use C<ppport.h>: because
the reduced pollution of newer Perl versions is an important thing, so
important that the old polluting ways of original Perl modules will not be
supported very far into the future, and your module will almost certainly
break! By adapting to it now, you'll gained compatibility and a sense of
having done the electronic ecology some good.
How to use ppport.h: Don't direct the user to download C<Devel::PPPort>,
and don't make C<ppport.h> optional. Rather, just take the most recent
copy of C<ppport.h> that you can find (probably in C<Devel::PPPort>
on CPAN), copy it into your project, adjust your project to use it,
and distribute the header along with your module.
C<Devel::PPPort> contains a single function, called C<WriteFile>. It's
purpose is to write a 'C' header file that is used when writing XS
modules. The file contains a series of macros that allow XS modules to
be built using older versions of Perl.
This module is used by h2xs to write the file F<ppport.h>.
=head2 WriteFile
C<WriteFile> takes a zero or one parameters. When called with one
parameter it expects to be passed a filename. When called with no
parameters, it defults to the filename C<./pport.h>.
The function returns TRUE if the file was written successfully. Otherwise
it returns FALSE.
=head1 ppport.h
The file written by this module, typically C<ppport.h>, provides access
to the following Perl API if not already available (and in some cases [*]
even if available, access to a fixed interface):
aMY_CXT
aMY_CXT_
_aMY_CXT
aTHX
aTHX_
AvFILLp
boolSV(b)
call_argv
call_method
call_pv
call_sv
dAX
DEFSV
dITEMS
dMY_CXT
dMY_CXT_SV
dNOOP
dTHR
dTHX
dTHXa
dTHXoa
ERRSV
get_av
get_cv
get_hv
get_sv
grok_hex
grok_oct
grok_bin
grok_number
grok_numeric_radix
gv_stashpvn(str,len,flags)
INT2PTR(type,int)
IVdf
MY_CXT
MY_CXT_INIT
newCONSTSUB(stash,name,sv)
newRV_inc(sv)
newRV_noinc(sv)
newSVpvn(data,len)
NOOP
NV
NVef
NVff
NVgf
PERL_REVISION
PERL_SUBVERSION
PERL_UNUSED_DECL
PERL_VERSION
PL_compiling
PL_copline
PL_curcop
PL_curstash
PL_defgv
PL_dirty
PL_hints
PL_na
PL_perldb
PL_rsfp_filters
PL_rsfpv
PL_stdingv
PL_Sv
PL_sv_no
PL_sv_undef
PL_sv_yes
pMY_CXT
pMY_CXT_
_pMY_CXT
pTHX
pTHX_
PTR2IV(ptr)
PTR2NV(ptr)
PTR2ul(ptr)
PTR2UV(ptr)
SAVE_DEFSV
START_MY_CXT
SvPVbyte(sv,lp) [*]
UVof
UVSIZE
UVuf
UVxf
UVXf
=head1 AUTHOR
Version 1.x of Devel::PPPort was written by Kenneth Albanowski.
Version 2.x was ported to the Perl core by Paul Marquess.
=head1 SEE ALSO
See L<h2xs>.
=cut
require Exporter;
require DynaLoader;
#use warnings;
use strict;
$VERSION = "2.011";
@EXPORT = qw();
# Other items we are prepared to export if requested
@EXPORT_OK = qw( );
{
local $/ = undef;
my $now = localtime;
my $pkg = __PACKAGE__;
}
sub WriteFile
{
my $file = shift || 'ppport.h' ;
open F, ">$file" || return undef ;
print F $data ;
close F;
return 1 ;
}
1;
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*/
* modules.
*
*
*/
*
*
* doesn't attempt to account for global macro or function definitions,
*
*
*/
/*
foreach (<DATA>) {
}
unless (open(IN, "<$filename")) {
warn "Unable to read from $file: $!\n";
next;
}
print "Scanning $filename...\n";
$has_include = ($c =~ /#.*include.*ppport/m);
if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) {
if ($c !~ /\b$func\b/m) {
print "If $func isn't needed, you don't need to request it.\n" if
$changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m);
} else {
print "Uses $func\n";
$need_include = 1;
}
} else {
if ($c =~ /\b$func\b/m) {
print "Uses $func\n";
$need_include = 1;
}
}
}
if (not $need_include) {
if ($c =~ /\b$macro\b/m) {
print "Uses $macro\n";
$need_include = 1;
}
}
}
if ($c =~ /\b$badmacro\b/m) {
print "Uses $badmacros{$badmacro} (instead of $badmacro)\n";
$need_include = 1;
}
}
if (!$has_include) {
"#include \"ppport.h\"\n";
$c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m;
} elsif (keys %add_func) {
$c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m;
}
if (!$need_include) {
print "Doesn't seem to need ppport.h.\n";
$c =~ s/^.*#.*include.*ppport.*\n//m;
}
$changes++;
}
if ($changes) {
print OUT $c;
close(OUT);
close(DIFF);
} else {
print "Looks OK\n";
}
}
*/
#ifndef _P_P_PORTABILITY_H_
#define _P_P_PORTABILITY_H_
#ifndef PERL_REVISION
# ifndef __PATCHLEVEL_H_INCLUDED__
# define PERL_PATCHLEVEL_H_IMPLICIT
# include <patchlevel.h>
# endif
# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL)))
# include <could_not_find_Perl_patchlevel.h>
# endif
# ifndef PERL_REVISION
# define PERL_REVISION (5)
/* Replace: 1 */
# define PERL_VERSION PATCHLEVEL
# define PERL_SUBVERSION SUBVERSION
/* Replace: 0 */
# endif
#endif
#define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION)
*/
#if PERL_REVISION != 5
# error ppport.h only works with Perl version 5
#endif /* PERL_REVISION != 5 */
#ifndef ERRSV
# define ERRSV perl_get_sv("@",FALSE)
#endif
#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5))
/* Replace: 1 */
# define PL_Sv Sv
# define PL_compiling compiling
# define PL_copline copline
# define PL_curcop curcop
# define PL_curstash curstash
# define PL_defgv defgv
# define PL_dirty dirty
# define PL_dowarn dowarn
# define PL_hints hints
# define PL_na na
# define PL_perldb perldb
# define PL_rsfp_filters rsfp_filters
# define PL_rsfpv rsfp
# define PL_stdingv stdingv
# define PL_sv_no sv_no
# define PL_sv_undef sv_undef
# define PL_sv_yes sv_yes
/* Replace: 0 */
#endif
#ifdef HASATTRIBUTE
# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER)
# define PERL_UNUSED_DECL
# else
# define PERL_UNUSED_DECL __attribute__((unused))
# endif
#else
# define PERL_UNUSED_DECL
#endif
#ifndef dNOOP
# define NOOP (void)0
# define dNOOP extern int Perl___notused PERL_UNUSED_DECL
#endif
#ifndef dTHR
# define dTHR dNOOP
#endif
#ifndef dTHX
# define dTHX dNOOP
# define dTHXa(x) dNOOP
# define dTHXoa(x) dNOOP
#endif
#ifndef pTHX
# define pTHX void
# define pTHX_
# define aTHX
# define aTHX_
#endif
#ifndef dAX
# define dAX I32 ax = MARK - PL_stack_base + 1
#endif
#ifndef dITEMS
# define dITEMS I32 items = SP - MARK
#endif
#if !defined(IVSIZE) && defined(LONGSIZE)
# define IVSIZE LONGSIZE
#endif
#ifndef IVSIZE
# define IVSIZE 4 /* A bold guess, but the best we can make. */
#endif
#ifndef UVSIZE
# define UVSIZE IVSIZE
#endif
#ifndef NVTYPE
# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE)
# define NVTYPE long double
# else
# define NVTYPE double
# endif
#endif
#ifndef INT2PTR
#if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE)
# define PTRV UV
# define INT2PTR(any,d) (any)(d)
#else
# if PTRSIZE == LONGSIZE
# define PTRV unsigned long
# else
# define PTRV unsigned
# endif
# define INT2PTR(any,d) (any)(PTRV)(d)
#endif
#define NUM2PTR(any,d) (any)(PTRV)(d)
#define PTR2IV(p) INT2PTR(IV,p)
#define PTR2UV(p) INT2PTR(UV,p)
#define PTR2NV(p) NUM2PTR(NV,p)
#if PTRSIZE == LONGSIZE
# define PTR2ul(p) (unsigned long)(p)
#else
# define PTR2ul(p) INT2PTR(unsigned long,p)
#endif
#endif /* !INT2PTR */
#ifndef boolSV
# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
#endif
#ifndef gv_stashpvn
# define gv_stashpvn(str,len,flags) gv_stashpv(str,flags)
#endif
#ifndef newSVpvn
# define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0))
#endif
#ifndef newRV_inc
/* Replace: 1 */
# define newRV_inc(sv) newRV(sv)
/* Replace: 0 */
#endif
#ifndef DEFSV
# define DEFSV GvSV(PL_defgv)
#endif
#ifndef SAVE_DEFSV
# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
#endif
#ifndef newRV_noinc
# ifdef __GNUC__
# define newRV_noinc(sv) \
({ \
SvREFCNT_dec(sv); \
nsv; \
})
# else
# if defined(USE_THREADS)
{
return nsv;
}
# else
# define newRV_noinc(sv) \
# endif
# endif
#endif
/* Provide: newCONSTSUB */
#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63))
#if defined(NEED_newCONSTSUB)
#else
#endif
#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL)
{
PL_hints &= ~HINT_BLOCK_SCOPE;
if (stash)
#if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22))
#else
# if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22)
/* 5.003_22 */
start_subparse(0),
# else
# endif
#endif
);
}
#endif
#endif /* newCONSTSUB */
#ifndef START_MY_CXT
/*
*
* 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts"
*/
#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \
defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT)
#define START_MY_CXT
#if (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION < 68 ))
#define dMY_CXT_SV \
#else /* >= perl5.004_68 */
#define dMY_CXT_SV \
#endif /* < perl5.004_68 */
* interpreter-local data. */
#define dMY_CXT \
dMY_CXT_SV; \
#define MY_CXT_INIT \
dMY_CXT_SV; \
#define MY_CXT (*my_cxtp)
#define pMY_CXT my_cxt_t *my_cxtp
#define pMY_CXT_ pMY_CXT,
#define _pMY_CXT ,pMY_CXT
#define aMY_CXT my_cxtp
#define aMY_CXT_ aMY_CXT,
#define _aMY_CXT ,aMY_CXT
#else /* single interpreter */
#define START_MY_CXT static my_cxt_t my_cxt;
#define dMY_CXT_SV dNOOP
#define dMY_CXT dNOOP
#define MY_CXT_INIT NOOP
#define MY_CXT my_cxt
#define pMY_CXT void
#define pMY_CXT_
#define _pMY_CXT
#define aMY_CXT
#define aMY_CXT_
#define _aMY_CXT
#endif
#endif /* START_MY_CXT */
#ifndef IVdf
# if IVSIZE == LONGSIZE
# define IVdf "ld"
# define UVuf "lu"
# define UVof "lo"
# define UVxf "lx"
# define UVXf "lX"
# else
# if IVSIZE == INTSIZE
# define IVdf "d"
# define UVuf "u"
# define UVof "o"
# define UVxf "x"
# define UVXf "X"
# endif
# endif
#endif
#ifndef NVef
# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \
# define NVef PERL_PRIeldbl
# define NVff PERL_PRIfldbl
# define NVgf PERL_PRIgldbl
# else
# define NVef "e"
# define NVff "f"
# define NVgf "g"
# endif
#endif
#ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */
# define AvFILLp AvFILL
#endif
#ifdef SvPVbyte
# if PERL_REVISION == 5 && PERL_VERSION < 7
# undef SvPVbyte
# define SvPVbyte(sv, lp) \
{
}
# endif
#else
# define SvPVbyte SvPV
#endif
#ifndef SvPV_nolen
# define SvPV_nolen(sv) \
{
}
#endif
#ifndef get_cv
# define get_cv(name,create) perl_get_cv(name,create)
#endif
#ifndef get_sv
# define get_sv(name,create) perl_get_sv(name,create)
#endif
#ifndef get_av
# define get_av(name,create) perl_get_av(name,create)
#endif
#ifndef get_hv
# define get_hv(name,create) perl_get_hv(name,create)
#endif
#ifndef call_argv
# define call_argv perl_call_argv
#endif
#ifndef call_method
# define call_method perl_call_method
#endif
#ifndef call_pv
# define call_pv perl_call_pv
#endif
#ifndef call_sv
# define call_sv perl_call_sv
#endif
#ifndef eval_pv
# define eval_pv perl_eval_pv
#endif
#ifndef eval_sv
# define eval_sv perl_eval_sv
#endif
#ifndef PERL_SCAN_GREATER_THAN_UV_MAX
# define PERL_SCAN_GREATER_THAN_UV_MAX 0x02
#endif
#ifndef PERL_SCAN_SILENT_ILLDIGIT
# define PERL_SCAN_SILENT_ILLDIGIT 0x04
#endif
#ifndef PERL_SCAN_ALLOW_UNDERSCORES
# define PERL_SCAN_ALLOW_UNDERSCORES 0x01
#endif
#ifndef PERL_SCAN_DISALLOW_PREFIX
# define PERL_SCAN_DISALLOW_PREFIX 0x02
#endif
#if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1))
#define I32_CAST
#else
#define I32_CAST (I32*)
#endif
#ifndef grok_hex
if (r > UV_MAX) {
return UV_MAX;
}
return (UV)r;
}
# define grok_hex(string, len, flags, result) \
#endif
#ifndef grok_oct
if (r > UV_MAX) {
return UV_MAX;
}
return (UV)r;
}
# define grok_oct(string, len, flags, result) \
#endif
#if !defined(grok_bin) && defined(scan_bin)
if (r > UV_MAX) {
return UV_MAX;
}
return (UV)r;
}
# define grok_bin(string, len, flags, result) \
#endif
#ifndef IN_LOCALE
# define IN_LOCALE \
#endif
#ifndef IN_LOCALE_RUNTIME
# define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE)
#endif
#ifndef IN_LOCALE_COMPILETIME
# define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE)
#endif
#ifndef IS_NUMBER_IN_UV
# define IS_NUMBER_IN_UV 0x01
# define IS_NUMBER_GREATER_THAN_UV_MAX 0x02
# define IS_NUMBER_NOT_INT 0x04
# define IS_NUMBER_NEG 0x08
# define IS_NUMBER_INFINITY 0x10
# define IS_NUMBER_NAN 0x20
#endif
#ifndef grok_numeric_radix
# define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(aTHX_ sp, send)
#define grok_numeric_radix Perl_grok_numeric_radix
{
#ifdef USE_LOCALE_NUMERIC
#if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1))
if (PL_numeric_radix_sv && IN_LOCALE) {
return TRUE;
}
}
#else
#include <locale.h>
return TRUE;
}
}
#endif /* PERL_VERSION */
#endif /* USE_LOCALE_NUMERIC */
++*sp;
return TRUE;
}
return FALSE;
}
#endif /* grok_numeric_radix */
#ifndef grok_number
#define grok_number Perl_grok_number
int
{
int numtype = 0;
int sawinf = 0;
int sawnan = 0;
while (s < send && isSPACE(*s))
s++;
if (s == send) {
return 0;
} else if (*s == '-') {
s++;
}
else if (*s == '+')
s++;
if (s == send)
return 0;
if (isDIGIT(*s)) {
overflow. */
if (++s < send) {
int digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
each time for overflow. */
digit = *s - '0';
&& (value < max_div_10
|| (value == max_div_10
&& digit <= max_mod_10))) {
if (++s < send)
digit = *s - '0';
else
break;
}
&& (s < send)) {
/* value overflowed.
do {
s++;
} while (s < send && isDIGIT(*s));
numtype |=
goto skip_value;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
if (valuep)
if (GROK_NUMERIC_RADIX(&s, send)) {
s++;
}
}
else if (GROK_NUMERIC_RADIX(&s, send)) {
if (s < send && isDIGIT(*s)) {
do {
s++;
} while (s < send && isDIGIT(*s));
if (valuep) {
*valuep = 0;
}
}
else
return 0;
} else if (*s == 'I' || *s == 'i') {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'F' && *s != 'f')) return 0;
s++; if (s < send && (*s == 'I' || *s == 'i')) {
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++; if (s == send || (*s != 'I' && *s != 'i')) return 0;
s++; if (s == send || (*s != 'T' && *s != 't')) return 0;
s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0;
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
} else if (sawnan) {
} else if (s < send) {
if (*s == 'e' || *s == 'E') {
numtype &= IS_NUMBER_NEG;
s++;
if (s < send && (*s == '-' || *s == '+'))
s++;
if (s < send && isDIGIT(*s)) {
do {
s++;
} while (s < send && isDIGIT(*s));
}
else
return 0;
}
}
while (s < send && isSPACE(*s))
s++;
if (s >= send)
return numtype;
if (valuep)
*valuep = 0;
return IS_NUMBER_IN_UV;
}
return 0;
}
#endif /* grok_number */
#ifndef PERL_MAGIC_sv
# define PERL_MAGIC_sv '\0'
#endif
#ifndef PERL_MAGIC_overload
# define PERL_MAGIC_overload 'A'
#endif
#ifndef PERL_MAGIC_overload_elem
# define PERL_MAGIC_overload_elem 'a'
#endif
#ifndef PERL_MAGIC_overload_table
# define PERL_MAGIC_overload_table 'c'
#endif
#ifndef PERL_MAGIC_bm
# define PERL_MAGIC_bm 'B'
#endif
#ifndef PERL_MAGIC_regdata
# define PERL_MAGIC_regdata 'D'
#endif
#ifndef PERL_MAGIC_regdatum
# define PERL_MAGIC_regdatum 'd'
#endif
#ifndef PERL_MAGIC_env
# define PERL_MAGIC_env 'E'
#endif
#ifndef PERL_MAGIC_envelem
# define PERL_MAGIC_envelem 'e'
#endif
#ifndef PERL_MAGIC_fm
# define PERL_MAGIC_fm 'f'
#endif
#ifndef PERL_MAGIC_regex_global
# define PERL_MAGIC_regex_global 'g'
#endif
#ifndef PERL_MAGIC_isa
# define PERL_MAGIC_isa 'I'
#endif
#ifndef PERL_MAGIC_isaelem
# define PERL_MAGIC_isaelem 'i'
#endif
#ifndef PERL_MAGIC_nkeys
# define PERL_MAGIC_nkeys 'k'
#endif
#ifndef PERL_MAGIC_dbfile
# define PERL_MAGIC_dbfile 'L'
#endif
#ifndef PERL_MAGIC_dbline
# define PERL_MAGIC_dbline 'l'
#endif
#ifndef PERL_MAGIC_mutex
# define PERL_MAGIC_mutex 'm'
#endif
#ifndef PERL_MAGIC_shared
# define PERL_MAGIC_shared 'N'
#endif
#ifndef PERL_MAGIC_shared_scalar
# define PERL_MAGIC_shared_scalar 'n'
#endif
#ifndef PERL_MAGIC_collxfrm
# define PERL_MAGIC_collxfrm 'o'
#endif
#ifndef PERL_MAGIC_tied
# define PERL_MAGIC_tied 'P'
#endif
#ifndef PERL_MAGIC_tiedelem
# define PERL_MAGIC_tiedelem 'p'
#endif
#ifndef PERL_MAGIC_tiedscalar
# define PERL_MAGIC_tiedscalar 'q'
#endif
#ifndef PERL_MAGIC_qr
# define PERL_MAGIC_qr 'r'
#endif
#ifndef PERL_MAGIC_sig
# define PERL_MAGIC_sig 'S'
#endif
#ifndef PERL_MAGIC_sigelem
# define PERL_MAGIC_sigelem 's'
#endif
#ifndef PERL_MAGIC_taint
# define PERL_MAGIC_taint 't'
#endif
#ifndef PERL_MAGIC_uvar
# define PERL_MAGIC_uvar 'U'
#endif
#ifndef PERL_MAGIC_uvar_elem
# define PERL_MAGIC_uvar_elem 'u'
#endif
#ifndef PERL_MAGIC_vstring
# define PERL_MAGIC_vstring 'V'
#endif
#ifndef PERL_MAGIC_vec
# define PERL_MAGIC_vec 'v'
#endif
#ifndef PERL_MAGIC_utf8
# define PERL_MAGIC_utf8 'w'
#endif
#ifndef PERL_MAGIC_substr
# define PERL_MAGIC_substr 'x'
#endif
#ifndef PERL_MAGIC_defelem
# define PERL_MAGIC_defelem 'y'
#endif
#ifndef PERL_MAGIC_glob
# define PERL_MAGIC_glob '*'
#endif
#ifndef PERL_MAGIC_arylen
# define PERL_MAGIC_arylen '#'
#endif
#ifndef PERL_MAGIC_pos
# define PERL_MAGIC_pos '.'
#endif
#ifndef PERL_MAGIC_backref
# define PERL_MAGIC_backref '<'
#endif
#ifndef PERL_MAGIC_ext
# define PERL_MAGIC_ext '~'
#endif
#endif /* _P_P_PORTABILITY_H_ */