aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-07-20 17:34:03 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-07-20 18:22:16 +0300
commit7f26449a38b4a491880d05ea36a10e1cfd111808 (patch)
treefdf338b02ef535ea6b0bef6edd6187f9e6097ae6
downloadposixruncapture-7f26449a38b4a491880d05ea36a10e1cfd111808.tar.gz
posixruncapture-7f26449a38b4a491880d05ea36a10e1cfd111808.tar.bz2
Initial commit
-rw-r--r--.gitignore16
-rw-r--r--.gitmodules3
-rw-r--r--Capture.xs74
-rw-r--r--Changes5
-rw-r--r--MANIFEST15
-rw-r--r--Makefile.PL41
-rw-r--r--README40
-rw-r--r--capture.c86
-rw-r--r--capture.h14
-rw-r--r--debug.sh3
-rw-r--r--lib/POSIX/Run/Capture.pm95
-rw-r--r--ppport.h7258
m---------runcap0
-rw-r--r--t/POSIX-Run-Capture.t18
-rw-r--r--typemap1
15 files changed, 7669 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fc1dace
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+/Makefile
+*~
+*.tar
+*.tar.*
+.emacs*
+\#*#
+/MYMETA.json
+/MYMETA.yml
+/blib
+/pm_to_blib
+/tmp
+/Capture.bs
+/Capture.c
+*.o
+Makefile.old
+/capture.o
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..99b6953
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "runcap"]
+ path = runcap
+ url = git://git.gnu.org.ua/runcap.git
diff --git a/Capture.xs b/Capture.xs
new file mode 100644
index 0000000..ac80697
--- /dev/null
+++ b/Capture.xs
@@ -0,0 +1,74 @@
+#include "capture.h"
+
+MODULE = POSIX::Run::Capture PACKAGE = POSIX::Run::Capture PREFIX = capture_
+PROTOTYPES: ENABLE
+
+POSIX::Run::Capture
+capture_new(package, argv)
+ char *package;
+ AV *argv;
+ CODE:
+ RETVAL = capture_new(argv);
+ if (!RETVAL)
+ croak("Out of memory!");
+ OUTPUT:
+ RETVAL
+
+void
+capture_DESTROY(rc)
+ POSIX::Run::Capture rc;
+
+int
+capture_run(rc)
+ POSIX::Run::Capture rc;
+ CODE:
+ if (!rc->rc_argv)
+ croak("no command line given");
+ RETVAL = runcap(rc, 0);
+ OUTPUT:
+ RETVAL
+
+int
+capture_status(rc)
+ POSIX::Run::Capture rc;
+ CODE:
+ RETVAL = rc->rc_status;
+ OUTPUT:
+ RETVAL
+
+int
+capture_errno(rc)
+ POSIX::Run::Capture rc;
+ CODE:
+ RETVAL = rc->rc_errno;
+ OUTPUT:
+ RETVAL
+
+size_t
+capture_nlines(rc, n)
+ POSIX::Run::Capture rc;
+ int n;
+ CODE:
+ if (n != RUNCAP_STDOUT && n != RUNCAP_STDERR) {
+ croak("invalid stream number: %d", n);
+ }
+ RETVAL = rc->rc_cap[n].sc_nlines;
+ OUTPUT:
+ RETVAL
+
+size_t
+capture_length(rc, n)
+ POSIX::Run::Capture rc;
+ int n;
+ CODE:
+ if (n != RUNCAP_STDOUT && n != RUNCAP_STDERR) {
+ croak("invalid stream number: %d", n);
+ }
+ RETVAL = rc->rc_cap[n].sc_leng;
+ OUTPUT:
+ RETVAL
+
+char *
+capture_next_line(rc, n)
+ POSIX::Run::Capture rc;
+ int n;
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..8ab064a
--- /dev/null
+++ b/Changes
@@ -0,0 +1,5 @@
+Revision history for Perl extension POSIX::Run::Capture.
+
+0.01 Thu Jul 20 18:17:18 2017
+ - original revision
+
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..54d3dcd
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,15 @@
+Capture.xs
+Changes
+Makefile.PL
+MANIFEST
+ppport.h
+README
+t/POSIX-Run-Capture.t
+lib/POSIX/Run/Capture.pm
+runcap/Makefile
+runcap/runcap.h
+runcap/runcap.c
+runcap/getc.c
+runcap/getl.c
+runcap/seek.c
+runcap/tell.c
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644
index 0000000..25f93c4
--- /dev/null
+++ b/Makefile.PL
@@ -0,0 +1,41 @@
+use 5.016001;
+use strict;
+use warnings;
+use ExtUtils::MakeMaker;
+use Module::Metadata;
+
+WriteMakefile(
+ NAME => 'POSIX::Run::Capture',
+ VERSION_FROM => 'lib/POSIX/Run/Capture.pm',
+ LICENSE => 'gpl_3',
+ PREREQ_PM => {}, # e.g., Module::Name => 1.1
+ MIN_PERL_VERSION => 5.006,
+ ABSTRACT_FROM => 'lib/POSIX/Run/Capture.pm',
+ AUTHOR => 'Sergey Poznyakoff <gray@gnu.org>',
+ LIBS => [''], # e.g., '-lm'
+ DEFINE => '',
+ INC => '-I.', # e.g., '-I. -I/usr/include/other'
+ OBJECT => '$(O_FILES) runcap/libruncap.a',
+ DIR => [ 'runcap' ],
+ META_MERGE => {
+ 'meta-spec' => { version => 2 },
+ resources => {
+ repository => {
+ type => 'git',
+ url => 'git://git.gnu.org.ua/posixruncapture.git',
+ web => 'http://git.gnu.org.ua/cgit/posixruncapture.git/',
+ },
+ },
+ provides => Module::Metadata->provides(version => '1.4',
+ dir => 'lib')
+ }
+);
+
+package MY;
+
+sub pasthru {
+ my $val = shift->SUPER::pasthru(@_);
+ chomp($val);
+ return $val . "\\\n O='\$(CCFLAGS)'";
+}
+
diff --git a/README b/README
new file mode 100644
index 0000000..40160b5
--- /dev/null
+++ b/README
@@ -0,0 +1,40 @@
+POSIX-Run-Capture version 0.01
+============================
+
+The README is used to introduce the module and provide instructions on
+how to install the module, any machine dependencies it may have (for
+example C compilers and installed libraries) and any other information
+that should be provided before the module is installed.
+
+A README file is required for CPAN modules since CPAN extracts the
+README file from a module distribution so that people browsing the
+archive can use it get an idea of the modules uses. It is usually a
+good idea to provide version information here so that people can
+decide whether fixes for the module are worth downloading.
+
+INSTALLATION
+
+To install this module type the following:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+
+ blah blah blah
+
+COPYRIGHT AND LICENCE
+
+Put the correct copyright and licence information here.
+
+Copyright (C) 2017 by Sergey Poznyakoff
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.16.1 or,
+at your option, any later version of Perl 5 you may have available.
+
+
diff --git a/capture.c b/capture.c
new file mode 100644
index 0000000..11fbc17
--- /dev/null
+++ b/capture.c
@@ -0,0 +1,86 @@
+#include "capture.h"
+#include <stdlib.h>
+
+struct runcap *
+capture_new(AV *av)
+{
+ struct runcap *rc;
+ I32 i, n;
+ char **argv;
+
+ rc = malloc(sizeof *rc);
+ if (!rc)
+ goto nomem;
+ memset(rc, 0, sizeof *rc);
+ n = av_len(av);
+ if (n == -1)
+ return rc;
+ argv = calloc(n + 2, sizeof *argv);
+ if (!argv)
+ goto nomem;
+ for (i = 0; i <= n; i++) {
+ SV *sv, **psv = av_fetch(av, i, 0);
+ if (!psv)
+ croak("element %d doesn't exist", i);
+ sv = *psv;
+ if (SvTYPE(sv) == SVt_PV) {
+ char *s = SvPV_nolen(sv);
+ if ((argv[i] = strdup(s)) == NULL)
+ goto nomem;
+ }
+ }
+ argv[i] = NULL;
+
+ rc->rc_argv = argv;
+
+ return rc;
+ nomem:
+ return NULL;
+}
+
+void
+capture_DESTROY(struct runcap *rc)
+{
+// printf("DESTROY\n");
+ if (rc->rc_argv) {
+ size_t i;
+ for (i = 0; rc->rc_argv[i]; i++) {
+ free(rc->rc_argv[i]);
+ }
+ free(rc->rc_argv);
+ }
+ runcap_free(rc);
+ free(rc);
+}
+
+char *
+capture_next_line(struct runcap *rc, int fd)
+{
+ char *buf = NULL;
+ size_t sz = 0;
+ ssize_t n;
+
+ if (fd != RUNCAP_STDOUT && fd != RUNCAP_STDERR) {
+ croak("invalid stream number: %d", fd);
+ }
+ n = runcap_getline(rc, fd, &buf, &sz);
+ if (n == -1)
+ croak("error getting line: %s", strerror(errno));
+ if (n == 0)
+ return NULL;
+ return realloc(buf, n + 1);
+}
+
+void
+capture_wd()
+{
+ volatile int _st=0;
+ printf("ENTER\n");
+ while (!_st) {
+ printf("WAIING\n");
+ sleep(1);
+ _st = _st;
+ }
+ printf("EXIT\n");
+}
+
diff --git a/capture.h b/capture.h
new file mode 100644
index 0000000..0a94b45
--- /dev/null
+++ b/capture.h
@@ -0,0 +1,14 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "ppport.h"
+
+#include <stdlib.h>
+#include <runcap/runcap.h>
+
+typedef struct runcap *POSIX__Run__Capture;
+
+struct runcap *capture_new(AV *av);
+void capture_DESTROY(struct runcap *rc);
+char *capture_next_line(struct runcap *rc, int fd);
diff --git a/debug.sh b/debug.sh
new file mode 100644
index 0000000..354f589
--- /dev/null
+++ b/debug.sh
@@ -0,0 +1,3 @@
+export PERL5LIB=`pwd`/lib
+export PERL5OPT=-MCarp=verbose
+export LD_LIBRARY_PATH=blib/arch/auto/POSIX/Run/Capture
diff --git a/lib/POSIX/Run/Capture.pm b/lib/POSIX/Run/Capture.pm
new file mode 100644
index 0000000..1d70d43
--- /dev/null
+++ b/lib/POSIX/Run/Capture.pm
@@ -0,0 +1,95 @@
+package POSIX::Run::Capture;
+
+use 5.016001;
+use strict;
+use warnings;
+
+require Exporter;
+
+our @ISA = qw(Exporter);
+
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+
+# This allows declaration use POSIX::Run::Capture ':all';
+# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
+# will save memory.
+our %EXPORT_TAGS = ( 'all' => [ qw(
+ STDOUT,
+ STDERR
+) ],
+ 'std' => [ qw(
+ STDOUT,
+ STDERR
+) ] );
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+#our @EXPORT = qw();
+
+our $VERSION = '0.01';
+
+require XSLoader;
+XSLoader::load('POSIX::Run::Capture', $VERSION);
+
+use constant {
+ STDOUT => 1,
+ STDERR => 2
+};
+
+# Preloaded methods go here.
+
+1;
+__END__
+=head1 NAME
+
+POSIX::Run::Capture - run command and capture its output
+
+=head1 SYNOPSIS
+
+ use POSIX::Run::Capture;
+
+
+=head1 DESCRIPTION
+
+The API is in development.
+
+=head2 EXPORT
+
+None by default. Use B<:std> to export the B<STDOUT> and B<STDERR> constants.
+
+
+=head1 SEE ALSO
+
+Mention other useful documentation such as the documentation of
+related modules or operating system documentation (such as man pages
+in UNIX), or any relevant external documentation such as RFCs or
+standards.
+
+If you have a mailing list set up for your module, mention it here.
+
+If you have a web site set up for your module, mention it here.
+
+=head1 AUTHOR
+
+Sergey Poznyakoff, E<lt>gray@gnu.orgE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2017 by Sergey Poznyakoff
+
+This library is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+It is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this library. If not, see <http://www.gnu.org/licenses/>.
+
+=cut
diff --git a/ppport.h b/ppport.h
new file mode 100644
index 0000000..89772c9
--- /dev/null
+++ b/ppport.h
@@ -0,0 +1,7258 @@
+#if 0
+<<'SKIP';
+#endif
+/*
+----------------------------------------------------------------------
+
+ ppport.h -- Perl/Pollution/Portability Version 3.20
+
+ Automatically created by Devel::PPPort running under perl 5.016001.
+
+ Do NOT edit this file directly! -- Edit PPPort_pm.PL and the
+ includes in parts/inc/ instead.
+
+ Use 'perldoc ppport.h' to view the documentation below.
+
+----------------------------------------------------------------------
+
+SKIP
+
+=pod
+
+=head1 NAME
+
+ppport.h - Perl/Pollution/Portability version 3.20
+
+=head1 SYNOPSIS
+
+ perl ppport.h [options] [source files]
+
+ Searches current directory for files if no [source files] are given
+
+ --help show short help
+
+ --version show version
+
+ --patch=file write one patch file with changes
+ --copy=suffix write changed copies with suffix
+ --diff=program use diff program and options
+
+ --compat-version=version provide compatibility with Perl version
+ --cplusplus accept C++ comments
+
+ --quiet don't output anything except fatal errors
+ --nodiag don't show diagnostics
+ --nohints don't show hints
+ --nochanges don't suggest changes
+ --nofilter don't filter input files
+
+ --strip strip all script and doc functionality from
+ ppport.h
+
+ --list-provided list provided API
+ --list-unsupported list unsupported API
+ --api-info=name show Perl API portability information
+
+=head1 COMPATIBILITY
+
+This version of F<ppport.h> is designed to support operation with Perl
+installations back to 5.003, and has been tested up to 5.11.5.
+
+=head1 OPTIONS
+
+=head2 --help
+
+Display a brief usage summary.
+
+=head2 --version
+
+Display the version of F<ppport.h>.
+
+=head2 --patch=I<file>
+
+If this option is given, a single patch file will be created if
+any changes are suggested. This requires a working diff program
+to be installed on your system.
+
+=head2 --copy=I<suffix>
+
+If this option is given, a copy of each file will be saved with
+the given suffix that contains the suggested changes. This does
+not require any external programs. Note that this does not
+automagially add a dot between the original filename and the
+suffix. If you want the dot, you have to include it in the option
+argument.
+
+If neither C<--patch> or C<--copy> are given, the default is to
+simply print the diffs for each file. This requires either
+C<Text::Diff> or a C<diff> program to be installed.
+
+=head2 --diff=I<program>
+
+Manually set the diff program and options to use. The default
+is to use C<Text::Diff>, when installed, and output unified
+context diffs.
+
+=head2 --compat-version=I<version>
+
+Tell F<ppport.h> to check for compatibility with the given
+Perl version. The default is to check for compatibility with Perl
+version 5.003. You can use this option to reduce the output
+of F<ppport.h> if you intend to be backward compatible only
+down to a certain Perl version.
+
+=head2 --cplusplus
+
+Usually, F<ppport.h> will detect C++ style comments and
+replace them with C style comments for portability reasons.
+Using this option instructs F<ppport.h> to leave C++
+comments untouched.
+
+=head2 --quiet
+
+Be quiet. Don't print anything except fatal errors.
+
+=head2 --nodiag
+
+Don't output any diagnostic messages. Only portability
+alerts will be printed.
+
+=head2 --nohints
+
+Don't output any hints. Hints often contain useful portability
+notes. Warnings will still be displayed.
+
+=head2 --nochanges
+
+Don't suggest any changes. Only give diagnostic output and hints
+unless these are also deactivated.
+
+=head2 --nofilter
+
+Don't filter the list of input files. By default, files not looking
+like source code (i.e. not *.xs, *.c, *.cc, *.cpp or *.h) are skipped.
+
+=head2 --strip
+
+Strip all script and documentation functionality from F<ppport.h>.
+This reduces the size of F<ppport.h> dramatically and may be useful
+if you want to include F<ppport.h> in smaller modules without
+increasing their distribution size too much.
+
+The stripped F<ppport.h> will have a C<--unstrip> option that allows
+you to undo the stripping, but only if an appropriate C<Devel::PPPort>
+module is installed.
+
+=head2 --list-provided
+
+Lists the API elements for which compatibility is provided by
+F<ppport.h>. Also lists if it must be explicitly requested,
+if it has dependencies, and if there are hints or warnings for it.
+
+=head2 --list-unsupported
+
+Lists the API elements that are known not to be supported by
+F<ppport.h> and below which version of Perl they probably
+won't be available or work.
+
+=head2 --api-info=I<name>
+
+Show portability information for API elements matching I<name>.
+If I<name> is surrounded by slashes, it is interpreted as a regular
+expression.
+
+=head1 DESCRIPTION
+
+In order for a Perl extension (XS) module to be as portable as possible
+across differing versions of Perl itself, certain steps need to be taken.
+
+=over 4
+
+=item *
+
+Including this header is the first major one. This alone will give you
+access to a large part of the Perl API that hasn't been available in
+earlier Perl releases. Use
+
+ perl ppport.h --list-provided
+
+to see which API elements are provided by ppport.h.
+
+=item *
+
+You should avoid using deprecated parts of the API. For example, using
+global Perl variables without the C<PL_> prefix is deprecated. Also,
+some API functions used to have a C<perl_> prefix. Using this form is
+also deprecated. You can safely use the supported API, as F<ppport.h>
+will provide wrappers for older Perl versions.
+
+=item *
+
+If you use one of a few functions or variables that were not present in
+earlier versions of Perl, and that can't be provided using a macro, you
+have to explicitly request support for these functions by adding one or
+more C<#define>s in your source code before the inclusion of F<ppport.h>.
+
+These functions or variables will be marked C<explicit> in the list shown
+by C<--list-provided>.
+
+Depending on whether you module has a single or multiple files that
+use such functions or variables, you want either C<static> or global
+variants.
+
+For a C<static> function or variable (used only in a single source
+file), use:
+
+ #define NEED_function
+ #define NEED_variable
+
+For a global function or variable (used in multiple source files),
+use:
+
+ #define NEED_function_GLOBAL
+ #define NEED_variable_GLOBAL
+
+Note that you mustn't have more than one global request for the
+same function or variable in your project.
+
+ Function / Variable Static Request Global Request
+ -----------------------------------------------------------------------------------------
+ PL_parser NEED_PL_parser NEED_PL_parser_GLOBAL
+ PL_signals NEED_PL_signals NEED_PL_signals_GLOBAL
+ eval_pv() NEED_eval_pv NEED_eval_pv_GLOBAL
+ grok_bin() NEED_grok_bin NEED_grok_bin_GLOBAL
+ grok_hex() NEED_grok_hex NEED_grok_hex_GLOBAL
+ grok_number() NEED_grok_number NEED_grok_number_GLOBAL
+ grok_numeric_radix() NEED_grok_numeric_radix NEED_grok_numeric_radix_GLOBAL
+ grok_oct() NEED_grok_oct NEED_grok_oct_GLOBAL
+ load_module() NEED_load_module NEED_load_module_GLOBAL
+ my_snprintf() NEED_my_snprintf NEED_my_snprintf_GLOBAL
+ my_sprintf() NEED_my_sprintf NEED_my_sprintf_GLOBAL
+ my_strlcat() NEED_my_strlcat NEED_my_strlcat_GLOBAL
+ my_strlcpy() NEED_my_strlcpy NEED_my_strlcpy_GLOBAL
+ newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL
+ newRV_noinc() NEED_newRV_noinc NEED_newRV_noinc_GLOBAL
+ newSV_type() NEED_newSV_type NEED_newSV_type_GLOBAL
+ newSVpvn_flags() NEED_newSVpvn_flags NEED_newSVpvn_flags_GLOBAL
+ newSVpvn_share() NEED_newSVpvn_share NEED_newSVpvn_share_GLOBAL
+ pv_display() NEED_pv_display NEED_pv_display_GLOBAL
+ pv_escape() NEED_pv_escape NEED_pv_escape_GLOBAL
+ pv_pretty() NEED_pv_pretty NEED_pv_pretty_GLOBAL
+ sv_2pv_flags() NEED_sv_2pv_flags NEED_sv_2pv_flags_GLOBAL
+ sv_2pvbyte() NEED_sv_2pvbyte NEED_sv_2pvbyte_GLOBAL
+ sv_catpvf_mg() NEED_sv_catpvf_mg NEED_sv_catpvf_mg_GLOBAL
+ sv_catpvf_mg_nocontext() NEED_sv_catpvf_mg_nocontext NEED_sv_catpvf_mg_nocontext_GLOBAL
+ sv_pvn_force_flags() NEED_sv_pvn_force_flags NEED_sv_pvn_force_flags_GLOBAL
+ sv_setpvf_mg() NEED_sv_setpvf_mg NEED_sv_setpvf_mg_GLOBAL
+ sv_setpvf_mg_nocontext() NEED_sv_setpvf_mg_nocontext NEED_sv_setpvf_mg_nocontext_GLOBAL
+ vload_module() NEED_vload_module NEED_vload_module_GLOBAL
+ vnewSVpvf() NEED_vnewSVpvf NEED_vnewSVpvf_GLOBAL
+ warner() NEED_warner NEED_warner_GLOBAL
+
+To avoid namespace conflicts, you can change the namespace of the
+explicitly exported functions / variables using the C<DPPP_NAMESPACE>
+macro. Just C<#define> the macro before including C<ppport.h>:
+
+ #define DPPP_NAMESPACE MyOwnNamespace_
+ #include "ppport.h"
+
+The default namespace is C<DPPP_>.
+
+=back
+
+The good thing is that most of the above can be checked by running
+F<ppport.h> on your source code. See the next section for
+details.
+
+=head1 EXAMPLES
+
+To verify whether F<ppport.h> is needed for your module, whether you
+should make any changes to your code, and whether any special defines
+should be used, F<ppport.h> can be run as a Perl script to check your
+source code. Simply say:
+
+ perl ppport.h
+
+The result will usually be a list of patches suggesting changes
+that should at least be acceptable, if not necessarily the most
+efficient solution, or a fix for all possible problems.
+
+If you know that your XS module uses features only available in
+newer Perl releases, if you're aware that it uses C++ comments,
+and if you want all suggestions as a single patch file, you could
+use something like this:
+
+ perl ppport.h --compat-version=5.6.0 --cplusplus --patch=test.diff
+
+If you only want your code to be scanned without any suggestions
+for changes, use:
+
+ perl ppport.h --nochanges
+
+You can specify a different C<diff> program or options, using
+the C<--diff> option:
+
+ perl ppport.h --diff='diff -C 10'
+
+This would output context diffs with 10 lines of context.
+
+If you want to create patched copies of your files instead, use:
+
+ perl ppport.h --copy=.new
+
+To display portability information for the C<newSVpvn> function,
+use:
+
+ perl ppport.h --api-info=newSVpvn
+
+Since the argument to C<--api-info> can be a regular expression,
+you can use
+
+ perl ppport.h --api-info=/_nomg$/
+
+to display portability information for all C<_nomg> functions or
+
+ perl ppport.h --api-info=/./
+
+to display information for all known API elements.
+
+=head1 BUGS
+
+If this version of F<ppport.h> is causing failure during
+the compilation of this module, please check if newer versions
+of either this module or C<Devel::PPPort> are available on CPAN
+before sending a bug report.
+
+If F<ppport.h> was generated using the latest version of
+C<Devel::PPPort> and is causing failure of this module, please
+file a bug report using the CPAN Request Tracker at L<http://rt.cpan.org/>.
+
+Please include the following information:
+
+=over 4
+
+=item 1.
+
+The complete output from running "perl -V"
+
+=item 2.
+
+This file.
+
+=item 3.
+
+The name and version of the module you were trying to build.
+
+=item 4.
+
+A full log of the build that failed.
+
+=item 5.
+
+Any other information that you think could be relevant.
+
+=back
+
+For the latest version of this code, please get the C<Devel::PPPort>
+module from CPAN.
+
+=head1 COPYRIGHT
+
+Version 3.x, Copyright (c) 2004-2010, Marcus Holland-Moritz.
+
+Version 2.x, Copyright (C) 2001, Paul Marquess.
+
+Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+See L<Devel::PPPort>.
+
+=cut
+
+use strict;
+
+# Disable broken TRIE-optimization
+BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 }
+
+my $VERSION = 3.20;
+
+my %opt = (
+ quiet => 0,
+ diag => 1,
+ hints => 1,
+ changes => 1,
+ cplusplus => 0,
+ filter => 1,
+ strip => 0,
+ version => 0,
+);
+
+my($ppport) = $0 =~ /([\w.]+)$/;
+my $LF = '(?:\r\n|[\r\n])'; # line feed
+my $HS = "[ \t]"; # horizontal whitespace
+
+# Never use C comments in this file!
+my $ccs = '/'.'*';
+my $cce = '*'.'/';
+my $rccs = quotemeta $ccs;
+my $rcce = quotemeta $cce;
+
+eval {
+ require Getopt::Long;
+ Getopt::Long::GetOptions(\%opt, qw(
+ help quiet diag! filter! hints! changes! cplusplus strip version
+ patch=s copy=s diff=s compat-version=s
+ list-provided list-unsupported api-info=s
+ )) or usage();
+};
+
+if ($@ and grep /^-/, @ARGV) {
+ usage() if "@ARGV" =~ /^--?h(?:elp)?$/;
+ die "Getopt::Long not found. Please don't use any options.\n";
+}
+
+if ($opt{version}) {
+ print "This is $0 $VERSION.\n";
+ exit 0;
+}
+
+usage() if $opt{help};
+strip() if $opt{strip};
+
+if (exists $opt{'compat-version'}) {
+ my($r,$v,$s) = eval { parse_version($opt{'compat-version'}) };
+ if ($@) {
+ die "Invalid version number format: '$opt{'compat-version'}'\n";
+ }
+ die "Only Perl 5 is supported\n" if $r != 5;
+ die "Invalid version number: $opt{'compat-version'}\n" if $v >= 1000 || $s >= 1000;
+ $opt{'compat-version'} = sprintf "%d.%03d%03d", $r, $v, $s;
+}
+else {
+ $opt{'compat-version'} = 5;
+}
+
+my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
+ ? ( $1 => {
+ ($2 ? ( base => $2 ) : ()),
+ ($3 ? ( todo => $3 ) : ()),
+ (index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
+ (index($4, 'p') >= 0 ? ( provided => 1 ) : ()),
+ (index($4, 'n') >= 0 ? ( nothxarg => 1 ) : ()),
+ } )
+ : die "invalid spec: $_" } qw(
+AvFILLp|5.004050||p
+AvFILL|||
+BhkDISABLE||5.014000|
+BhkENABLE||5.014000|
+BhkENTRY_set||5.014000|
+BhkENTRY|||
+BhkFLAGS|||
+CALL_BLOCK_HOOKS|||
+CLASS|||n
+CPERLscope|5.005000||p
+CX_CURPAD_SAVE|||
+CX_CURPAD_SV|||
+CopFILEAV|5.006000||p
+CopFILEGV_set|5.006000||p
+CopFILEGV|5.006000||p
+CopFILESV|5.006000||p
+CopFILE_set|5.006000||p
+CopFILE|5.006000||p
+CopSTASHPV_set|5.006000||p
+CopSTASHPV|5.006000||p
+CopSTASH_eq|5.006000||p
+CopSTASH_set|5.006000||p
+CopSTASH|5.006000||p
+CopyD|5.009002||p
+Copy|||
+CvPADLIST|||
+CvSTASH|||
+CvWEAKOUTSIDE|||
+DEFSV_set|5.010001||p
+DEFSV|5.004050||p
+END_EXTERN_C|5.005000||p
+ENTER|||
+ERRSV|5.004050||p
+EXTEND|||
+EXTERN_C|5.005000||p
+F0convert|||n
+FREETMPS|||
+GIMME_V||5.004000|n
+GIMME|||n
+GROK_NUMERIC_RADIX|5.007002||p
+G_ARRAY|||
+G_DISCARD|||
+G_EVAL|||
+G_METHOD|5.006001||p
+G_NOARGS|||
+G_SCALAR|||
+G_VOID||5.004000|
+GetVars|||
+GvSVn|5.009003||p
+GvSV|||
+Gv_AMupdate||5.011000|
+HEf_SVKEY||5.004000|
+HeHASH||5.004000|
+HeKEY||5.004000|
+HeKLEN||5.004000|
+HePV||5.004000|
+HeSVKEY_force||5.004000|
+HeSVKEY_set||5.004000|
+HeSVKEY||5.004000|
+HeUTF8||5.010001|
+HeVAL||5.004000|
+HvENAME||5.013007|
+HvNAMELEN_get|5.009003||p
+HvNAME_get|5.009003||p
+HvNAME|||
+INT2PTR|5.006000||p
+IN_LOCALE_COMPILETIME|5.007002||p
+IN_LOCALE_RUNTIME|5.007002||p
+IN_LOCALE|5.007002||p
+IN_PERL_COMPILETIME|5.008001||p
+IS_NUMBER_GREATER_THAN_UV_MAX|5.007002||p
+IS_NUMBER_INFINITY|5.007002||p
+IS_NUMBER_IN_UV|5.007002||p
+IS_NUMBER_NAN|5.007003||p
+IS_NUMBER_NEG|5.007002||p
+IS_NUMBER_NOT_INT|5.007002||p
+IVSIZE|5.006000||p
+IVTYPE|5.006000||p
+IVdf|5.006000||p
+LEAVE|||
+LINKLIST||5.013006|
+LVRET|||
+MARK|||
+MULTICALL||5.014000|
+MY_CXT_CLONE|5.009002||p
+MY_CXT_INIT|5.007003||p
+MY_CXT|5.007003||p
+MoveD|5.009002||p
+Move|||
+NOOP|5.005000||p
+NUM2PTR|5.006000||p
+NVTYPE|5.006000||p
+NVef|5.006001||p
+NVff|5.006001||p
+NVgf|5.006001||p
+Newxc|5.009003||p
+Newxz|5.009003||p
+Newx|5.009003||p
+Nullav|||
+Nullch|||
+Nullcv|||
+Nullhv|||
+Nullsv|||
+OP_CLASS||5.013007|
+OP_DESC||5.007003|
+OP_NAME||5.007003|
+ORIGMARK|||
+PAD_BASE_SV|||
+PAD_CLONE_VARS|||
+PAD_COMPNAME_FLAGS|||
+PAD_COMPNAME_GEN_set|||
+PAD_COMPNAME_GEN|||
+PAD_COMPNAME_OURSTASH|||
+PAD_COMPNAME_PV|||
+PAD_COMPNAME_TYPE|||
+PAD_DUP|||
+PAD_RESTORE_LOCAL|||
+PAD_SAVE_LOCAL|||
+PAD_SAVE_SETNULLPAD|||
+PAD_SETSV|||
+PAD_SET_CUR_NOSAVE|||
+PAD_SET_CUR|||
+PAD_SVl|||
+PAD_SV|||
+PERLIO_FUNCS_CAST|5.009003||p
+PERLIO_FUNCS_DECL|5.009003||p
+PERL_ABS|5.008001||p
+PERL_BCDVERSION|5.014000||p
+PERL_GCC_BRACE_GROUPS_FORBIDDEN|5.008001||p
+PERL_HASH|5.004000||p
+PERL_INT_MAX|5.004000||p
+PERL_INT_MIN|5.004000||p
+PERL_LONG_MAX|5.004000||p
+PERL_LONG_MIN|5.004000||p
+PERL_MAGIC_arylen|5.007002||p
+PERL_MAGIC_backref|5.007002||p
+PERL_MAGIC_bm|5.007002||p
+PERL_MAGIC_collxfrm|5.007002||p
+PERL_MAGIC_dbfile|5.007002||p
+PERL_MAGIC_dbline|5.007002||p
+PERL_MAGIC_defelem|5.007002||p
+PERL_MAGIC_envelem|5.007002||p
+PERL_MAGIC_env|5.007002||p
+PERL_MAGIC_ext|5.007002||p
+PERL_MAGIC_fm|5.007002||p
+PERL_MAGIC_glob|5.014000||p
+PERL_MAGIC_isaelem|5.007002||p
+PERL_MAGIC_isa|5.007002||p
+PERL_MAGIC_mutex|5.014000||p
+PERL_MAGIC_nkeys|5.007002||p
+PERL_MAGIC_overload_elem|5.007002||p
+PERL_MAGIC_overload_table|5.007002||p
+PERL_MAGIC_overload|5.007002||p
+PERL_MAGIC_pos|5.007002||p
+PERL_MAGIC_qr|5.007002||p
+PERL_MAGIC_regdata|5.007002||p
+PERL_MAGIC_regdatum|5.007002||p
+PERL_MAGIC_regex_global|5.007002||p
+PERL_MAGIC_shared_scalar|5.007003||p
+PERL_MAGIC_shared|5.007003||p
+PERL_MAGIC_sigelem|5.007002||p
+PERL_MAGIC_sig|5.007002||p
+PERL_MAGIC_substr|5.007002||p
+PERL_MAGIC_sv|5.007002||p
+PERL_MAGIC_taint|5.007002||p
+PERL_MAGIC_tiedelem|5.007002||p
+PERL_MAGIC_tiedscalar|5.007002||p
+PERL_MAGIC_tied|5.007002||p
+PERL_MAGIC_utf8|5.008001||p
+PERL_MAGIC_uvar_elem|5.007003||p
+PERL_MAGIC_uvar|5.007002||p
+PERL_MAGIC_vec|5.007002||p
+PERL_MAGIC_vstring|5.008001||p
+PERL_PV_ESCAPE_ALL|5.009004||p
+PERL_PV_ESCAPE_FIRSTCHAR|5.009004||p
+PERL_PV_ESCAPE_NOBACKSLASH|5.009004||p
+PERL_PV_ESCAPE_NOCLEAR|5.009004||p
+PERL_PV_ESCAPE_QUOTE|5.009004||p