1N/A Devel::PPPort::WriteFile() ; # defaults to ./ppport.h 1N/A Devel::PPPort::WriteFile('someheader.h') ; 1N/APerl has changed over time, gaining new features, new functions, 1N/Aincreasing its flexibility, and reducing the impact on the C namespace 1N/Aenvironment (reduced pollution). The header file, typicaly C<ppport.h>, 1N/Awritten by this module attempts to bring some of the newer Perl 1N/Afeatures to older versions of Perl, so that you can worry less about 1N/Akeeping track of old releases, but users can still reap the benefit. 1N/AWhy you should use C<ppport.h> in modern code: so that your code will work 1N/Awith the widest range of Perl interpreters possible, without significant 1N/AWhy you should attempt older code to fully use C<ppport.h>: because 1N/Athe reduced pollution of newer Perl versions is an important thing, so 1N/Aimportant that the old polluting ways of original Perl modules will not be 1N/Asupported very far into the future, and your module will almost certainly 1N/Abreak! By adapting to it now, you'll gained compatibility and a sense of 1N/Ahaving done the electronic ecology some good. 1N/AHow to use ppport.h: Don't direct the user to download C<Devel::PPPort>, 1N/Aand don't make C<ppport.h> optional. Rather, just take the most recent 1N/Acopy of C<ppport.h> that you can find (probably in C<Devel::PPPort> 1N/Aon CPAN), copy it into your project, adjust your project to use it, 1N/Aand distribute the header along with your module. 1N/AC<Devel::PPPort> contains a single function, called C<WriteFile>. It's 1N/Apurpose is to write a 'C' header file that is used when writing XS 1N/Amodules. The file contains a series of macros that allow XS modules to 1N/Abe built using older versions of Perl. 1N/AThis module is used by h2xs to write the file F<ppport.h>. 1N/AC<WriteFile> takes a zero or one parameters. When called with one 1N/Aparameter it expects to be passed a filename. When called with no 1N/Aparameters, it defults to the filename C<./pport.h>. 1N/AThe function returns TRUE if the file was written successfully. Otherwise 1N/AThe file written by this module, typically C<ppport.h>, provides access 1N/Ato the following Perl API if not already available (and in some cases [*] 1N/Aeven if available, access to a fixed interface): 1N/A gv_stashpvn(str,len,flags) 1N/A newCONSTSUB(stash,name,sv) 1N/AVersion 1.x of Devel::PPPort was written by Kenneth Albanowski. 1N/AVersion 2.x was ported to the Perl core by Paul Marquess. 1N/A# Other items we are prepared to export if requested 1N/A open F,
">$file" ||
return undef ;
1N/A *
doesn't attempt to account for global macro or function definitions, 1N/A $
macros{$
1} =
1 if /^
#\s*define\s+([a-zA-Z0-9_]+)/; 1N/A unless (
open(
IN,
"<$filename")) {
1N/A warn "Unable to read from $file: $!\n";
1N/A print "Scanning $filename...\n";
1N/A $c =
"";
while (<
IN>) { $c .= $_; }
close(
IN);
1N/A if ($c =~ /
#.*define.*\bNEED_$func(_GLOBAL)?\b/m) { 1N/A print "If $func isn't needed, you don't need to request it.\n" if 1N/A $
changes += ($c =~ s/^.*
#.*define.*\bNEED_$func\b.*\n//m); 1N/A print "Uses $func\n";
1N/A print "Uses $func\n";
1N/A print "Uses $macro\n";
1N/A print "Uses $badmacros{$badmacro} (instead of $badmacro)\n";
1N/A "#include \"ppport.h\"\n";
1N/A $c =
"$inc$c" unless $c =~ s/
#.*include.*XSUB.*\n/$&$inc/m; 1N/A $c =
"$inc$c" unless $c =~ s/^.*
#.*include.*ppport.*$/$inc$&/m; 1N/A print "Doesn't seem to need ppport.h.\n";
1N/A $c =~ s/^.*
#.*include.*ppport.*\n//m; 1N/A#ifndef _P_P_PORTABILITY_H_ 1N/A#define _P_P_PORTABILITY_H_ 1N/A#ifndef PERL_REVISION 1N/A# ifndef __PATCHLEVEL_H_INCLUDED__ 1N/A# define PERL_PATCHLEVEL_H_IMPLICIT 1N/A# include <patchlevel.h> 1N/A# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) 1N/A# include <could_not_find_Perl_patchlevel.h> 1N/A# ifndef PERL_REVISION 1N/A# define PERL_REVISION (5) 1N/A# define PERL_VERSION PATCHLEVEL 1N/A# define PERL_SUBVERSION SUBVERSION 1N/A#define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION) 1N/A#if PERL_REVISION != 5 1N/A# error ppport.h only works with Perl version 5 1N/A#endif /* PERL_REVISION != 5 */ 1N/A# define ERRSV perl_get_sv("@",FALSE) 1N/A#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)) 1N/A# define PL_compiling compiling 1N/A# define PL_copline copline 1N/A# define PL_curcop curcop 1N/A# define PL_curstash curstash 1N/A# define PL_defgv defgv 1N/A# define PL_dirty dirty 1N/A# define PL_dowarn dowarn 1N/A# define PL_hints hints 1N/A# define PL_perldb perldb 1N/A# define PL_rsfp_filters rsfp_filters 1N/A# define PL_rsfpv rsfp 1N/A# define PL_stdingv stdingv 1N/A# define PL_sv_no sv_no 1N/A# define PL_sv_undef sv_undef 1N/A# define PL_sv_yes sv_yes 1N/A# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) 1N/A# define PERL_UNUSED_DECL 1N/A# define PERL_UNUSED_DECL __attribute__((unused)) 1N/A# define PERL_UNUSED_DECL 1N/A# define NOOP (void)0 1N/A# define dNOOP extern int Perl___notused PERL_UNUSED_DECL 1N/A# define dTHXa(x) dNOOP 1N/A# define dTHXoa(x) dNOOP 1N/A# define dAX I32 ax = MARK - PL_stack_base + 1 1N/A# define dITEMS I32 items = SP - MARK 1N/A#if !defined(IVSIZE) && defined(LONGSIZE) 1N/A# define IVSIZE LONGSIZE 1N/A# define IVSIZE 4 /* A bold guess, but the best we can make. */ 1N/A# define UVSIZE IVSIZE 1N/A# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) 1N/A# define NVTYPE long double 1N/A# define NVTYPE double 1N/A#if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) 1N/A# define INT2PTR(any,d) (any)(d) 1N/A# if PTRSIZE == LONGSIZE 1N/A# define PTRV unsigned long 1N/A# define PTRV unsigned 1N/A# define INT2PTR(any,d) (any)(PTRV)(d) 1N/A#define NUM2PTR(any,d) (any)(PTRV)(d) 1N/A#define PTR2IV(p) INT2PTR(IV,p) 1N/A#define PTR2UV(p) INT2PTR(UV,p) 1N/A#define PTR2NV(p) NUM2PTR(NV,p) 1N/A#if PTRSIZE == LONGSIZE 1N/A# define PTR2ul(p) (unsigned long)(p) 1N/A# define PTR2ul(p) INT2PTR(unsigned long,p) 1N/A#endif /* !INT2PTR */ 1N/A# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) 1N/A# define gv_stashpvn(str,len,flags) gv_stashpv(str,flags) 1N/A# define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0)) 1N/A# define newRV_inc(sv) newRV(sv) 1N/A# define DEFSV GvSV(PL_defgv) 1N/A# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) 1N/A# define newRV_noinc(sv) \ 1N/A# if defined(USE_THREADS) 1N/A# define newRV_noinc(sv) \ 1N/A#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63)) 1N/A#if defined(NEED_newCONSTSUB) 1N/A#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) 1N/A#if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22)) 1N/A# if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22) 1N/A#endif /* newCONSTSUB */ 1N/A *
1.
#define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" 1N/A#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ 1N/A#if (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION < 68 )) 1N/A#else /* >= perl5.004_68 */ 1N/A#endif /* < perl5.004_68 */ 1N/A#define MY_CXT_INIT \ 1N/A#define MY_CXT (*my_cxtp) 1N/A#define pMY_CXT my_cxt_t *my_cxtp 1N/A#define pMY_CXT_ pMY_CXT, 1N/A#define _pMY_CXT ,pMY_CXT 1N/A#define aMY_CXT my_cxtp 1N/A#define aMY_CXT_ aMY_CXT, 1N/A#define _aMY_CXT ,aMY_CXT 1N/A#else /* single interpreter */ 1N/A#define START_MY_CXT static my_cxt_t my_cxt; 1N/A#define dMY_CXT_SV dNOOP 1N/A#define dMY_CXT dNOOP 1N/A#define MY_CXT_INIT NOOP 1N/A#define MY_CXT my_cxt 1N/A#endif /* START_MY_CXT */ 1N/A# if IVSIZE == LONGSIZE 1N/A# if IVSIZE == INTSIZE 1N/A# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ 1N/A# define NVef PERL_PRIeldbl 1N/A# define NVff PERL_PRIfldbl 1N/A# define NVgf PERL_PRIgldbl 1N/A#ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */ 1N/A# define AvFILLp AvFILL 1N/A# if PERL_REVISION == 5 && PERL_VERSION < 7 1N/A# define SvPVbyte(sv, lp) \ 1N/A# define SvPVbyte SvPV 1N/A# define SvPV_nolen(sv) \ 1N/A# define get_cv(name,create) perl_get_cv(name,create) 1N/A# define get_sv(name,create) perl_get_sv(name,create) 1N/A# define get_av(name,create) perl_get_av(name,create) 1N/A# define get_hv(name,create) perl_get_hv(name,create) 1N/A# define call_argv perl_call_argv 1N/A# define call_method perl_call_method 1N/A# define call_pv perl_call_pv 1N/A# define call_sv perl_call_sv 1N/A# define eval_pv perl_eval_pv 1N/A# define eval_sv perl_eval_sv 1N/A#ifndef PERL_SCAN_GREATER_THAN_UV_MAX 1N/A# define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 1N/A#ifndef PERL_SCAN_SILENT_ILLDIGIT 1N/A# define PERL_SCAN_SILENT_ILLDIGIT 0x04 1N/A#ifndef PERL_SCAN_ALLOW_UNDERSCORES 1N/A# define PERL_SCAN_ALLOW_UNDERSCORES 0x01 1N/A#ifndef PERL_SCAN_DISALLOW_PREFIX 1N/A# define PERL_SCAN_DISALLOW_PREFIX 0x02 1N/A#if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1)) 1N/A#define I32_CAST (I32*) 1N/A# define grok_hex(string, len, flags, result) \ 1N/A# define grok_oct(string, len, flags, result) \ 1N/A#if !defined(grok_bin) && defined(scan_bin) 1N/A# define grok_bin(string, len, flags, result) \ 1N/A#ifndef IN_LOCALE_RUNTIME 1N/A# define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) 1N/A#ifndef IN_LOCALE_COMPILETIME 1N/A# define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) 1N/A#ifndef IS_NUMBER_IN_UV 1N/A# define IS_NUMBER_IN_UV 0x01 1N/A# define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 1N/A# define IS_NUMBER_NOT_INT 0x04 1N/A# define IS_NUMBER_NEG 0x08 1N/A# define IS_NUMBER_INFINITY 0x10 1N/A# define IS_NUMBER_NAN 0x20 1N/A#ifndef grok_numeric_radix 1N/A# define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(aTHX_ sp, send) 1N/A#define grok_numeric_radix Perl_grok_numeric_radix 1N/A#ifdef USE_LOCALE_NUMERIC 1N/A#if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1)) 1N/A#endif /* PERL_VERSION */ 1N/A#endif /* USE_LOCALE_NUMERIC */ 1N/A#endif /* grok_numeric_radix */ 1N/A#define grok_number Perl_grok_number 1N/A }
else if (*s ==
'-') {
1N/A }
else if (*s ==
'I' || *s ==
'i') {
1N/A s++;
if (s ==
send || (*s !=
'N' && *s !=
'n'))
return 0;
1N/A s++;
if (s ==
send || (*s !=
'F' && *s !=
'f'))
return 0;
1N/A s++;
if (s <
send && (*s ==
'I' || *s ==
'i')) {
1N/A s++;
if (s ==
send || (*s !=
'N' && *s !=
'n'))
return 0;
1N/A s++;
if (s ==
send || (*s !=
'I' && *s !=
'i'))
return 0;
1N/A s++;
if (s ==
send || (*s !=
'T' && *s !=
't'))
return 0;
1N/A s++;
if (s ==
send || (*s !=
'Y' && *s !=
'y'))
return 0;
1N/A }
else if (*s ==
'N' || *s ==
'n') {
1N/A s++;
if (s ==
send || (*s !=
'A' && *s !=
'a'))
return 0;
1N/A s++;
if (s ==
send || (*s !=
'N' && *s !=
'n'))
return 0;
1N/A }
else if (s <
send) {
1N/A if (*s ==
'e' || *s ==
'E') {
1N/A if (s <
send && (*s ==
'-' || *s ==
'+'))
1N/A#endif /* grok_number */ 1N/A#ifndef PERL_MAGIC_sv 1N/A# define PERL_MAGIC_sv '\0' 1N/A#ifndef PERL_MAGIC_overload 1N/A# define PERL_MAGIC_overload 'A' 1N/A#ifndef PERL_MAGIC_overload_elem 1N/A# define PERL_MAGIC_overload_elem 'a' 1N/A#ifndef PERL_MAGIC_overload_table 1N/A# define PERL_MAGIC_overload_table 'c' 1N/A#ifndef PERL_MAGIC_bm 1N/A# define PERL_MAGIC_bm 'B' 1N/A#ifndef PERL_MAGIC_regdata 1N/A# define PERL_MAGIC_regdata 'D' 1N/A#ifndef PERL_MAGIC_regdatum 1N/A# define PERL_MAGIC_regdatum 'd' 1N/A#ifndef PERL_MAGIC_env 1N/A# define PERL_MAGIC_env 'E' 1N/A#ifndef PERL_MAGIC_envelem 1N/A# define PERL_MAGIC_envelem 'e' 1N/A#ifndef PERL_MAGIC_fm 1N/A# define PERL_MAGIC_fm 'f' 1N/A#ifndef PERL_MAGIC_regex_global 1N/A# define PERL_MAGIC_regex_global 'g' 1N/A#ifndef PERL_MAGIC_isa 1N/A# define PERL_MAGIC_isa 'I' 1N/A#ifndef PERL_MAGIC_isaelem 1N/A# define PERL_MAGIC_isaelem 'i' 1N/A#ifndef PERL_MAGIC_nkeys 1N/A# define PERL_MAGIC_nkeys 'k' 1N/A#ifndef PERL_MAGIC_dbfile 1N/A# define PERL_MAGIC_dbfile 'L' 1N/A#ifndef PERL_MAGIC_dbline 1N/A# define PERL_MAGIC_dbline 'l' 1N/A#ifndef PERL_MAGIC_mutex 1N/A# define PERL_MAGIC_mutex 'm' 1N/A#ifndef PERL_MAGIC_shared 1N/A# define PERL_MAGIC_shared 'N' 1N/A#ifndef PERL_MAGIC_shared_scalar 1N/A# define PERL_MAGIC_shared_scalar 'n' 1N/A#ifndef PERL_MAGIC_collxfrm 1N/A# define PERL_MAGIC_collxfrm 'o' 1N/A#ifndef PERL_MAGIC_tied 1N/A# define PERL_MAGIC_tied 'P' 1N/A#ifndef PERL_MAGIC_tiedelem 1N/A# define PERL_MAGIC_tiedelem 'p' 1N/A#ifndef PERL_MAGIC_tiedscalar 1N/A# define PERL_MAGIC_tiedscalar 'q' 1N/A#ifndef PERL_MAGIC_qr 1N/A# define PERL_MAGIC_qr 'r' 1N/A#ifndef PERL_MAGIC_sig 1N/A# define PERL_MAGIC_sig 'S' 1N/A#ifndef PERL_MAGIC_sigelem 1N/A# define PERL_MAGIC_sigelem 's' 1N/A#ifndef PERL_MAGIC_taint 1N/A# define PERL_MAGIC_taint 't' 1N/A#ifndef PERL_MAGIC_uvar 1N/A# define PERL_MAGIC_uvar 'U' 1N/A#ifndef PERL_MAGIC_uvar_elem 1N/A# define PERL_MAGIC_uvar_elem 'u' 1N/A#ifndef PERL_MAGIC_vstring 1N/A# define PERL_MAGIC_vstring 'V' 1N/A#ifndef PERL_MAGIC_vec 1N/A# define PERL_MAGIC_vec 'v' 1N/A#ifndef PERL_MAGIC_utf8 1N/A# define PERL_MAGIC_utf8 'w' 1N/A#ifndef PERL_MAGIC_substr 1N/A# define PERL_MAGIC_substr 'x' 1N/A#ifndef PERL_MAGIC_defelem 1N/A# define PERL_MAGIC_defelem 'y' 1N/A#ifndef PERL_MAGIC_glob 1N/A# define PERL_MAGIC_glob '*' 1N/A#ifndef PERL_MAGIC_arylen 1N/A# define PERL_MAGIC_arylen '#' 1N/A#ifndef PERL_MAGIC_pos 1N/A# define PERL_MAGIC_pos '.' 1N/A#ifndef PERL_MAGIC_backref 1N/A# define PERL_MAGIC_backref '<' 1N/A#ifndef PERL_MAGIC_ext 1N/A# define PERL_MAGIC_ext '~' 1N/A#endif /* _P_P_PORTABILITY_H_ */