This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
PPPort_pm.PL: Revise pod
[perl5.git] / dist / Devel-PPPort / PPPort_pm.PL
CommitLineData
adfe19db
MHM
1################################################################################
2#
3# PPPort_pm.PL -- generate PPPort.pm
4#
6d0401f9
KW
5# Set the environment variable DPPP_CHECK_LEVEL to more than zero for some
6# extra checking. 1 or 2 currently
7
adfe19db
MHM
8################################################################################
9#
b2049988 10# Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
d8ad1cc3 11# Copyright (C) 2018, The perl5 porters
adfe19db
MHM
12# Version 2.x, Copyright (C) 2001, Paul Marquess.
13# Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
14#
15# This program is free software; you can redistribute it and/or
16# modify it under the same terms as Perl itself.
17#
18################################################################################
19
20use strict;
91900b62 21BEGIN { $^W = 1; }
874389ae 22require "./parts/ppptools.pl";
55179e46 23require "./parts/inc/inctools";
adfe19db
MHM
24
25my $INCLUDE = 'parts/inc';
26my $DPPP = 'DPPP_';
27
8ab9a900
KW
28# The keys of %embed are the names of the items found in all the .fnc files,
29# and each value is all the information parse_embed returns for that item.
adfe19db 30my %embed = map { ( $_->{name} => $_ ) }
679ad62d 31 parse_embed(qw(parts/embed.fnc parts/apidoc.fnc parts/ppport.fnc));
adfe19db
MHM
32
33my(%provides, %prototypes, %explicit);
34
35my $data = do { local $/; <DATA> };
6d0401f9
KW
36
37# Call include(file, params) for every line that begins with %include
8ab9a900
KW
38# These fill in %provides and %prototypes.
39# The keys of %provides are the items provided by Devel::PPPort, and each
40# value is the name of the file (in parts/inc/) that has the code to provide
41# it.
42# An entry in %prototypes looks like:
43# 'grok_bin' => 'UV grok_bin(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result)',
44
adfe19db
MHM
45$data =~ s{^\%(include)\s+(\w+)((?:[^\S\r\n]+.*?)?)\s*$}
46 {eval "$1('$2', $3)" or die $@}gem;
47
8ab9a900 48# And expand it.
adfe19db
MHM
49$data = expand($data);
50
8ab9a900 51# Just the list of provided items.
514aceb6 52my @provided = sort dictionary_order keys %provides;
adfe19db 53
8ab9a900 54# which further expands $data.
adfe19db 55$data =~ s{^(.*)__PROVIDED_API__(\s*?)^}
514aceb6 56 {join '', map "$1$_\n", @provided}gem;
adfe19db
MHM
57
58{
59 my $len = 0;
60 for (keys %explicit) {
61 length > $len and $len = length;
62 }
4a582685 63 my $format = sprintf '%%-%ds %%-%ds %%s', $len+2, $len+5;
adfe19db
MHM
64 $len = 3*$len + 23;
65
0d0f8426
MHM
66$data =~ s!^(.*)__EXPLICIT_API__(\s*?)^!
67 sprintf("$1$format\n", 'Function / Variable', 'Static Request', 'Global Request') .
adfe19db 68 $1 . '-'x$len . "\n" .
0d0f8426 69 join('', map { sprintf "$1$format\n", $explicit{$_} eq 'var' ? $_ : "$_()", "NEED_$_", "NEED_${_}_GLOBAL" }
55179e46 70 sort dictionary_order keys %explicit)
0d0f8426 71 !gem;
adfe19db
MHM
72}
73
8ab9a900
KW
74# These hashes look like:
75# { ... 'gv_check' => '5.003007',
76# 'gv_const_sv' => '5.009003',
77# 'gv_dump' => '5.006000',
78# ... },
79
80# What's provided when without ppport.h, as far as we've been able to
81# determine
adfe19db 82my %raw_base = %{&parse_todo('parts/base')};
8ab9a900
KW
83
84# What's provided when using ppport.h, as far as we've been able to
85# determine
adfe19db
MHM
86my %raw_todo = %{&parse_todo('parts/todo')};
87
e8c2b34a
KW
88# Invert so each key is the 7 digit version number, and it's value is an array
89# of all symbols within it, like:
90# '5005003' => [
91# 'POPpx',
92# 'get_vtbl',
93# 'save_generic_svref'
94# ],
adfe19db
MHM
95my %todo;
96for (keys %raw_todo) {
e8c2b34a 97 push @{$todo{int_parse_version($raw_todo{$_})}}, $_;
adfe19db
MHM
98}
99
72dc7531
KW
100# Most recent first
101my @todo_list = reverse sort keys %todo;
102
8ab9a900 103# Here, @todo_list contains the integer version numbers that have support.
72dc7531
KW
104# The first and final elements give the extremes of the supported versions.
105# (Use defaults that were reasonable at the time of this commit if the
106# directories are empty (which should only happen during regeneration of the
e8c2b34a
KW
107# base and todo files).). Actually the final element is for blead (at the
108# time things were regenerated), which is 1 beyond the max version supported.
109my $INT_MAX_PERL = (@todo_list) ? $todo_list[0] - 1 : '5030000';
110my $MAX_PERL = format_version($INT_MAX_PERL);
72dc7531
KW
111my $INT_MIN_PERL = (@todo_list) ? $todo_list[-1] : 5003007;
112my $MIN_PERL = format_version($INT_MIN_PERL);
113
8ab9a900
KW
114# check consistency between our list of everything provided, and our lists of
115# what got provided when
514aceb6 116for (@provided) {
e8c2b34a
KW
117 if ( exists $raw_todo{$_}
118 && $raw_todo{$_} > $INT_MIN_PERL # INT_MIN_PERL contents are real
119 # symbols, not something to do
120 && exists $raw_base{$_})
121 {
122 if ($raw_base{$_} == $raw_todo{$_}) {
96ad942f
MHM
123 warn "$INCLUDE/$provides{$_} provides $_, which is still marked "
124 . "todo for " . format_version($raw_todo{$_}) . "\n";
125 }
126 else {
127 check(2, "$_ was ported back to " . format_version($raw_todo{$_}) .
8ab9a900 128 " (baseline revision: " . format_version($raw_base{$_}) . ").");
96ad942f 129 }
adfe19db
MHM
130 }
131}
132
133my @perl_api;
514aceb6 134for (@provided) {
aab9a3b6 135 next if /^Perl_(.*)/ && exists $embed{$1};
adfe19db
MHM
136 next if exists $embed{$_};
137 push @perl_api, $_;
138 check(2, "No API definition for provided element $_ found.");
139}
140
8ab9a900
KW
141# At this point @perl_api is the list of things we provide that weren't found
142# in the .fnc files.
143# Add in the .fnc file definitions.
adfe19db 144push @perl_api, keys %embed;
55179e46 145@perl_api = sort dictionary_order @perl_api;
adfe19db 146
8ab9a900 147for (@perl_api) { # $_ is the item name
adfe19db
MHM
148 if (exists $provides{$_} && !exists $raw_base{$_}) {
149 check(2, "Mmmh, $_ doesn't seem to need backporting.");
150 }
8ab9a900
KW
151
152 # Create the lines that ppport.h reads. These look like
153 # CopyD|5.009002|5.003007|p
adfe19db
MHM
154 my $line = "$_|" . (exists $provides{$_} && exists $raw_base{$_} ? $raw_base{$_} : '') . '|';
155 $line .= ($raw_todo{$_} || '') . '|';
156 $line .= 'p' if exists $provides{$_};
157 if (exists $embed{$_}) {
158 my $e = $embed{$_};
fc4763de 159 if (exists $e->{flags}{p}) { # Has 'Perl_' prefix
adfe19db
MHM
160 my $args = $e->{args};
161 $line .= 'v' if @$args && $args->[-1][0] eq '...';
162 }
fc4763de 163 $line .= 'n' if exists $e->{flags}{T}; # No thread context parameter
bf9610ae
KW
164 $line .= 'd' if exists $e->{flags}{D}; # deprecated
165 $line .= 'x' if exists $e->{flags}{x}; # experimental
166 $line .= 'c' if exists $e->{flags}{C} # core-only
167 || ( exists $e->{flags}{X}
168 && (exists $e->{flags}{E} || ! exists $e->{flags}{m}));
169 $line .= 'i' if exists $e->{flags}{A}
170 || exists $e->{flags}{C}
171 || ( exists $e->{flags}{X}
172 && ! exists $e->{flags}{E}
173 && exists $e->{flags}{m});
174 $line .= 'u' unless exists $e->{flags}{d}; # undocumented
adfe19db
MHM
175 }
176 $_ = $line;
177}
178
179$data =~ s/^([\t ]*)__PERL_API__(\s*?)$/
55179e46 180 join "\n", map "$1$_", sort dictionary_order @perl_api
adfe19db
MHM
181 /gem;
182
aff85f08
KW
183my $undocumented = "(undocumented)";
184
adfe19db 185my @todo;
72dc7531 186for (@todo_list) {
adfe19db 187 my $ver = format_version($_);
e8c2b34a 188 $ver .= " (at least)" if $_ == $todo_list[-1];
adfe19db 189 my $todo = "=item perl $ver\n\n";
55179e46 190 for (sort dictionary_order @{$todo{$_}}) {
aff85f08
KW
191 $todo .= " $_";
192 $todo .= " (DEPRECATED)" if $embed{$_}->{flags}{D};
193 $todo .= " (marked experimental)" if $embed{$_}->{flags}{x};
194 $todo .= " $undocumented" unless $embed{$_}->{flags}{d};
195 $todo .= "\n";
adfe19db
MHM
196 }
197 push @todo, $todo;
198}
199
200$data =~ s{^__UNSUPPORTED_API__(\s*?)^}
201 {join "\n", @todo}gem;
202
72dc7531
KW
203$data =~ s{__MIN_PERL__}{$MIN_PERL}g;
204$data =~ s{__MAX_PERL__}{$MAX_PERL}g;
adfe19db
MHM
205
206open FH, ">PPPort.pm" or die "PPPort.pm: $!\n";
207print FH $data;
208close FH;
209
210exit 0;
211
212sub include
213{
214 my($file, $opt) = @_;
215
216 print "including $file\n";
217
218 my $data = parse_partspec("$INCLUDE/$file");
219
220 for (@{$data->{provides}}) {
221 if (exists $provides{$_}) {
222 if ($provides{$_} ne $file) {
223 warn "$file: $_ already provided by $provides{$_}\n";
224 }
225 }
226 else {
227 $provides{$_} = $file;
228 }
229 }
230
231 for (keys %{$data->{prototypes}}) {
232 $prototypes{$_} = $data->{prototypes}{$_};
67e65113 233 $prototypes{$_} = normalize_prototype($data->{prototypes}{$_});
96ad942f 234 $data->{implementation} =~ s/^$_(?=\s*\()/$DPPP(my_$_)/mg;
adfe19db
MHM
235 }
236
237 my $out = $data->{implementation};
238
239 if (exists $opt->{indent}) {
240 $out =~ s/^/$opt->{indent}/gm;
241 }
242
243 return $out;
244}
245
246sub expand
247{
248 my $code = shift;
249 $code =~ s{^(\s*#\s*(?:el)?if\s+)(.*)$}{$1.expand_pp_expressions($2)}gem;
250 $code =~ s{^\s*
251 __UNDEFINED__
252 \s+
253 (
254 ( \w+ )
255 (?: \( [^)]* \) )?
256 )
257 [^\r\n\S]*
258 (
259 (?:[^\r\n\\]|\\[^\r\n])*
260 (?:
261 \\
262 (?:\r\n|[\r\n])
263 (?:[^\r\n\\]|\\[^\r\n])*
264 )*
265 )
266 \s*$}
267 {expand_undefined($2, $1, $3)}gemx;
c01be2ce 268 $code =~ s{^([^\S\r\n]*)__NEED_VAR__\s+(.*?)\s+(\w+)(?:\s*=\s*([^;]+?))?\s*;\s*$}
0d0f8426 269 {expand_need_var($1, $3, $2, $4)}gem;
c01be2ce
MHM
270 $code =~ s{^([^\S\r\n]*)__NEED_DUMMY_VAR__\s+(.*?)\s+(\w+)(?:\s*=\s*([^;]+?))?\s*;\s*$}
271 {expand_need_dummy_var($1, $3, $2, $4)}gem;
0d0f8426
MHM
272 return $code;
273}
274
275sub expand_need_var
276{
277 my($indent, $var, $type, $init) = @_;
278
279 $explicit{$var} = 'var';
280
281 my $myvar = "$DPPP(my_$var)";
c01be2ce 282 $init = defined $init ? " = $init" : "";
0d0f8426
MHM
283
284 my $code = <<ENDCODE;
285#if defined(NEED_$var)
c01be2ce 286static $type $myvar$init;
0d0f8426 287#elif defined(NEED_${var}_GLOBAL)
c01be2ce 288$type $myvar$init;
0d0f8426
MHM
289#else
290extern $type $myvar;
291#endif
292#define $var $myvar
293ENDCODE
294
295 $code =~ s/^/$indent/mg;
296
adfe19db
MHM
297 return $code;
298}
299
c01be2ce
MHM
300sub expand_need_dummy_var
301{
302 my($indent, $var, $type, $init) = @_;
303
304 $explicit{$var} = 'var';
305
306 my $myvar = "$DPPP(dummy_$var)";
307 $init = defined $init ? " = $init" : "";
308
309 my $code = <<ENDCODE;
310#if defined(NEED_$var)
311static $type $myvar$init;
312#elif defined(NEED_${var}_GLOBAL)
313$type $myvar$init;
314#else
315extern $type $myvar;
316#endif
317ENDCODE
318
319 $code =~ s/^/$indent/mg;
320
321 return $code;
322}
323
adfe19db
MHM
324sub expand_undefined
325{
326 my($macro, $withargs, $def) = @_;
327 my $rv = "#ifndef $macro\n# define ";
328
4a582685 329 if (defined $def && $def =~ /\S/) {
adfe19db
MHM
330 $rv .= sprintf "%-30s %s", $withargs, $def;
331 }
332 else {
333 $rv .= $withargs;
334 }
335
336 $rv .= "\n#endif\n";
337
338 return $rv;
339}
340
341sub expand_pp_expressions
342{
343 my $pp = shift;
344 $pp =~ s/\{([^\}]+)\}/expand_pp_expr($1)/ge;
345 return $pp;
346}
347
348sub expand_pp_expr
349{
350 my $expr = shift;
351
0d0f8426 352 if ($expr =~ /^\s*need\s+(\w+)\s*$/i) {
adfe19db
MHM
353 my $func = $1;
354 my $e = $embed{$func} or die "unknown API function '$func' in NEED\n";
355 my $proto = make_prototype($e);
356 if (exists $prototypes{$func}) {
357 if (compare_prototypes($proto, $prototypes{$func})) {
fc6aef98
KW
358 my $proto_no_pTHX = $proto;
359 $proto_no_pTHX =~ s/pTHX_\s*//;
360 if (compare_prototypes($proto_no_pTHX, $prototypes{$func})) {
361 check(1, "differing prototypes for $func:\n API: $proto\n PPP: $prototypes{$func}");
362 }
363 else {
364 check(1, "prototypes differ in pTHX_ for $func:\n API: $proto\n PPP: $prototypes{$func}");
365 }
adfe19db
MHM
366 $proto = $prototypes{$func};
367 }
368 }
369 else {
370 warn "found no prototype for $func\n";;
371 }
372
0d0f8426 373 $explicit{$func} = 'func';
adfe19db 374
96ad942f 375 $proto =~ s/\b$func(?=\s*\()/$DPPP(my_$func)/;
adfe19db
MHM
376 my $embed = make_embed($e);
377
378 return "defined(NEED_$func)\n"
379 . "static $proto;\n"
380 . "static\n"
381 . "#else\n"
382 . "extern $proto;\n"
383 . "#endif\n"
384 . "\n"
28e487a0 385 . "#if defined(NEED_$func) || defined(NEED_${func}_GLOBAL)\n"
adfe19db 386 . "\n"
28e487a0 387 . "$embed\n";
adfe19db
MHM
388 }
389
adfe19db
MHM
390 die "cannot expand preprocessor expression '$expr'\n";
391}
392
393sub make_embed
394{
395 my $f = shift;
396 my $n = $f->{name};
397 my $a = do { my $x = 'a'; join ',', map { $x++ } 1 .. @{$f->{args}} };
a89b7ab8 398 my $lastarg = ${$f->{args}}[-1];
adfe19db 399
fc4763de 400 if ($f->{flags}{T}) {
adfe19db 401 if ($f->{flags}{p}) {
96ad942f
MHM
402 return "#define $n $DPPP(my_$n)\n" .
403 "#define Perl_$n $DPPP(my_$n)";
adfe19db
MHM
404 }
405 else {
96ad942f 406 return "#define $n $DPPP(my_$n)";
adfe19db
MHM
407 }
408 }
409 else {
410 my $undef = <<UNDEF;
411#ifdef $n
412# undef $n
413#endif
414UNDEF
415 if ($f->{flags}{p}) {
96ad942f
MHM
416 if ($f->{flags}{f}) {
417 return "#define Perl_$n $DPPP(my_$n)";
418 }
a89b7ab8
MHM
419 elsif (@$lastarg && $lastarg->[0] =~ /\.\.\./) {
420 return $undef . "#define $n $DPPP(my_$n)\n" .
421 "#define Perl_$n $DPPP(my_$n)";
422 }
96ad942f
MHM
423 else {
424 return $undef . "#define $n($a) $DPPP(my_$n)(aTHX_ $a)\n" .
425 "#define Perl_$n $DPPP(my_$n)";
426 }
adfe19db
MHM
427 }
428 else {
96ad942f 429 return $undef . "#define $n($a) $DPPP(my_$n)(aTHX_ $a)";
adfe19db
MHM
430 }
431 }
432}
433
434sub check
435{
436 my $level = shift;
437
438 if (exists $ENV{DPPP_CHECK_LEVEL} and $ENV{DPPP_CHECK_LEVEL} >= $level) {
439 print STDERR @_, "\n";
440 }
441}
442
443__DATA__
444################################################################################
445#
446# !!!!! Do NOT edit this file directly! -- Edit PPPort_pm.PL instead. !!!!!
447#
cac25305
MHM
448# This file was automatically generated from the definition files in the
449# parts/inc/ subdirectory by PPPort_pm.PL. To learn more about how all this
450# works, please read the F<HACKERS> file that came with this distribution.
451#
adfe19db
MHM
452################################################################################
453#
454# Perl/Pollution/Portability
455#
456################################################################################
457#
b2049988 458# Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
d8ad1cc3 459# Copyright (C) 2018, The perl5 porters
adfe19db
MHM
460# Version 2.x, Copyright (C) 2001, Paul Marquess.
461# Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
462#
463# This program is free software; you can redistribute it and/or
464# modify it under the same terms as Perl itself.
465#
466################################################################################
467
468=head1 NAME
469
470Devel::PPPort - Perl/Pollution/Portability
471
472=head1 SYNOPSIS
473
d8ad1cc3
MB
474 Devel::PPPort::WriteFile(); # defaults to ./ppport.h
475 Devel::PPPort::WriteFile('someheader.h');
adfe19db 476
d8ad1cc3
MB
477 # Same as above but retrieve contents rather than write file
478 my $contents = Devel::PPPort::GetFileContents();
479 my $contents = Devel::PPPort::GetFileContents('someheader.h');
480
481=head1 Start using Devel::PPPort for XS projects
482
483 $ cpan Devel::PPPort
484 $ perl -MDevel::PPPort -e'Devel::PPPort::WriteFile'
485 $ perl ppport.h --compat-version=5.6.1 --patch=diff.patch *.xs
486 $ patch -p0 < diff.patch
487 $ echo ppport.h >>MANIFEST
ea4b7f32 488
adfe19db
MHM
489=head1 DESCRIPTION
490
491Perl's API has changed over time, gaining new features, new functions,
492increasing its flexibility, and reducing the impact on the C namespace
493environment (reduced pollution). The header file written by this module,
494typically F<ppport.h>, attempts to bring some of the newer Perl API
495features to older versions of Perl, so that you can worry less about
496keeping track of old releases, but users can still reap the benefit.
497
ea4b7f32
JH
498C<Devel::PPPort> contains two functions, C<WriteFile> and C<GetFileContents>.
499C<WriteFile>'s only purpose is to write the F<ppport.h> C header file.
500This file contains a series of macros and, if explicitly requested, functions
501that allow XS modules to be built using older versions of Perl. Currently,
adfe19db
MHM
502Perl versions from __MIN_PERL__ to __MAX_PERL__ are supported.
503
ea4b7f32
JH
504C<GetFileContents> can be used to retrieve the file contents rather than
505writing it out.
506
4a582685 507This module is used by C<h2xs> to write the file F<ppport.h>.
adfe19db
MHM
508
509=head2 Why use ppport.h?
4a582685 510
adfe19db
MHM
511You should use F<ppport.h> in modern code so that your code will work
512with the widest range of Perl interpreters possible, without significant
513additional work.
514
6d0401f9 515You should attempt to get older code to fully use F<ppport.h>, because the
adfe19db
MHM
516reduced pollution of newer Perl versions is an important thing. It's so
517important that the old polluting ways of original Perl modules will not be
518supported very far into the future, and your module will almost certainly
519break! By adapting to it now, you'll gain compatibility and a sense of
520having done the electronic ecology some good.
521
522=head2 How to use ppport.h
523
524Don't direct the users of your module to download C<Devel::PPPort>.
6d0401f9 525They are most probably not XS writers. Also, don't make F<ppport.h>
adfe19db
MHM
526optional. Rather, just take the most recent copy of F<ppport.h> that
527you can find (e.g. by generating it with the latest C<Devel::PPPort>
528release from CPAN), copy it into your project, adjust your project to
4a582685 529use it, and distribute the header along with your module.
adfe19db
MHM
530
531=head2 Running ppport.h
532
533But F<ppport.h> is more than just a C header. It's also a Perl script
534that can check your source code. It will suggest hints and portability
535notes, and can even make suggestions on how to change your code. You
536can run it like any other Perl program:
537
9132e1a3 538 perl ppport.h [options] [files]
adfe19db
MHM
539
540It also has embedded documentation, so you can use
541
542 perldoc ppport.h
543
544to find out more about how to use it.
545
546=head1 FUNCTIONS
547
548=head2 WriteFile
549
550C<WriteFile> takes one optional argument. When called with one
551argument, it expects to be passed a filename. When called with
552no arguments, it defaults to the filename F<ppport.h>.
553
554The function returns a true value if the file was written successfully.
555Otherwise it returns a false value.
556
ea4b7f32
JH
557=head2 GetFileContents
558
559C<GetFileContents> behaves like C<WriteFile> above, but returns the contents
560of the would-be file rather than writing it out.
561
adfe19db
MHM
562=head1 COMPATIBILITY
563
564F<ppport.h> supports Perl versions from __MIN_PERL__ to __MAX_PERL__
565in threaded and non-threaded configurations.
566
567=head2 Provided Perl compatibility API
568
77feee66
KW
569The header file written by this module, typically F<ppport.h>, provides access
570to the following elements of the Perl API that are not otherwise available in
571Perl releases older than when the elements were first introduced. (Note that
572many of these are not supported all the way back to __MIN_PERL__, but it may
573be that they are supported back as far as you need; see L</Supported Perl API,
574sorted by version> for that information.)
adfe19db
MHM
575
576 __PROVIDED_API__
577
77feee66 578=head2 Supported Perl API, sorted by version
aff85f08 579
77feee66
KW
580The table in this section lists all the Perl API elements available, sorted by
581the version in which support starts. This includes all the elements that
582F<ppport.h> helps out with, as well as those elements that it doesn't.
aff85f08 583
77feee66
KW
584In some cases, it doesn't make practical sense for elements to be supported
585earlier than they already are. For example, UTF-8 functionality isn't
586provided prior to the release where it was first introduced.
aff85f08 587
77feee66
KW
588But in other cases, it just is that no one has implemented support yet.
589Patches welcome! Some elements are ported backward for some releases, but not
590all the way to __MIN_PERL__.
591
592If an element, call it ELEMENT, is not on this list, try using this command to
593find out why:
594
595 perl ppport.h --api-info=ELEMENT
596
597A few of the entries in the list below are marked as DEPRECATED. You should
598not use these for new code, and should be converting existing uses to use
599something better.
600
601Some of the entries in the list are marked as "experimental". This means
602these should not generally be used. They may be removed or changed without
603notice. You can ask why they are experimental by sending email to
604L<mailto:perl5-porters@perl.org>.
605
606And some of the entries are marked as "undocumented". This means that they
aff85f08
KW
607aren't necessarily considered stable, and could be changed or removed in some
608future release without warning. It is therefore a bad idea to use them
609without further checking. It could be that these are considered to be for
610perl core use only; or it could be, though, that C<Devel::PPPort> doesn't know
611where to find their documentation, or that it's just an oversight that they
612haven't been documented. If you want to use one, and potentially have it
613backported, first send mail to L<mailto:perl5-porters@perl.org>.
adfe19db
MHM
614
615=over 4
616
617__UNSUPPORTED_API__
618
619=back
620
621=head1 BUGS
622
623If you find any bugs, C<Devel::PPPort> doesn't seem to build on your
c601e8c7 624system, or any of its tests fail, please send a bug report to
77feee66 625L<https://github.com/Dual-Life/Devel-PPPort/issues/new>.
adfe19db
MHM
626
627=head1 AUTHORS
628
629=over 2
630
631=item *
632
633Version 1.x of Devel::PPPort was written by Kenneth Albanowski.
634
635=item *
636
637Version 2.x was ported to the Perl core by Paul Marquess.
638
639=item *
640
641Version 3.x was ported back to CPAN by Marcus Holland-Moritz.
642
8ab9a900 643=item *
ea4b7f32 644
6d0401f9 645Versions >= 3.22 are maintained by perl5 porters
ea4b7f32 646
adfe19db
MHM
647=back
648
649=head1 COPYRIGHT
650
b2049988 651Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
adfe19db 652
d8ad1cc3
MB
653 Copyright (C) 2018, The perl5 porters
654
adfe19db
MHM
655Version 2.x, Copyright (C) 2001, Paul Marquess.
656
657Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
658
659This program is free software; you can redistribute it and/or
660modify it under the same terms as Perl itself.
661
662=head1 SEE ALSO
663
664See L<h2xs>, L<ppport.h>.
665
666=cut
667
668package Devel::PPPort;
669
adfe19db 670use strict;
236afa0a 671use vars qw($VERSION $data);
adfe19db 672
34ad2e9c 673$VERSION = '3.55';
adfe19db 674
4a582685 675sub _init_data
adfe19db
MHM
676{
677 $data = do { local $/; <DATA> };
adfe19db
MHM
678 my $pkg = 'Devel::PPPort';
679 $data =~ s/__PERL_VERSION__/$]/g;
680 $data =~ s/__VERSION__/$VERSION/g;
adfe19db 681 $data =~ s/__PKG__/$pkg/g;
4a582685 682 $data =~ s/^\|>//gm;
adfe19db
MHM
683}
684
ea4b7f32 685sub GetFileContents {
adfe19db 686 my $file = shift || 'ppport.h';
4a582685 687 defined $data or _init_data();
adfe19db
MHM
688 my $copy = $data;
689 $copy =~ s/\bppport\.h\b/$file/g;
690
ea4b7f32
JH
691 return $copy;
692}
693
694sub WriteFile
695{
696 my $file = shift || 'ppport.h';
697 my $data = GetFileContents($file);
adfe19db 698 open F, ">$file" or return undef;
ea4b7f32 699 print F $data;
adfe19db
MHM
700 close F;
701
702 return 1;
703}
704
7051;
706
707__DATA__
708#if 0
709<<'SKIP';
710#endif
711/*
712----------------------------------------------------------------------
713
4a582685
NC
714 ppport.h -- Perl/Pollution/Portability Version __VERSION__
715
d31fb070 716 Automatically created by __PKG__ running under perl __PERL_VERSION__.
4a582685 717
adfe19db
MHM
718 Do NOT edit this file directly! -- Edit PPPort_pm.PL and the
719 includes in parts/inc/ instead.
4a582685 720
adfe19db
MHM
721 Use 'perldoc ppport.h' to view the documentation below.
722
723----------------------------------------------------------------------
724
725SKIP
726
4a582685 727%include ppphdoc { indent => '|>' }
adfe19db 728
55179e46
KW
729%include inctools
730
adfe19db
MHM
731%include ppphbin
732
733__DATA__
734*/
735
736#ifndef _P_P_PORTABILITY_H_
737#define _P_P_PORTABILITY_H_
738
739#ifndef DPPP_NAMESPACE
740# define DPPP_NAMESPACE DPPP_
741#endif
742
743#define DPPP_CAT2(x,y) CAT2(x,y)
744#define DPPP_(name) DPPP_CAT2(DPPP_NAMESPACE, name)
745
746%include version
747
fd7af155
MHM
748%include threads
749
adfe19db
MHM
750%include limits
751
43ffb552
KW
752%include variables
753
754%include newCONSTSUB
755
9aa6a863
N
756%include magic_defs
757
9daab086
MB
758%include misc
759
9aa6a863
N
760%include sv_xpvf
761
762%include SvPV
763
d350906e
MB
764%include warn
765
9aa6a863
N
766%include format
767
adfe19db
MHM
768%include uv
769
0d0f8426
MHM
770%include memory
771
f87c37b1
P
772%include mess
773
adfe19db
MHM
774%include mPUSH
775
776%include call
777
778%include newRV
779
adfe19db
MHM
780%include MY_CXT
781
c07deaaf
MHM
782%include SvREFCNT
783
8565c31a
MHM
784%include newSV_type
785
c1a049cb
MHM
786%include newSVpv
787
0d0f8426
MHM
788%include Sv_set
789
c83e6f19
MHM
790%include shared_pv
791
8565c31a
MHM
792%include HvNAME
793
794%include gv
795
f2ab5a41
MHM
796%include pvs
797
d19dbf9c
S
798%include magic
799
adfe19db
MHM
800%include cop
801
802%include grok
803
f2ab5a41
MHM
804%include snprintf
805
c01be2ce
MHM
806%include sprintf
807
9132e1a3
MHM
808%include exception
809
aef0a14c
MHM
810%include strlfuncs
811
5ef77e59
KW
812%include utf8
813
db42c902
MHM
814%include pv_tools
815
adfe19db
MHM
816#endif /* _P_P_PORTABILITY_H_ */
817
818/* End of File ppport.h */