Devel::PPPort - Perl/Pollution/Portability
Devel::PPPort::WriteFile(); # defaults to ./ppport.h
Devel::PPPort::WriteFile('someheader.h');
# Same as above but retrieve contents rather than write file
my $contents = Devel::PPPort::GetFileContents();
my $contents = Devel::PPPort::GetFileContents('someheader.h');
$ cpan Devel::PPPort
$ perl -MDevel::PPPort -e'Devel::PPPort::WriteFile'
$ perl ppport.h --compat-version=5.6.1 --patch=diff.patch *.xs
$ patch -p0 < diff.patch
$ echo ppport.h >>MANIFEST
Perl's API 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 written by this module, typically ppport.h, attempts to bring some of the newer Perl API 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.
Devel::PPPort contains two functions, WriteFile and GetFileContents. WriteFile's only purpose is to write the ppport.h C header file. This file contains a series of macros and, if explicitly requested, functions that allow XS modules to be built using older versions of Perl. Currently, Perl versions from 5.003_07 to 5.35.9 are supported.
GetFileContents can be used to retrieve the file contents rather than writing it out.
This module is used by h2xs to write the file ppport.h.
You should use ppport.h in modern code so that your code will work with the widest range of Perl interpreters possible, without significant additional work.
You should attempt to get older code to fully use ppport.h, because the reduced pollution of newer Perl versions is an important thing. It's 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 gain compatibility and a sense of having done the electronic ecology some good.
Don't direct the users of your module to download Devel::PPPort. They are most probably not XS writers. Also, don't make ppport.h optional. Rather, just take the most recent copy of ppport.h that you can find (e.g. by generating it with the latest Devel::PPPort release from CPAN), copy it into your project, adjust your project to use it, test it, and distribute the header along with your module.
It is important to use the most recent version of ppport.h. You do need to test before shipping a newer version than you already had. One possible failure is that someone had to convert a backported element from a macro into a function, and actual functions must be enabled with a NEED macro to minimize the possibility of namespace pollution. See HACKERS for details. The developers of Devel::PPPort want to hear if there are other problems that arise from using a later ppport.h. Use https://github.com/Dual-Life/Devel-PPPort/issues to report any.
But ppport.h is more than just a C header. It's also a Perl script that can check your source code. It will suggest hints and portability notes, and can even make suggestions on how to change your code. You can run it like any other Perl program:
perl ppport.h [options] [files]
It also has embedded documentation, so you can use
perldoc ppport.h
to find out more about how to use it.
WriteFile takes one optional argument. When called with one argument, it expects to be passed a filename. When called with no arguments, it defaults to the filename ppport.h.
The function returns a true value if the file was written successfully. Otherwise it returns a false value.
GetFileContents behaves like WriteFile above, but returns the contents of the would-be file rather than writing it out.
ppport.h supports Perl versions from 5.003_07 to 5.35.9 in threaded and non-threaded configurations.
The header file written by this module, typically ppport.h, provides access to the following elements of the Perl API that are not otherwise available in Perl releases older than when the elements were first introduced. (Note that many of these are not supported all the way back to 5.003_07, but it may be that they are supported back as far as you need; see "Supported Perl API, sorted by version" for that information.)
_aMY_CXT
aMY_CXT
aMY_CXT_
__ASSERT_
ASSUME
aTHX
aTHX_
aTHXR
aTHXR_
av_count
AvFILLp
av_tindex
av_top_index
BOM_UTF8
boolSV
call_argv
caller_cx
call_method
call_pv
call_sv
C_ARRAY_END
C_ARRAY_LENGTH
cBOOL
ckWARN
ckWARN2
ckWARN2_d
ckWARN3
ckWARN3_d
ckWARN4
ckWARN4_d
ckWARN_d
ck_warner
ck_warner_d
CopFILE
CopFILEAV
CopFILEGV
CopFILEGV_set
CopFILE_set
CopFILESV
CopSTASH
CopSTASH_eq
CopSTASHPV
CopSTASHPV_set
CopSTASH_set
CopyD
CPERLscope
croak_memory_wrap
croak_nocontext
croak_no_modify
croak_sv
croak_xs_usage
dAX
dAXMARK
DECLARATION_FOR_LC_NUMERIC_MANIPULATION
DEFSV
DEFSV_set
die_sv
dITEMS
dMY_CXT
dMY_CXT_SV
dNOOP
dTHR
dTHX
dTHXa
dTHXoa
dTHXR
dUNDERBAR
dVAR
dXCPT
dXSTARG
END_EXTERN_C
ERRSV
eval_pv
eval_sv
EXTERN_C
foldEQ_utf8
get_av
get_cv
get_cvn_flags
get_cvs
get_hv
get_sv
G_METHOD
G_RETHROW
grok_bin
grok_hex
grok_number
GROK_NUMERIC_RADIX
grok_numeric_radix
grok_oct
gv_fetchpvn_flags
gv_fetchpvs
gv_fetchsv
gv_init_pvn
gv_stashpvn
gv_stashpvs
GvSVn
HEf_SVKEY
HeUTF8
hv_fetchs
HvNAME_get
HvNAMELEN_get
hv_stores
IN_LOCALE
IN_LOCALE_COMPILETIME
IN_LOCALE_RUNTIME
IN_PERL_COMPILETIME
INT2PTR
isALNUM
isALNUM_A
isALNUMC
isALNUMC_A
isALNUMC_L1
isALPHA
isALPHA_A
isALPHA_L1
isALPHA_LC_utf8_safe
isALPHANUMERIC
isALPHANUMERIC_A
isALPHANUMERIC_L1
isALPHANUMERIC_LC
isALPHANUMERIC_LC_utf8_safe
isALPHANUMERIC_utf8_safe
isALPHANUMERIC_uvchr
isALPHA_utf8_safe
isALPHA_uvchr
isASCII
isASCII_A
isASCII_L1
isASCII_LC
isASCII_utf8_safe
isASCII_uvchr
isBLANK
isBLANK_A
isBLANK_L1
isBLANK_LC
isBLANK_LC_utf8_safe
isBLANK_utf8_safe
isBLANK_uvchr
isCNTRL
isCNTRL_A
isCNTRL_L1
isCNTRL_LC_utf8_safe
isCNTRL_utf8_safe
isCNTRL_uvchr
isDIGIT
isDIGIT_A
isDIGIT_L1
isDIGIT_LC_utf8_safe
isDIGIT_utf8_safe
isDIGIT_uvchr
isGRAPH
isGRAPH_A
isGRAPH_L1
isGRAPH_LC_utf8_safe
isGRAPH_utf8_safe
isGRAPH_uvchr
isGV_with_GP
isIDCONT
isIDCONT_A
isIDCONT_L1
isIDCONT_LC
isIDCONT_LC_utf8_safe
isIDCONT_utf8_safe
isIDCONT_uvchr
isIDFIRST
isIDFIRST_A
isIDFIRST_L1
isIDFIRST_LC
isIDFIRST_LC_utf8_safe
isIDFIRST_utf8_safe
isIDFIRST_uvchr
is_invariant_string
isLOWER
isLOWER_A
isLOWER_L1
isLOWER_LC_utf8_safe
isLOWER_utf8_safe
isLOWER_uvchr
IS_NUMBER_GREATER_THAN_UV_MAX
IS_NUMBER_INFINITY
IS_NUMBER_IN_UV
IS_NUMBER_NAN
IS_NUMBER_NEG
IS_NUMBER_NOT_INT
isOCTAL
isOCTAL_A
isOCTAL_L1
isPRINT
isPRINT_A
isPRINT_L1
isPRINT_LC_utf8_safe
isPRINT_utf8_safe
isPRINT_uvchr
isPSXSPC
isPSXSPC_A
isPSXSPC_L1
isPSXSPC_LC_utf8_safe
isPSXSPC_utf8_safe
isPSXSPC_uvchr
isPUNCT
isPUNCT_A
isPUNCT_L1
isPUNCT_LC_utf8_safe
isPUNCT_utf8_safe
isPUNCT_uvchr
isSPACE
isSPACE_A
isSPACE_L1
isSPACE_LC_utf8_safe
isSPACE_utf8_safe
isSPACE_uvchr
isUPPER
isUPPER_A
isUPPER_L1
isUPPER_LC_utf8_safe
isUPPER_utf8_safe
isUPPER_uvchr
isUTF8_CHAR
is_utf8_invariant_string
isWORDCHAR
isWORDCHAR_A
isWORDCHAR_L1
isWORDCHAR_LC
isWORDCHAR_LC_utf8_safe
isWORDCHAR_utf8_safe
isWORDCHAR_uvchr
isXDIGIT
isXDIGIT_A
isXDIGIT_L1
isXDIGIT_LC
isXDIGIT_LC_utf8_safe
isXDIGIT_utf8_safe
isXDIGIT_uvchr
IVdf
IVSIZE
IVTYPE
LATIN1_TO_NATIVE
LC_NUMERIC_LOCK
LC_NUMERIC_UNLOCK
LIKELY
load_module
LOCK_LC_NUMERIC_STANDARD
LOCK_NUMERIC_STANDARD
memCHRs
memEQ
memEQs
memNE
memNEs
mess
mess_nocontext
mess_sv
mg_findext
MoveD
mPUSHi
mPUSHn
mPUSHp
mPUSHs
mPUSHu
MUTABLE_AV
MUTABLE_CV
MUTABLE_GV
MUTABLE_HV
MUTABLE_IO
MUTABLE_PTR
MUTABLE_SV
mXPUSHi
mXPUSHn
mXPUSHp
mXPUSHs
mXPUSHu
MY_CXT
MY_CXT_CLONE
MY_CXT_INIT
my_snprintf
my_sprintf
my_strlcat
my_strlcpy
my_strnlen
NATIVE_TO_LATIN1
NATIVE_TO_UNI
newCONSTSUB
newRV_inc
newRV_noinc
newSVpvn
newSVpvn_flags
newSVpvn_share
newSVpvn_utf8
newSVpvs
newSVpvs_flags
newSVpvs_share
newSVsv_flags
newSVsv_nomg
newSV_type
newSVuv
Newx
Newxc
Newxz
NOOP
NOT_REACHED
NUM2PTR
NVef
NVff
NVgf
NVTYPE
OpHAS_SIBLING
OpLASTSIB_set
OpMAYBESIB_set
OpMORESIB_set
OpSIBLING
packWARN
packWARN2
packWARN3
packWARN4
PERL_ABS
PERL_ARGS_ASSERT_CROAK_XS_USAGE
Perl_ck_warner
Perl_ck_warner_d
Perl_croak_no_modify
PERL_HASH
PERL_INT_MAX
PERL_INT_MIN
PERLIO_FUNCS_CAST
PERLIO_FUNCS_DECL
PERL_LONG_MAX
PERL_LONG_MIN
PERL_MAGIC_arylen
PERL_MAGIC_backref
PERL_MAGIC_bm
PERL_MAGIC_collxfrm
PERL_MAGIC_dbfile
PERL_MAGIC_dbline
PERL_MAGIC_defelem
PERL_MAGIC_env
PERL_MAGIC_envelem
PERL_MAGIC_ext
PERL_MAGIC_fm
PERL_MAGIC_glob
PERL_MAGIC_isa
PERL_MAGIC_isaelem
PERL_MAGIC_mutex
PERL_MAGIC_nkeys
PERL_MAGIC_overload
PERL_MAGIC_overload_elem
PERL_MAGIC_overload_table
PERL_MAGIC_pos
PERL_MAGIC_qr
PERL_MAGIC_regdata
PERL_MAGIC_regdatum
PERL_MAGIC_regex_global
PERL_MAGIC_shared
PERL_MAGIC_shared_scalar
PERL_MAGIC_sig
PERL_MAGIC_sigelem
PERL_MAGIC_substr
PERL_MAGIC_sv
PERL_MAGIC_taint
PERL_MAGIC_tied
PERL_MAGIC_tiedelem
PERL_MAGIC_tiedscalar
PERL_MAGIC_utf8
PERL_MAGIC_uvar
PERL_MAGIC_uvar_elem
PERL_MAGIC_vec
PERL_MAGIC_vstring
PERL_PV_ESCAPE_ALL
PERL_PV_ESCAPE_FIRSTCHAR
PERL_PV_ESCAPE_NOBACKSLASH
PERL_PV_ESCAPE_NOCLEAR
PERL_PV_ESCAPE_QUOTE
PERL_PV_ESCAPE_RE
PERL_PV_ESCAPE_UNI
PERL_PV_ESCAPE_UNI_DETECT
PERL_PV_PRETTY_DUMP
PERL_PV_PRETTY_ELLIPSES
PERL_PV_PRETTY_LTGT
PERL_PV_PRETTY_NOCLEAR
PERL_PV_PRETTY_QUOTE
PERL_PV_PRETTY_REGPROP
PERL_QUAD_MAX
PERL_QUAD_MIN
PERL_SCAN_ALLOW_UNDERSCORES
PERL_SCAN_DISALLOW_PREFIX
PERL_SCAN_GREATER_THAN_UV_MAX
PERL_SCAN_SILENT_ILLDIGIT
PERL_SHORT_MAX
PERL_SHORT_MIN
PERL_SIGNALS_UNSAFE_FLAG
PERL_STACK_OFFSET_DEFINED
PERL_STATIC_INLINE
PERL_UCHAR_MAX
PERL_UCHAR_MIN
PERL_UINT_MAX
PERL_UINT_MIN
PERL_ULONG_MAX
PERL_ULONG_MIN
PERL_UNUSED_ARG
PERL_UNUSED_CONTEXT
PERL_UNUSED_DECL
PERL_UNUSED_RESULT
PERL_UNUSED_VAR
PERL_UQUAD_MAX
PERL_UQUAD_MIN
PERL_USE_GCC_BRACE_GROUPS
PERL_USHORT_MAX
PERL_USHORT_MIN
PERL_VERSION_EQ
PERL_VERSION_GE
PERL_VERSION_GT
PERL_VERSION_LE
PERL_VERSION_LT
PERL_VERSION_NE
Perl_warner
Perl_warner_nocontext
PL_bufend
PL_bufptr
PL_compiling
PL_copline
PL_curcop
PL_curstash
PL_DBsignal
PL_DBsingle
PL_DBsub
PL_DBtrace
PL_debstash
PL_defgv
PL_diehook
PL_dirty
PL_dowarn
PL_errgv
PL_error_count
PL_expect
PL_hexdigit
PL_hints
PL_in_my
PL_in_my_stash
PL_laststatval
PL_lex_state
PL_lex_stuff
PL_linestr
PL_mess_sv
PL_na
PL_no_modify
PL_parser
PL_perldb
PL_perl_destruct_level
PL_ppaddr
PL_rsfp
PL_rsfp_filters
PL_signals
PL_stack_base
PL_stack_sp
PL_statcache
PL_stdingv
PL_Sv
PL_sv_arenaroot
PL_sv_no
PL_sv_undef
PL_sv_yes
PL_tainted
PL_tainting
PL_tokenbuf
PL_Xpv
_pMY_CXT
pMY_CXT
pMY_CXT_
Poison
PoisonFree
PoisonNew
PoisonWith
pTHX
pTHX_
PTR2IV
PTR2nat
PTR2NV
PTR2ul
PTR2UV
PTRV
PUSHmortal
PUSHu
pv_display
pv_escape
pv_pretty
REPLACEMENT_CHARACTER_UTF8
RESTORE_LC_NUMERIC
SAVE_DEFSV
Stack_off_t
Stack_off_t_MAX
START_EXTERN_C
START_MY_CXT
start_subparse
STMT_END
STMT_START
STORE_LC_NUMERIC_SET_STANDARD
STORE_NUMERIC_SET_STANDARD
STR_WITH_LEN
sv_2pv
sv_2pvbyte
sv_2pvbyte_nolen
sv_2pv_flags
sv_2pv_nolen
sv_2uv
sv_catpvf_mg
sv_catpvf_mg_nocontext
sv_catpv_mg
sv_catpvn_mg
sv_catpvn_nomg
sv_catpvs
sv_catsv_mg
sv_catsv_nomg
SV_CONST_RETURN
SV_COW_DROP_PV
SV_COW_SHARED_HASH_KEYS
SVf
SVfARG
SVf_UTF8
SvGETMAGIC
SV_GMAGIC
SV_HAS_TRAILING_NUL
SV_IMMEDIATE_UNREF
SvIV_nomg
sv_len_utf8
sv_len_utf8_nomg
sv_magic_portable
SvMAGIC_set
sv_mortalcopy_flags
SV_MUTABLE_RETURN
SV_NOSTEAL
SvNV_nomg
SvPVbyte
SvPVCLEAR
SvPV_const
SvPV_flags
SvPV_flags_const
SvPV_flags_const_nolen
SvPV_flags_mutable
SvPV_force
SvPV_force_flags
SvPV_force_flags_mutable
SvPV_force_flags_nolen
SvPV_force_mutable
SvPV_force_nolen
SvPV_force_nomg
SvPV_force_nomg_nolen
SvPV_mutable
sv_pvn_force_flags
sv_pvn_nomg
SvPV_nolen
SvPV_nolen_const
SvPV_nomg
SvPV_nomg_const
SvPV_nomg_const_nolen
SvPV_nomg_nolen
SvPV_renew
SvPVX_const
SvPVX_mutable
SvPVx_nolen_const
SvREFCNT_inc
SvREFCNT_inc_NN
SvREFCNT_inc_simple
SvREFCNT_inc_simple_NN
SvREFCNT_inc_simple_void
SvREFCNT_inc_simple_void_NN
SvREFCNT_inc_void
SvREFCNT_inc_void_NN
SvRV_set
SvRX
SvRXOK
sv_setiv_mg
sv_setnv_mg
sv_setpvf_mg
sv_setpvf_mg_nocontext
sv_setpv_mg
sv_setpvn_mg
sv_setpvs
sv_setsv_flags
sv_setsv_mg
sv_setsv_nomg
sv_setuv
sv_setuv_mg
SvSHARED_HASH
SV_SMAGIC
SvSTASH_set
SvTRUE_nomg
sv_unmagicext
SvUOK
sv_usepvn_mg
SvUTF8
SV_UTF8_NO_ENCODING
sv_uv
SvUV
SvUV_nomg
SvUV_set
SvUVX
SvUVx
SvUVXx
sv_vcatpvf
sv_vcatpvf_mg
sv_vsetpvf
sv_vsetpvf_mg
SvVSTRING_mg
switch_to_global_locale
sync_locale
toFOLD_utf8_safe
toFOLD_uvchr
toLOWER_utf8_safe
toLOWER_uvchr
toTITLE_utf8_safe
toTITLE_uvchr
toUPPER_utf8_safe
toUPPER_uvchr
UNDERBAR
UNICODE_REPLACEMENT
UNI_TO_NATIVE
UNLIKELY
UNLOCK_LC_NUMERIC_STANDARD
UNLOCK_NUMERIC_STANDARD
UTF8_CHK_SKIP
UTF8f
UTF8fARG
UTF8_IS_INVARIANT
UTF8_MAXBYTES
UTF8_MAXBYTES_CASE
UTF8_SAFE_SKIP
UTF8_SKIP
utf8_to_uvchr
utf8_to_uvchr_buf
UVCHR_IS_INVARIANT
UVCHR_SKIP
UVof
UVSIZE
UVTYPE
UVuf
UVXf
UVxf
vload_module
vmess
vnewSVpvf
vwarner
WARN_ALL
WARN_AMBIGUOUS
WARN_ASSERTIONS
WARN_BAREWORD
WARN_CLOSED
WARN_CLOSURE
WARN_DEBUGGING
WARN_DEPRECATED
WARN_DIGIT
warner
WARN_EXEC
WARN_EXITING
WARN_GLOB
WARN_INPLACE
WARN_INTERNAL
WARN_IO
WARN_LAYER
WARN_MALLOC
WARN_MISC
WARN_NEWLINE
warn_nocontext
WARN_NUMERIC
WARN_ONCE
WARN_OVERFLOW
WARN_PACK
WARN_PARENTHESIS
WARN_PIPE
WARN_PORTABLE
WARN_PRECEDENCE
WARN_PRINTF
WARN_PROTOTYPE
WARN_QW
WARN_RECURSION
WARN_REDEFINE
WARN_REGEXP
WARN_RESERVED
WARN_SEMICOLON
WARN_SEVERE
WARN_SIGNAL
WARN_SUBSTR
warn_sv
WARN_SYNTAX
WARN_TAINT
WARN_THREADS
WARN_UNINITIALIZED
WARN_UNOPENED
WARN_UNPACK
WARN_UNTIE
WARN_UTF8
WARN_VOID
WIDEST_UTYPE
XCPT_CATCH
XCPT_RETHROW
XCPT_TRY_END
XCPT_TRY_START
XPUSHmortal
XPUSHu
XSprePUSH
XSPROTO
XSRETURN
XSRETURN_UV
XST_mUV
ZeroD
The table in this section lists all the Perl API elements available, sorted by the version in which support starts. This includes all the elements that ppport.h helps out with, as well as those elements that it doesn't.
In some cases, it doesn't make practical sense for elements to be supported earlier than they already are. For example, UTF-8 functionality isn't provided prior to the release where it was first introduced.
But in other cases, it just is that no one has implemented support yet. Patches welcome! Some elements are ported backward for some releases, but not all the way to 5.003_07.
If an element, call it ELEMENT, is not on this list, try using this command to find out why:
perl ppport.h --api-info=ELEMENT
A few of the entries in the list below are marked as DEPRECATED. You should not use these for new code, and should be converting existing uses to use something better.
Some of the entries in the list are marked as "experimental". This means these should not generally be used. They may be removed or changed without notice. You can ask why they are experimental by sending email to mailto:perl5-porters@perl.org.
And some of the entries are marked as "undocumented". This means that they aren't necessarily considered stable, and could be changed or removed in some future release without warning. It is therefore a bad idea to use them without further checking. It could be that these are considered to be for perl core use only; or it could be, though, that Devel::PPPort doesn't know where to find their documentation, or that it's just an oversight that they haven't been documented. If you want to use one, and potentially have it backported, first send mail to mailto:perl5-porters@perl.org.