summaryrefslogtreecommitdiffstats
path: root/upstream/fedora-rawhide/man1/perlapi.1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:43:11 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:43:11 +0000
commitfc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch)
treece1e3bce06471410239a6f41282e328770aa404a /upstream/fedora-rawhide/man1/perlapi.1
parentInitial commit. (diff)
downloadmanpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.tar.xz
manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.zip
Adding upstream version 4.22.0.upstream/4.22.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/fedora-rawhide/man1/perlapi.1')
-rw-r--r--upstream/fedora-rawhide/man1/perlapi.129981
1 files changed, 29981 insertions, 0 deletions
diff --git a/upstream/fedora-rawhide/man1/perlapi.1 b/upstream/fedora-rawhide/man1/perlapi.1
new file mode 100644
index 00000000..2fb329dc
--- /dev/null
+++ b/upstream/fedora-rawhide/man1/perlapi.1
@@ -0,0 +1,29981 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "PERLAPI 1"
+.TH PERLAPI 1 2024-01-25 "perl v5.38.2" "Perl Programmers Reference Guide"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH NAME
+perlapi \- autogenerated documentation for the perl public API
+.SH DESCRIPTION
+.IX Xref "Perl API API api"
+.IX Header "DESCRIPTION"
+This file contains most of the documentation of the perl public API, as
+generated by \fIembed.pl\fR. Specifically, it is a listing of functions,
+macros, flags, and variables that may be used by extension writers. Besides
+perlintern and \fIconfig.h\fR, some items are listed here as being actually
+documented in another pod.
+.PP
+At the end is a list of functions which have yet
+to be documented. Patches welcome! The interfaces of these are subject to
+change without notice.
+.PP
+Some of the functions documented here are consolidated so that a single entry
+serves for multiple functions which all do basically the same thing, but have
+some slight differences. For example, one form might process magic, while
+another doesn't. The name of each variation is listed at the top of the
+single entry. But if all have the same signature (arguments and return type)
+except for their names, only the usage for the base form is shown. If any
+one of the forms has a different signature (such as returning \f(CW\*(C`const\*(C'\fR or
+not) every function's signature is explicitly displayed.
+.PP
+Anything not listed here or in the other mentioned pods is not part of the
+public API, and should not be used by extension writers at all. For these
+reasons, blindly using functions listed in \fIproto.h\fR is to be avoided when
+writing extensions.
+.PP
+In Perl, unlike C, a string of characters may generally contain embedded
+\&\f(CW\*(C`NUL\*(C'\fR characters. Sometimes in the documentation a Perl string is referred
+to as a "buffer" to distinguish it from a C string, but sometimes they are
+both just referred to as strings.
+.PP
+Note that all Perl API global variables must be referenced with the \f(CW\*(C`PL_\*(C'\fR
+prefix. Again, those not listed here are not to be used by extension writers,
+and may be changed or removed without notice; same with macros.
+Some macros are provided for compatibility with the older,
+unadorned names, but this support may be disabled in a future release.
+.PP
+Perl was originally written to handle US-ASCII only (that is characters
+whose ordinal numbers are in the range 0 \- 127).
+And documentation and comments may still use the term ASCII, when
+sometimes in fact the entire range from 0 \- 255 is meant.
+.PP
+The non-ASCII characters below 256 can have various meanings, depending on
+various things. (See, most notably, perllocale.) But usually the whole
+range can be referred to as ISO\-8859\-1. Often, the term "Latin\-1" (or
+"Latin1") is used as an equivalent for ISO\-8859\-1. But some people treat
+"Latin1" as referring just to the characters in the range 128 through 255, or
+sometimes from 160 through 255.
+This documentation uses "Latin1" and "Latin\-1" to refer to all 256 characters.
+.PP
+Note that Perl can be compiled and run under either ASCII or EBCDIC (See
+perlebcdic). Most of the documentation (and even comments in the code)
+ignore the EBCDIC possibility.
+For almost all purposes the differences are transparent.
+As an example, under EBCDIC,
+instead of UTF\-8, UTF-EBCDIC is used to encode Unicode strings, and so
+whenever this documentation refers to \f(CW\*(C`utf8\*(C'\fR
+(and variants of that name, including in function names),
+it also (essentially transparently) means \f(CW\*(C`UTF\-EBCDIC\*(C'\fR.
+But the ordinals of characters differ between ASCII, EBCDIC, and
+the UTF\- encodings, and a string encoded in UTF-EBCDIC may occupy a different
+number of bytes than in UTF\-8.
+.PP
+The organization of this document is tentative and subject to change.
+Suggestions and patches welcome
+perl5\-porters@perl.org <mailto:perl5-porters@perl.org>.
+.PP
+The sections in this document currently are
+.IP """AV Handling""" 4
+.IX Item """AV Handling"""
+.PD 0
+.IP """Callback Functions""" 4
+.IX Item """Callback Functions"""
+.IP """Casting""" 4
+.IX Item """Casting"""
+.IP """Character case changing""" 4
+.IX Item """Character case changing"""
+.IP """Character classification""" 4
+.IX Item """Character classification"""
+.IP """Compiler and Preprocessor information""" 4
+.IX Item """Compiler and Preprocessor information"""
+.IP """Compiler directives""" 4
+.IX Item """Compiler directives"""
+.IP """Compile-time scope hooks""" 4
+.IX Item """Compile-time scope hooks"""
+.IP """Concurrency""" 4
+.IX Item """Concurrency"""
+.IP """COPs and Hint Hashes""" 4
+.IX Item """COPs and Hint Hashes"""
+.IP """Custom Operators""" 4
+.IX Item """Custom Operators"""
+.IP """CV Handling""" 4
+.IX Item """CV Handling"""
+.IP """Debugging""" 4
+.IX Item """Debugging"""
+.IP """Display functions""" 4
+.IX Item """Display functions"""
+.IP """Embedding, Threads, and Interpreter Cloning""" 4
+.IX Item """Embedding, Threads, and Interpreter Cloning"""
+.IP """Errno""" 4
+.IX Item """Errno"""
+.IP """Exception Handling (simple) Macros""" 4
+.IX Item """Exception Handling (simple) Macros"""
+.IP """Filesystem configuration values""" 4
+.IX Item """Filesystem configuration values"""
+.IP """Floating point""" 4
+.IX Item """Floating point"""
+.IP """General Configuration""" 4
+.IX Item """General Configuration"""
+.IP """Global Variables""" 4
+.IX Item """Global Variables"""
+.IP """GV Handling and Stashes""" 4
+.IX Item """GV Handling and Stashes"""
+.IP """Hook manipulation""" 4
+.IX Item """Hook manipulation"""
+.IP """HV Handling""" 4
+.IX Item """HV Handling"""
+.IP """Input/Output""" 4
+.IX Item """Input/Output"""
+.IP """Integer""" 4
+.IX Item """Integer"""
+.IP """I/O Formats""" 4
+.IX Item """I/O Formats"""
+.IP """Lexer interface""" 4
+.IX Item """Lexer interface"""
+.IP """Locales""" 4
+.IX Item """Locales"""
+.IP """Magic""" 4
+.IX Item """Magic"""
+.IP """Memory Management""" 4
+.IX Item """Memory Management"""
+.IP """MRO""" 4
+.IX Item """MRO"""
+.IP """Multicall Functions""" 4
+.IX Item """Multicall Functions"""
+.IP """Numeric Functions""" 4
+.IX Item """Numeric Functions"""
+.IP """Optrees""" 4
+.IX Item """Optrees"""
+.IP """Pack and Unpack""" 4
+.IX Item """Pack and Unpack"""
+.IP """Pad Data Structures""" 4
+.IX Item """Pad Data Structures"""
+.IP """Password and Group access""" 4
+.IX Item """Password and Group access"""
+.IP """Paths to system commands""" 4
+.IX Item """Paths to system commands"""
+.IP """Prototype information""" 4
+.IX Item """Prototype information"""
+.IP """REGEXP Functions""" 4
+.IX Item """REGEXP Functions"""
+.IP """Reports and Formats""" 4
+.IX Item """Reports and Formats"""
+.IP """Signals""" 4
+.IX Item """Signals"""
+.IP """Site configuration""" 4
+.IX Item """Site configuration"""
+.IP """Sockets configuration values""" 4
+.IX Item """Sockets configuration values"""
+.IP """Source Filters""" 4
+.IX Item """Source Filters"""
+.IP """Stack Manipulation Macros""" 4
+.IX Item """Stack Manipulation Macros"""
+.IP """String Handling""" 4
+.IX Item """String Handling"""
+.IP """SV Flags""" 4
+.IX Item """SV Flags"""
+.IP """SV Handling""" 4
+.IX Item """SV Handling"""
+.IP """Tainting""" 4
+.IX Item """Tainting"""
+.IP """Time""" 4
+.IX Item """Time"""
+.IP """Typedef names""" 4
+.IX Item """Typedef names"""
+.IP """Unicode Support""" 4
+.IX Item """Unicode Support"""
+.IP """Utility Functions""" 4
+.IX Item """Utility Functions"""
+.IP """Versioning""" 4
+.IX Item """Versioning"""
+.IP """Warning and Dieing""" 4
+.IX Item """Warning and Dieing"""
+.IP """XS""" 4
+.IX Item """XS"""
+.IP """Undocumented elements""" 4
+.IX Item """Undocumented elements"""
+.PD
+.PP
+The listing below is alphabetical, case insensitive.
+.SH "AV Handling"
+.IX Header "AV Handling"
+.ie n .IP """AV""" 4
+.el .IP \f(CWAV\fR 4
+.IX Item "AV"
+Described in perlguts.
+.ie n .IP """AvALLOC""" 4
+.el .IP \f(CWAvALLOC\fR 4
+.IX Item "AvALLOC"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& AvALLOC(AV* av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """AvARRAY""" 4
+.el .IP \f(CWAvARRAY\fR 4
+.IX Xref "AvARRAY"
+.IX Item "AvARRAY"
+Returns a pointer to the AV's internal SV* array.
+.Sp
+This is useful for doing pointer arithmetic on the array.
+If all you need is to look up an array element, then prefer \f(CW\*(C`av_fetch\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV** AvARRAY(AV* av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_clear""" 4
+.el .IP \f(CWav_clear\fR 4
+.IX Xref "av_clear"
+.IX Item "av_clear"
+Frees all the elements of an array, leaving it empty.
+The XS equivalent of \f(CW\*(C`@array = ()\*(C'\fR. See also "av_undef".
+.Sp
+Note that it is possible that the actions of a destructor called directly
+or indirectly by freeing an element of the array could cause the reference
+count of the array itself to be reduced (e.g. by deleting an entry in the
+symbol table). So it is a possibility that the AV could have been freed
+(or even reallocated) on return from the call unless you hold a reference
+to it.
+.RS 4
+.Sp
+.Vb 1
+\& void av_clear(AV *av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_count""" 4
+.el .IP \f(CWav_count\fR 4
+.IX Xref "av_count"
+.IX Item "av_count"
+Returns the number of elements in the array \f(CW\*(C`av\*(C'\fR. This is the true length of
+the array, including any undefined elements. It is always the same as
+\&\f(CW\*(C`av_top_index(av)\ +\ 1\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& Size_t av_count(AV *av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_create_and_push""" 4
+.el .IP \f(CWav_create_and_push\fR 4
+.IX Xref "av_create_and_push"
+.IX Item "av_create_and_push"
+Push an SV onto the end of the array, creating the array if necessary.
+A small internal helper function to remove a commonly duplicated idiom.
+.Sp
+NOTE: \f(CW\*(C`av_create_and_push\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_av_create_and_push\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& void Perl_av_create_and_push(pTHX_ AV ** const avp,
+\& SV * const val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_create_and_unshift_one""" 4
+.el .IP \f(CWav_create_and_unshift_one\fR 4
+.IX Xref "av_create_and_unshift_one"
+.IX Item "av_create_and_unshift_one"
+Unshifts an SV onto the beginning of the array, creating the array if
+necessary.
+A small internal helper function to remove a commonly duplicated idiom.
+.Sp
+NOTE: \f(CW\*(C`av_create_and_unshift_one\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_av_create_and_unshift_one\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& SV ** Perl_av_create_and_unshift_one(pTHX_ AV ** const avp,
+\& SV * const val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_delete""" 4
+.el .IP \f(CWav_delete\fR 4
+.IX Xref "av_delete"
+.IX Item "av_delete"
+Deletes the element indexed by \f(CW\*(C`key\*(C'\fR from the array, makes the element
+mortal, and returns it. If \f(CW\*(C`flags\*(C'\fR equals \f(CW\*(C`G_DISCARD\*(C'\fR, the element is
+freed and NULL is returned. NULL is also returned if \f(CW\*(C`key\*(C'\fR is out of
+range.
+.Sp
+Perl equivalent: \f(CW\*(C`splice(@myarray,\ $key,\ 1,\ undef)\*(C'\fR (with the
+\&\f(CW\*(C`splice\*(C'\fR in void context if \f(CW\*(C`G_DISCARD\*(C'\fR is present).
+.RS 4
+.Sp
+.Vb 1
+\& SV * av_delete(AV *av, SSize_t key, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_exists""" 4
+.el .IP \f(CWav_exists\fR 4
+.IX Xref "av_exists"
+.IX Item "av_exists"
+Returns true if the element indexed by \f(CW\*(C`key\*(C'\fR has been initialized.
+.Sp
+This relies on the fact that uninitialized array elements are set to
+\&\f(CW\*(C`NULL\*(C'\fR.
+.Sp
+Perl equivalent: \f(CWexists($myarray[$key])\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool av_exists(AV *av, SSize_t key)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_extend""" 4
+.el .IP \f(CWav_extend\fR 4
+.IX Xref "av_extend"
+.IX Item "av_extend"
+Pre-extend an array so that it is capable of storing values at indexes
+\&\f(CW\*(C`0..key\*(C'\fR. Thus \f(CW\*(C`av_extend(av,99)\*(C'\fR guarantees that the array can store 100
+elements, i.e. that \f(CW\*(C`av_store(av, 0, sv)\*(C'\fR through \f(CW\*(C`av_store(av, 99, sv)\*(C'\fR
+on a plain array will work without any further memory allocation.
+.Sp
+If the av argument is a tied array then will call the \f(CW\*(C`EXTEND\*(C'\fR tied
+array method with an argument of \f(CW\*(C`(key+1)\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void av_extend(AV *av, SSize_t key)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_fetch""" 4
+.el .IP \f(CWav_fetch\fR 4
+.IX Xref "av_fetch"
+.IX Item "av_fetch"
+Returns the SV at the specified index in the array. The \f(CW\*(C`key\*(C'\fR is the
+index. If \f(CW\*(C`lval\*(C'\fR is true, you are guaranteed to get a real SV back (in case
+it wasn't real before), which you can then modify. Check that the return
+value is non-NULL before dereferencing it to a \f(CW\*(C`SV*\*(C'\fR.
+.Sp
+See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for
+more information on how to use this function on tied arrays.
+.Sp
+The rough perl equivalent is \f(CW$myarray[$key]\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV ** av_fetch(AV *av, SSize_t key, I32 lval)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """AvFILL""" 4
+.el .IP \f(CWAvFILL\fR 4
+.IX Xref "AvFILL"
+.IX Item "AvFILL"
+Same as \f(CW"av_top_index"\fR or \f(CW"av_tindex"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t AvFILL(AV* av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_fill""" 4
+.el .IP \f(CWav_fill\fR 4
+.IX Xref "av_fill"
+.IX Item "av_fill"
+Set the highest index in the array to the given number, equivalent to
+Perl's \f(CW\*(C`$#array\ =\ $fill;\*(C'\fR.
+.Sp
+The number of elements in the array will be \f(CW\*(C`fill\ +\ 1\*(C'\fR after
+\&\f(CWav_fill()\fR returns. If the array was previously shorter, then the
+additional elements appended are set to NULL. If the array
+was longer, then the excess elements are freed. \f(CW\*(C`av_fill(av,\ \-1)\*(C'\fR is
+the same as \f(CWav_clear(av)\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void av_fill(AV *av, SSize_t fill)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_len""" 4
+.el .IP \f(CWav_len\fR 4
+.IX Xref "av_len"
+.IX Item "av_len"
+Same as "av_top_index". Note that, unlike what the name implies, it returns
+the maximum index in the array. This is unlike "sv_len", which returns what
+you would expect.
+.Sp
+\&\fBTo get the true number of elements in the array, instead use \fR\f(CB"av_count"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t av_len(AV *av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_make""" 4
+.el .IP \f(CWav_make\fR 4
+.IX Xref "av_make"
+.IX Item "av_make"
+Creates a new AV and populates it with a list (\f(CW**strp\fR, length \f(CW\*(C`size\*(C'\fR) of
+SVs. A copy is made of each SV, so their refcounts are not changed. The new
+AV will have a reference count of 1.
+.Sp
+Perl equivalent: \f(CW\*(C`my @new_array = ($scalar1, $scalar2, $scalar3...);\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& AV * av_make(SSize_t size, SV **strp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_pop""" 4
+.el .IP \f(CWav_pop\fR 4
+.IX Xref "av_pop"
+.IX Item "av_pop"
+Removes one SV from the end of the array, reducing its size by one and
+returning the SV (transferring control of one reference count) to the
+caller. Returns \f(CW&PL_sv_undef\fR if the array is empty.
+.Sp
+Perl equivalent: \f(CW\*(C`pop(@myarray);\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& SV * av_pop(AV *av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_push""" 4
+.el .IP \f(CWav_push\fR 4
+.IX Xref "av_push"
+.IX Item "av_push"
+Pushes an SV (transferring control of one reference count) onto the end of the
+array. The array will grow automatically to accommodate the addition.
+.Sp
+Perl equivalent: \f(CW\*(C`push @myarray, $val;\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void av_push(AV *av, SV *val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_push_simple""" 4
+.el .IP \f(CWav_push_simple\fR 4
+.IX Xref "av_push_simple"
+.IX Item "av_push_simple"
+This is a cut-down version of av_push that assumes that the array is very
+straightforward \- no magic, not readonly, and AvREAL \- and that \f(CW\*(C`key\*(C'\fR is
+not less than \-1. This function MUST NOT be used in situations where any
+of those assumptions may not hold.
+.Sp
+Pushes an SV (transferring control of one reference count) onto the end of the
+array. The array will grow automatically to accommodate the addition.
+.Sp
+Perl equivalent: \f(CW\*(C`push @myarray, $val;\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void av_push_simple(AV *av, SV *val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_shift""" 4
+.el .IP \f(CWav_shift\fR 4
+.IX Xref "av_shift"
+.IX Item "av_shift"
+Removes one SV from the start of the array, reducing its size by one and
+returning the SV (transferring control of one reference count) to the
+caller. Returns \f(CW&PL_sv_undef\fR if the array is empty.
+.Sp
+Perl equivalent: \f(CW\*(C`shift(@myarray);\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& SV * av_shift(AV *av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_store""" 4
+.el .IP \f(CWav_store\fR 4
+.IX Xref "av_store"
+.IX Item "av_store"
+Stores an SV in an array. The array index is specified as \f(CW\*(C`key\*(C'\fR. The
+return value will be \f(CW\*(C`NULL\*(C'\fR if the operation failed or if the value did not
+need to be actually stored within the array (as in the case of tied
+arrays). Otherwise, it can be dereferenced
+to get the \f(CW\*(C`SV*\*(C'\fR that was stored
+there (= \f(CW\*(C`val\*(C'\fR)).
+.Sp
+Note that the caller is responsible for suitably incrementing the reference
+count of \f(CW\*(C`val\*(C'\fR before the call, and decrementing it if the function
+returned \f(CW\*(C`NULL\*(C'\fR.
+.Sp
+Approximate Perl equivalent: \f(CW\*(C`splice(@myarray, $key, 1, $val)\*(C'\fR.
+.Sp
+See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for
+more information on how to use this function on tied arrays.
+.RS 4
+.Sp
+.Vb 1
+\& SV ** av_store(AV *av, SSize_t key, SV *val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_tindex""" 4
+.el .IP \f(CWav_tindex\fR 4
+.IX Item "av_tindex"
+.PD 0
+.ie n .IP """av_top_index""" 4
+.el .IP \f(CWav_top_index\fR 4
+.IX Xref "av_tindex av_top_index"
+.IX Item "av_top_index"
+.PD
+These behave identically.
+If the array \f(CW\*(C`av\*(C'\fR is empty, these return \-1; otherwise they return the maximum
+value of the indices of all the array elements which are currently defined in
+\&\f(CW\*(C`av\*(C'\fR.
+.Sp
+They process 'get' magic.
+.Sp
+The Perl equivalent for these is \f(CW$#av\fR.
+.Sp
+Use \f(CW"av_count"\fR to get the number of elements in an array.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t av_tindex(AV *av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_undef""" 4
+.el .IP \f(CWav_undef\fR 4
+.IX Xref "av_undef"
+.IX Item "av_undef"
+Undefines the array. The XS equivalent of \f(CWundef(@array)\fR.
+.Sp
+As well as freeing all the elements of the array (like \f(CWav_clear()\fR), this
+also frees the memory used by the av to store its list of scalars.
+.Sp
+See "av_clear" for a note about the array possibly being invalid on
+return.
+.RS 4
+.Sp
+.Vb 1
+\& void av_undef(AV *av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """av_unshift""" 4
+.el .IP \f(CWav_unshift\fR 4
+.IX Xref "av_unshift"
+.IX Item "av_unshift"
+Unshift the given number of \f(CW\*(C`undef\*(C'\fR values onto the beginning of the
+array. The array will grow automatically to accommodate the addition.
+.Sp
+Perl equivalent: \f(CW\*(C`unshift\ @myarray,\ ((undef)\ x\ $num);\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& void av_unshift(AV *av, SSize_t num)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """get_av""" 4
+.el .IP \f(CWget_av\fR 4
+.IX Xref "get_av"
+.IX Item "get_av"
+Returns the AV of the specified Perl global or package array with the given
+name (so it won't work on lexical variables). \f(CW\*(C`flags\*(C'\fR are passed
+to \f(CW\*(C`gv_fetchpv\*(C'\fR. If \f(CW\*(C`GV_ADD\*(C'\fR is set and the
+Perl variable does not exist then it will be created. If \f(CW\*(C`flags\*(C'\fR is zero
+(ignoring \f(CW\*(C`SVf_UTF8\*(C'\fR) and the variable does not exist then \f(CW\*(C`NULL\*(C'\fR is
+returned.
+.Sp
+Perl equivalent: \f(CW\*(C`@{"$name"}\*(C'\fR.
+.Sp
+NOTE: the \f(CWperl_get_av()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& AV * get_av(const char *name, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newAV""" 4
+.el .IP \f(CWnewAV\fR 4
+.IX Item "newAV"
+.PD 0
+.ie n .IP """newAV_alloc_x""" 4
+.el .IP \f(CWnewAV_alloc_x\fR 4
+.IX Item "newAV_alloc_x"
+.ie n .IP """newAV_alloc_xz""" 4
+.el .IP \f(CWnewAV_alloc_xz\fR 4
+.IX Xref "newAV newAV_alloc_x newAV_alloc_xz"
+.IX Item "newAV_alloc_xz"
+.PD
+These all create a new AV, setting the reference count to 1. If you also know
+the initial elements of the array with, see "\f(CW\*(C`av_make\*(C'\fR".
+.Sp
+As background, an array consists of three things:
+.RS 4
+.IP 1. 4
+A data structure containing information about the array as a whole, such as its
+size and reference count.
+.IP 2. 4
+A C language array of pointers to the individual elements. These are treated
+as pointers to SVs, so all must be castable to SV*.
+.IP 3. 4
+The individual elements themselves. These could be, for instance, SVs and/or
+AVs and/or HVs, etc.
+.RE
+.RS 4
+.Sp
+An empty array need only have the first data structure, and all these functions
+create that. They differ in what else they do, as follows:
+.ie n .IP """newAV"" form" 4
+.el .IP "\f(CWnewAV\fR form" 4
+.IX Item "newAV form"
+This does nothing beyond creating the whole-array data structure.
+The Perl equivalent is approximately \f(CW\*(C`my\ @array;\*(C'\fR
+.Sp
+This is useful when the minimum size of the array could be zero (perhaps there
+are likely code paths that will entirely skip using it).
+.Sp
+If the array does get used, the pointers data structure will need to be
+allocated at that time. This will end up being done by "av_extend">,
+either explicitly:
+.Sp
+.Vb 1
+\& av_extend(av, len);
+.Ve
+.Sp
+or implicitly when the first element is stored:
+.Sp
+.Vb 1
+\& (void)av_store(av, 0, sv);
+.Ve
+.Sp
+Unused array elements are typically initialized by \f(CW\*(C`av_extend\*(C'\fR.
+.ie n .IP """newAV_alloc_x"" form" 4
+.el .IP "\f(CWnewAV_alloc_x\fR form" 4
+.IX Item "newAV_alloc_x form"
+This effectively does a \f(CW\*(C`newAV\*(C'\fR followed by also allocating (uninitialized)
+space for the pointers array. This is used when you know ahead of time the
+likely minimum size of the array. It is more efficient to do this than doing a
+plain \f(CW\*(C`newAV\*(C'\fR followed by an \f(CW\*(C`av_extend\*(C'\fR.
+.Sp
+Of course the array can be extended later should it become necessary.
+.Sp
+\&\f(CW\*(C`size\*(C'\fR must be at least 1.
+.ie n .IP """newAV_alloc_xz"" form" 4
+.el .IP "\f(CWnewAV_alloc_xz\fR form" 4
+.IX Item "newAV_alloc_xz form"
+This is \f(CW\*(C`newAV_alloc_x\*(C'\fR, but initializes each pointer in it to NULL. This
+gives added safety to guard against them being read before being set.
+.Sp
+\&\f(CW\*(C`size\*(C'\fR must be at least 1.
+.RE
+.RS 4
+.Sp
+The following examples all result in an array that can fit four elements
+(indexes 0 .. 3):
+.Sp
+.Vb 2
+\& AV *av = newAV();
+\& av_extend(av, 3);
+\&
+\& AV *av = newAV_alloc_x(4);
+\&
+\& AV *av = newAV_alloc_xz(4);
+.Ve
+.Sp
+In contrast, the following examples allocate an array that is only guaranteed
+to fit one element without extending:
+.Sp
+.Vb 2
+\& AV *av = newAV_alloc_x(1);
+\& AV *av = newAV_alloc_xz(1);
+.Ve
+.Sp
+.Vb 3
+\& AV * newAV ()
+\& AV * newAV_alloc_x (SSize_t size)
+\& AV * newAV_alloc_xz(SSize_t size)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newAVav""" 4
+.el .IP \f(CWnewAVav\fR 4
+.IX Xref "newAVav"
+.IX Item "newAVav"
+Creates a new AV and populates it with values copied from an existing AV. The
+new AV will have a reference count of 1, and will contain newly created SVs
+copied from the original SV. The original source will remain unchanged.
+.Sp
+Perl equivalent: \f(CW\*(C`my @new_array = @existing_array;\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& AV * newAVav(AV *oav)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newAVhv""" 4
+.el .IP \f(CWnewAVhv\fR 4
+.IX Xref "newAVhv"
+.IX Item "newAVhv"
+Creates a new AV and populates it with keys and values copied from an existing
+HV. The new AV will have a reference count of 1, and will contain newly
+created SVs copied from the original HV. The original source will remain
+unchanged.
+.Sp
+Perl equivalent: \f(CW\*(C`my @new_array = %existing_hash;\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& AV * newAVhv(HV *ohv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Nullav""" 4
+.el .IP \f(CWNullav\fR 4
+.IX Xref "Nullav"
+.IX Item "Nullav"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`Nullav\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Null AV pointer.
+.Sp
+(deprecated \- use \f(CW\*(C`(AV *)NULL\*(C'\fR instead)
+.SH "Callback Functions"
+.IX Xref "G_METHOD G_METHOD_NAMED G_RETHROW SAVEf_KEEPOLDELEM SAVEf_SETMAGIC"
+.IX Header "Callback Functions"
+.ie n .IP """call_argv""" 4
+.el .IP \f(CWcall_argv\fR 4
+.IX Xref "call_argv"
+.IX Item "call_argv"
+Performs a callback to the specified named and package-scoped Perl subroutine
+with \f(CW\*(C`argv\*(C'\fR (a \f(CW\*(C`NULL\*(C'\fR\-terminated array of strings) as arguments. See
+perlcall.
+.Sp
+Approximate Perl equivalent: \f(CW\*(C`&{"$sub_name"}(@$argv)\*(C'\fR.
+.Sp
+NOTE: the \f(CWperl_call_argv()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 call_argv(const char *sub_name, I32 flags, char **argv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """call_method""" 4
+.el .IP \f(CWcall_method\fR 4
+.IX Xref "call_method"
+.IX Item "call_method"
+Performs a callback to the specified Perl method. The blessed object must
+be on the stack. See perlcall.
+.Sp
+NOTE: the \f(CWperl_call_method()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 call_method(const char *methname, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """call_pv""" 4
+.el .IP \f(CWcall_pv\fR 4
+.IX Xref "call_pv"
+.IX Item "call_pv"
+Performs a callback to the specified Perl sub. See perlcall.
+.Sp
+NOTE: the \f(CWperl_call_pv()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 call_pv(const char *sub_name, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """call_sv""" 4
+.el .IP \f(CWcall_sv\fR 4
+.IX Xref "call_sv"
+.IX Item "call_sv"
+Performs a callback to the Perl sub specified by the SV.
+.Sp
+If neither the \f(CW\*(C`G_METHOD\*(C'\fR nor \f(CW\*(C`G_METHOD_NAMED\*(C'\fR flag is supplied, the
+SV may be any of a CV, a GV, a reference to a CV, a reference to a GV
+or \f(CWSvPV(sv)\fR will be used as the name of the sub to call.
+.Sp
+If the \f(CW\*(C`G_METHOD\*(C'\fR flag is supplied, the SV may be a reference to a CV or
+\&\f(CWSvPV(sv)\fR will be used as the name of the method to call.
+.Sp
+If the \f(CW\*(C`G_METHOD_NAMED\*(C'\fR flag is supplied, \f(CWSvPV(sv)\fR will be used as
+the name of the method to call.
+.Sp
+Some other values are treated specially for internal use and should
+not be depended on.
+.Sp
+See perlcall.
+.Sp
+NOTE: the \f(CWperl_call_sv()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 call_sv(SV *sv, volatile I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """DESTRUCTORFUNC_NOCONTEXT_t""" 4
+.el .IP \f(CWDESTRUCTORFUNC_NOCONTEXT_t\fR 4
+.IX Item "DESTRUCTORFUNC_NOCONTEXT_t"
+Described in perlguts.
+.ie n .IP """DESTRUCTORFUNC_t""" 4
+.el .IP \f(CWDESTRUCTORFUNC_t\fR 4
+.IX Item "DESTRUCTORFUNC_t"
+Described in perlguts.
+.ie n .IP """ENTER""" 4
+.el .IP \f(CWENTER\fR 4
+.IX Xref "ENTER"
+.IX Item "ENTER"
+Opening bracket on a callback. See \f(CW"LEAVE"\fR and perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& ENTER;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ENTER_with_name""" 4
+.el .IP \f(CWENTER_with_name\fR 4
+.IX Xref "ENTER_with_name"
+.IX Item "ENTER_with_name"
+Same as \f(CW"ENTER"\fR, but when debugging is enabled it also associates the
+given literal string with the new scope.
+.RS 4
+.Sp
+.Vb 1
+\& ENTER_with_name("name");
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """eval_pv""" 4
+.el .IP \f(CWeval_pv\fR 4
+.IX Xref "eval_pv"
+.IX Item "eval_pv"
+Tells Perl to \f(CW\*(C`eval\*(C'\fR the given string in scalar context and return an SV* result.
+.Sp
+NOTE: the \f(CWperl_eval_pv()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * eval_pv(const char *p, I32 croak_on_error)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """eval_sv""" 4
+.el .IP \f(CWeval_sv\fR 4
+.IX Xref "eval_sv"
+.IX Item "eval_sv"
+Tells Perl to \f(CW\*(C`eval\*(C'\fR the string in the SV. It supports the same flags
+as \f(CW\*(C`call_sv\*(C'\fR, with the obvious exception of \f(CW\*(C`G_EVAL\*(C'\fR. See perlcall.
+.Sp
+The \f(CW\*(C`G_RETHROW\*(C'\fR flag can be used if you only need \fBeval_sv()\fR to
+execute code specified by a string, but not catch any errors.
+.Sp
+NOTE: the \f(CWperl_eval_sv()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 eval_sv(SV *sv, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """FREETMPS""" 4
+.el .IP \f(CWFREETMPS\fR 4
+.IX Xref "FREETMPS"
+.IX Item "FREETMPS"
+Closing bracket for temporaries on a callback. See \f(CW"SAVETMPS"\fR and
+perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& FREETMPS;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """G_DISCARD""" 4
+.el .IP \f(CWG_DISCARD\fR 4
+.IX Item "G_DISCARD"
+Described in perlcall.
+.ie n .IP """G_EVAL""" 4
+.el .IP \f(CWG_EVAL\fR 4
+.IX Item "G_EVAL"
+Described in perlcall.
+.ie n .IP """GIMME""" 4
+.el .IP \f(CWGIMME\fR 4
+.IX Xref "GIMME"
+.IX Item "GIMME"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`GIMME\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+A backward-compatible version of \f(CW\*(C`GIMME_V\*(C'\fR which can only return
+\&\f(CW\*(C`G_SCALAR\*(C'\fR or \f(CW\*(C`G_LIST\*(C'\fR; in a void context, it returns \f(CW\*(C`G_SCALAR\*(C'\fR.
+Deprecated. Use \f(CW\*(C`GIMME_V\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& U32 GIMME
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """GIMME_V""" 4
+.el .IP \f(CWGIMME_V\fR 4
+.IX Xref "GIMME_V"
+.IX Item "GIMME_V"
+The XSUB-writer's equivalent to Perl's \f(CW\*(C`wantarray\*(C'\fR. Returns \f(CW\*(C`G_VOID\*(C'\fR,
+\&\f(CW\*(C`G_SCALAR\*(C'\fR or \f(CW\*(C`G_LIST\*(C'\fR for void, scalar or list context,
+respectively. See perlcall for a usage example.
+.RS 4
+.Sp
+.Vb 1
+\& U32 GIMME_V
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """G_KEEPERR""" 4
+.el .IP \f(CWG_KEEPERR\fR 4
+.IX Item "G_KEEPERR"
+Described in perlcall.
+.ie n .IP """G_LIST""" 4
+.el .IP \f(CWG_LIST\fR 4
+.IX Item "G_LIST"
+Described in perlcall.
+.ie n .IP """G_NOARGS""" 4
+.el .IP \f(CWG_NOARGS\fR 4
+.IX Item "G_NOARGS"
+Described in perlcall.
+.ie n .IP """G_SCALAR""" 4
+.el .IP \f(CWG_SCALAR\fR 4
+.IX Item "G_SCALAR"
+Described in perlcall.
+.ie n .IP """G_VOID""" 4
+.el .IP \f(CWG_VOID\fR 4
+.IX Item "G_VOID"
+Described in perlcall.
+.ie n .IP """is_lvalue_sub""" 4
+.el .IP \f(CWis_lvalue_sub\fR 4
+.IX Xref "is_lvalue_sub"
+.IX Item "is_lvalue_sub"
+Returns non-zero if the sub calling this function is being called in an lvalue
+context. Returns 0 otherwise.
+.RS 4
+.Sp
+.Vb 1
+\& I32 is_lvalue_sub()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LEAVE""" 4
+.el .IP \f(CWLEAVE\fR 4
+.IX Xref "LEAVE"
+.IX Item "LEAVE"
+Closing bracket on a callback. See \f(CW"ENTER"\fR and perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& LEAVE;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LEAVE_with_name""" 4
+.el .IP \f(CWLEAVE_with_name\fR 4
+.IX Xref "LEAVE_with_name"
+.IX Item "LEAVE_with_name"
+Same as \f(CW"LEAVE"\fR, but when debugging is enabled it first checks that the
+scope has the given name. \f(CW\*(C`name\*(C'\fR must be a literal string.
+.RS 4
+.Sp
+.Vb 1
+\& LEAVE_with_name("name");
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MORTALDESTRUCTOR_SV""" 4
+.el .IP \f(CWMORTALDESTRUCTOR_SV\fR 4
+.IX Item "MORTALDESTRUCTOR_SV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& MORTALDESTRUCTOR_SV(SV *coderef, SV *args)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mortal_destructor_sv""" 4
+.el .IP \f(CWmortal_destructor_sv\fR 4
+.IX Xref "mortal_destructor_sv"
+.IX Item "mortal_destructor_sv"
+This function arranges for either a Perl code reference, or a C function
+reference to be called at the \fBend of the current statement\fR.
+.Sp
+The \f(CW\*(C`coderef\*(C'\fR argument determines the type of function that will be
+called. If it is \f(CWSvROK()\fR it is assumed to be a reference to a CV and
+will arrange for the coderef to be called. If it is not \fBSvROK()\fR then it
+is assumed to be a \f(CWSvIV()\fR which is \f(CWSvIOK()\fR whose value is a pointer
+to a C function of type \f(CW\*(C`DESTRUCTORFUNC_t\*(C'\fR created using \f(CWPTR2INT()\fR.
+Either way the \f(CW\*(C`args\*(C'\fR parameter will be provided to the callback as a
+parameter, although the rules for doing so differ between the Perl and
+C mode. Normally this function is only used directly for the Perl case
+and the wrapper \f(CWmortal_destructor_x()\fR is used for the C function case.
+.Sp
+When operating in Perl callback mode the \f(CW\*(C`args\*(C'\fR parameter may be NULL
+in which case the code reference is called with no arguments, otherwise
+if it is an AV (SvTYPE(args) == SVt_PVAV) then the contents of the AV
+will be used as the arguments to the code reference, and if it is any
+other type then the \f(CW\*(C`args\*(C'\fR SV will be provided as a single argument to
+the code reference.
+.Sp
+When operating in a C callback mode the \f(CW\*(C`args\*(C'\fR parameter will be passed
+directly to the C function as a \f(CW\*(C`void *\*(C'\fR pointer. No additional
+processing of the argument will be peformed, and it is the callers
+responsibility to free the \f(CW\*(C`args\*(C'\fR parameter if necessary.
+.Sp
+Be aware that there is a signficant difference in timing between the
+\&\fIend of the current statement\fR and the \fIend of the current pseudo
+block\fR. If you are looking for a mechanism to trigger a function at the
+end of the \fBcurrent pseudo block\fR you should look at
+\&\f(CWSAVEDESTRUCTORX()\fR instead of this function.
+.RS 4
+.Sp
+.Vb 1
+\& void mortal_destructor_sv(SV *coderef, SV *args)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MORTALDESTRUCTOR_X""" 4
+.el .IP \f(CWMORTALDESTRUCTOR_X\fR 4
+.IX Item "MORTALDESTRUCTOR_X"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& MORTALDESTRUCTOR_X(DESTRUCTORFUNC_t f, SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_errgv""" 4
+.el .IP \f(CWPL_errgv\fR 4
+.IX Item "PL_errgv"
+Described in perlcall.
+.ie n .IP """save_aelem""" 4
+.el .IP \f(CWsave_aelem\fR 4
+.IX Item "save_aelem"
+.PD 0
+.ie n .IP """save_aelem_flags""" 4
+.el .IP \f(CWsave_aelem_flags\fR 4
+.IX Xref "save_aelem save_aelem_flags"
+.IX Item "save_aelem_flags"
+.PD
+These each arrange for the value of the array element \f(CW\*(C`av[idx]\*(C'\fR to be restored
+at the end of the enclosing \fIpseudo-block\fR.
+.Sp
+In \f(CW\*(C`save_aelem\*(C'\fR, the SV at C**sptr> will be replaced by a new \f(CW\*(C`undef\*(C'\fR
+scalar. That scalar will inherit any magic from the original \f(CW**sptr\fR,
+and any 'set' magic will be processed.
+.Sp
+In \f(CW\*(C`save_aelem_flags\*(C'\fR, \f(CW\*(C`SAVEf_KEEPOLDELEM\*(C'\fR being set in \f(CW\*(C`flags\*(C'\fR causes
+the function to forgo all that: the scalar at \f(CW**sptr\fR is untouched.
+If \f(CW\*(C`SAVEf_KEEPOLDELEM\*(C'\fR is not set, the SV at C**sptr> will be replaced by a
+new \f(CW\*(C`undef\*(C'\fR scalar. That scalar will inherit any magic from the original
+\&\f(CW**sptr\fR. Any 'set' magic will be processed if and only if \f(CW\*(C`SAVEf_SETMAGIC\*(C'\fR
+is set in in \f(CW\*(C`flags\*(C'\fR.
+.RS 4
+.Sp
+.Vb 3
+\& void save_aelem (AV *av, SSize_t idx, SV **sptr)
+\& void save_aelem_flags(AV *av, SSize_t idx, SV **sptr,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """save_aptr""" 4
+.el .IP \f(CWsave_aptr\fR 4
+.IX Item "save_aptr"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& void save_aptr(AV **aptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """save_ary""" 4
+.el .IP \f(CWsave_ary\fR 4
+.IX Item "save_ary"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& AV * save_ary(GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEBOOL""" 4
+.el .IP \f(CWSAVEBOOL\fR 4
+.IX Item "SAVEBOOL"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEBOOL(bool i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEDELETE""" 4
+.el .IP \f(CWSAVEDELETE\fR 4
+.IX Item "SAVEDELETE"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEDELETE(HV * hv, char * key, I32 length)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEDESTRUCTOR""" 4
+.el .IP \f(CWSAVEDESTRUCTOR\fR 4
+.IX Item "SAVEDESTRUCTOR"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEDESTRUCTOR(DESTRUCTORFUNC_NOCONTEXT_t f, void *p)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEDESTRUCTOR_X""" 4
+.el .IP \f(CWSAVEDESTRUCTOR_X\fR 4
+.IX Item "SAVEDESTRUCTOR_X"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEDESTRUCTOR_X(DESTRUCTORFUNC_t f, void *p)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEFREEOP""" 4
+.el .IP \f(CWSAVEFREEOP\fR 4
+.IX Item "SAVEFREEOP"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEFREEOP(OP *op)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEFREEPV""" 4
+.el .IP \f(CWSAVEFREEPV\fR 4
+.IX Item "SAVEFREEPV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEFREEPV(char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEFREERCPV""" 4
+.el .IP \f(CWSAVEFREERCPV\fR 4
+.IX Item "SAVEFREERCPV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEFREERCPV(char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEFREESV""" 4
+.el .IP \f(CWSAVEFREESV\fR 4
+.IX Item "SAVEFREESV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEFREESV(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEGENERICSV""" 4
+.el .IP \f(CWSAVEGENERICSV\fR 4
+.IX Item "SAVEGENERICSV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEGENERICSV(char **psv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """save_hash""" 4
+.el .IP \f(CWsave_hash\fR 4
+.IX Item "save_hash"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& HV * save_hash(GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """save_helem""" 4
+.el .IP \f(CWsave_helem\fR 4
+.IX Item "save_helem"
+.PD 0
+.ie n .IP """save_helem_flags""" 4
+.el .IP \f(CWsave_helem_flags\fR 4
+.IX Xref "save_helem save_helem_flags"
+.IX Item "save_helem_flags"
+.PD
+These each arrange for the value of the hash element (in Perlish terms)
+\&\f(CW\*(C`$hv{key}]\*(C'\fR to be restored at the end of the enclosing \fIpseudo-block\fR.
+.Sp
+In \f(CW\*(C`save_helem\*(C'\fR, the SV at C**sptr> will be replaced by a new \f(CW\*(C`undef\*(C'\fR
+scalar. That scalar will inherit any magic from the original \f(CW**sptr\fR,
+and any 'set' magic will be processed.
+.Sp
+In \f(CW\*(C`save_helem_flags\*(C'\fR, \f(CW\*(C`SAVEf_KEEPOLDELEM\*(C'\fR being set in \f(CW\*(C`flags\*(C'\fR causes
+the function to forgo all that: the scalar at \f(CW**sptr\fR is untouched.
+If \f(CW\*(C`SAVEf_KEEPOLDELEM\*(C'\fR is not set, the SV at C**sptr> will be replaced by a
+new \f(CW\*(C`undef\*(C'\fR scalar. That scalar will inherit any magic from the original
+\&\f(CW**sptr\fR. Any 'set' magic will be processed if and only if \f(CW\*(C`SAVEf_SETMAGIC\*(C'\fR
+is set in in \f(CW\*(C`flags\*(C'\fR.
+.RS 4
+.Sp
+.Vb 3
+\& void save_helem (HV *hv, SV *key, SV **sptr)
+\& void save_helem_flags(HV *hv, SV *key, SV **sptr,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """save_hptr""" 4
+.el .IP \f(CWsave_hptr\fR 4
+.IX Item "save_hptr"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& void save_hptr(HV **hptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEINT""" 4
+.el .IP \f(CWSAVEINT\fR 4
+.IX Item "SAVEINT"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEINT(int i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """save_item""" 4
+.el .IP \f(CWsave_item\fR 4
+.IX Item "save_item"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& void save_item(SV *item)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEIV""" 4
+.el .IP \f(CWSAVEIV\fR 4
+.IX Item "SAVEIV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEIV(IV i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEI8""" 4
+.el .IP \f(CWSAVEI8\fR 4
+.IX Item "SAVEI8"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEI8(I8 i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEI16""" 4
+.el .IP \f(CWSAVEI16\fR 4
+.IX Item "SAVEI16"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEI16(I16 i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEI32""" 4
+.el .IP \f(CWSAVEI32\fR 4
+.IX Item "SAVEI32"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEI32(I32 i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVELONG""" 4
+.el .IP \f(CWSAVELONG\fR 4
+.IX Item "SAVELONG"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVELONG(long i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEMORTALIZESV""" 4
+.el .IP \f(CWSAVEMORTALIZESV\fR 4
+.IX Item "SAVEMORTALIZESV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEMORTALIZESV(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEPPTR""" 4
+.el .IP \f(CWSAVEPPTR\fR 4
+.IX Item "SAVEPPTR"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVEPPTR(char * p)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVERCPV""" 4
+.el .IP \f(CWSAVERCPV\fR 4
+.IX Item "SAVERCPV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVERCPV(char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """save_scalar""" 4
+.el .IP \f(CWsave_scalar\fR 4
+.IX Item "save_scalar"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SV * save_scalar(GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVESPTR""" 4
+.el .IP \f(CWSAVESPTR\fR 4
+.IX Item "SAVESPTR"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVESPTR(SV * s)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVESTACK_POS""" 4
+.el .IP \f(CWSAVESTACK_POS\fR 4
+.IX Item "SAVESTACK_POS"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVESTACK_POS()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVESTRLEN""" 4
+.el .IP \f(CWSAVESTRLEN\fR 4
+.IX Item "SAVESTRLEN"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SAVESTRLEN(STRLEN i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """save_svref""" 4
+.el .IP \f(CWsave_svref\fR 4
+.IX Item "save_svref"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SV * save_svref(SV **sptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVETMPS""" 4
+.el .IP \f(CWSAVETMPS\fR 4
+.IX Xref "SAVETMPS"
+.IX Item "SAVETMPS"
+Opening bracket for temporaries on a callback. See \f(CW"FREETMPS"\fR and
+perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& SAVETMPS;
+.Ve
+.RE
+.RS 4
+.RE
+.SH Casting
+.IX Header "Casting"
+.ie n .IP """Atof""" 4
+.el .IP \f(CWAtof\fR 4
+.IX Xref "Atof"
+.IX Item "Atof"
+This is a synonym for "\f(CW\*(C`my_atof\*(C'\fR".
+.RS 4
+.Sp
+.Vb 1
+\& NV Atof(NN const char * const s)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cBOOL""" 4
+.el .IP \f(CWcBOOL\fR 4
+.IX Xref "cBOOL"
+.IX Item "cBOOL"
+Cast-to-bool. When Perl was able to be compiled on pre\-C99 compilers, a
+\&\f(CW\*(C`(bool)\*(C'\fR cast didn't necessarily do the right thing, so this macro was
+created (and made somewhat complicated to work around bugs in old
+compilers). Now, many years later, and C99 is used, this is no longer
+required, but is kept for backwards compatibility.
+.RS 4
+.Sp
+.Vb 1
+\& bool cBOOL(bool expr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """INT2PTR""" 4
+.el .IP \f(CWINT2PTR\fR 4
+.IX Item "INT2PTR"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& type INT2PTR(type, int value)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_V""" 4
+.el .IP \f(CWI_V\fR 4
+.IX Xref "I_V"
+.IX Item "I_V"
+Cast an NV to IV while avoiding undefined C behavior
+.RS 4
+.Sp
+.Vb 1
+\& IV I_V(NV what)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_32""" 4
+.el .IP \f(CWI_32\fR 4
+.IX Xref "I_32"
+.IX Item "I_32"
+Cast an NV to I32 while avoiding undefined C behavior
+.RS 4
+.Sp
+.Vb 1
+\& I32 I_32(NV what)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PTR2IV""" 4
+.el .IP \f(CWPTR2IV\fR 4
+.IX Item "PTR2IV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& IV PTR2IV(void * ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PTR2nat""" 4
+.el .IP \f(CWPTR2nat\fR 4
+.IX Item "PTR2nat"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& IV PTR2nat(void *)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PTR2NV""" 4
+.el .IP \f(CWPTR2NV\fR 4
+.IX Item "PTR2NV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& NV PTR2NV(void * ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PTR2ul""" 4
+.el .IP \f(CWPTR2ul\fR 4
+.IX Item "PTR2ul"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& unsigned long PTR2ul(void *)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PTR2UV""" 4
+.el .IP \f(CWPTR2UV\fR 4
+.IX Item "PTR2UV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& UV PTR2UV(void * ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PTRV""" 4
+.el .IP \f(CWPTRV\fR 4
+.IX Item "PTRV"
+Described in perlguts.
+.ie n .IP """U_V""" 4
+.el .IP \f(CWU_V\fR 4
+.IX Xref "U_V"
+.IX Item "U_V"
+Cast an NV to UV while avoiding undefined C behavior
+.RS 4
+.Sp
+.Vb 1
+\& UV U_V(NV what)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """U_32""" 4
+.el .IP \f(CWU_32\fR 4
+.IX Xref "U_32"
+.IX Item "U_32"
+Cast an NV to U32 while avoiding undefined C behavior
+.RS 4
+.Sp
+.Vb 1
+\& U32 U_32(NV what)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Character case changing"
+.IX Header "Character case changing"
+Perl uses "full" Unicode case mappings. This means that converting a single
+character to another case may result in a sequence of more than one character.
+For example, the uppercase of \f(CW\*(C`ß\*(C'\fR (LATIN SMALL LETTER SHARP S) is the two
+character sequence \f(CW\*(C`SS\*(C'\fR. This presents some complications The lowercase of
+all characters in the range 0..255 is a single character, and thus
+\&\f(CW"toLOWER_L1"\fR is furnished. But, \f(CW\*(C`toUPPER_L1\*(C'\fR can't exist, as it couldn't
+return a valid result for all legal inputs. Instead \f(CW"toUPPER_uvchr"\fR has
+an API that does allow every possible legal result to be returned.) Likewise
+no other function that is crippled by not being able to give the correct
+results for the full range of possible inputs has been implemented here.
+.ie n .IP """toFOLD""" 4
+.el .IP \f(CWtoFOLD\fR 4
+.IX Item "toFOLD"
+.PD 0
+.ie n .IP """toFOLD_A""" 4
+.el .IP \f(CWtoFOLD_A\fR 4
+.IX Item "toFOLD_A"
+.ie n .IP """toFOLD_utf8""" 4
+.el .IP \f(CWtoFOLD_utf8\fR 4
+.IX Item "toFOLD_utf8"
+.ie n .IP """toFOLD_utf8_safe""" 4
+.el .IP \f(CWtoFOLD_utf8_safe\fR 4
+.IX Item "toFOLD_utf8_safe"
+.ie n .IP """toFOLD_uvchr""" 4
+.el .IP \f(CWtoFOLD_uvchr\fR 4
+.IX Xref "toFOLD toFOLD_A toFOLD_utf8 toFOLD_utf8_safe toFOLD_uvchr"
+.IX Item "toFOLD_uvchr"
+.PD
+These all return the foldcase of a character. "foldcase" is an internal case
+for \f(CW\*(C`/i\*(C'\fR pattern matching. If the foldcase of character A and the foldcase of
+character B are the same, they match caselessly; otherwise they don't.
+.Sp
+The differences in the forms are what domain they operate on, and whether the
+input is specified as a code point (those forms with a \f(CW\*(C`cp\*(C'\fR parameter) or as a
+UTF\-8 string (the others). In the latter case, the code point to use is the
+first one in the buffer of UTF\-8 encoded code points, delineated by the
+arguments \f(CW\*(C`p\ ..\ e\ \-\ 1\*(C'\fR.
+.Sp
+\&\f(CW\*(C`toFOLD\*(C'\fR and \f(CW\*(C`toFOLD_A\*(C'\fR are synonyms of each other. They return the
+foldcase of any ASCII-range code point. In this range, the foldcase is
+identical to the lowercase. All other inputs are returned unchanged. Since
+these are macros, the input type may be any integral one, and the output will
+occupy the same number of bits as the input.
+.Sp
+There is no \f(CW\*(C`toFOLD_L1\*(C'\fR nor \f(CW\*(C`toFOLD_LATIN1\*(C'\fR as the foldcase of some code
+points in the 0..255 range is above that range or consists of multiple
+characters. Instead use \f(CW\*(C`toFOLD_uvchr\*(C'\fR.
+.Sp
+\&\f(CW\*(C`toFOLD_uvchr\*(C'\fR returns the foldcase of any Unicode code point. The return
+value is identical to that of \f(CW\*(C`toFOLD_A\*(C'\fR for input code points in the ASCII
+range. The foldcase of the vast majority of Unicode code points is the same
+as the code point itself. For these, and for code points above the legal
+Unicode maximum, this returns the input code point unchanged. It additionally
+stores the UTF\-8 of the result into the buffer beginning at \f(CW\*(C`s\*(C'\fR, and its
+length in bytes into \f(CW*lenp\fR. The caller must have made \f(CW\*(C`s\*(C'\fR large enough to
+contain at least \f(CW\*(C`UTF8_MAXBYTES_CASE+1\*(C'\fR bytes to avoid possible overflow.
+.Sp
+NOTE: the foldcase of a code point may be more than one code point. The
+return value of this function is only the first of these. The entire foldcase
+is returned in \f(CW\*(C`s\*(C'\fR. To determine if the result is more than a single code
+point, you can do something like this:
+.Sp
+.Vb 3
+\& uc = toFOLD_uvchr(cp, s, &len);
+\& if (len > UTF8SKIP(s)) { is multiple code points }
+\& else { is a single code point }
+.Ve
+.Sp
+\&\f(CW\*(C`toFOLD_utf8\*(C'\fR and \f(CW\*(C`toFOLD_utf8_safe\*(C'\fR are synonyms of each other. The only
+difference between these and \f(CW\*(C`toFOLD_uvchr\*(C'\fR is that the source for these is
+encoded in UTF\-8, instead of being a code point. It is passed as a buffer
+starting at \f(CW\*(C`p\*(C'\fR, with \f(CW\*(C`e\*(C'\fR pointing to one byte beyond its end. The \f(CW\*(C`p\*(C'\fR
+buffer may certainly contain more than one code point; but only the first one
+(up through \f(CW\*(C`e\ \-\ 1\*(C'\fR) is examined. If the UTF\-8 for the input character is
+malformed in some way, the program may croak, or the function may return the
+REPLACEMENT CHARACTER, at the discretion of the implementation, and subject to
+change in future releases.
+.RS 4
+.Sp
+.Vb 5
+\& UV toFOLD (UV cp)
+\& UV toFOLD_A (UV cp)
+\& UV toFOLD_utf8 (U8* p, U8* e, U8* s, STRLEN* lenp)
+\& UV toFOLD_utf8_safe(U8* p, U8* e, U8* s, STRLEN* lenp)
+\& UV toFOLD_uvchr (UV cp, U8* s, STRLEN* lenp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """toLOWER""" 4
+.el .IP \f(CWtoLOWER\fR 4
+.IX Item "toLOWER"
+.PD 0
+.ie n .IP """toLOWER_A""" 4
+.el .IP \f(CWtoLOWER_A\fR 4
+.IX Item "toLOWER_A"
+.ie n .IP """toLOWER_LATIN1""" 4
+.el .IP \f(CWtoLOWER_LATIN1\fR 4
+.IX Item "toLOWER_LATIN1"
+.ie n .IP """toLOWER_LC""" 4
+.el .IP \f(CWtoLOWER_LC\fR 4
+.IX Item "toLOWER_LC"
+.ie n .IP """toLOWER_L1""" 4
+.el .IP \f(CWtoLOWER_L1\fR 4
+.IX Item "toLOWER_L1"
+.ie n .IP """toLOWER_utf8""" 4
+.el .IP \f(CWtoLOWER_utf8\fR 4
+.IX Item "toLOWER_utf8"
+.ie n .IP """toLOWER_utf8_safe""" 4
+.el .IP \f(CWtoLOWER_utf8_safe\fR 4
+.IX Item "toLOWER_utf8_safe"
+.ie n .IP """toLOWER_uvchr""" 4
+.el .IP \f(CWtoLOWER_uvchr\fR 4
+.IX Xref "toLOWER toLOWER_A toLOWER_LATIN1 toLOWER_LC toLOWER_L1 toLOWER_utf8 toLOWER_utf8_safe toLOWER_uvchr"
+.IX Item "toLOWER_uvchr"
+.PD
+These all return the lowercase of a character. The differences are what domain
+they operate on, and whether the input is specified as a code point (those
+forms with a \f(CW\*(C`cp\*(C'\fR parameter) or as a UTF\-8 string (the others). In the latter
+case, the code point to use is the first one in the buffer of UTF\-8 encoded
+code points, delineated by the arguments \f(CW\*(C`p\ ..\ e\ \-\ 1\*(C'\fR.
+.Sp
+\&\f(CW\*(C`toLOWER\*(C'\fR and \f(CW\*(C`toLOWER_A\*(C'\fR are synonyms of each other. They return the
+lowercase of any uppercase ASCII-range code point. All other inputs are
+returned unchanged. Since these are macros, the input type may be any integral
+one, and the output will occupy the same number of bits as the input.
+.Sp
+\&\f(CW\*(C`toLOWER_L1\*(C'\fR and \f(CW\*(C`toLOWER_LATIN1\*(C'\fR are synonyms of each other. They behave
+identically as \f(CW\*(C`toLOWER\*(C'\fR for ASCII-range input. But additionally will return
+the lowercase of any uppercase code point in the entire 0..255 range, assuming
+a Latin\-1 encoding (or the EBCDIC equivalent on such platforms).
+.Sp
+\&\f(CW\*(C`toLOWER_LC\*(C'\fR returns the lowercase of the input code point according to the
+rules of the current POSIX locale. Input code points outside the range 0..255
+are returned unchanged.
+.Sp
+\&\f(CW\*(C`toLOWER_uvchr\*(C'\fR returns the lowercase of any Unicode code point. The return
+value is identical to that of \f(CW\*(C`toLOWER_L1\*(C'\fR for input code points in the 0..255
+range. The lowercase of the vast majority of Unicode code points is the same
+as the code point itself. For these, and for code points above the legal
+Unicode maximum, this returns the input code point unchanged. It additionally
+stores the UTF\-8 of the result into the buffer beginning at \f(CW\*(C`s\*(C'\fR, and its
+length in bytes into \f(CW*lenp\fR. The caller must have made \f(CW\*(C`s\*(C'\fR large enough to
+contain at least \f(CW\*(C`UTF8_MAXBYTES_CASE+1\*(C'\fR bytes to avoid possible overflow.
+.Sp
+NOTE: the lowercase of a code point may be more than one code point. The
+return value of this function is only the first of these. The entire lowercase
+is returned in \f(CW\*(C`s\*(C'\fR. To determine if the result is more than a single code
+point, you can do something like this:
+.Sp
+.Vb 3
+\& uc = toLOWER_uvchr(cp, s, &len);
+\& if (len > UTF8SKIP(s)) { is multiple code points }
+\& else { is a single code point }
+.Ve
+.Sp
+\&\f(CW\*(C`toLOWER_utf8\*(C'\fR and \f(CW\*(C`toLOWER_utf8_safe\*(C'\fR are synonyms of each other. The only
+difference between these and \f(CW\*(C`toLOWER_uvchr\*(C'\fR is that the source for these is
+encoded in UTF\-8, instead of being a code point. It is passed as a buffer
+starting at \f(CW\*(C`p\*(C'\fR, with \f(CW\*(C`e\*(C'\fR pointing to one byte beyond its end. The \f(CW\*(C`p\*(C'\fR
+buffer may certainly contain more than one code point; but only the first one
+(up through \f(CW\*(C`e\ \-\ 1\*(C'\fR) is examined. If the UTF\-8 for the input character is
+malformed in some way, the program may croak, or the function may return the
+REPLACEMENT CHARACTER, at the discretion of the implementation, and subject to
+change in future releases.
+.RS 4
+.Sp
+.Vb 8
+\& UV toLOWER (UV cp)
+\& UV toLOWER_A (UV cp)
+\& UV toLOWER_LATIN1 (UV cp)
+\& UV toLOWER_LC (UV cp)
+\& UV toLOWER_L1 (UV cp)
+\& UV toLOWER_utf8 (U8* p, U8* e, U8* s, STRLEN* lenp)
+\& UV toLOWER_utf8_safe(U8* p, U8* e, U8* s, STRLEN* lenp)
+\& UV toLOWER_uvchr (UV cp, U8* s, STRLEN* lenp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """toTITLE""" 4
+.el .IP \f(CWtoTITLE\fR 4
+.IX Item "toTITLE"
+.PD 0
+.ie n .IP """toTITLE_A""" 4
+.el .IP \f(CWtoTITLE_A\fR 4
+.IX Item "toTITLE_A"
+.ie n .IP """toTITLE_utf8""" 4
+.el .IP \f(CWtoTITLE_utf8\fR 4
+.IX Item "toTITLE_utf8"
+.ie n .IP """toTITLE_utf8_safe""" 4
+.el .IP \f(CWtoTITLE_utf8_safe\fR 4
+.IX Item "toTITLE_utf8_safe"
+.ie n .IP """toTITLE_uvchr""" 4
+.el .IP \f(CWtoTITLE_uvchr\fR 4
+.IX Xref "toTITLE toTITLE_A toTITLE_utf8 toTITLE_utf8_safe toTITLE_uvchr"
+.IX Item "toTITLE_uvchr"
+.PD
+These all return the titlecase of a character. The differences are what domain
+they operate on, and whether the input is specified as a code point (those
+forms with a \f(CW\*(C`cp\*(C'\fR parameter) or as a UTF\-8 string (the others). In the latter
+case, the code point to use is the first one in the buffer of UTF\-8 encoded
+code points, delineated by the arguments \f(CW\*(C`p\ ..\ e\ \-\ 1\*(C'\fR.
+.Sp
+\&\f(CW\*(C`toTITLE\*(C'\fR and \f(CW\*(C`toTITLE_A\*(C'\fR are synonyms of each other. They return the
+titlecase of any lowercase ASCII-range code point. In this range, the
+titlecase is identical to the uppercase. All other inputs are returned
+unchanged. Since these are macros, the input type may be any integral one, and
+the output will occupy the same number of bits as the input.
+.Sp
+There is no \f(CW\*(C`toTITLE_L1\*(C'\fR nor \f(CW\*(C`toTITLE_LATIN1\*(C'\fR as the titlecase of some code
+points in the 0..255 range is above that range or consists of multiple
+characters. Instead use \f(CW\*(C`toTITLE_uvchr\*(C'\fR.
+.Sp
+\&\f(CW\*(C`toTITLE_uvchr\*(C'\fR returns the titlecase of any Unicode code point. The return
+value is identical to that of \f(CW\*(C`toTITLE_A\*(C'\fR for input code points in the ASCII
+range. The titlecase of the vast majority of Unicode code points is the same
+as the code point itself. For these, and for code points above the legal
+Unicode maximum, this returns the input code point unchanged. It additionally
+stores the UTF\-8 of the result into the buffer beginning at \f(CW\*(C`s\*(C'\fR, and its
+length in bytes into \f(CW*lenp\fR. The caller must have made \f(CW\*(C`s\*(C'\fR large enough to
+contain at least \f(CW\*(C`UTF8_MAXBYTES_CASE+1\*(C'\fR bytes to avoid possible overflow.
+.Sp
+NOTE: the titlecase of a code point may be more than one code point. The
+return value of this function is only the first of these. The entire titlecase
+is returned in \f(CW\*(C`s\*(C'\fR. To determine if the result is more than a single code
+point, you can do something like this:
+.Sp
+.Vb 3
+\& uc = toTITLE_uvchr(cp, s, &len);
+\& if (len > UTF8SKIP(s)) { is multiple code points }
+\& else { is a single code point }
+.Ve
+.Sp
+\&\f(CW\*(C`toTITLE_utf8\*(C'\fR and \f(CW\*(C`toTITLE_utf8_safe\*(C'\fR are synonyms of each other. The only
+difference between these and \f(CW\*(C`toTITLE_uvchr\*(C'\fR is that the source for these is
+encoded in UTF\-8, instead of being a code point. It is passed as a buffer
+starting at \f(CW\*(C`p\*(C'\fR, with \f(CW\*(C`e\*(C'\fR pointing to one byte beyond its end. The \f(CW\*(C`p\*(C'\fR
+buffer may certainly contain more than one code point; but only the first one
+(up through \f(CW\*(C`e\ \-\ 1\*(C'\fR) is examined. If the UTF\-8 for the input character is
+malformed in some way, the program may croak, or the function may return the
+REPLACEMENT CHARACTER, at the discretion of the implementation, and subject to
+change in future releases.
+.RS 4
+.Sp
+.Vb 5
+\& UV toTITLE (UV cp)
+\& UV toTITLE_A (UV cp)
+\& UV toTITLE_utf8 (U8* p, U8* e, U8* s, STRLEN* lenp)
+\& UV toTITLE_utf8_safe(U8* p, U8* e, U8* s, STRLEN* lenp)
+\& UV toTITLE_uvchr (UV cp, U8* s, STRLEN* lenp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """toUPPER""" 4
+.el .IP \f(CWtoUPPER\fR 4
+.IX Item "toUPPER"
+.PD 0
+.ie n .IP """toUPPER_A""" 4
+.el .IP \f(CWtoUPPER_A\fR 4
+.IX Item "toUPPER_A"
+.ie n .IP """toUPPER_utf8""" 4
+.el .IP \f(CWtoUPPER_utf8\fR 4
+.IX Item "toUPPER_utf8"
+.ie n .IP """toUPPER_utf8_safe""" 4
+.el .IP \f(CWtoUPPER_utf8_safe\fR 4
+.IX Item "toUPPER_utf8_safe"
+.ie n .IP """toUPPER_uvchr""" 4
+.el .IP \f(CWtoUPPER_uvchr\fR 4
+.IX Xref "toUPPER toUPPER_A toUPPER_utf8 toUPPER_utf8_safe toUPPER_uvchr"
+.IX Item "toUPPER_uvchr"
+.PD
+These all return the uppercase of a character. The differences are what domain
+they operate on, and whether the input is specified as a code point (those
+forms with a \f(CW\*(C`cp\*(C'\fR parameter) or as a UTF\-8 string (the others). In the latter
+case, the code point to use is the first one in the buffer of UTF\-8 encoded
+code points, delineated by the arguments \f(CW\*(C`p\ ..\ e\ \-\ 1\*(C'\fR.
+.Sp
+\&\f(CW\*(C`toUPPER\*(C'\fR and \f(CW\*(C`toUPPER_A\*(C'\fR are synonyms of each other. They return the
+uppercase of any lowercase ASCII-range code point. All other inputs are
+returned unchanged. Since these are macros, the input type may be any integral
+one, and the output will occupy the same number of bits as the input.
+.Sp
+There is no \f(CW\*(C`toUPPER_L1\*(C'\fR nor \f(CW\*(C`toUPPER_LATIN1\*(C'\fR as the uppercase of some code
+points in the 0..255 range is above that range or consists of multiple
+characters. Instead use \f(CW\*(C`toUPPER_uvchr\*(C'\fR.
+.Sp
+\&\f(CW\*(C`toUPPER_uvchr\*(C'\fR returns the uppercase of any Unicode code point. The return
+value is identical to that of \f(CW\*(C`toUPPER_A\*(C'\fR for input code points in the ASCII
+range. The uppercase of the vast majority of Unicode code points is the same
+as the code point itself. For these, and for code points above the legal
+Unicode maximum, this returns the input code point unchanged. It additionally
+stores the UTF\-8 of the result into the buffer beginning at \f(CW\*(C`s\*(C'\fR, and its
+length in bytes into \f(CW*lenp\fR. The caller must have made \f(CW\*(C`s\*(C'\fR large enough to
+contain at least \f(CW\*(C`UTF8_MAXBYTES_CASE+1\*(C'\fR bytes to avoid possible overflow.
+.Sp
+NOTE: the uppercase of a code point may be more than one code point. The
+return value of this function is only the first of these. The entire uppercase
+is returned in \f(CW\*(C`s\*(C'\fR. To determine if the result is more than a single code
+point, you can do something like this:
+.Sp
+.Vb 3
+\& uc = toUPPER_uvchr(cp, s, &len);
+\& if (len > UTF8SKIP(s)) { is multiple code points }
+\& else { is a single code point }
+.Ve
+.Sp
+\&\f(CW\*(C`toUPPER_utf8\*(C'\fR and \f(CW\*(C`toUPPER_utf8_safe\*(C'\fR are synonyms of each other. The only
+difference between these and \f(CW\*(C`toUPPER_uvchr\*(C'\fR is that the source for these is
+encoded in UTF\-8, instead of being a code point. It is passed as a buffer
+starting at \f(CW\*(C`p\*(C'\fR, with \f(CW\*(C`e\*(C'\fR pointing to one byte beyond its end. The \f(CW\*(C`p\*(C'\fR
+buffer may certainly contain more than one code point; but only the first one
+(up through \f(CW\*(C`e\ \-\ 1\*(C'\fR) is examined. If the UTF\-8 for the input character is
+malformed in some way, the program may croak, or the function may return the
+REPLACEMENT CHARACTER, at the discretion of the implementation, and subject to
+change in future releases.
+.RS 4
+.Sp
+.Vb 5
+\& UV toUPPER (UV cp)
+\& UV toUPPER_A (UV cp)
+\& UV toUPPER_utf8 (U8* p, U8* e, U8* s, STRLEN* lenp)
+\& UV toUPPER_utf8_safe(U8* p, U8* e, U8* s, STRLEN* lenp)
+\& UV toUPPER_uvchr (UV cp, U8* s, STRLEN* lenp)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Character classification"
+.IX Header "Character classification"
+This section is about functions (really macros) that classify characters
+into types, such as punctuation versus alphabetic, etc. Most of these are
+analogous to regular expression character classes. (See
+"POSIX Character Classes" in perlrecharclass.) There are several variants for
+each class. (Not all macros have all variants; each item below lists the
+ones valid for it.) None are affected by \f(CW\*(C`use bytes\*(C'\fR, and only the ones
+with \f(CW\*(C`LC\*(C'\fR in the name are affected by the current locale.
+.PP
+The base function, e.g., \f(CWisALPHA()\fR, takes any signed or unsigned value,
+treating it as a code point, and returns a boolean as to whether or not the
+character represented by it is (or on non-ASCII platforms, corresponds to) an
+ASCII character in the named class based on platform, Unicode, and Perl rules.
+If the input is a number that doesn't fit in an octet, FALSE is returned.
+.PP
+Variant \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_A\*(C'\fR (e.g., \f(CWisALPHA_A()\fR) is identical to the base function
+with no suffix \f(CW"_A"\fR. This variant is used to emphasize by its name that
+only ASCII-range characters can return TRUE.
+.PP
+Variant \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_L1\*(C'\fR imposes the Latin\-1 (or EBCDIC equivalent) character set
+onto the platform. That is, the code points that are ASCII are unaffected,
+since ASCII is a subset of Latin\-1. But the non-ASCII code points are treated
+as if they are Latin\-1 characters. For example, \f(CWisWORDCHAR_L1()\fR will return
+true when called with the code point 0xDF, which is a word character in both
+ASCII and EBCDIC (though it represents different characters in each).
+If the input is a number that doesn't fit in an octet, FALSE is returned.
+(Perl's documentation uses a colloquial definition of Latin\-1, to include all
+code points below 256.)
+.PP
+Variant \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_uvchr\*(C'\fR is exactly like the \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_L1\*(C'\fR variant, for
+inputs below 256, but if the code point is larger than 255, Unicode rules are
+used to determine if it is in the character class. For example,
+\&\f(CWisWORDCHAR_uvchr(0x100)\fR returns TRUE, since 0x100 is LATIN CAPITAL LETTER A
+WITH MACRON in Unicode, and is a word character.
+.PP
+Variants \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_utf8\*(C'\fR and \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_utf8_safe\*(C'\fR are like \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_uvchr\*(C'\fR,
+but are used for UTF\-8 encoded strings. The two forms are different names for
+the same thing. Each call to one of these classifies the first character of
+the string starting at \f(CW\*(C`p\*(C'\fR. The second parameter, \f(CW\*(C`e\*(C'\fR, points to anywhere in
+the string beyond the first character, up to one byte past the end of the
+entire string. Although both variants are identical, the suffix \f(CW\*(C`_safe\*(C'\fR in
+one name emphasizes that it will not attempt to read beyond \f(CW\*(C`e\ \-\ 1\*(C'\fR,
+provided that the constraint \f(CW\*(C`s\ <\ e\*(C'\fR is true (this is asserted for in
+\&\f(CW\*(C`\-DDEBUGGING\*(C'\fR builds). If the UTF\-8 for the input character is malformed in
+some way, the program may croak, or the function may return FALSE, at the
+discretion of the implementation, and subject to change in future releases.
+.PP
+Variant \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_LC\*(C'\fR is like the \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_A\*(C'\fR and \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_L1\*(C'\fR variants,
+but the result is based on the current locale, which is what \f(CW\*(C`LC\*(C'\fR in the name
+stands for. If Perl can determine that the current locale is a UTF\-8 locale,
+it uses the published Unicode rules; otherwise, it uses the C library function
+that gives the named classification. For example, \f(CWisDIGIT_LC()\fR when not in
+a UTF\-8 locale returns the result of calling \f(CWisdigit()\fR. FALSE is always
+returned if the input won't fit into an octet. On some platforms where the C
+library function is known to be defective, Perl changes its result to follow
+the POSIX standard's rules.
+.PP
+Variant \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_LC_uvchr\*(C'\fR acts exactly like \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_LC\*(C'\fR for inputs less
+than 256, but for larger ones it returns the Unicode classification of the code
+point.
+.PP
+Variants \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_LC_utf8\*(C'\fR and \f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_LC_utf8_safe\*(C'\fR are like
+\&\f(CW\*(C`is\fR\f(CIFOO\fR\f(CW_LC_uvchr\*(C'\fR, but are used for UTF\-8 encoded strings. The two forms
+are different names for the same thing. Each call to one of these classifies
+the first character of the string starting at \f(CW\*(C`p\*(C'\fR. The second parameter,
+\&\f(CW\*(C`e\*(C'\fR, points to anywhere in the string beyond the first character, up to one
+byte past the end of the entire string. Although both variants are identical,
+the suffix \f(CW\*(C`_safe\*(C'\fR in one name emphasizes that it will not attempt to read
+beyond \f(CW\*(C`e\ \-\ 1\*(C'\fR, provided that the constraint \f(CW\*(C`s\ <\ e\*(C'\fR is true (this
+is asserted for in \f(CW\*(C`\-DDEBUGGING\*(C'\fR builds). If the UTF\-8 for the input
+character is malformed in some way, the program may croak, or the function may
+return FALSE, at the discretion of the implementation, and subject to change in
+future releases.
+.ie n .IP """isALNUM""" 4
+.el .IP \f(CWisALNUM\fR 4
+.IX Item "isALNUM"
+.PD 0
+.ie n .IP """isALNUM_A""" 4
+.el .IP \f(CWisALNUM_A\fR 4
+.IX Item "isALNUM_A"
+.ie n .IP """isALNUM_LC""" 4
+.el .IP \f(CWisALNUM_LC\fR 4
+.IX Item "isALNUM_LC"
+.ie n .IP """isALNUM_LC_uvchr""" 4
+.el .IP \f(CWisALNUM_LC_uvchr\fR 4
+.IX Xref "isALNUM isALNUM_A isALNUM_LC isALNUM_LC_uvchr"
+.IX Item "isALNUM_LC_uvchr"
+.PD
+These are each a synonym for their respectively named "\f(CW\*(C`isWORDCHAR\*(C'\fR"
+variant.
+.Sp
+They are provided for backward compatibility, even though a word character
+includes more than the standard C language meaning of alphanumeric.
+To get the C language definition, use the corresponding "\f(CW\*(C`isALPHANUMERIC\*(C'\fR"
+variant.
+.RS 4
+.Sp
+.Vb 1
+\& bool isALNUM(UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isALNUMC""" 4
+.el .IP \f(CWisALNUMC\fR 4
+.IX Item "isALNUMC"
+.PD 0
+.ie n .IP """isALNUMC_A""" 4
+.el .IP \f(CWisALNUMC_A\fR 4
+.IX Item "isALNUMC_A"
+.ie n .IP """isALNUMC_LC""" 4
+.el .IP \f(CWisALNUMC_LC\fR 4
+.IX Item "isALNUMC_LC"
+.ie n .IP """isALNUMC_LC_uvchr""" 4
+.el .IP \f(CWisALNUMC_LC_uvchr\fR 4
+.IX Item "isALNUMC_LC_uvchr"
+.ie n .IP """isALNUMC_L1""" 4
+.el .IP \f(CWisALNUMC_L1\fR 4
+.IX Xref "isALNUMC isALNUMC_A isALNUMC_LC isALNUMC_LC_uvchr isALNUMC_L1"
+.IX Item "isALNUMC_L1"
+.PD
+These are discouraged, backward compatibility macros for "\f(CW\*(C`isALPHANUMERIC\*(C'\fR".
+That is, each returns a boolean indicating whether the specified character is
+one of \f(CW\*(C`[A\-Za\-z0\-9]\*(C'\fR, analogous to \f(CW\*(C`m/[[:alnum:]]/\*(C'\fR.
+.Sp
+The \f(CW\*(C`C\*(C'\fR suffix in the names was meant to indicate that they correspond to the
+C language \f(CWisalnum(3)\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool isALNUMC(UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isALPHA""" 4
+.el .IP \f(CWisALPHA\fR 4
+.IX Item "isALPHA"
+.PD 0
+.ie n .IP """isALPHA_A""" 4
+.el .IP \f(CWisALPHA_A\fR 4
+.IX Item "isALPHA_A"
+.ie n .IP """isALPHA_LC""" 4
+.el .IP \f(CWisALPHA_LC\fR 4
+.IX Item "isALPHA_LC"
+.ie n .IP """isALPHA_LC_utf8_safe""" 4
+.el .IP \f(CWisALPHA_LC_utf8_safe\fR 4
+.IX Item "isALPHA_LC_utf8_safe"
+.ie n .IP """isALPHA_LC_uvchr""" 4
+.el .IP \f(CWisALPHA_LC_uvchr\fR 4
+.IX Item "isALPHA_LC_uvchr"
+.ie n .IP """isALPHA_L1""" 4
+.el .IP \f(CWisALPHA_L1\fR 4
+.IX Item "isALPHA_L1"
+.ie n .IP """isALPHA_utf8""" 4
+.el .IP \f(CWisALPHA_utf8\fR 4
+.IX Item "isALPHA_utf8"
+.ie n .IP """isALPHA_utf8_safe""" 4
+.el .IP \f(CWisALPHA_utf8_safe\fR 4
+.IX Item "isALPHA_utf8_safe"
+.ie n .IP """isALPHA_uvchr""" 4
+.el .IP \f(CWisALPHA_uvchr\fR 4
+.IX Xref "isALPHA isALPHA_A isALPHA_LC isALPHA_LC_utf8_safe isALPHA_LC_uvchr isALPHA_L1 isALPHA_utf8 isALPHA_utf8_safe isALPHA_uvchr"
+.IX Item "isALPHA_uvchr"
+.PD
+Returns a boolean indicating whether the specified input is one of \f(CW\*(C`[A\-Za\-z]\*(C'\fR,
+analogous to \f(CW\*(C`m/[[:alpha:]]/\*(C'\fR.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isALPHA (UV ch)
+\& bool isALPHA_A (UV ch)
+\& bool isALPHA_LC (UV ch)
+\& bool isALPHA_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isALPHA_LC_uvchr (UV ch)
+\& bool isALPHA_L1 (UV ch)
+\& bool isALPHA_utf8 (U8 * s, U8 * end)
+\& bool isALPHA_utf8_safe (U8 * s, U8 * end)
+\& bool isALPHA_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isALPHANUMERIC""" 4
+.el .IP \f(CWisALPHANUMERIC\fR 4
+.IX Item "isALPHANUMERIC"
+.PD 0
+.ie n .IP """isALPHANUMERIC_A""" 4
+.el .IP \f(CWisALPHANUMERIC_A\fR 4
+.IX Item "isALPHANUMERIC_A"
+.ie n .IP """isALPHANUMERIC_LC""" 4
+.el .IP \f(CWisALPHANUMERIC_LC\fR 4
+.IX Item "isALPHANUMERIC_LC"
+.ie n .IP """isALPHANUMERIC_LC_utf8_safe""" 4
+.el .IP \f(CWisALPHANUMERIC_LC_utf8_safe\fR 4
+.IX Item "isALPHANUMERIC_LC_utf8_safe"
+.ie n .IP """isALPHANUMERIC_LC_uvchr""" 4
+.el .IP \f(CWisALPHANUMERIC_LC_uvchr\fR 4
+.IX Item "isALPHANUMERIC_LC_uvchr"
+.ie n .IP """isALPHANUMERIC_L1""" 4
+.el .IP \f(CWisALPHANUMERIC_L1\fR 4
+.IX Item "isALPHANUMERIC_L1"
+.ie n .IP """isALPHANUMERIC_utf8""" 4
+.el .IP \f(CWisALPHANUMERIC_utf8\fR 4
+.IX Item "isALPHANUMERIC_utf8"
+.ie n .IP """isALPHANUMERIC_utf8_safe""" 4
+.el .IP \f(CWisALPHANUMERIC_utf8_safe\fR 4
+.IX Item "isALPHANUMERIC_utf8_safe"
+.ie n .IP """isALPHANUMERIC_uvchr""" 4
+.el .IP \f(CWisALPHANUMERIC_uvchr\fR 4
+.IX Xref "isALPHANUMERIC isALPHANUMERIC_A isALPHANUMERIC_LC isALPHANUMERIC_LC_utf8_safe isALPHANUMERIC_LC_uvchr isALPHANUMERIC_L1 isALPHANUMERIC_utf8 isALPHANUMERIC_utf8_safe isALPHANUMERIC_uvchr"
+.IX Item "isALPHANUMERIC_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is one of
+\&\f(CW\*(C`[A\-Za\-z0\-9]\*(C'\fR, analogous to \f(CW\*(C`m/[[:alnum:]]/\*(C'\fR.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isALPHANUMERIC (UV ch)
+\& bool isALPHANUMERIC_A (UV ch)
+\& bool isALPHANUMERIC_LC (UV ch)
+\& bool isALPHANUMERIC_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isALPHANUMERIC_LC_uvchr (UV ch)
+\& bool isALPHANUMERIC_L1 (UV ch)
+\& bool isALPHANUMERIC_utf8 (U8 * s, U8 * end)
+\& bool isALPHANUMERIC_utf8_safe (U8 * s, U8 * end)
+\& bool isALPHANUMERIC_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isASCII""" 4
+.el .IP \f(CWisASCII\fR 4
+.IX Item "isASCII"
+.PD 0
+.ie n .IP """isASCII_A""" 4
+.el .IP \f(CWisASCII_A\fR 4
+.IX Item "isASCII_A"
+.ie n .IP """isASCII_LC""" 4
+.el .IP \f(CWisASCII_LC\fR 4
+.IX Item "isASCII_LC"
+.ie n .IP """isASCII_LC_utf8_safe""" 4
+.el .IP \f(CWisASCII_LC_utf8_safe\fR 4
+.IX Item "isASCII_LC_utf8_safe"
+.ie n .IP """isASCII_LC_uvchr""" 4
+.el .IP \f(CWisASCII_LC_uvchr\fR 4
+.IX Item "isASCII_LC_uvchr"
+.ie n .IP """isASCII_L1""" 4
+.el .IP \f(CWisASCII_L1\fR 4
+.IX Item "isASCII_L1"
+.ie n .IP """isASCII_utf8""" 4
+.el .IP \f(CWisASCII_utf8\fR 4
+.IX Item "isASCII_utf8"
+.ie n .IP """isASCII_utf8_safe""" 4
+.el .IP \f(CWisASCII_utf8_safe\fR 4
+.IX Item "isASCII_utf8_safe"
+.ie n .IP """isASCII_uvchr""" 4
+.el .IP \f(CWisASCII_uvchr\fR 4
+.IX Xref "isASCII isASCII_A isASCII_LC isASCII_LC_utf8_safe isASCII_LC_uvchr isASCII_L1 isASCII_utf8 isASCII_utf8_safe isASCII_uvchr"
+.IX Item "isASCII_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is one of the 128
+characters in the ASCII character set, analogous to \f(CW\*(C`m/[[:ascii:]]/\*(C'\fR.
+On non-ASCII platforms, it returns TRUE iff this
+character corresponds to an ASCII character. Variants \f(CWisASCII_A()\fR and
+\&\f(CWisASCII_L1()\fR are identical to \f(CWisASCII()\fR.
+See the top of this section for an explanation of
+the variants.
+Note, however, that some platforms do not have the C library routine
+\&\f(CWisascii()\fR. In these cases, the variants whose names contain \f(CW\*(C`LC\*(C'\fR are the
+same as the corresponding ones without.
+.Sp
+Also note, that because all ASCII characters are UTF\-8 invariant (meaning they
+have the exact same representation (always a single byte) whether encoded in
+UTF\-8 or not), \f(CW\*(C`isASCII\*(C'\fR will give the correct results when called with any
+byte in any string encoded or not in UTF\-8. And similarly \f(CW\*(C`isASCII_utf8\*(C'\fR and
+\&\f(CW\*(C`isASCII_utf8_safe\*(C'\fR will work properly on any string encoded or not in UTF\-8.
+.RS 4
+.Sp
+.Vb 9
+\& bool isASCII (UV ch)
+\& bool isASCII_A (UV ch)
+\& bool isASCII_LC (UV ch)
+\& bool isASCII_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isASCII_LC_uvchr (UV ch)
+\& bool isASCII_L1 (UV ch)
+\& bool isASCII_utf8 (U8 * s, U8 * end)
+\& bool isASCII_utf8_safe (U8 * s, U8 * end)
+\& bool isASCII_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isBLANK""" 4
+.el .IP \f(CWisBLANK\fR 4
+.IX Item "isBLANK"
+.PD 0
+.ie n .IP """isBLANK_A""" 4
+.el .IP \f(CWisBLANK_A\fR 4
+.IX Item "isBLANK_A"
+.ie n .IP """isBLANK_LC""" 4
+.el .IP \f(CWisBLANK_LC\fR 4
+.IX Item "isBLANK_LC"
+.ie n .IP """isBLANK_LC_utf8_safe""" 4
+.el .IP \f(CWisBLANK_LC_utf8_safe\fR 4
+.IX Item "isBLANK_LC_utf8_safe"
+.ie n .IP """isBLANK_LC_uvchr""" 4
+.el .IP \f(CWisBLANK_LC_uvchr\fR 4
+.IX Item "isBLANK_LC_uvchr"
+.ie n .IP """isBLANK_L1""" 4
+.el .IP \f(CWisBLANK_L1\fR 4
+.IX Item "isBLANK_L1"
+.ie n .IP """isBLANK_utf8""" 4
+.el .IP \f(CWisBLANK_utf8\fR 4
+.IX Item "isBLANK_utf8"
+.ie n .IP """isBLANK_utf8_safe""" 4
+.el .IP \f(CWisBLANK_utf8_safe\fR 4
+.IX Item "isBLANK_utf8_safe"
+.ie n .IP """isBLANK_uvchr""" 4
+.el .IP \f(CWisBLANK_uvchr\fR 4
+.IX Xref "isBLANK isBLANK_A isBLANK_LC isBLANK_LC_utf8_safe isBLANK_LC_uvchr isBLANK_L1 isBLANK_utf8 isBLANK_utf8_safe isBLANK_uvchr"
+.IX Item "isBLANK_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a
+character considered to be a blank, analogous to \f(CW\*(C`m/[[:blank:]]/\*(C'\fR.
+See the top of this section for an explanation of
+the variants.
+Note,
+however, that some platforms do not have the C library routine
+\&\f(CWisblank()\fR. In these cases, the variants whose names contain \f(CW\*(C`LC\*(C'\fR are
+the same as the corresponding ones without.
+.RS 4
+.Sp
+.Vb 9
+\& bool isBLANK (UV ch)
+\& bool isBLANK_A (UV ch)
+\& bool isBLANK_LC (UV ch)
+\& bool isBLANK_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isBLANK_LC_uvchr (UV ch)
+\& bool isBLANK_L1 (UV ch)
+\& bool isBLANK_utf8 (U8 * s, U8 * end)
+\& bool isBLANK_utf8_safe (U8 * s, U8 * end)
+\& bool isBLANK_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isCNTRL""" 4
+.el .IP \f(CWisCNTRL\fR 4
+.IX Item "isCNTRL"
+.PD 0
+.ie n .IP """isCNTRL_A""" 4
+.el .IP \f(CWisCNTRL_A\fR 4
+.IX Item "isCNTRL_A"
+.ie n .IP """isCNTRL_LC""" 4
+.el .IP \f(CWisCNTRL_LC\fR 4
+.IX Item "isCNTRL_LC"
+.ie n .IP """isCNTRL_LC_utf8_safe""" 4
+.el .IP \f(CWisCNTRL_LC_utf8_safe\fR 4
+.IX Item "isCNTRL_LC_utf8_safe"
+.ie n .IP """isCNTRL_LC_uvchr""" 4
+.el .IP \f(CWisCNTRL_LC_uvchr\fR 4
+.IX Item "isCNTRL_LC_uvchr"
+.ie n .IP """isCNTRL_L1""" 4
+.el .IP \f(CWisCNTRL_L1\fR 4
+.IX Item "isCNTRL_L1"
+.ie n .IP """isCNTRL_utf8""" 4
+.el .IP \f(CWisCNTRL_utf8\fR 4
+.IX Item "isCNTRL_utf8"
+.ie n .IP """isCNTRL_utf8_safe""" 4
+.el .IP \f(CWisCNTRL_utf8_safe\fR 4
+.IX Item "isCNTRL_utf8_safe"
+.ie n .IP """isCNTRL_uvchr""" 4
+.el .IP \f(CWisCNTRL_uvchr\fR 4
+.IX Xref "isCNTRL isCNTRL_A isCNTRL_LC isCNTRL_LC_utf8_safe isCNTRL_LC_uvchr isCNTRL_L1 isCNTRL_utf8 isCNTRL_utf8_safe isCNTRL_uvchr"
+.IX Item "isCNTRL_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a
+control character, analogous to \f(CW\*(C`m/[[:cntrl:]]/\*(C'\fR.
+See the top of this section for an explanation of
+the variants.
+On EBCDIC platforms, you almost always want to use the \f(CW\*(C`isCNTRL_L1\*(C'\fR variant.
+.RS 4
+.Sp
+.Vb 9
+\& bool isCNTRL (UV ch)
+\& bool isCNTRL_A (UV ch)
+\& bool isCNTRL_LC (UV ch)
+\& bool isCNTRL_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isCNTRL_LC_uvchr (UV ch)
+\& bool isCNTRL_L1 (UV ch)
+\& bool isCNTRL_utf8 (U8 * s, U8 * end)
+\& bool isCNTRL_utf8_safe (U8 * s, U8 * end)
+\& bool isCNTRL_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isDIGIT""" 4
+.el .IP \f(CWisDIGIT\fR 4
+.IX Item "isDIGIT"
+.PD 0
+.ie n .IP """isDIGIT_A""" 4
+.el .IP \f(CWisDIGIT_A\fR 4
+.IX Item "isDIGIT_A"
+.ie n .IP """isDIGIT_LC""" 4
+.el .IP \f(CWisDIGIT_LC\fR 4
+.IX Item "isDIGIT_LC"
+.ie n .IP """isDIGIT_LC_utf8_safe""" 4
+.el .IP \f(CWisDIGIT_LC_utf8_safe\fR 4
+.IX Item "isDIGIT_LC_utf8_safe"
+.ie n .IP """isDIGIT_LC_uvchr""" 4
+.el .IP \f(CWisDIGIT_LC_uvchr\fR 4
+.IX Item "isDIGIT_LC_uvchr"
+.ie n .IP """isDIGIT_L1""" 4
+.el .IP \f(CWisDIGIT_L1\fR 4
+.IX Item "isDIGIT_L1"
+.ie n .IP """isDIGIT_utf8""" 4
+.el .IP \f(CWisDIGIT_utf8\fR 4
+.IX Item "isDIGIT_utf8"
+.ie n .IP """isDIGIT_utf8_safe""" 4
+.el .IP \f(CWisDIGIT_utf8_safe\fR 4
+.IX Item "isDIGIT_utf8_safe"
+.ie n .IP """isDIGIT_uvchr""" 4
+.el .IP \f(CWisDIGIT_uvchr\fR 4
+.IX Xref "isDIGIT isDIGIT_A isDIGIT_LC isDIGIT_LC_utf8_safe isDIGIT_LC_uvchr isDIGIT_L1 isDIGIT_utf8 isDIGIT_utf8_safe isDIGIT_uvchr"
+.IX Item "isDIGIT_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a
+digit, analogous to \f(CW\*(C`m/[[:digit:]]/\*(C'\fR.
+Variants \f(CW\*(C`isDIGIT_A\*(C'\fR and \f(CW\*(C`isDIGIT_L1\*(C'\fR are identical to \f(CW\*(C`isDIGIT\*(C'\fR.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isDIGIT (UV ch)
+\& bool isDIGIT_A (UV ch)
+\& bool isDIGIT_LC (UV ch)
+\& bool isDIGIT_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isDIGIT_LC_uvchr (UV ch)
+\& bool isDIGIT_L1 (UV ch)
+\& bool isDIGIT_utf8 (U8 * s, U8 * end)
+\& bool isDIGIT_utf8_safe (U8 * s, U8 * end)
+\& bool isDIGIT_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isGRAPH""" 4
+.el .IP \f(CWisGRAPH\fR 4
+.IX Item "isGRAPH"
+.PD 0
+.ie n .IP """isGRAPH_A""" 4
+.el .IP \f(CWisGRAPH_A\fR 4
+.IX Item "isGRAPH_A"
+.ie n .IP """isGRAPH_LC""" 4
+.el .IP \f(CWisGRAPH_LC\fR 4
+.IX Item "isGRAPH_LC"
+.ie n .IP """isGRAPH_LC_utf8_safe""" 4
+.el .IP \f(CWisGRAPH_LC_utf8_safe\fR 4
+.IX Item "isGRAPH_LC_utf8_safe"
+.ie n .IP """isGRAPH_LC_uvchr""" 4
+.el .IP \f(CWisGRAPH_LC_uvchr\fR 4
+.IX Item "isGRAPH_LC_uvchr"
+.ie n .IP """isGRAPH_L1""" 4
+.el .IP \f(CWisGRAPH_L1\fR 4
+.IX Item "isGRAPH_L1"
+.ie n .IP """isGRAPH_utf8""" 4
+.el .IP \f(CWisGRAPH_utf8\fR 4
+.IX Item "isGRAPH_utf8"
+.ie n .IP """isGRAPH_utf8_safe""" 4
+.el .IP \f(CWisGRAPH_utf8_safe\fR 4
+.IX Item "isGRAPH_utf8_safe"
+.ie n .IP """isGRAPH_uvchr""" 4
+.el .IP \f(CWisGRAPH_uvchr\fR 4
+.IX Xref "isGRAPH isGRAPH_A isGRAPH_LC isGRAPH_LC_utf8_safe isGRAPH_LC_uvchr isGRAPH_L1 isGRAPH_utf8 isGRAPH_utf8_safe isGRAPH_uvchr"
+.IX Item "isGRAPH_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a
+graphic character, analogous to \f(CW\*(C`m/[[:graph:]]/\*(C'\fR.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isGRAPH (UV ch)
+\& bool isGRAPH_A (UV ch)
+\& bool isGRAPH_LC (UV ch)
+\& bool isGRAPH_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isGRAPH_LC_uvchr (UV ch)
+\& bool isGRAPH_L1 (UV ch)
+\& bool isGRAPH_utf8 (U8 * s, U8 * end)
+\& bool isGRAPH_utf8_safe (U8 * s, U8 * end)
+\& bool isGRAPH_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isIDCONT""" 4
+.el .IP \f(CWisIDCONT\fR 4
+.IX Item "isIDCONT"
+.PD 0
+.ie n .IP """isIDCONT_A""" 4
+.el .IP \f(CWisIDCONT_A\fR 4
+.IX Item "isIDCONT_A"
+.ie n .IP """isIDCONT_LC""" 4
+.el .IP \f(CWisIDCONT_LC\fR 4
+.IX Item "isIDCONT_LC"
+.ie n .IP """isIDCONT_LC_utf8_safe""" 4
+.el .IP \f(CWisIDCONT_LC_utf8_safe\fR 4
+.IX Item "isIDCONT_LC_utf8_safe"
+.ie n .IP """isIDCONT_LC_uvchr""" 4
+.el .IP \f(CWisIDCONT_LC_uvchr\fR 4
+.IX Item "isIDCONT_LC_uvchr"
+.ie n .IP """isIDCONT_L1""" 4
+.el .IP \f(CWisIDCONT_L1\fR 4
+.IX Item "isIDCONT_L1"
+.ie n .IP """isIDCONT_utf8""" 4
+.el .IP \f(CWisIDCONT_utf8\fR 4
+.IX Item "isIDCONT_utf8"
+.ie n .IP """isIDCONT_utf8_safe""" 4
+.el .IP \f(CWisIDCONT_utf8_safe\fR 4
+.IX Item "isIDCONT_utf8_safe"
+.ie n .IP """isIDCONT_uvchr""" 4
+.el .IP \f(CWisIDCONT_uvchr\fR 4
+.IX Xref "isIDCONT isIDCONT_A isIDCONT_LC isIDCONT_LC_utf8_safe isIDCONT_LC_uvchr isIDCONT_L1 isIDCONT_utf8 isIDCONT_utf8_safe isIDCONT_uvchr"
+.IX Item "isIDCONT_uvchr"
+.PD
+Returns a boolean indicating whether the specified character can be the
+second or succeeding character of an identifier. This is very close to, but
+not quite the same as the official Unicode property \f(CW\*(C`XID_Continue\*(C'\fR. The
+difference is that this returns true only if the input character also matches
+"isWORDCHAR". See the top of this section for
+an explanation of the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isIDCONT (UV ch)
+\& bool isIDCONT_A (UV ch)
+\& bool isIDCONT_LC (UV ch)
+\& bool isIDCONT_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isIDCONT_LC_uvchr (UV ch)
+\& bool isIDCONT_L1 (UV ch)
+\& bool isIDCONT_utf8 (U8 * s, U8 * end)
+\& bool isIDCONT_utf8_safe (U8 * s, U8 * end)
+\& bool isIDCONT_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isIDFIRST""" 4
+.el .IP \f(CWisIDFIRST\fR 4
+.IX Item "isIDFIRST"
+.PD 0
+.ie n .IP """isIDFIRST_A""" 4
+.el .IP \f(CWisIDFIRST_A\fR 4
+.IX Item "isIDFIRST_A"
+.ie n .IP """isIDFIRST_LC""" 4
+.el .IP \f(CWisIDFIRST_LC\fR 4
+.IX Item "isIDFIRST_LC"
+.ie n .IP """isIDFIRST_LC_utf8_safe""" 4
+.el .IP \f(CWisIDFIRST_LC_utf8_safe\fR 4
+.IX Item "isIDFIRST_LC_utf8_safe"
+.ie n .IP """isIDFIRST_LC_uvchr""" 4
+.el .IP \f(CWisIDFIRST_LC_uvchr\fR 4
+.IX Item "isIDFIRST_LC_uvchr"
+.ie n .IP """isIDFIRST_L1""" 4
+.el .IP \f(CWisIDFIRST_L1\fR 4
+.IX Item "isIDFIRST_L1"
+.ie n .IP """isIDFIRST_utf8""" 4
+.el .IP \f(CWisIDFIRST_utf8\fR 4
+.IX Item "isIDFIRST_utf8"
+.ie n .IP """isIDFIRST_utf8_safe""" 4
+.el .IP \f(CWisIDFIRST_utf8_safe\fR 4
+.IX Item "isIDFIRST_utf8_safe"
+.ie n .IP """isIDFIRST_uvchr""" 4
+.el .IP \f(CWisIDFIRST_uvchr\fR 4
+.IX Xref "isIDFIRST isIDFIRST_A isIDFIRST_LC isIDFIRST_LC_utf8_safe isIDFIRST_LC_uvchr isIDFIRST_L1 isIDFIRST_utf8 isIDFIRST_utf8_safe isIDFIRST_uvchr"
+.IX Item "isIDFIRST_uvchr"
+.PD
+Returns a boolean indicating whether the specified character can be the first
+character of an identifier. This is very close to, but not quite the same as
+the official Unicode property \f(CW\*(C`XID_Start\*(C'\fR. The difference is that this
+returns true only if the input character also matches "isWORDCHAR".
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isIDFIRST (UV ch)
+\& bool isIDFIRST_A (UV ch)
+\& bool isIDFIRST_LC (UV ch)
+\& bool isIDFIRST_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isIDFIRST_LC_uvchr (UV ch)
+\& bool isIDFIRST_L1 (UV ch)
+\& bool isIDFIRST_utf8 (U8 * s, U8 * end)
+\& bool isIDFIRST_utf8_safe (U8 * s, U8 * end)
+\& bool isIDFIRST_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isLOWER""" 4
+.el .IP \f(CWisLOWER\fR 4
+.IX Item "isLOWER"
+.PD 0
+.ie n .IP """isLOWER_A""" 4
+.el .IP \f(CWisLOWER_A\fR 4
+.IX Item "isLOWER_A"
+.ie n .IP """isLOWER_LC""" 4
+.el .IP \f(CWisLOWER_LC\fR 4
+.IX Item "isLOWER_LC"
+.ie n .IP """isLOWER_LC_utf8_safe""" 4
+.el .IP \f(CWisLOWER_LC_utf8_safe\fR 4
+.IX Item "isLOWER_LC_utf8_safe"
+.ie n .IP """isLOWER_LC_uvchr""" 4
+.el .IP \f(CWisLOWER_LC_uvchr\fR 4
+.IX Item "isLOWER_LC_uvchr"
+.ie n .IP """isLOWER_L1""" 4
+.el .IP \f(CWisLOWER_L1\fR 4
+.IX Item "isLOWER_L1"
+.ie n .IP """isLOWER_utf8""" 4
+.el .IP \f(CWisLOWER_utf8\fR 4
+.IX Item "isLOWER_utf8"
+.ie n .IP """isLOWER_utf8_safe""" 4
+.el .IP \f(CWisLOWER_utf8_safe\fR 4
+.IX Item "isLOWER_utf8_safe"
+.ie n .IP """isLOWER_uvchr""" 4
+.el .IP \f(CWisLOWER_uvchr\fR 4
+.IX Xref "isLOWER isLOWER_A isLOWER_LC isLOWER_LC_utf8_safe isLOWER_LC_uvchr isLOWER_L1 isLOWER_utf8 isLOWER_utf8_safe isLOWER_uvchr"
+.IX Item "isLOWER_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a
+lowercase character, analogous to \f(CW\*(C`m/[[:lower:]]/\*(C'\fR.
+See the top of this section for an explanation of
+the variants
+.RS 4
+.Sp
+.Vb 9
+\& bool isLOWER (UV ch)
+\& bool isLOWER_A (UV ch)
+\& bool isLOWER_LC (UV ch)
+\& bool isLOWER_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isLOWER_LC_uvchr (UV ch)
+\& bool isLOWER_L1 (UV ch)
+\& bool isLOWER_utf8 (U8 * s, U8 * end)
+\& bool isLOWER_utf8_safe (U8 * s, U8 * end)
+\& bool isLOWER_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isOCTAL""" 4
+.el .IP \f(CWisOCTAL\fR 4
+.IX Item "isOCTAL"
+.PD 0
+.ie n .IP """isOCTAL_A""" 4
+.el .IP \f(CWisOCTAL_A\fR 4
+.IX Item "isOCTAL_A"
+.ie n .IP """isOCTAL_L1""" 4
+.el .IP \f(CWisOCTAL_L1\fR 4
+.IX Xref "isOCTAL isOCTAL_A isOCTAL_L1"
+.IX Item "isOCTAL_L1"
+.PD
+Returns a boolean indicating whether the specified character is an
+octal digit, [0\-7].
+The only two variants are \f(CW\*(C`isOCTAL_A\*(C'\fR and \f(CW\*(C`isOCTAL_L1\*(C'\fR; each is identical to
+\&\f(CW\*(C`isOCTAL\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool isOCTAL(UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isPRINT""" 4
+.el .IP \f(CWisPRINT\fR 4
+.IX Item "isPRINT"
+.PD 0
+.ie n .IP """isPRINT_A""" 4
+.el .IP \f(CWisPRINT_A\fR 4
+.IX Item "isPRINT_A"
+.ie n .IP """isPRINT_LC""" 4
+.el .IP \f(CWisPRINT_LC\fR 4
+.IX Item "isPRINT_LC"
+.ie n .IP """isPRINT_LC_utf8_safe""" 4
+.el .IP \f(CWisPRINT_LC_utf8_safe\fR 4
+.IX Item "isPRINT_LC_utf8_safe"
+.ie n .IP """isPRINT_LC_uvchr""" 4
+.el .IP \f(CWisPRINT_LC_uvchr\fR 4
+.IX Item "isPRINT_LC_uvchr"
+.ie n .IP """isPRINT_L1""" 4
+.el .IP \f(CWisPRINT_L1\fR 4
+.IX Item "isPRINT_L1"
+.ie n .IP """isPRINT_utf8""" 4
+.el .IP \f(CWisPRINT_utf8\fR 4
+.IX Item "isPRINT_utf8"
+.ie n .IP """isPRINT_utf8_safe""" 4
+.el .IP \f(CWisPRINT_utf8_safe\fR 4
+.IX Item "isPRINT_utf8_safe"
+.ie n .IP """isPRINT_uvchr""" 4
+.el .IP \f(CWisPRINT_uvchr\fR 4
+.IX Xref "isPRINT isPRINT_A isPRINT_LC isPRINT_LC_utf8_safe isPRINT_LC_uvchr isPRINT_L1 isPRINT_utf8 isPRINT_utf8_safe isPRINT_uvchr"
+.IX Item "isPRINT_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a
+printable character, analogous to \f(CW\*(C`m/[[:print:]]/\*(C'\fR.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isPRINT (UV ch)
+\& bool isPRINT_A (UV ch)
+\& bool isPRINT_LC (UV ch)
+\& bool isPRINT_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isPRINT_LC_uvchr (UV ch)
+\& bool isPRINT_L1 (UV ch)
+\& bool isPRINT_utf8 (U8 * s, U8 * end)
+\& bool isPRINT_utf8_safe (U8 * s, U8 * end)
+\& bool isPRINT_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isPSXSPC""" 4
+.el .IP \f(CWisPSXSPC\fR 4
+.IX Item "isPSXSPC"
+.PD 0
+.ie n .IP """isPSXSPC_A""" 4
+.el .IP \f(CWisPSXSPC_A\fR 4
+.IX Item "isPSXSPC_A"
+.ie n .IP """isPSXSPC_LC""" 4
+.el .IP \f(CWisPSXSPC_LC\fR 4
+.IX Item "isPSXSPC_LC"
+.ie n .IP """isPSXSPC_LC_utf8_safe""" 4
+.el .IP \f(CWisPSXSPC_LC_utf8_safe\fR 4
+.IX Item "isPSXSPC_LC_utf8_safe"
+.ie n .IP """isPSXSPC_LC_uvchr""" 4
+.el .IP \f(CWisPSXSPC_LC_uvchr\fR 4
+.IX Item "isPSXSPC_LC_uvchr"
+.ie n .IP """isPSXSPC_L1""" 4
+.el .IP \f(CWisPSXSPC_L1\fR 4
+.IX Item "isPSXSPC_L1"
+.ie n .IP """isPSXSPC_utf8""" 4
+.el .IP \f(CWisPSXSPC_utf8\fR 4
+.IX Item "isPSXSPC_utf8"
+.ie n .IP """isPSXSPC_utf8_safe""" 4
+.el .IP \f(CWisPSXSPC_utf8_safe\fR 4
+.IX Item "isPSXSPC_utf8_safe"
+.ie n .IP """isPSXSPC_uvchr""" 4
+.el .IP \f(CWisPSXSPC_uvchr\fR 4
+.IX Xref "isPSXSPC isPSXSPC_A isPSXSPC_LC isPSXSPC_LC_utf8_safe isPSXSPC_LC_uvchr isPSXSPC_L1 isPSXSPC_utf8 isPSXSPC_utf8_safe isPSXSPC_uvchr"
+.IX Item "isPSXSPC_uvchr"
+.PD
+(short for Posix Space)
+Starting in 5.18, this is identical in all its forms to the
+corresponding \f(CWisSPACE()\fR macros.
+The locale forms of this macro are identical to their corresponding
+\&\f(CWisSPACE()\fR forms in all Perl releases. In releases prior to 5.18, the
+non-locale forms differ from their \f(CWisSPACE()\fR forms only in that the
+\&\f(CWisSPACE()\fR forms don't match a Vertical Tab, and the \f(CWisPSXSPC()\fR forms do.
+Otherwise they are identical. Thus this macro is analogous to what
+\&\f(CW\*(C`m/[[:space:]]/\*(C'\fR matches in a regular expression.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isPSXSPC (UV ch)
+\& bool isPSXSPC_A (UV ch)
+\& bool isPSXSPC_LC (UV ch)
+\& bool isPSXSPC_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isPSXSPC_LC_uvchr (UV ch)
+\& bool isPSXSPC_L1 (UV ch)
+\& bool isPSXSPC_utf8 (U8 * s, U8 * end)
+\& bool isPSXSPC_utf8_safe (U8 * s, U8 * end)
+\& bool isPSXSPC_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isPUNCT""" 4
+.el .IP \f(CWisPUNCT\fR 4
+.IX Item "isPUNCT"
+.PD 0
+.ie n .IP """isPUNCT_A""" 4
+.el .IP \f(CWisPUNCT_A\fR 4
+.IX Item "isPUNCT_A"
+.ie n .IP """isPUNCT_LC""" 4
+.el .IP \f(CWisPUNCT_LC\fR 4
+.IX Item "isPUNCT_LC"
+.ie n .IP """isPUNCT_LC_utf8_safe""" 4
+.el .IP \f(CWisPUNCT_LC_utf8_safe\fR 4
+.IX Item "isPUNCT_LC_utf8_safe"
+.ie n .IP """isPUNCT_LC_uvchr""" 4
+.el .IP \f(CWisPUNCT_LC_uvchr\fR 4
+.IX Item "isPUNCT_LC_uvchr"
+.ie n .IP """isPUNCT_L1""" 4
+.el .IP \f(CWisPUNCT_L1\fR 4
+.IX Item "isPUNCT_L1"
+.ie n .IP """isPUNCT_utf8""" 4
+.el .IP \f(CWisPUNCT_utf8\fR 4
+.IX Item "isPUNCT_utf8"
+.ie n .IP """isPUNCT_utf8_safe""" 4
+.el .IP \f(CWisPUNCT_utf8_safe\fR 4
+.IX Item "isPUNCT_utf8_safe"
+.ie n .IP """isPUNCT_uvchr""" 4
+.el .IP \f(CWisPUNCT_uvchr\fR 4
+.IX Xref "isPUNCT isPUNCT_A isPUNCT_LC isPUNCT_LC_utf8_safe isPUNCT_LC_uvchr isPUNCT_L1 isPUNCT_utf8 isPUNCT_utf8_safe isPUNCT_uvchr"
+.IX Item "isPUNCT_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a
+punctuation character, analogous to \f(CW\*(C`m/[[:punct:]]/\*(C'\fR.
+Note that the definition of what is punctuation isn't as
+straightforward as one might desire. See "POSIX Character
+Classes" in perlrecharclass for details.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isPUNCT (UV ch)
+\& bool isPUNCT_A (UV ch)
+\& bool isPUNCT_LC (UV ch)
+\& bool isPUNCT_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isPUNCT_LC_uvchr (UV ch)
+\& bool isPUNCT_L1 (UV ch)
+\& bool isPUNCT_utf8 (U8 * s, U8 * end)
+\& bool isPUNCT_utf8_safe (U8 * s, U8 * end)
+\& bool isPUNCT_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isSPACE""" 4
+.el .IP \f(CWisSPACE\fR 4
+.IX Item "isSPACE"
+.PD 0
+.ie n .IP """isSPACE_A""" 4
+.el .IP \f(CWisSPACE_A\fR 4
+.IX Item "isSPACE_A"
+.ie n .IP """isSPACE_LC""" 4
+.el .IP \f(CWisSPACE_LC\fR 4
+.IX Item "isSPACE_LC"
+.ie n .IP """isSPACE_LC_utf8_safe""" 4
+.el .IP \f(CWisSPACE_LC_utf8_safe\fR 4
+.IX Item "isSPACE_LC_utf8_safe"
+.ie n .IP """isSPACE_LC_uvchr""" 4
+.el .IP \f(CWisSPACE_LC_uvchr\fR 4
+.IX Item "isSPACE_LC_uvchr"
+.ie n .IP """isSPACE_L1""" 4
+.el .IP \f(CWisSPACE_L1\fR 4
+.IX Item "isSPACE_L1"
+.ie n .IP """isSPACE_utf8""" 4
+.el .IP \f(CWisSPACE_utf8\fR 4
+.IX Item "isSPACE_utf8"
+.ie n .IP """isSPACE_utf8_safe""" 4
+.el .IP \f(CWisSPACE_utf8_safe\fR 4
+.IX Item "isSPACE_utf8_safe"
+.ie n .IP """isSPACE_uvchr""" 4
+.el .IP \f(CWisSPACE_uvchr\fR 4
+.IX Xref "isSPACE isSPACE_A isSPACE_LC isSPACE_LC_utf8_safe isSPACE_LC_uvchr isSPACE_L1 isSPACE_utf8 isSPACE_utf8_safe isSPACE_uvchr"
+.IX Item "isSPACE_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a
+whitespace character. This is analogous
+to what \f(CW\*(C`m/\es/\*(C'\fR matches in a regular expression. Starting in Perl 5.18
+this also matches what \f(CW\*(C`m/[[:space:]]/\*(C'\fR does. Prior to 5.18, only the
+locale forms of this macro (the ones with \f(CW\*(C`LC\*(C'\fR in their names) matched
+precisely what \f(CW\*(C`m/[[:space:]]/\*(C'\fR does. In those releases, the only difference,
+in the non-locale variants, was that \f(CWisSPACE()\fR did not match a vertical tab.
+(See "isPSXSPC" for a macro that matches a vertical tab in all releases.)
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isSPACE (UV ch)
+\& bool isSPACE_A (UV ch)
+\& bool isSPACE_LC (UV ch)
+\& bool isSPACE_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isSPACE_LC_uvchr (UV ch)
+\& bool isSPACE_L1 (UV ch)
+\& bool isSPACE_utf8 (U8 * s, U8 * end)
+\& bool isSPACE_utf8_safe (U8 * s, U8 * end)
+\& bool isSPACE_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isUPPER""" 4
+.el .IP \f(CWisUPPER\fR 4
+.IX Item "isUPPER"
+.PD 0
+.ie n .IP """isUPPER_A""" 4
+.el .IP \f(CWisUPPER_A\fR 4
+.IX Item "isUPPER_A"
+.ie n .IP """isUPPER_LC""" 4
+.el .IP \f(CWisUPPER_LC\fR 4
+.IX Item "isUPPER_LC"
+.ie n .IP """isUPPER_LC_utf8_safe""" 4
+.el .IP \f(CWisUPPER_LC_utf8_safe\fR 4
+.IX Item "isUPPER_LC_utf8_safe"
+.ie n .IP """isUPPER_LC_uvchr""" 4
+.el .IP \f(CWisUPPER_LC_uvchr\fR 4
+.IX Item "isUPPER_LC_uvchr"
+.ie n .IP """isUPPER_L1""" 4
+.el .IP \f(CWisUPPER_L1\fR 4
+.IX Item "isUPPER_L1"
+.ie n .IP """isUPPER_utf8""" 4
+.el .IP \f(CWisUPPER_utf8\fR 4
+.IX Item "isUPPER_utf8"
+.ie n .IP """isUPPER_utf8_safe""" 4
+.el .IP \f(CWisUPPER_utf8_safe\fR 4
+.IX Item "isUPPER_utf8_safe"
+.ie n .IP """isUPPER_uvchr""" 4
+.el .IP \f(CWisUPPER_uvchr\fR 4
+.IX Xref "isUPPER isUPPER_A isUPPER_LC isUPPER_LC_utf8_safe isUPPER_LC_uvchr isUPPER_L1 isUPPER_utf8 isUPPER_utf8_safe isUPPER_uvchr"
+.IX Item "isUPPER_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is an
+uppercase character, analogous to \f(CW\*(C`m/[[:upper:]]/\*(C'\fR.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isUPPER (UV ch)
+\& bool isUPPER_A (UV ch)
+\& bool isUPPER_LC (UV ch)
+\& bool isUPPER_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isUPPER_LC_uvchr (UV ch)
+\& bool isUPPER_L1 (UV ch)
+\& bool isUPPER_utf8 (U8 * s, U8 * end)
+\& bool isUPPER_utf8_safe (U8 * s, U8 * end)
+\& bool isUPPER_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isWORDCHAR""" 4
+.el .IP \f(CWisWORDCHAR\fR 4
+.IX Item "isWORDCHAR"
+.PD 0
+.ie n .IP """isWORDCHAR_A""" 4
+.el .IP \f(CWisWORDCHAR_A\fR 4
+.IX Item "isWORDCHAR_A"
+.ie n .IP """isWORDCHAR_LC""" 4
+.el .IP \f(CWisWORDCHAR_LC\fR 4
+.IX Item "isWORDCHAR_LC"
+.ie n .IP """isWORDCHAR_LC_utf8_safe""" 4
+.el .IP \f(CWisWORDCHAR_LC_utf8_safe\fR 4
+.IX Item "isWORDCHAR_LC_utf8_safe"
+.ie n .IP """isWORDCHAR_LC_uvchr""" 4
+.el .IP \f(CWisWORDCHAR_LC_uvchr\fR 4
+.IX Item "isWORDCHAR_LC_uvchr"
+.ie n .IP """isWORDCHAR_L1""" 4
+.el .IP \f(CWisWORDCHAR_L1\fR 4
+.IX Item "isWORDCHAR_L1"
+.ie n .IP """isWORDCHAR_utf8""" 4
+.el .IP \f(CWisWORDCHAR_utf8\fR 4
+.IX Item "isWORDCHAR_utf8"
+.ie n .IP """isWORDCHAR_utf8_safe""" 4
+.el .IP \f(CWisWORDCHAR_utf8_safe\fR 4
+.IX Item "isWORDCHAR_utf8_safe"
+.ie n .IP """isWORDCHAR_uvchr""" 4
+.el .IP \f(CWisWORDCHAR_uvchr\fR 4
+.IX Xref "isWORDCHAR isWORDCHAR_A isWORDCHAR_LC isWORDCHAR_LC_utf8_safe isWORDCHAR_LC_uvchr isWORDCHAR_L1 isWORDCHAR_utf8 isWORDCHAR_utf8_safe isWORDCHAR_uvchr"
+.IX Item "isWORDCHAR_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a character
+that is a word character, analogous to what \f(CW\*(C`m/\ew/\*(C'\fR and \f(CW\*(C`m/[[:word:]]/\*(C'\fR match
+in a regular expression. A word character is an alphabetic character, a
+decimal digit, a connecting punctuation character (such as an underscore), or
+a "mark" character that attaches to one of those (like some sort of accent).
+.Sp
+See the top of this section for an explanation of
+the variants.
+.Sp
+\&\f(CW\*(C`isWORDCHAR_A\*(C'\fR, \f(CW\*(C`isWORDCHAR_L1\*(C'\fR, \f(CW\*(C`isWORDCHAR_uvchr\*(C'\fR,
+\&\f(CW\*(C`isWORDCHAR_LC\*(C'\fR, \f(CW\*(C`isWORDCHAR_LC_uvchr\*(C'\fR, \f(CW\*(C`isWORDCHAR_LC_utf8\*(C'\fR, and
+\&\f(CW\*(C`isWORDCHAR_LC_utf8_safe\*(C'\fR are also as described there, but additionally
+include the platform's native underscore.
+.RS 4
+.Sp
+.Vb 9
+\& bool isWORDCHAR (UV ch)
+\& bool isWORDCHAR_A (UV ch)
+\& bool isWORDCHAR_LC (UV ch)
+\& bool isWORDCHAR_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isWORDCHAR_LC_uvchr (UV ch)
+\& bool isWORDCHAR_L1 (UV ch)
+\& bool isWORDCHAR_utf8 (U8 * s, U8 * end)
+\& bool isWORDCHAR_utf8_safe (U8 * s, U8 * end)
+\& bool isWORDCHAR_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isXDIGIT""" 4
+.el .IP \f(CWisXDIGIT\fR 4
+.IX Item "isXDIGIT"
+.PD 0
+.ie n .IP """isXDIGIT_A""" 4
+.el .IP \f(CWisXDIGIT_A\fR 4
+.IX Item "isXDIGIT_A"
+.ie n .IP """isXDIGIT_LC""" 4
+.el .IP \f(CWisXDIGIT_LC\fR 4
+.IX Item "isXDIGIT_LC"
+.ie n .IP """isXDIGIT_LC_utf8_safe""" 4
+.el .IP \f(CWisXDIGIT_LC_utf8_safe\fR 4
+.IX Item "isXDIGIT_LC_utf8_safe"
+.ie n .IP """isXDIGIT_LC_uvchr""" 4
+.el .IP \f(CWisXDIGIT_LC_uvchr\fR 4
+.IX Item "isXDIGIT_LC_uvchr"
+.ie n .IP """isXDIGIT_L1""" 4
+.el .IP \f(CWisXDIGIT_L1\fR 4
+.IX Item "isXDIGIT_L1"
+.ie n .IP """isXDIGIT_utf8""" 4
+.el .IP \f(CWisXDIGIT_utf8\fR 4
+.IX Item "isXDIGIT_utf8"
+.ie n .IP """isXDIGIT_utf8_safe""" 4
+.el .IP \f(CWisXDIGIT_utf8_safe\fR 4
+.IX Item "isXDIGIT_utf8_safe"
+.ie n .IP """isXDIGIT_uvchr""" 4
+.el .IP \f(CWisXDIGIT_uvchr\fR 4
+.IX Xref "isXDIGIT isXDIGIT_A isXDIGIT_LC isXDIGIT_LC_utf8_safe isXDIGIT_LC_uvchr isXDIGIT_L1 isXDIGIT_utf8 isXDIGIT_utf8_safe isXDIGIT_uvchr"
+.IX Item "isXDIGIT_uvchr"
+.PD
+Returns a boolean indicating whether the specified character is a hexadecimal
+digit. In the ASCII range these are \f(CW\*(C`[0\-9A\-Fa\-f]\*(C'\fR. Variants \f(CWisXDIGIT_A()\fR
+and \f(CWisXDIGIT_L1()\fR are identical to \f(CWisXDIGIT()\fR.
+See the top of this section for an explanation of
+the variants.
+.RS 4
+.Sp
+.Vb 9
+\& bool isXDIGIT (UV ch)
+\& bool isXDIGIT_A (UV ch)
+\& bool isXDIGIT_LC (UV ch)
+\& bool isXDIGIT_LC_utf8_safe(U8 * s, U8 *end)
+\& bool isXDIGIT_LC_uvchr (UV ch)
+\& bool isXDIGIT_L1 (UV ch)
+\& bool isXDIGIT_utf8 (U8 * s, U8 * end)
+\& bool isXDIGIT_utf8_safe (U8 * s, U8 * end)
+\& bool isXDIGIT_uvchr (UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Compiler and Preprocessor information"
+.IX Header "Compiler and Preprocessor information"
+.ie n .IP """CPPLAST""" 4
+.el .IP \f(CWCPPLAST\fR 4
+.IX Xref "CPPLAST"
+.IX Item "CPPLAST"
+This symbol is intended to be used along with \f(CW\*(C`CPPRUN\*(C'\fR in the same manner
+symbol \f(CW\*(C`CPPMINUS\*(C'\fR is used with \f(CW\*(C`CPPSTDIN\*(C'\fR. It contains either "\-" or "".
+.ie n .IP """CPPMINUS""" 4
+.el .IP \f(CWCPPMINUS\fR 4
+.IX Xref "CPPMINUS"
+.IX Item "CPPMINUS"
+This symbol contains the second part of the string which will invoke
+the C preprocessor on the standard input and produce to standard
+output. This symbol will have the value "\-" if \f(CW\*(C`CPPSTDIN\*(C'\fR needs a minus
+to specify standard input, otherwise the value is "".
+.ie n .IP """CPPRUN""" 4
+.el .IP \f(CWCPPRUN\fR 4
+.IX Xref "CPPRUN"
+.IX Item "CPPRUN"
+This symbol contains the string which will invoke a C preprocessor on
+the standard input and produce to standard output. It needs to end
+with \f(CW\*(C`CPPLAST\*(C'\fR, after all other preprocessor flags have been specified.
+The main difference with \f(CW\*(C`CPPSTDIN\*(C'\fR is that this program will never be a
+pointer to a shell wrapper, i.e. it will be empty if no preprocessor is
+available directly to the user. Note that it may well be different from
+the preprocessor used to compile the C program.
+.ie n .IP """CPPSTDIN""" 4
+.el .IP \f(CWCPPSTDIN\fR 4
+.IX Xref "CPPSTDIN"
+.IX Item "CPPSTDIN"
+This symbol contains the first part of the string which will invoke
+the C preprocessor on the standard input and produce to standard
+output. Typical value of "cc \-E" or "\fI/lib/cpp\fR", but it can also
+call a wrapper. See \f(CW"CPPRUN"\fR.
+.ie n .IP """HASATTRIBUTE_ALWAYS_INLINE""" 4
+.el .IP \f(CWHASATTRIBUTE_ALWAYS_INLINE\fR 4
+.IX Xref "HASATTRIBUTE_ALWAYS_INLINE"
+.IX Item "HASATTRIBUTE_ALWAYS_INLINE"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for functions that should always be
+inlined.
+.ie n .IP """HASATTRIBUTE_DEPRECATED""" 4
+.el .IP \f(CWHASATTRIBUTE_DEPRECATED\fR 4
+.IX Xref "HASATTRIBUTE_DEPRECATED"
+.IX Item "HASATTRIBUTE_DEPRECATED"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for marking deprecated \f(CW\*(C`APIs\*(C'\fR
+.ie n .IP """HASATTRIBUTE_FORMAT""" 4
+.el .IP \f(CWHASATTRIBUTE_FORMAT\fR 4
+.IX Xref "HASATTRIBUTE_FORMAT"
+.IX Item "HASATTRIBUTE_FORMAT"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for checking printf-style formats
+.ie n .IP """HASATTRIBUTE_NONNULL""" 4
+.el .IP \f(CWHASATTRIBUTE_NONNULL\fR 4
+.IX Xref "HASATTRIBUTE_NONNULL"
+.IX Item "HASATTRIBUTE_NONNULL"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for nonnull function parms.
+.ie n .IP """HASATTRIBUTE_NORETURN""" 4
+.el .IP \f(CWHASATTRIBUTE_NORETURN\fR 4
+.IX Xref "HASATTRIBUTE_NORETURN"
+.IX Item "HASATTRIBUTE_NORETURN"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for functions that do not return
+.ie n .IP """HASATTRIBUTE_PURE""" 4
+.el .IP \f(CWHASATTRIBUTE_PURE\fR 4
+.IX Xref "HASATTRIBUTE_PURE"
+.IX Item "HASATTRIBUTE_PURE"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for pure functions
+.ie n .IP """HASATTRIBUTE_UNUSED""" 4
+.el .IP \f(CWHASATTRIBUTE_UNUSED\fR 4
+.IX Xref "HASATTRIBUTE_UNUSED"
+.IX Item "HASATTRIBUTE_UNUSED"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for unused variables and arguments
+.ie n .IP """HASATTRIBUTE_VISIBILITY""" 4
+.el .IP \f(CWHASATTRIBUTE_VISIBILITY\fR 4
+.IX Xref "HASATTRIBUTE_VISIBILITY"
+.IX Item "HASATTRIBUTE_VISIBILITY"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for functions that should have a
+different visibility.
+.ie n .IP """HASATTRIBUTE_WARN_UNUSED_RESULT""" 4
+.el .IP \f(CWHASATTRIBUTE_WARN_UNUSED_RESULT\fR 4
+.IX Xref "HASATTRIBUTE_WARN_UNUSED_RESULT"
+.IX Item "HASATTRIBUTE_WARN_UNUSED_RESULT"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for warning on unused results
+.ie n .IP """HAS_BUILTIN_ADD_OVERFLOW""" 4
+.el .IP \f(CWHAS_BUILTIN_ADD_OVERFLOW\fR 4
+.IX Xref "HAS_BUILTIN_ADD_OVERFLOW"
+.IX Item "HAS_BUILTIN_ADD_OVERFLOW"
+This symbol, if defined, indicates that the compiler supports
+\&\f(CW\*(C`_\|_builtin_add_overflow\*(C'\fR for adding integers with overflow checks.
+.ie n .IP """HAS_BUILTIN_CHOOSE_EXPR""" 4
+.el .IP \f(CWHAS_BUILTIN_CHOOSE_EXPR\fR 4
+.IX Xref "HAS_BUILTIN_CHOOSE_EXPR"
+.IX Item "HAS_BUILTIN_CHOOSE_EXPR"
+Can we handle \f(CW\*(C`GCC\*(C'\fR builtin for compile-time ternary-like expressions
+.ie n .IP """HAS_BUILTIN_EXPECT""" 4
+.el .IP \f(CWHAS_BUILTIN_EXPECT\fR 4
+.IX Xref "HAS_BUILTIN_EXPECT"
+.IX Item "HAS_BUILTIN_EXPECT"
+Can we handle \f(CW\*(C`GCC\*(C'\fR builtin for telling that certain values are more
+likely
+.ie n .IP """HAS_BUILTIN_MUL_OVERFLOW""" 4
+.el .IP \f(CWHAS_BUILTIN_MUL_OVERFLOW\fR 4
+.IX Xref "HAS_BUILTIN_MUL_OVERFLOW"
+.IX Item "HAS_BUILTIN_MUL_OVERFLOW"
+This symbol, if defined, indicates that the compiler supports
+\&\f(CW\*(C`_\|_builtin_mul_overflow\*(C'\fR for multiplying integers with overflow checks.
+.ie n .IP """HAS_BUILTIN_SUB_OVERFLOW""" 4
+.el .IP \f(CWHAS_BUILTIN_SUB_OVERFLOW\fR 4
+.IX Xref "HAS_BUILTIN_SUB_OVERFLOW"
+.IX Item "HAS_BUILTIN_SUB_OVERFLOW"
+This symbol, if defined, indicates that the compiler supports
+\&\f(CW\*(C`_\|_builtin_sub_overflow\*(C'\fR for subtracting integers with overflow checks.
+.ie n .IP """HAS_C99_VARIADIC_MACROS""" 4
+.el .IP \f(CWHAS_C99_VARIADIC_MACROS\fR 4
+.IX Xref "HAS_C99_VARIADIC_MACROS"
+.IX Item "HAS_C99_VARIADIC_MACROS"
+If defined, the compiler supports C99 variadic macros.
+.ie n .IP """HAS_STATIC_INLINE""" 4
+.el .IP \f(CWHAS_STATIC_INLINE\fR 4
+.IX Xref "HAS_STATIC_INLINE"
+.IX Item "HAS_STATIC_INLINE"
+This symbol, if defined, indicates that the C compiler supports
+C99\-style static inline. That is, the function can't be called
+from another translation unit.
+.ie n .IP """MEM_ALIGNBYTES""" 4
+.el .IP \f(CWMEM_ALIGNBYTES\fR 4
+.IX Xref "MEM_ALIGNBYTES"
+.IX Item "MEM_ALIGNBYTES"
+This symbol contains the number of bytes required to align a
+double, or a long double when applicable. Usual values are 2,
+4 and 8. The default is eight, for safety. For cross-compiling
+or multiarch support, Configure will set a minimum of 8.
+.ie n .IP """PERL_STATIC_INLINE""" 4
+.el .IP \f(CWPERL_STATIC_INLINE\fR 4
+.IX Xref "PERL_STATIC_INLINE"
+.IX Item "PERL_STATIC_INLINE"
+This symbol gives the best-guess incantation to use for static
+inline functions. If \f(CW\*(C`HAS_STATIC_INLINE\*(C'\fR is defined, this will
+give C99\-style inline. If \f(CW\*(C`HAS_STATIC_INLINE\*(C'\fR is not defined,
+this will give a plain 'static'. It will always be defined
+to something that gives static linkage.
+Possibilities include
+.Sp
+.Vb 5
+\& static inline (c99)
+\& static _\|_inline_\|_ (gcc \-ansi)
+\& static _\|_inline (MSVC)
+\& static _inline (older MSVC)
+\& static (c89 compilers)
+.Ve
+.ie n .IP """PERL_THREAD_LOCAL""" 4
+.el .IP \f(CWPERL_THREAD_LOCAL\fR 4
+.IX Xref "PERL_THREAD_LOCAL"
+.IX Item "PERL_THREAD_LOCAL"
+This symbol, if defined, gives a linkage specification for thread-local
+storage. For example, for a C11 compiler this will be \f(CW\*(C`_Thread_local\*(C'\fR.
+Beware, some compilers are sensitive to the C language standard they are
+told to parse. For example, suncc defaults to C11, so our probe will
+report that \f(CW\*(C`_Thread_local\*(C'\fR can be used. However, if the \-std=c99 is later
+added to the compiler flags, then \f(CW\*(C`_Thread_local\*(C'\fR will become a syntax
+error. Hence it is important for these flags to be consistent between
+probing and use.
+.ie n .IP """U32_ALIGNMENT_REQUIRED""" 4
+.el .IP \f(CWU32_ALIGNMENT_REQUIRED\fR 4
+.IX Xref "U32_ALIGNMENT_REQUIRED"
+.IX Item "U32_ALIGNMENT_REQUIRED"
+This symbol, if defined, indicates that you must access
+character data through U32\-aligned pointers.
+.SH "Compiler directives"
+.IX Header "Compiler directives"
+.ie n .IP """_\|_ASSERT_""" 4
+.el .IP \f(CW_\|_ASSERT_\fR 4
+.IX Xref "__ASSERT_"
+.IX Item "__ASSERT_"
+This is a helper macro to avoid preprocessor issues, replaced by nothing
+unless under DEBUGGING, where it expands to an assert of its argument,
+followed by a comma (hence the comma operator). If we just used a straight
+\&\fBassert()\fR, we would get a comma with nothing before it when not DEBUGGING.
+.RS 4
+.Sp
+.Vb 1
+\& _\|_ASSERT_(bool expr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ASSUME""" 4
+.el .IP \f(CWASSUME\fR 4
+.IX Xref "ASSUME"
+.IX Item "ASSUME"
+\&\f(CW\*(C`ASSUME\*(C'\fR is like \f(CWassert()\fR, but it has a benefit in a release build. It is a
+hint to a compiler about a statement of fact in a function call free
+expression, which allows the compiler to generate better machine code. In a
+debug build, \f(CWASSUME(x)\fR is a synonym for \f(CWassert(x)\fR. \f(CWASSUME(0)\fR means the
+control path is unreachable. In a for loop, \f(CW\*(C`ASSUME\*(C'\fR can be used to hint that
+a loop will run at least X times. \f(CW\*(C`ASSUME\*(C'\fR is based off MSVC's \f(CW\*(C`_\|_assume\*(C'\fR
+intrinsic function, see its documents for more details.
+.RS 4
+.Sp
+.Vb 1
+\& ASSUME(bool expr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dNOOP""" 4
+.el .IP \f(CWdNOOP\fR 4
+.IX Xref "dNOOP"
+.IX Item "dNOOP"
+Declare nothing; typically used as a placeholder to replace something that used
+to declare something. Works on compilers that require declarations before any
+code.
+.RS 4
+.Sp
+.Vb 1
+\& dNOOP;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """END_EXTERN_C""" 4
+.el .IP \f(CWEND_EXTERN_C\fR 4
+.IX Xref "END_EXTERN_C"
+.IX Item "END_EXTERN_C"
+When not compiling using C++, expands to nothing.
+Otherwise ends a section of code already begun by a \f(CW"START_EXTERN_C"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& END_EXTERN_C
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """EXTERN_C""" 4
+.el .IP \f(CWEXTERN_C\fR 4
+.IX Xref "EXTERN_C"
+.IX Item "EXTERN_C"
+When not compiling using C++, expands to nothing.
+Otherwise is used in a declaration of a function to indicate the function
+should have external C linkage. This is required for things to work for just
+about all functions with external linkage compiled into perl.
+Often, you can use \f(CW"START_EXTERN_C"\fR ... \f(CW"END_EXTERN_C"\fR blocks
+surrounding all your code that you need to have this linkage.
+.Sp
+Example usage:
+.Sp
+.Vb 1
+\& EXTERN_C int flock(int fd, int op);
+.Ve
+.ie n .IP """LIKELY""" 4
+.el .IP \f(CWLIKELY\fR 4
+.IX Xref "LIKELY"
+.IX Item "LIKELY"
+Returns the input unchanged, but at the same time it gives a branch prediction
+hint to the compiler that this condition is likely to be true.
+.RS 4
+.Sp
+.Vb 1
+\& LIKELY(bool expr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """NOOP""" 4
+.el .IP \f(CWNOOP\fR 4
+.IX Xref "NOOP"
+.IX Item "NOOP"
+Do nothing; typically used as a placeholder to replace something that used to
+do something.
+.RS 4
+.Sp
+.Vb 1
+\& NOOP;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_UNUSED_ARG""" 4
+.el .IP \f(CWPERL_UNUSED_ARG\fR 4
+.IX Xref "PERL_UNUSED_ARG"
+.IX Item "PERL_UNUSED_ARG"
+This is used to suppress compiler warnings that a parameter to a function is
+not used. This situation can arise, for example, when a parameter is needed
+under some configuration conditions, but not others, so that C preprocessor
+conditional compilation causes it be used just sometimes.
+.RS 4
+.Sp
+.Vb 1
+\& PERL_UNUSED_ARG(void x);
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_UNUSED_CONTEXT""" 4
+.el .IP \f(CWPERL_UNUSED_CONTEXT\fR 4
+.IX Xref "PERL_UNUSED_CONTEXT"
+.IX Item "PERL_UNUSED_CONTEXT"
+This is used to suppress compiler warnings that the thread context parameter to
+a function is not used. This situation can arise, for example, when a
+C preprocessor conditional compilation causes it be used just some times.
+.RS 4
+.Sp
+.Vb 1
+\& PERL_UNUSED_CONTEXT;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_UNUSED_DECL""" 4
+.el .IP \f(CWPERL_UNUSED_DECL\fR 4
+.IX Xref "PERL_UNUSED_DECL"
+.IX Item "PERL_UNUSED_DECL"
+Tells the compiler that the parameter in the function prototype just before it
+is not necessarily expected to be used in the function. Not that many
+compilers understand this, so this should only be used in cases where
+\&\f(CW"PERL_UNUSED_ARG"\fR can't conveniently be used.
+.Sp
+Example usage:
+.RS 4
+.Sp
+.Vb 3
+\& Signal_t
+\& Perl_perly_sighandler(int sig, Siginfo_t *sip PERL_UNUSED_DECL,
+\& void *uap PERL_UNUSED_DECL, bool safe)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_UNUSED_RESULT""" 4
+.el .IP \f(CWPERL_UNUSED_RESULT\fR 4
+.IX Xref "PERL_UNUSED_RESULT"
+.IX Item "PERL_UNUSED_RESULT"
+This macro indicates to discard the return value of the function call inside
+it, \fIe.g.\fR,
+.Sp
+.Vb 1
+\& PERL_UNUSED_RESULT(foo(a, b))
+.Ve
+.Sp
+The main reason for this is that the combination of \f(CW\*(C`gcc \-Wunused\-result\*(C'\fR
+(part of \f(CW\*(C`\-Wall\*(C'\fR) and the \f(CW\*(C`_\|_attribute_\|_((warn_unused_result))\*(C'\fR cannot
+be silenced with casting to \f(CW\*(C`void\*(C'\fR. This causes trouble when the system
+header files use the attribute.
+.Sp
+Use \f(CW\*(C`PERL_UNUSED_RESULT\*(C'\fR sparingly, though, since usually the warning
+is there for a good reason: you might lose success/failure information,
+or leak resources, or changes in resources.
+.Sp
+But sometimes you just want to ignore the return value, \fIe.g.\fR, on
+codepaths soon ending up in abort, or in "best effort" attempts,
+or in situations where there is no good way to handle failures.
+.Sp
+Sometimes \f(CW\*(C`PERL_UNUSED_RESULT\*(C'\fR might not be the most natural way:
+another possibility is that you can capture the return value
+and use \f(CW"PERL_UNUSED_VAR"\fR on that.
+.RS 4
+.Sp
+.Vb 1
+\& PERL_UNUSED_RESULT(void x)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_UNUSED_VAR""" 4
+.el .IP \f(CWPERL_UNUSED_VAR\fR 4
+.IX Xref "PERL_UNUSED_VAR"
+.IX Item "PERL_UNUSED_VAR"
+This is used to suppress compiler warnings that the variable \fIx\fR is not used.
+This situation can arise, for example, when a C preprocessor conditional
+compilation causes it be used just some times.
+.RS 4
+.Sp
+.Vb 1
+\& PERL_UNUSED_VAR(void x);
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """START_EXTERN_C""" 4
+.el .IP \f(CWSTART_EXTERN_C\fR 4
+.IX Xref "START_EXTERN_C"
+.IX Item "START_EXTERN_C"
+When not compiling using C++, expands to nothing.
+Otherwise begins a section of code in which every function will effectively
+have \f(CW"EXTERN_C"\fR applied to it, that is to have external C linkage. The
+section is ended by a \f(CW"END_EXTERN_C"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& START_EXTERN_C
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """STATIC""" 4
+.el .IP \f(CWSTATIC\fR 4
+.IX Item "STATIC"
+Described in perlguts.
+.ie n .IP """STMT_END""" 4
+.el .IP \f(CWSTMT_END\fR 4
+.IX Item "STMT_END"
+.PD 0
+.ie n .IP """STMT_START""" 4
+.el .IP \f(CWSTMT_START\fR 4
+.IX Xref "STMT_END STMT_START"
+.IX Item "STMT_START"
+.PD
+These allow a series of statements in a macro to be used as a single statement,
+as in
+.Sp
+.Vb 1
+\& if (x) STMT_START { ... } STMT_END else ...
+.Ve
+.Sp
+Note that you can't return a value out of this construct and cannot use it as
+an operand to the comma operator. These limit its utility.
+.Sp
+But, a value could be returned by constructing the API so that a pointer is
+passed and the macro dereferences this to set the return. If the value can be
+any of various types, depending on context, you can handle that situation in
+some situations by adding the type of the return as an extra accompanying
+parameter:
+.Sp
+.Vb 3
+\& #define foo(param, type) STMT_START {
+\& type * param; *param = do_calc; ...
+\& } STMT_END
+.Ve
+.Sp
+This could be awkward, so consider instead using a C language \f(CW\*(C`static inline\*(C'\fR
+function.
+.Sp
+If you do use this construct, it is easy to forget that it is a macro and not a
+function, and hence fall into traps that might not show up until someone
+someday writes code which contains names that clash with the ones you chose
+here, or calls it with a parameter which is an expression with side effects,
+the consequences of which you didn't think about. See "Writing
+safer macros" in perlhacktips for how to avoid these.
+.ie n .IP """UNLIKELY""" 4
+.el .IP \f(CWUNLIKELY\fR 4
+.IX Xref "UNLIKELY"
+.IX Item "UNLIKELY"
+Returns the input unchanged, but at the same time it gives a branch prediction
+hint to the compiler that this condition is likely to be false.
+.RS 4
+.Sp
+.Vb 1
+\& UNLIKELY(bool expr)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Compile-time scope hooks"
+.IX Header "Compile-time scope hooks"
+.ie n .IP """BhkDISABLE""" 4
+.el .IP \f(CWBhkDISABLE\fR 4
+.IX Xref "BhkDISABLE"
+.IX Item "BhkDISABLE"
+NOTE: \f(CW\*(C`BhkDISABLE\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Temporarily disable an entry in this BHK structure, by clearing the
+appropriate flag. \f(CW\*(C`which\*(C'\fR is a preprocessor token indicating which
+entry to disable.
+.RS 4
+.Sp
+.Vb 1
+\& void BhkDISABLE(BHK *hk, token which)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """BhkENABLE""" 4
+.el .IP \f(CWBhkENABLE\fR 4
+.IX Xref "BhkENABLE"
+.IX Item "BhkENABLE"
+NOTE: \f(CW\*(C`BhkENABLE\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Re-enable an entry in this BHK structure, by setting the appropriate
+flag. \f(CW\*(C`which\*(C'\fR is a preprocessor token indicating which entry to enable.
+This will assert (under \-DDEBUGGING) if the entry doesn't contain a valid
+pointer.
+.RS 4
+.Sp
+.Vb 1
+\& void BhkENABLE(BHK *hk, token which)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """BhkENTRY_set""" 4
+.el .IP \f(CWBhkENTRY_set\fR 4
+.IX Xref "BhkENTRY_set"
+.IX Item "BhkENTRY_set"
+NOTE: \f(CW\*(C`BhkENTRY_set\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Set an entry in the BHK structure, and set the flags to indicate it is
+valid. \f(CW\*(C`which\*(C'\fR is a preprocessing token indicating which entry to set.
+The type of \f(CW\*(C`ptr\*(C'\fR depends on the entry.
+.RS 4
+.Sp
+.Vb 1
+\& void BhkENTRY_set(BHK *hk, token which, void *ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """blockhook_register""" 4
+.el .IP \f(CWblockhook_register\fR 4
+.IX Xref "blockhook_register"
+.IX Item "blockhook_register"
+NOTE: \f(CW\*(C`blockhook_register\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Register a set of hooks to be called when the Perl lexical scope changes
+at compile time. See "Compile-time scope hooks" in perlguts.
+.Sp
+NOTE: \f(CW\*(C`blockhook_register\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_blockhook_register\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 1
+\& void Perl_blockhook_register(pTHX_ BHK *hk)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Concurrency
+.IX Header "Concurrency"
+.ie n .IP """aTHX""" 4
+.el .IP \f(CWaTHX\fR 4
+.IX Item "aTHX"
+Described in perlguts.
+.ie n .IP """aTHX_""" 4
+.el .IP \f(CWaTHX_\fR 4
+.IX Item "aTHX_"
+Described in perlguts.
+.ie n .IP """CPERLscope""" 4
+.el .IP \f(CWCPERLscope\fR 4
+.IX Xref "CPERLscope"
+.IX Item "CPERLscope"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`CPERLscope\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Now a no-op.
+.RS 4
+.Sp
+.Vb 1
+\& void CPERLscope(void x)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dTHR""" 4
+.el .IP \f(CWdTHR\fR 4
+.IX Item "dTHR"
+Described in perlguts.
+.ie n .IP """dTHX""" 4
+.el .IP \f(CWdTHX\fR 4
+.IX Item "dTHX"
+Described in perlguts.
+.ie n .IP """dTHXa""" 4
+.el .IP \f(CWdTHXa\fR 4
+.IX Xref "dTHXa"
+.IX Item "dTHXa"
+On threaded perls, set \f(CW\*(C`pTHX\*(C'\fR to \f(CW\*(C`a\*(C'\fR; on unthreaded perls, do nothing
+.ie n .IP """dTHXoa""" 4
+.el .IP \f(CWdTHXoa\fR 4
+.IX Xref "dTHXoa"
+.IX Item "dTHXoa"
+Now a synonym for \f(CW"dTHXa"\fR.
+.ie n .IP """dVAR""" 4
+.el .IP \f(CWdVAR\fR 4
+.IX Xref "dVAR"
+.IX Item "dVAR"
+This is now a synonym for dNOOP: declare nothing
+.ie n .IP """GETENV_PRESERVES_OTHER_THREAD""" 4
+.el .IP \f(CWGETENV_PRESERVES_OTHER_THREAD\fR 4
+.IX Xref "GETENV_PRESERVES_OTHER_THREAD"
+.IX Item "GETENV_PRESERVES_OTHER_THREAD"
+This symbol, if defined, indicates that the getenv system call doesn't
+zap the static buffer of \f(CWgetenv()\fR in a different thread.
+The typical \f(CWgetenv()\fR implementation will return a pointer to the proper
+position in **environ. But some may instead copy them to a static
+buffer in \f(CWgetenv()\fR. If there is a per-thread instance of that buffer,
+or the return points to **environ, then a many\-reader/1\-writer mutex
+will work; otherwise an exclusive locking mutex is required to prevent
+races.
+.ie n .IP """HAS_PTHREAD_ATFORK""" 4
+.el .IP \f(CWHAS_PTHREAD_ATFORK\fR 4
+.IX Xref "HAS_PTHREAD_ATFORK"
+.IX Item "HAS_PTHREAD_ATFORK"
+This symbol, if defined, indicates that the \f(CW\*(C`pthread_atfork\*(C'\fR routine
+is available to setup fork handlers.
+.ie n .IP """HAS_PTHREAD_ATTR_SETSCOPE""" 4
+.el .IP \f(CWHAS_PTHREAD_ATTR_SETSCOPE\fR 4
+.IX Xref "HAS_PTHREAD_ATTR_SETSCOPE"
+.IX Item "HAS_PTHREAD_ATTR_SETSCOPE"
+This symbol, if defined, indicates that the \f(CW\*(C`pthread_attr_setscope\*(C'\fR
+system call is available to set the contention scope attribute of
+a thread attribute object.
+.ie n .IP """HAS_PTHREAD_YIELD""" 4
+.el .IP \f(CWHAS_PTHREAD_YIELD\fR 4
+.IX Xref "HAS_PTHREAD_YIELD"
+.IX Item "HAS_PTHREAD_YIELD"
+This symbol, if defined, indicates that the \f(CW\*(C`pthread_yield\*(C'\fR
+routine is available to yield the execution of the current
+thread. \f(CW\*(C`sched_yield\*(C'\fR is preferable to \f(CW\*(C`pthread_yield\*(C'\fR.
+.ie n .IP """HAS_SCHED_YIELD""" 4
+.el .IP \f(CWHAS_SCHED_YIELD\fR 4
+.IX Xref "HAS_SCHED_YIELD"
+.IX Item "HAS_SCHED_YIELD"
+This symbol, if defined, indicates that the \f(CW\*(C`sched_yield\*(C'\fR
+routine is available to yield the execution of the current
+thread. \f(CW\*(C`sched_yield\*(C'\fR is preferable to \f(CW\*(C`pthread_yield\*(C'\fR.
+.ie n .IP """I_MACH_CTHREADS""" 4
+.el .IP \f(CWI_MACH_CTHREADS\fR 4
+.IX Xref "I_MACH_CTHREADS"
+.IX Item "I_MACH_CTHREADS"
+This symbol, if defined, indicates to the C program that it should
+include \fImach/cthreads.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_MACH_CTHREADS
+\& #include <mach_cthreads.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_PTHREAD""" 4
+.el .IP \f(CWI_PTHREAD\fR 4
+.IX Xref "I_PTHREAD"
+.IX Item "I_PTHREAD"
+This symbol, if defined, indicates to the C program that it should
+include \fIpthread.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_PTHREAD
+\& #include <pthread.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MULTIPLICITY""" 4
+.el .IP \f(CWMULTIPLICITY\fR 4
+.IX Item "MULTIPLICITY"
+This symbol, if defined, indicates that Perl should
+be built to use multiplicity.
+.ie n .IP """OLD_PTHREAD_CREATE_JOINABLE""" 4
+.el .IP \f(CWOLD_PTHREAD_CREATE_JOINABLE\fR 4
+.IX Xref "OLD_PTHREAD_CREATE_JOINABLE"
+.IX Item "OLD_PTHREAD_CREATE_JOINABLE"
+This symbol, if defined, indicates how to create pthread
+in joinable (aka undetached) state. \f(CW\*(C`NOTE\*(C'\fR: not defined
+if \fIpthread.h\fR already has defined \f(CW\*(C`PTHREAD_CREATE_JOINABLE\*(C'\fR
+(the new version of the constant).
+If defined, known values are \f(CW\*(C`PTHREAD_CREATE_UNDETACHED\*(C'\fR
+and \f(CW\*(C`_\|_UNDETACHED\*(C'\fR.
+.ie n .IP """OLD_PTHREADS_API""" 4
+.el .IP \f(CWOLD_PTHREADS_API\fR 4
+.IX Xref "OLD_PTHREADS_API"
+.IX Item "OLD_PTHREADS_API"
+This symbol, if defined, indicates that Perl should
+be built to use the old draft \f(CW\*(C`POSIX\*(C'\fR threads \f(CW\*(C`API\*(C'\fR.
+.ie n .IP """PERL_IMPLICIT_CONTEXT""" 4
+.el .IP \f(CWPERL_IMPLICIT_CONTEXT\fR 4
+.IX Item "PERL_IMPLICIT_CONTEXT"
+Described in perlguts.
+.ie n .IP """PERL_NO_GET_CONTEXT""" 4
+.el .IP \f(CWPERL_NO_GET_CONTEXT\fR 4
+.IX Item "PERL_NO_GET_CONTEXT"
+Described in perlguts.
+.ie n .IP """pTHX""" 4
+.el .IP \f(CWpTHX\fR 4
+.IX Item "pTHX"
+Described in perlguts.
+.ie n .IP """pTHX_""" 4
+.el .IP \f(CWpTHX_\fR 4
+.IX Item "pTHX_"
+Described in perlguts.
+.ie n .IP """SCHED_YIELD""" 4
+.el .IP \f(CWSCHED_YIELD\fR 4
+.IX Xref "SCHED_YIELD"
+.IX Item "SCHED_YIELD"
+This symbol defines the way to yield the execution of
+the current thread. Known ways are \f(CW\*(C`sched_yield\*(C'\fR,
+\&\f(CW\*(C`pthread_yield\*(C'\fR, and \f(CW\*(C`pthread_yield\*(C'\fR with \f(CW\*(C`NULL\*(C'\fR.
+.SH "COPs and Hint Hashes"
+.IX Xref "COPHH_KEY_UTF8"
+.IX Header "COPs and Hint Hashes"
+.ie n .IP """cop_fetch_label""" 4
+.el .IP \f(CWcop_fetch_label\fR 4
+.IX Xref "cop_fetch_label"
+.IX Item "cop_fetch_label"
+NOTE: \f(CW\*(C`cop_fetch_label\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Returns the label attached to a cop, and stores its length in bytes into
+\&\f(CW*len\fR.
+Upon return, \f(CW*flags\fR will be set to either \f(CW\*(C`SVf_UTF8\*(C'\fR or 0.
+.Sp
+Alternatively, use the macro \f(CW"CopLABEL_len_flags"\fR;
+or if you don't need to know if the label is UTF\-8 or not, the macro
+\&\f(CW"CopLABEL_len"\fR;
+or if you additionally don't need to know the length, \f(CW"CopLABEL"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& const char * cop_fetch_label(COP * const cop, STRLEN *len,
+\& U32 *flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILE""" 4
+.el .IP \f(CWCopFILE\fR 4
+.IX Xref "CopFILE"
+.IX Item "CopFILE"
+Returns the name of the file associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& const char * CopFILE(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILEAV""" 4
+.el .IP \f(CWCopFILEAV\fR 4
+.IX Xref "CopFILEAV"
+.IX Item "CopFILEAV"
+Returns the AV associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR, creating it if necessary.
+.RS 4
+.Sp
+.Vb 1
+\& AV * CopFILEAV(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILEAVn""" 4
+.el .IP \f(CWCopFILEAVn\fR 4
+.IX Xref "CopFILEAVn"
+.IX Item "CopFILEAVn"
+Returns the AV associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR, returning NULL if it
+doesn't already exist.
+.RS 4
+.Sp
+.Vb 1
+\& AV * CopFILEAVn(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILE_copy""" 4
+.el .IP \f(CWCopFILE_copy\fR 4
+.IX Xref "CopFILE_copy"
+.IX Item "CopFILE_copy"
+Efficiently copies the cop file name from one COP to another. Wraps
+the required logic to do a refcounted copy under threads or not.
+.RS 4
+.Sp
+.Vb 1
+\& void CopFILE_copy(COP * dst, COP * src)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILE_free""" 4
+.el .IP \f(CWCopFILE_free\fR 4
+.IX Xref "CopFILE_free"
+.IX Item "CopFILE_free"
+Frees the file data in a cop. Under the hood this is a refcounting
+operation.
+.RS 4
+.Sp
+.Vb 1
+\& void CopFILE_free(COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILEGV""" 4
+.el .IP \f(CWCopFILEGV\fR 4
+.IX Xref "CopFILEGV"
+.IX Item "CopFILEGV"
+Returns the GV associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& GV * CopFILEGV(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILEGV_set""" 4
+.el .IP \f(CWCopFILEGV_set\fR 4
+.IX Xref "CopFILEGV_set"
+.IX Item "CopFILEGV_set"
+Available only on unthreaded perls. Makes \f(CW\*(C`pv\*(C'\fR the name of the file
+associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& void CopFILEGV_set(COP *c, GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILE_LEN""" 4
+.el .IP \f(CWCopFILE_LEN\fR 4
+.IX Xref "CopFILE_LEN"
+.IX Item "CopFILE_LEN"
+Returns the length of the file associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& const char * CopFILE_LEN(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILE_set""" 4
+.el .IP \f(CWCopFILE_set\fR 4
+.IX Xref "CopFILE_set"
+.IX Item "CopFILE_set"
+Makes \f(CW\*(C`pv\*(C'\fR the name of the file associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& void CopFILE_set(COP * c, const char * pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILE_setn""" 4
+.el .IP \f(CWCopFILE_setn\fR 4
+.IX Xref "CopFILE_setn"
+.IX Item "CopFILE_setn"
+Makes \f(CW\*(C`pv\*(C'\fR the name of the file associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& void CopFILE_setn(COP * c, const char * pv, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopFILESV""" 4
+.el .IP \f(CWCopFILESV\fR 4
+.IX Xref "CopFILESV"
+.IX Item "CopFILESV"
+Returns the SV associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& SV * CopFILESV(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cophh_copy""" 4
+.el .IP \f(CWcophh_copy\fR 4
+.IX Xref "cophh_copy"
+.IX Item "cophh_copy"
+NOTE: \f(CW\*(C`cophh_copy\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Make and return a complete copy of the cop hints hash \f(CW\*(C`cophh\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& COPHH * cophh_copy(COPHH *cophh)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cophh_delete_pv""" 4
+.el .IP \f(CWcophh_delete_pv\fR 4
+.IX Item "cophh_delete_pv"
+.PD 0
+.ie n .IP """cophh_delete_pvn""" 4
+.el .IP \f(CWcophh_delete_pvn\fR 4
+.IX Item "cophh_delete_pvn"
+.ie n .IP """cophh_delete_pvs""" 4
+.el .IP \f(CWcophh_delete_pvs\fR 4
+.IX Item "cophh_delete_pvs"
+.ie n .IP """cophh_delete_sv""" 4
+.el .IP \f(CWcophh_delete_sv\fR 4
+.IX Xref "cophh_delete_pv cophh_delete_pvn cophh_delete_pvs cophh_delete_sv"
+.IX Item "cophh_delete_sv"
+.PD
+NOTE: all these forms are \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+These delete a key and its associated value from the cop hints hash \f(CW\*(C`cophh\*(C'\fR,
+and return the modified hash. The returned hash pointer is in general
+not the same as the hash pointer that was passed in. The input hash is
+consumed by the function, and the pointer to it must not be subsequently
+used. Use "cophh_copy" if you need both hashes.
+.Sp
+The forms differ in how the key is specified. In all forms, the key is pointed
+to by \f(CW\*(C`key\*(C'\fR.
+In the plain \f(CW\*(C`pv\*(C'\fR form, the key is a C language NUL-terminated string.
+In the \f(CW\*(C`pvs\*(C'\fR form, the key is a C language string literal.
+In the \f(CW\*(C`pvn\*(C'\fR form, an additional parameter, \f(CW\*(C`keylen\*(C'\fR, specifies the length of
+the string, which hence, may contain embedded-NUL characters.
+In the \f(CW\*(C`sv\*(C'\fR form, \f(CW*key\fR is an SV, and the key is the PV extracted from that.
+using \f(CW"SvPV_const"\fR.
+.Sp
+\&\f(CW\*(C`hash\*(C'\fR is a precomputed hash of the key string, or zero if it has not been
+precomputed. This parameter is omitted from the \f(CW\*(C`pvs\*(C'\fR form, as it is computed
+automatically at compile time.
+.Sp
+The only flag currently used from the \f(CW\*(C`flags\*(C'\fR parameter is \f(CW\*(C`COPHH_KEY_UTF8\*(C'\fR.
+It is illegal to set this in the \f(CW\*(C`sv\*(C'\fR form. In the \f(CW\*(C`pv*\*(C'\fR forms, it specifies
+whether the key octets are interpreted as UTF\-8 (if set) or as Latin\-1 (if
+cleared). The \f(CW\*(C`sv\*(C'\fR form uses the underlying SV to determine the UTF\-8ness of
+the octets.
+.RS 4
+.Sp
+.Vb 7
+\& COPHH * cophh_delete_pv (COPHH *cophh, const char *key, U32 hash,
+\& U32 flags)
+\& COPHH * cophh_delete_pvn(COPHH *cophh, const char *key,
+\& STRLEN keylen, U32 hash, U32 flags)
+\& COPHH * cophh_delete_pvs(COPHH *cophh, "key", U32 flags)
+\& COPHH * cophh_delete_sv (COPHH *cophh, SV *key, U32 hash,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cophh_exists_pvn""" 4
+.el .IP \f(CWcophh_exists_pvn\fR 4
+.IX Xref "cophh_exists_pvn"
+.IX Item "cophh_exists_pvn"
+NOTE: \f(CW\*(C`cophh_exists_pvn\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+These look up the hint entry in the cop \f(CW\*(C`cop\*(C'\fR with the key specified by
+\&\f(CW\*(C`key\*(C'\fR (and \f(CW\*(C`keylen\*(C'\fR in the \f(CW\*(C`pvn\*(C'\fR form), returning true if a value exists,
+and false otherwise.
+.Sp
+The forms differ in how the key is specified.
+In the plain \f(CW\*(C`pv\*(C'\fR form, the key is a C language NUL-terminated string.
+In the \f(CW\*(C`pvs\*(C'\fR form, the key is a C language string literal.
+In the \f(CW\*(C`pvn\*(C'\fR form, an additional parameter, \f(CW\*(C`keylen\*(C'\fR, specifies the length of
+the string, which hence, may contain embedded-NUL characters.
+In the \f(CW\*(C`sv\*(C'\fR form, \f(CW*key\fR is an SV, and the key is the PV extracted from that.
+using \f(CW"SvPV_const"\fR.
+.Sp
+\&\f(CW\*(C`hash\*(C'\fR is a precomputed hash of the key string, or zero if it has not been
+precomputed. This parameter is omitted from the \f(CW\*(C`pvs\*(C'\fR form, as it is computed
+automatically at compile time.
+.Sp
+The only flag currently used from the \f(CW\*(C`flags\*(C'\fR parameter is \f(CW\*(C`COPHH_KEY_UTF8\*(C'\fR.
+It is illegal to set this in the \f(CW\*(C`sv\*(C'\fR form. In the \f(CW\*(C`pv*\*(C'\fR forms, it specifies
+whether the key octets are interpreted as UTF\-8 (if set) or as Latin\-1 (if
+cleared). The \f(CW\*(C`sv\*(C'\fR form uses the underlying SV to determine the UTF\-8ness of
+the octets.
+.RS 4
+.Sp
+.Vb 2
+\& bool cophh_exists_pvn(const COPHH *cophh, const char *key,
+\& STRLEN keylen, U32 hash, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cophh_fetch_pv""" 4
+.el .IP \f(CWcophh_fetch_pv\fR 4
+.IX Item "cophh_fetch_pv"
+.PD 0
+.ie n .IP """cophh_fetch_pvn""" 4
+.el .IP \f(CWcophh_fetch_pvn\fR 4
+.IX Item "cophh_fetch_pvn"
+.ie n .IP """cophh_fetch_pvs""" 4
+.el .IP \f(CWcophh_fetch_pvs\fR 4
+.IX Item "cophh_fetch_pvs"
+.ie n .IP """cophh_fetch_sv""" 4
+.el .IP \f(CWcophh_fetch_sv\fR 4
+.IX Xref "cophh_fetch_pv cophh_fetch_pvn cophh_fetch_pvs cophh_fetch_sv"
+.IX Item "cophh_fetch_sv"
+.PD
+NOTE: all these forms are \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+These look up the entry in the cop hints hash \f(CW\*(C`cophh\*(C'\fR with the key specified by
+\&\f(CW\*(C`key\*(C'\fR (and \f(CW\*(C`keylen\*(C'\fR in the \f(CW\*(C`pvn\*(C'\fR form), returning that value as a mortal
+scalar copy, or \f(CW&PL_sv_placeholder\fR if there is no value associated with the
+key.
+.Sp
+The forms differ in how the key is specified.
+In the plain \f(CW\*(C`pv\*(C'\fR form, the key is a C language NUL-terminated string.
+In the \f(CW\*(C`pvs\*(C'\fR form, the key is a C language string literal.
+In the \f(CW\*(C`pvn\*(C'\fR form, an additional parameter, \f(CW\*(C`keylen\*(C'\fR, specifies the length of
+the string, which hence, may contain embedded-NUL characters.
+In the \f(CW\*(C`sv\*(C'\fR form, \f(CW*key\fR is an SV, and the key is the PV extracted from that.
+using \f(CW"SvPV_const"\fR.
+.Sp
+\&\f(CW\*(C`hash\*(C'\fR is a precomputed hash of the key string, or zero if it has not been
+precomputed. This parameter is omitted from the \f(CW\*(C`pvs\*(C'\fR form, as it is computed
+automatically at compile time.
+.Sp
+The only flag currently used from the \f(CW\*(C`flags\*(C'\fR parameter is \f(CW\*(C`COPHH_KEY_UTF8\*(C'\fR.
+It is illegal to set this in the \f(CW\*(C`sv\*(C'\fR form. In the \f(CW\*(C`pv*\*(C'\fR forms, it specifies
+whether the key octets are interpreted as UTF\-8 (if set) or as Latin\-1 (if
+cleared). The \f(CW\*(C`sv\*(C'\fR form uses the underlying SV to determine the UTF\-8ness of
+the octets.
+.RS 4
+.Sp
+.Vb 7
+\& SV * cophh_fetch_pv (const COPHH *cophh, const char *key,
+\& U32 hash, U32 flags)
+\& SV * cophh_fetch_pvn(const COPHH *cophh, const char *key,
+\& STRLEN keylen, U32 hash, U32 flags)
+\& SV * cophh_fetch_pvs(const COPHH *cophh, "key", U32 flags)
+\& SV * cophh_fetch_sv (const COPHH *cophh, SV *key, U32 hash,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cophh_free""" 4
+.el .IP \f(CWcophh_free\fR 4
+.IX Xref "cophh_free"
+.IX Item "cophh_free"
+NOTE: \f(CW\*(C`cophh_free\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Discard the cop hints hash \f(CW\*(C`cophh\*(C'\fR, freeing all resources associated
+with it.
+.RS 4
+.Sp
+.Vb 1
+\& void cophh_free(COPHH *cophh)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cophh_2hv""" 4
+.el .IP \f(CWcophh_2hv\fR 4
+.IX Xref "cophh_2hv"
+.IX Item "cophh_2hv"
+NOTE: \f(CW\*(C`cophh_2hv\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Generates and returns a standard Perl hash representing the full set of
+key/value pairs in the cop hints hash \f(CW\*(C`cophh\*(C'\fR. \f(CW\*(C`flags\*(C'\fR is currently
+unused and must be zero.
+.RS 4
+.Sp
+.Vb 1
+\& HV * cophh_2hv(const COPHH *cophh, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cophh_new_empty""" 4
+.el .IP \f(CWcophh_new_empty\fR 4
+.IX Xref "cophh_new_empty"
+.IX Item "cophh_new_empty"
+NOTE: \f(CW\*(C`cophh_new_empty\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Generate and return a fresh cop hints hash containing no entries.
+.RS 4
+.Sp
+.Vb 1
+\& COPHH * cophh_new_empty()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cophh_store_pv""" 4
+.el .IP \f(CWcophh_store_pv\fR 4
+.IX Item "cophh_store_pv"
+.PD 0
+.ie n .IP """cophh_store_pvn""" 4
+.el .IP \f(CWcophh_store_pvn\fR 4
+.IX Item "cophh_store_pvn"
+.ie n .IP """cophh_store_pvs""" 4
+.el .IP \f(CWcophh_store_pvs\fR 4
+.IX Item "cophh_store_pvs"
+.ie n .IP """cophh_store_sv""" 4
+.el .IP \f(CWcophh_store_sv\fR 4
+.IX Xref "cophh_store_pv cophh_store_pvn cophh_store_pvs cophh_store_sv"
+.IX Item "cophh_store_sv"
+.PD
+NOTE: all these forms are \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+These store a value, associated with a key, in the cop hints hash \f(CW\*(C`cophh\*(C'\fR,
+and return the modified hash. The returned hash pointer is in general
+not the same as the hash pointer that was passed in. The input hash is
+consumed by the function, and the pointer to it must not be subsequently
+used. Use "cophh_copy" if you need both hashes.
+.Sp
+\&\f(CW\*(C`value\*(C'\fR is the scalar value to store for this key. \f(CW\*(C`value\*(C'\fR is copied
+by these functions, which thus do not take ownership of any reference
+to it, and hence later changes to the scalar will not be reflected in the value
+visible in the cop hints hash. Complex types of scalar will not be stored with
+referential integrity, but will be coerced to strings.
+.Sp
+The forms differ in how the key is specified. In all forms, the key is pointed
+to by \f(CW\*(C`key\*(C'\fR.
+In the plain \f(CW\*(C`pv\*(C'\fR form, the key is a C language NUL-terminated string.
+In the \f(CW\*(C`pvs\*(C'\fR form, the key is a C language string literal.
+In the \f(CW\*(C`pvn\*(C'\fR form, an additional parameter, \f(CW\*(C`keylen\*(C'\fR, specifies the length of
+the string, which hence, may contain embedded-NUL characters.
+In the \f(CW\*(C`sv\*(C'\fR form, \f(CW*key\fR is an SV, and the key is the PV extracted from that.
+using \f(CW"SvPV_const"\fR.
+.Sp
+\&\f(CW\*(C`hash\*(C'\fR is a precomputed hash of the key string, or zero if it has not been
+precomputed. This parameter is omitted from the \f(CW\*(C`pvs\*(C'\fR form, as it is computed
+automatically at compile time.
+.Sp
+The only flag currently used from the \f(CW\*(C`flags\*(C'\fR parameter is \f(CW\*(C`COPHH_KEY_UTF8\*(C'\fR.
+It is illegal to set this in the \f(CW\*(C`sv\*(C'\fR form. In the \f(CW\*(C`pv*\*(C'\fR forms, it specifies
+whether the key octets are interpreted as UTF\-8 (if set) or as Latin\-1 (if
+cleared). The \f(CW\*(C`sv\*(C'\fR form uses the underlying SV to determine the UTF\-8ness of
+the octets.
+.RS 4
+.Sp
+.Vb 9
+\& COPHH * cophh_store_pv (COPHH *cophh, const char *key, U32 hash,
+\& SV *value, U32 flags)
+\& COPHH * cophh_store_pvn(COPHH *cophh, const char *key,
+\& STRLEN keylen, U32 hash, SV *value,
+\& U32 flags)
+\& COPHH * cophh_store_pvs(COPHH *cophh, "key", SV *value,
+\& U32 flags)
+\& COPHH * cophh_store_sv (COPHH *cophh, SV *key, U32 hash,
+\& SV *value, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cop_hints_exists_pv""" 4
+.el .IP \f(CWcop_hints_exists_pv\fR 4
+.IX Item "cop_hints_exists_pv"
+.PD 0
+.ie n .IP """cop_hints_exists_pvn""" 4
+.el .IP \f(CWcop_hints_exists_pvn\fR 4
+.IX Item "cop_hints_exists_pvn"
+.ie n .IP """cop_hints_exists_pvs""" 4
+.el .IP \f(CWcop_hints_exists_pvs\fR 4
+.IX Item "cop_hints_exists_pvs"
+.ie n .IP """cop_hints_exists_sv""" 4
+.el .IP \f(CWcop_hints_exists_sv\fR 4
+.IX Xref "cop_hints_exists_pv cop_hints_exists_pvn cop_hints_exists_pvs cop_hints_exists_sv"
+.IX Item "cop_hints_exists_sv"
+.PD
+These look up the hint entry in the cop \f(CW\*(C`cop\*(C'\fR with the key specified by
+\&\f(CW\*(C`key\*(C'\fR (and \f(CW\*(C`keylen\*(C'\fR in the \f(CW\*(C`pvn\*(C'\fR form), returning true if a value exists,
+and false otherwise.
+.Sp
+The forms differ in how the key is specified. In all forms, the key is pointed
+to by \f(CW\*(C`key\*(C'\fR.
+In the plain \f(CW\*(C`pv\*(C'\fR form, the key is a C language NUL-terminated string.
+In the \f(CW\*(C`pvs\*(C'\fR form, the key is a C language string literal.
+In the \f(CW\*(C`pvn\*(C'\fR form, an additional parameter, \f(CW\*(C`keylen\*(C'\fR, specifies the length of
+the string, which hence, may contain embedded-NUL characters.
+In the \f(CW\*(C`sv\*(C'\fR form, \f(CW*key\fR is an SV, and the key is the PV extracted from that.
+using \f(CW"SvPV_const"\fR.
+.Sp
+\&\f(CW\*(C`hash\*(C'\fR is a precomputed hash of the key string, or zero if it has not been
+precomputed. This parameter is omitted from the \f(CW\*(C`pvs\*(C'\fR form, as it is computed
+automatically at compile time.
+.Sp
+The only flag currently used from the \f(CW\*(C`flags\*(C'\fR parameter is \f(CW\*(C`COPHH_KEY_UTF8\*(C'\fR.
+It is illegal to set this in the \f(CW\*(C`sv\*(C'\fR form. In the \f(CW\*(C`pv*\*(C'\fR forms, it specifies
+whether the key octets are interpreted as UTF\-8 (if set) or as Latin\-1 (if
+cleared). The \f(CW\*(C`sv\*(C'\fR form uses the underlying SV to determine the UTF\-8ness of
+the octets.
+.RS 4
+.Sp
+.Vb 7
+\& bool cop_hints_exists_pv (const COP *cop, const char *key,
+\& U32 hash, U32 flags)
+\& bool cop_hints_exists_pvn(const COP *cop, const char *key,
+\& STRLEN keylen, U32 hash, U32 flags)
+\& bool cop_hints_exists_pvs(const COP *cop, "key", U32 flags)
+\& bool cop_hints_exists_sv (const COP *cop, SV *key, U32 hash,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cop_hints_fetch_pv""" 4
+.el .IP \f(CWcop_hints_fetch_pv\fR 4
+.IX Item "cop_hints_fetch_pv"
+.PD 0
+.ie n .IP """cop_hints_fetch_pvn""" 4
+.el .IP \f(CWcop_hints_fetch_pvn\fR 4
+.IX Item "cop_hints_fetch_pvn"
+.ie n .IP """cop_hints_fetch_pvs""" 4
+.el .IP \f(CWcop_hints_fetch_pvs\fR 4
+.IX Item "cop_hints_fetch_pvs"
+.ie n .IP """cop_hints_fetch_sv""" 4
+.el .IP \f(CWcop_hints_fetch_sv\fR 4
+.IX Xref "cop_hints_fetch_pv cop_hints_fetch_pvn cop_hints_fetch_pvs cop_hints_fetch_sv"
+.IX Item "cop_hints_fetch_sv"
+.PD
+These look up the hint entry in the cop \f(CW\*(C`cop\*(C'\fR with the key specified by
+\&\f(CW\*(C`key\*(C'\fR (and \f(CW\*(C`keylen\*(C'\fR in the \f(CW\*(C`pvn\*(C'\fR form), returning that value as a mortal
+scalar copy, or \f(CW&PL_sv_placeholder\fR if there is no value associated with the
+key.
+.Sp
+The forms differ in how the key is specified.
+In the plain \f(CW\*(C`pv\*(C'\fR form, the key is a C language NUL-terminated string.
+In the \f(CW\*(C`pvs\*(C'\fR form, the key is a C language string literal.
+In the \f(CW\*(C`pvn\*(C'\fR form, an additional parameter, \f(CW\*(C`keylen\*(C'\fR, specifies the length of
+the string, which hence, may contain embedded-NUL characters.
+In the \f(CW\*(C`sv\*(C'\fR form, \f(CW*key\fR is an SV, and the key is the PV extracted from that.
+using \f(CW"SvPV_const"\fR.
+.Sp
+\&\f(CW\*(C`hash\*(C'\fR is a precomputed hash of the key string, or zero if it has not been
+precomputed. This parameter is omitted from the \f(CW\*(C`pvs\*(C'\fR form, as it is computed
+automatically at compile time.
+.Sp
+The only flag currently used from the \f(CW\*(C`flags\*(C'\fR parameter is \f(CW\*(C`COPHH_KEY_UTF8\*(C'\fR.
+It is illegal to set this in the \f(CW\*(C`sv\*(C'\fR form. In the \f(CW\*(C`pv*\*(C'\fR forms, it specifies
+whether the key octets are interpreted as UTF\-8 (if set) or as Latin\-1 (if
+cleared). The \f(CW\*(C`sv\*(C'\fR form uses the underlying SV to determine the UTF\-8ness of
+the octets.
+.RS 4
+.Sp
+.Vb 7
+\& SV * cop_hints_fetch_pv (const COP *cop, const char *key,
+\& U32 hash, U32 flags)
+\& SV * cop_hints_fetch_pvn(const COP *cop, const char *key,
+\& STRLEN keylen, U32 hash, U32 flags)
+\& SV * cop_hints_fetch_pvs(const COP *cop, "key", U32 flags)
+\& SV * cop_hints_fetch_sv (const COP *cop, SV *key, U32 hash,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cop_hints_2hv""" 4
+.el .IP \f(CWcop_hints_2hv\fR 4
+.IX Xref "cop_hints_2hv"
+.IX Item "cop_hints_2hv"
+Generates and returns a standard Perl hash representing the full set of
+hint entries in the cop \f(CW\*(C`cop\*(C'\fR. \f(CW\*(C`flags\*(C'\fR is currently unused and must
+be zero.
+.RS 4
+.Sp
+.Vb 1
+\& HV * cop_hints_2hv(const COP *cop, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopLABEL""" 4
+.el .IP \f(CWCopLABEL\fR 4
+.IX Item "CopLABEL"
+.PD 0
+.ie n .IP """CopLABEL_len""" 4
+.el .IP \f(CWCopLABEL_len\fR 4
+.IX Item "CopLABEL_len"
+.ie n .IP """CopLABEL_len_flags""" 4
+.el .IP \f(CWCopLABEL_len_flags\fR 4
+.IX Xref "CopLABEL CopLABEL_len CopLABEL_len_flags"
+.IX Item "CopLABEL_len_flags"
+.PD
+These return the label attached to a cop.
+.Sp
+\&\f(CW\*(C`CopLABEL_len\*(C'\fR and \f(CW\*(C`CopLABEL_len_flags\*(C'\fR additionally store the number of
+bytes comprising the returned label into \f(CW*len\fR.
+.Sp
+\&\f(CW\*(C`CopLABEL_len_flags\*(C'\fR additionally returns the UTF\-8ness of the returned label,
+by setting \f(CW*flags\fR to 0 or \f(CW\*(C`SVf_UTF8\*(C'\fR.
+.RS 4
+.Sp
+.Vb 4
+\& const char * CopLABEL (COP *const cop)
+\& const char * CopLABEL_len (COP *const cop, STRLEN *len)
+\& const char * CopLABEL_len_flags(COP *const cop, STRLEN *len,
+\& U32 *flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopLINE""" 4
+.el .IP \f(CWCopLINE\fR 4
+.IX Xref "CopLINE"
+.IX Item "CopLINE"
+Returns the line number in the source code associated with the \f(CW\*(C`COP\*(C'\fR \f(CW\*(C`c\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& line_t CopLINE(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopSTASH""" 4
+.el .IP \f(CWCopSTASH\fR 4
+.IX Xref "CopSTASH"
+.IX Item "CopSTASH"
+Returns the stash associated with \f(CW\*(C`c\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& HV * CopSTASH(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopSTASH_eq""" 4
+.el .IP \f(CWCopSTASH_eq\fR 4
+.IX Xref "CopSTASH_eq"
+.IX Item "CopSTASH_eq"
+Returns a boolean as to whether or not \f(CW\*(C`hv\*(C'\fR is the stash associated with \f(CW\*(C`c\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool CopSTASH_eq(const COP * c, const HV * hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopSTASHPV""" 4
+.el .IP \f(CWCopSTASHPV\fR 4
+.IX Xref "CopSTASHPV"
+.IX Item "CopSTASHPV"
+Returns the package name of the stash associated with \f(CW\*(C`c\*(C'\fR, or \f(CW\*(C`NULL\*(C'\fR if no
+associated stash
+.RS 4
+.Sp
+.Vb 1
+\& char * CopSTASHPV(const COP * c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopSTASHPV_set""" 4
+.el .IP \f(CWCopSTASHPV_set\fR 4
+.IX Xref "CopSTASHPV_set"
+.IX Item "CopSTASHPV_set"
+Set the package name of the stash associated with \f(CW\*(C`c\*(C'\fR, to the NUL-terminated C
+string \f(CW\*(C`p\*(C'\fR, creating the package if necessary.
+.RS 4
+.Sp
+.Vb 1
+\& void CopSTASHPV_set(COP * c, const char * pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CopSTASH_set""" 4
+.el .IP \f(CWCopSTASH_set\fR 4
+.IX Xref "CopSTASH_set"
+.IX Item "CopSTASH_set"
+Set the stash associated with \f(CW\*(C`c\*(C'\fR to \f(CW\*(C`hv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool CopSTASH_set(COP * c, HV * hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cop_store_label""" 4
+.el .IP \f(CWcop_store_label\fR 4
+.IX Xref "cop_store_label"
+.IX Item "cop_store_label"
+NOTE: \f(CW\*(C`cop_store_label\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Save a label into a \f(CW\*(C`cop_hints_hash\*(C'\fR.
+You need to set flags to \f(CW\*(C`SVf_UTF8\*(C'\fR
+for a UTF\-8 label. Any other flag is ignored.
+.RS 4
+.Sp
+.Vb 2
+\& void cop_store_label(COP * const cop, const char *label,
+\& STRLEN len, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_SI""" 4
+.el .IP \f(CWPERL_SI\fR 4
+.IX Xref "PERL_SI"
+.IX Item "PERL_SI"
+Use this typedef to declare variables that are to hold \f(CW\*(C`struct stackinfo\*(C'\fR.
+.ie n .IP """PL_curcop""" 4
+.el .IP \f(CWPL_curcop\fR 4
+.IX Xref "PL_curcop"
+.IX Item "PL_curcop"
+The currently active COP (control op) roughly representing the current
+statement in the source.
+.Sp
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+.RS 4
+.Sp
+.Vb 1
+\& COP* PL_curcop
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """RCPV_LEN""" 4
+.el .IP \f(CWRCPV_LEN\fR 4
+.IX Xref "RCPV_LEN"
+.IX Item "RCPV_LEN"
+Returns the length of a pv created with \f(CWrcpv_new()\fR.
+Note that this reflects the length of the string from the callers
+point of view, it does not include the mandatory null which is
+always injected at the end of the string by \fBrcpv_new()\fR.
+No checks are performed to ensure that \f(CW\*(C`pv\*(C'\fR was actually allocated
+with \f(CWrcpv_new()\fR, it is the callers responsibility to ensure that
+this is the case.
+.RS 4
+.Sp
+.Vb 1
+\& RCPV * RCPV_LEN(char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """RCPV_REFCNT_dec""" 4
+.el .IP \f(CWRCPV_REFCNT_dec\fR 4
+.IX Xref "RCPV_REFCNT_dec"
+.IX Item "RCPV_REFCNT_dec"
+Decrements the refcount for a \f(CW\*(C`char *\*(C'\fR pointer which was created
+with a call to \f(CWrcpv_new()\fR. Same as calling \fBrcpv_free()\fR.
+No checks are performed to ensure that \f(CW\*(C`pv\*(C'\fR was actually allocated
+with \f(CWrcpv_new()\fR, it is the callers responsibility to ensure that
+this is the case.
+.RS 4
+.Sp
+.Vb 1
+\& RCPV * RCPV_REFCNT_dec(char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """RCPV_REFCNT_inc""" 4
+.el .IP \f(CWRCPV_REFCNT_inc\fR 4
+.IX Xref "RCPV_REFCNT_inc"
+.IX Item "RCPV_REFCNT_inc"
+Increments the refcount for a \f(CW\*(C`char *\*(C'\fR pointer which was created
+with a call to \f(CWrcpv_new()\fR. Same as calling \fBrcpv_copy()\fR.
+No checks are performed to ensure that \f(CW\*(C`pv\*(C'\fR was actually allocated
+with \f(CWrcpv_new()\fR, it is the callers responsibility to ensure that
+this is the case.
+.RS 4
+.Sp
+.Vb 1
+\& RCPV * RCPV_REFCNT_inc(char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """RCPV_REFCOUNT""" 4
+.el .IP \f(CWRCPV_REFCOUNT\fR 4
+.IX Xref "RCPV_REFCOUNT"
+.IX Item "RCPV_REFCOUNT"
+Returns the refcount for a pv created with \f(CWrcpv_new()\fR.
+No checks are performed to ensure that \f(CW\*(C`pv\*(C'\fR was actually allocated
+with \f(CWrcpv_new()\fR, it is the callers responsibility to ensure that
+this is the case.
+.RS 4
+.Sp
+.Vb 1
+\& RCPV * RCPV_REFCOUNT(char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """RCPVx""" 4
+.el .IP \f(CWRCPVx\fR 4
+.IX Xref "RCPVx"
+.IX Item "RCPVx"
+Returns the RCPV structure (struct rcpv) for a refcounted
+string pv created with \f(CWrcpv_new()\fR.
+No checks are performed to ensure that \f(CW\*(C`pv\*(C'\fR was actually allocated
+with \f(CWrcpv_new()\fR, it is the callers responsibility to ensure that
+this is the case.
+.RS 4
+.Sp
+.Vb 1
+\& RCPV * RCPVx(char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Custom Operators"
+.IX Header "Custom Operators"
+.ie n .IP """custom_op_register""" 4
+.el .IP \f(CWcustom_op_register\fR 4
+.IX Xref "custom_op_register"
+.IX Item "custom_op_register"
+Register a custom op. See "Custom Operators" in perlguts.
+.Sp
+NOTE: \f(CW\*(C`custom_op_register\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_custom_op_register\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& void Perl_custom_op_register(pTHX_ Perl_ppaddr_t ppaddr,
+\& const XOP *xop)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Perl_custom_op_xop""" 4
+.el .IP \f(CWPerl_custom_op_xop\fR 4
+.IX Xref "Perl_custom_op_xop"
+.IX Item "Perl_custom_op_xop"
+Return the XOP structure for a given custom op. This macro should be
+considered internal to \f(CW\*(C`OP_NAME\*(C'\fR and the other access macros: use them instead.
+This macro does call a function. Prior
+to 5.19.6, this was implemented as a
+function.
+.RS 4
+.Sp
+.Vb 1
+\& const XOP * Perl_custom_op_xop(pTHX_ const OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XopDISABLE""" 4
+.el .IP \f(CWXopDISABLE\fR 4
+.IX Xref "XopDISABLE"
+.IX Item "XopDISABLE"
+Temporarily disable a member of the XOP, by clearing the appropriate flag.
+.RS 4
+.Sp
+.Vb 1
+\& void XopDISABLE(XOP *xop, token which)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XopENABLE""" 4
+.el .IP \f(CWXopENABLE\fR 4
+.IX Xref "XopENABLE"
+.IX Item "XopENABLE"
+Reenable a member of the XOP which has been disabled.
+.RS 4
+.Sp
+.Vb 1
+\& void XopENABLE(XOP *xop, token which)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XopENTRY""" 4
+.el .IP \f(CWXopENTRY\fR 4
+.IX Xref "XopENTRY"
+.IX Item "XopENTRY"
+Return a member of the XOP structure. \f(CW\*(C`which\*(C'\fR is a cpp token
+indicating which entry to return. If the member is not set
+this will return a default value. The return type depends
+on \f(CW\*(C`which\*(C'\fR. This macro evaluates its arguments more than
+once. If you are using \f(CW\*(C`Perl_custom_op_xop\*(C'\fR to retrieve a
+\&\f(CW\*(C`XOP *\*(C'\fR from a \f(CW\*(C`OP *\*(C'\fR, use the more efficient "XopENTRYCUSTOM" instead.
+.RS 4
+.Sp
+.Vb 1
+\& XopENTRY(XOP *xop, token which)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XopENTRYCUSTOM""" 4
+.el .IP \f(CWXopENTRYCUSTOM\fR 4
+.IX Xref "XopENTRYCUSTOM"
+.IX Item "XopENTRYCUSTOM"
+Exactly like \f(CW\*(C`XopENTRY(XopENTRY(Perl_custom_op_xop(aTHX_ o), which)\*(C'\fR but more
+efficient. The \f(CW\*(C`which\*(C'\fR parameter is identical to "XopENTRY".
+.RS 4
+.Sp
+.Vb 1
+\& XopENTRYCUSTOM(const OP *o, token which)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XopENTRY_set""" 4
+.el .IP \f(CWXopENTRY_set\fR 4
+.IX Xref "XopENTRY_set"
+.IX Item "XopENTRY_set"
+Set a member of the XOP structure. \f(CW\*(C`which\*(C'\fR is a cpp token
+indicating which entry to set. See "Custom Operators" in perlguts
+for details about the available members and how
+they are used. This macro evaluates its argument
+more than once.
+.RS 4
+.Sp
+.Vb 1
+\& void XopENTRY_set(XOP *xop, token which, value)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XopFLAGS""" 4
+.el .IP \f(CWXopFLAGS\fR 4
+.IX Xref "XopFLAGS"
+.IX Item "XopFLAGS"
+Return the XOP's flags.
+.RS 4
+.Sp
+.Vb 1
+\& U32 XopFLAGS(XOP *xop)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "CV Handling"
+.IX Xref "CV GV_ADD"
+.IX Header "CV Handling"
+This section documents functions to manipulate CVs which are
+code-values, meaning subroutines. For more information, see
+perlguts.
+.ie n .IP """caller_cx""" 4
+.el .IP \f(CWcaller_cx\fR 4
+.IX Xref "caller_cx"
+.IX Item "caller_cx"
+The XSUB-writer's equivalent of \fBcaller()\fR. The
+returned \f(CW\*(C`PERL_CONTEXT\*(C'\fR structure can be interrogated to find all the
+information returned to Perl by \f(CW\*(C`caller\*(C'\fR. Note that XSUBs don't get a
+stack frame, so \f(CW\*(C`caller_cx(0, NULL)\*(C'\fR will return information for the
+immediately-surrounding Perl code.
+.Sp
+This function skips over the automatic calls to \f(CW&DB::sub\fR made on the
+behalf of the debugger. If the stack frame requested was a sub called by
+\&\f(CW\*(C`DB::sub\*(C'\fR, the return value will be the frame for the call to
+\&\f(CW\*(C`DB::sub\*(C'\fR, since that has the correct line number/etc. for the call
+site. If \fIdbcxp\fR is non\-\f(CW\*(C`NULL\*(C'\fR, it will be set to a pointer to the
+frame for the sub call itself.
+.RS 4
+.Sp
+.Vb 2
+\& const PERL_CONTEXT * caller_cx(I32 level,
+\& const PERL_CONTEXT **dbcxp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CvDEPTH""" 4
+.el .IP \f(CWCvDEPTH\fR 4
+.IX Xref "CvDEPTH"
+.IX Item "CvDEPTH"
+Returns the recursion level of the CV \f(CW\*(C`sv\*(C'\fR. Hence >= 2 indicates we are in a
+recursive call.
+.RS 4
+.Sp
+.Vb 1
+\& I32 * CvDEPTH(const CV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CvGV""" 4
+.el .IP \f(CWCvGV\fR 4
+.IX Xref "CvGV"
+.IX Item "CvGV"
+Returns the GV associated with the CV \f(CW\*(C`sv\*(C'\fR, reifying it if necessary.
+.RS 4
+.Sp
+.Vb 1
+\& GV * CvGV(CV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CvSTASH""" 4
+.el .IP \f(CWCvSTASH\fR 4
+.IX Xref "CvSTASH"
+.IX Item "CvSTASH"
+Returns the stash of the CV. A stash is the symbol table hash, containing
+the package-scoped variables in the package where the subroutine was defined.
+For more information, see perlguts.
+.Sp
+This also has a special use with XS AUTOLOAD subs.
+See "Autoloading with XSUBs" in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& HV* CvSTASH(CV* cv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """find_runcv""" 4
+.el .IP \f(CWfind_runcv\fR 4
+.IX Xref "find_runcv"
+.IX Item "find_runcv"
+Locate the CV corresponding to the currently executing sub or eval.
+If \f(CW\*(C`db_seqp\*(C'\fR is non_null, skip CVs that are in the DB package and populate
+\&\f(CW*db_seqp\fR with the cop sequence number at the point that the DB:: code was
+entered. (This allows debuggers to eval in the scope of the breakpoint
+rather than in the scope of the debugger itself.)
+.RS 4
+.Sp
+.Vb 1
+\& CV * find_runcv(U32 *db_seqp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """get_cv""" 4
+.el .IP \f(CWget_cv\fR 4
+.IX Item "get_cv"
+.PD 0
+.ie n .IP """get_cvn_flags""" 4
+.el .IP \f(CWget_cvn_flags\fR 4
+.IX Item "get_cvn_flags"
+.ie n .IP """get_cvs""" 4
+.el .IP \f(CWget_cvs\fR 4
+.IX Xref "get_cv get_cvn_flags get_cvs"
+.IX Item "get_cvs"
+.PD
+These return the CV of the specified Perl subroutine. \f(CW\*(C`flags\*(C'\fR are passed to
+\&\f(CW\*(C`gv_fetchpvn_flags\*(C'\fR. If \f(CW\*(C`GV_ADD\*(C'\fR is set and the Perl subroutine does not
+exist then it will be declared (which has the same effect as saying
+\&\f(CW\*(C`sub name;\*(C'\fR). If \f(CW\*(C`GV_ADD\*(C'\fR is not set and the subroutine does not exist,
+then NULL is returned.
+.Sp
+The forms differ only in how the subroutine is specified.. With \f(CW\*(C`get_cvs\*(C'\fR,
+the name is a literal C string, enclosed in double quotes. With \f(CW\*(C`get_cv\*(C'\fR, the
+name is given by the \f(CW\*(C`name\*(C'\fR parameter, which must be a NUL-terminated C
+string. With \f(CW\*(C`get_cvn_flags\*(C'\fR, the name is also given by the \f(CW\*(C`name\*(C'\fR
+parameter, but it is a Perl string (possibly containing embedded NUL bytes),
+and its length in bytes is contained in the \f(CW\*(C`len\*(C'\fR parameter.
+.Sp
+NOTE: the \f(CWperl_get_cv()\fR form is \fBdeprecated\fR.
+.Sp
+NOTE: the \f(CWperl_get_cvn_flags()\fR form is \fBdeprecated\fR.
+.Sp
+NOTE: the \f(CWperl_get_cvs()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 3
+\& CV * get_cv (const char *name, I32 flags)
+\& CV * get_cvn_flags(const char *name, STRLEN len, I32 flags)
+\& CV * get_cvs ("string", I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Nullcv""" 4
+.el .IP \f(CWNullcv\fR 4
+.IX Xref "Nullcv"
+.IX Item "Nullcv"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`Nullcv\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Null CV pointer.
+.Sp
+(deprecated \- use \f(CW\*(C`(CV *)NULL\*(C'\fR instead)
+.SH Debugging
+.IX Header "Debugging"
+.ie n .IP """av_dump""" 4
+.el .IP \f(CWav_dump\fR 4
+.IX Xref "av_dump"
+.IX Item "av_dump"
+Dumps the contents of an AV to the \f(CW\*(C`STDERR\*(C'\fR filehandle,
+Similar to using Devel::Peek on an arrayref but does not
+expect an RV wrapper. Dumps contents to a depth of 3 levels
+deep.
+.RS 4
+.Sp
+.Vb 1
+\& void av_dump(AV *av)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """deb""" 4
+.el .IP \f(CWdeb\fR 4
+.IX Item "deb"
+.PD 0
+.ie n .IP """deb_nocontext""" 4
+.el .IP \f(CWdeb_nocontext\fR 4
+.IX Xref "deb deb_nocontext"
+.IX Item "deb_nocontext"
+.PD
+When perl is compiled with \f(CW\*(C`\-DDEBUGGING\*(C'\fR, this prints to STDERR the
+information given by the arguments, prefaced by the name of the file containing
+the script causing the call, and the line number within that file.
+.Sp
+If the \f(CW\*(C`v\*(C'\fR (verbose) debugging option is in effect, the process id is also
+printed.
+.Sp
+The two forms differ only in that \f(CW\*(C`deb_nocontext\*(C'\fR does not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter, so is used in situations where the caller doesn't
+already have the thread context.
+.Sp
+NOTE: \f(CW\*(C`deb\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_deb\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& void Perl_deb (pTHX_ const char *pat, ...)
+\& void deb_nocontext(const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """debstack""" 4
+.el .IP \f(CWdebstack\fR 4
+.IX Xref "debstack"
+.IX Item "debstack"
+Dump the current stack
+.RS 4
+.Sp
+.Vb 1
+\& I32 debstack()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dump_all""" 4
+.el .IP \f(CWdump_all\fR 4
+.IX Xref "dump_all"
+.IX Item "dump_all"
+Dumps the entire optree of the current program starting at \f(CW\*(C`PL_main_root\*(C'\fR to
+\&\f(CW\*(C`STDERR\*(C'\fR. Also dumps the optrees for all visible subroutines in
+\&\f(CW\*(C`PL_defstash\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void dump_all()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dump_c_backtrace""" 4
+.el .IP \f(CWdump_c_backtrace\fR 4
+.IX Xref "dump_c_backtrace"
+.IX Item "dump_c_backtrace"
+Dumps the C backtrace to the given \f(CW\*(C`fp\*(C'\fR.
+.Sp
+Returns true if a backtrace could be retrieved, false if not.
+.RS 4
+.Sp
+.Vb 1
+\& bool dump_c_backtrace(PerlIO *fp, int max_depth, int skip)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dump_eval""" 4
+.el .IP \f(CWdump_eval\fR 4
+.IX Item "dump_eval"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& void dump_eval()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dump_form""" 4
+.el .IP \f(CWdump_form\fR 4
+.IX Xref "dump_form"
+.IX Item "dump_form"
+Dumps the contents of the format contained in the GV \f(CW\*(C`gv\*(C'\fR to \f(CW\*(C`STDERR\*(C'\fR, or a
+message that one doesn't exist.
+.RS 4
+.Sp
+.Vb 1
+\& void dump_form(const GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dump_packsubs""" 4
+.el .IP \f(CWdump_packsubs\fR 4
+.IX Xref "dump_packsubs"
+.IX Item "dump_packsubs"
+Dumps the optrees for all visible subroutines in \f(CW\*(C`stash\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void dump_packsubs(const HV *stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dump_sub""" 4
+.el .IP \f(CWdump_sub\fR 4
+.IX Item "dump_sub"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& void dump_sub(const GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """get_c_backtrace_dump""" 4
+.el .IP \f(CWget_c_backtrace_dump\fR 4
+.IX Xref "get_c_backtrace_dump"
+.IX Item "get_c_backtrace_dump"
+Returns a SV containing a dump of \f(CW\*(C`depth\*(C'\fR frames of the call stack, skipping
+the \f(CW\*(C`skip\*(C'\fR innermost ones. \f(CW\*(C`depth\*(C'\fR of 20 is usually enough.
+.Sp
+The appended output looks like:
+.Sp
+.Vb 4
+\& ...
+\& 1 10e004812:0082 Perl_croak util.c:1716 /usr/bin/perl
+\& 2 10df8d6d2:1d72 perl_parse perl.c:3975 /usr/bin/perl
+\& ...
+.Ve
+.Sp
+The fields are tab-separated. The first column is the depth (zero
+being the innermost non-skipped frame). In the hex:offset, the hex is
+where the program counter was in \f(CW\*(C`S_parse_body\*(C'\fR, and the :offset (might
+be missing) tells how much inside the \f(CW\*(C`S_parse_body\*(C'\fR the program counter was.
+.Sp
+The \f(CW\*(C`util.c:1716\*(C'\fR is the source code file and line number.
+.Sp
+The \fI/usr/bin/perl\fR is obvious (hopefully).
+.Sp
+Unknowns are \f(CW"\-"\fR. Unknowns can happen unfortunately quite easily:
+if the platform doesn't support retrieving the information;
+if the binary is missing the debug information;
+if the optimizer has transformed the code by for example inlining.
+.RS 4
+.Sp
+.Vb 1
+\& SV * get_c_backtrace_dump(int max_depth, int skip)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_dump""" 4
+.el .IP \f(CWgv_dump\fR 4
+.IX Xref "gv_dump"
+.IX Item "gv_dump"
+Dump the name and, if they differ, the effective name of the GV \f(CW\*(C`gv\*(C'\fR to
+\&\f(CW\*(C`STDERR\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void gv_dump(GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HAS_BACKTRACE""" 4
+.el .IP \f(CWHAS_BACKTRACE\fR 4
+.IX Xref "HAS_BACKTRACE"
+.IX Item "HAS_BACKTRACE"
+This symbol, if defined, indicates that the \f(CWbacktrace()\fR routine is
+available to get a stack trace. The \fIexecinfo.h\fR header must be
+included to use this routine.
+.ie n .IP """hv_dump""" 4
+.el .IP \f(CWhv_dump\fR 4
+.IX Xref "hv_dump"
+.IX Item "hv_dump"
+Dumps the contents of an HV to the \f(CW\*(C`STDERR\*(C'\fR filehandle.
+Similar to using Devel::Peek on an hashref but does not
+expect an RV wrapper. Dumps contents to a depth of 3 levels
+deep.
+.RS 4
+.Sp
+.Vb 1
+\& void hv_dump(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """magic_dump""" 4
+.el .IP \f(CWmagic_dump\fR 4
+.IX Xref "magic_dump"
+.IX Item "magic_dump"
+Dumps the contents of the MAGIC \f(CW\*(C`mg\*(C'\fR to \f(CW\*(C`STDERR\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void magic_dump(const MAGIC *mg)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_class""" 4
+.el .IP \f(CWop_class\fR 4
+.IX Xref "op_class"
+.IX Item "op_class"
+Given an op, determine what type of struct it has been allocated as.
+Returns one of the OPclass enums, such as OPclass_LISTOP.
+.RS 4
+.Sp
+.Vb 1
+\& OPclass op_class(const OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_dump""" 4
+.el .IP \f(CWop_dump\fR 4
+.IX Xref "op_dump"
+.IX Item "op_dump"
+Dumps the optree starting at OP \f(CW\*(C`o\*(C'\fR to \f(CW\*(C`STDERR\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void op_dump(const OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_op""" 4
+.el .IP \f(CWPL_op\fR 4
+.IX Item "PL_op"
+Described in perlhacktips.
+.ie n .IP """PL_runops""" 4
+.el .IP \f(CWPL_runops\fR 4
+.IX Item "PL_runops"
+Described in perlguts.
+.ie n .IP """PL_sv_serial""" 4
+.el .IP \f(CWPL_sv_serial\fR 4
+.IX Item "PL_sv_serial"
+Described in perlhacktips.
+.ie n .IP """pmop_dump""" 4
+.el .IP \f(CWpmop_dump\fR 4
+.IX Xref "pmop_dump"
+.IX Item "pmop_dump"
+Dump an OP that is related to Pattern Matching, such as \f(CW\*(C`s/foo/bar/\*(C'\fR; these require
+special handling.
+.RS 4
+.Sp
+.Vb 1
+\& void pmop_dump(PMOP *pm)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_dump""" 4
+.el .IP \f(CWsv_dump\fR 4
+.IX Xref "sv_dump"
+.IX Item "sv_dump"
+Dumps the contents of an SV to the \f(CW\*(C`STDERR\*(C'\fR filehandle.
+.Sp
+For an example of its output, see Devel::Peek. If
+the item is an SvROK it will dump items to a depth of 4,
+otherwise it will dump only the top level item, which
+means that it will not dump the contents of an AV * or
+HV *. For that use \f(CWav_dump()\fR or \f(CWhv_dump()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_dump(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_dump_depth""" 4
+.el .IP \f(CWsv_dump_depth\fR 4
+.IX Xref "sv_dump_depth"
+.IX Item "sv_dump_depth"
+Dumps the contents of an SV to the \f(CW\*(C`STDERR\*(C'\fR filehandle
+to the depth requested. This function can be used on any
+SV derived type (GV, HV, AV) with an appropriate cast.
+This is a more flexible variant of \fBsv_dump()\fR. For example
+.Sp
+.Vb 2
+\& HV *hv = ...;
+\& sv_dump_depth((SV*)hv, 2);
+.Ve
+.Sp
+would dump the hv, its keys and values, but would not recurse
+into any RV values.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_dump_depth(SV *sv, I32 depth)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vdeb""" 4
+.el .IP \f(CWvdeb\fR 4
+.IX Xref "vdeb"
+.IX Item "vdeb"
+This is like \f(CW"deb"\fR, but \f(CW\*(C`args\*(C'\fR are an encapsulated argument list.
+.RS 4
+.Sp
+.Vb 1
+\& void vdeb(const char *pat, va_list *args)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Display functions"
+.IX Xref "PERL_PV_ESCAPE_ALL PERL_PV_ESCAPE_FIRSTCHAR PERL_PV_ESCAPE_NOBACKSLASH PERL_PV_ESCAPE_NOCLEAR PERL_PV_ESCAPE_NONASCII PERL_PV_ESCAPE_NON_WC PERL_PV_ESCAPE_QUOTE PERL_PV_ESCAPE_RE PERL_PV_ESCAPE_UNI PERL_PV_ESCAPE_UNI_DETECT PERL_PV_PRETTY_ELLIPSES PERL_PV_PRETTY_LTGT PERL_PV_PRETTY_QUOTE"
+.IX Header "Display functions"
+.ie n .IP """form""" 4
+.el .IP \f(CWform\fR 4
+.IX Item "form"
+.PD 0
+.ie n .IP """form_nocontext""" 4
+.el .IP \f(CWform_nocontext\fR 4
+.IX Xref "form form_nocontext"
+.IX Item "form_nocontext"
+.PD
+These take a sprintf-style format pattern and conventional
+(non-SV) arguments and return the formatted string.
+.Sp
+.Vb 1
+\& (char *) Perl_form(pTHX_ const char* pat, ...)
+.Ve
+.Sp
+can be used any place a string (char *) is required:
+.Sp
+.Vb 1
+\& char * s = Perl_form("%d.%d",major,minor);
+.Ve
+.Sp
+They use a single (per-thread) private buffer so if you want to format several
+strings you must explicitly copy the earlier strings away (and free the copies
+when you are done).
+.Sp
+The two forms differ only in that \f(CW\*(C`form_nocontext\*(C'\fR does not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter, so is used in situations where the caller doesn't
+already have the thread context.
+.Sp
+NOTE: \f(CW\*(C`form\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_form\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& char * Perl_form (pTHX_ const char *pat, ...)
+\& char * form_nocontext(const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mess""" 4
+.el .IP \f(CWmess\fR 4
+.IX Item "mess"
+.PD 0
+.ie n .IP """mess_nocontext""" 4
+.el .IP \f(CWmess_nocontext\fR 4
+.IX Xref "mess mess_nocontext"
+.IX Item "mess_nocontext"
+.PD
+These take a sprintf-style format pattern and argument list, which are used to
+generate a string message. If the message does not end with a newline, then it
+will be extended with some indication of the current location in the code, as
+described for \f(CW"mess_sv"\fR.
+.Sp
+Normally, the resulting message is returned in a new mortal SV.
+But during global destruction a single SV may be shared between uses of
+this function.
+.Sp
+The two forms differ only in that \f(CW\*(C`mess_nocontext\*(C'\fR does not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter, so is used in situations where the caller doesn't
+already have the thread context.
+.Sp
+NOTE: \f(CW\*(C`mess\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_mess\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& SV * Perl_mess (pTHX_ const char *pat, ...)
+\& SV * mess_nocontext(const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mess_sv""" 4
+.el .IP \f(CWmess_sv\fR 4
+.IX Xref "mess_sv"
+.IX Item "mess_sv"
+Expands a message, intended for the user, to include an indication of
+the current location in the code, if the message does not already appear
+to be complete.
+.Sp
+\&\f(CW\*(C`basemsg\*(C'\fR is the initial message or object. If it is a reference, it
+will be used as-is and will be the result of this function. Otherwise it
+is used as a string, and if it already ends with a newline, it is taken
+to be complete, and the result of this function will be the same string.
+If the message does not end with a newline, then a segment such as \f(CW\*(C`at
+foo.pl line 37\*(C'\fR will be appended, and possibly other clauses indicating
+the current state of execution. The resulting message will end with a
+dot and a newline.
+.Sp
+Normally, the resulting message is returned in a new mortal SV.
+During global destruction a single SV may be shared between uses of this
+function. If \f(CW\*(C`consume\*(C'\fR is true, then the function is permitted (but not
+required) to modify and return \f(CW\*(C`basemsg\*(C'\fR instead of allocating a new SV.
+.RS 4
+.Sp
+.Vb 1
+\& SV * mess_sv(SV *basemsg, bool consume)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pv_display""" 4
+.el .IP \f(CWpv_display\fR 4
+.IX Xref "pv_display"
+.IX Item "pv_display"
+Similar to
+.Sp
+.Vb 1
+\& pv_escape(dsv,pv,cur,pvlim,PERL_PV_ESCAPE_QUOTE);
+.Ve
+.Sp
+except that an additional "\e0" will be appended to the string when
+len > cur and pv[cur] is "\e0".
+.Sp
+Note that the final string may be up to 7 chars longer than pvlim.
+.RS 4
+.Sp
+.Vb 2
+\& char * pv_display(SV *dsv, const char *pv, STRLEN cur,
+\& STRLEN len, STRLEN pvlim)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pv_escape""" 4
+.el .IP \f(CWpv_escape\fR 4
+.IX Xref "pv_escape"
+.IX Item "pv_escape"
+Escapes at most the first \f(CW\*(C`count\*(C'\fR chars of \f(CW\*(C`pv\*(C'\fR and puts the results into
+\&\f(CW\*(C`dsv\*(C'\fR such that the size of the escaped string will not exceed \f(CW\*(C`max\*(C'\fR chars
+and will not contain any incomplete escape sequences. The number of bytes
+escaped will be returned in the \f(CW\*(C`STRLEN *escaped\*(C'\fR parameter if it is not null.
+When the \f(CW\*(C`dsv\*(C'\fR parameter is null no escaping actually occurs, but the number
+of bytes that would be escaped were it not null will be calculated.
+.Sp
+If flags contains \f(CW\*(C`PERL_PV_ESCAPE_QUOTE\*(C'\fR then any double quotes in the string
+will also be escaped.
+.Sp
+Normally the SV will be cleared before the escaped string is prepared,
+but when \f(CW\*(C`PERL_PV_ESCAPE_NOCLEAR\*(C'\fR is set this will not occur.
+.Sp
+If \f(CW\*(C`PERL_PV_ESCAPE_UNI\*(C'\fR is set then the input string is treated as UTF\-8.
+If \f(CW\*(C`PERL_PV_ESCAPE_UNI_DETECT\*(C'\fR is set then the input string is scanned
+using \f(CWis_utf8_string()\fR to determine if it is UTF\-8.
+.Sp
+If \f(CW\*(C`PERL_PV_ESCAPE_ALL\*(C'\fR is set then all input chars will be output
+using \f(CW\*(C`\ex01F1\*(C'\fR style escapes, otherwise if \f(CW\*(C`PERL_PV_ESCAPE_NONASCII\*(C'\fR
+is set, only non-ASCII chars will be escaped using this style;
+otherwise, only chars above 255 will be so escaped; other non printable
+chars will use octal or common escaped patterns like \f(CW\*(C`\en\*(C'\fR. Otherwise,
+if \f(CW\*(C`PERL_PV_ESCAPE_NOBACKSLASH\*(C'\fR then all chars below 255 will be
+treated as printable and will be output as literals. The
+\&\f(CW\*(C`PERL_PV_ESCAPE_NON_WC\*(C'\fR modifies the previous rules to cause word
+chars, unicode or otherwise, to be output as literals, note this uses
+the *unicode* rules for deciding on word characters.
+.Sp
+If \f(CW\*(C`PERL_PV_ESCAPE_FIRSTCHAR\*(C'\fR is set then only the first char of the
+string will be escaped, regardless of max. If the output is to be in
+hex, then it will be returned as a plain hex sequence. Thus the output
+will either be a single char, an octal escape sequence, a special escape
+like \f(CW\*(C`\en\*(C'\fR or a hex value.
+.Sp
+If \f(CW\*(C`PERL_PV_ESCAPE_RE\*(C'\fR is set then the escape char used will be a
+\&\f(CW"%"\fR and not a \f(CW"\e\e"\fR. This is because regexes very often contain
+backslashed sequences, whereas \f(CW"%"\fR is not a particularly common
+character in patterns.
+.Sp
+Returns a pointer to the escaped text as held by \f(CW\*(C`dsv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 3
+\& char * pv_escape(SV *dsv, char const * const str,
+\& const STRLEN count, STRLEN max,
+\& STRLEN * const escaped, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pv_pretty""" 4
+.el .IP \f(CWpv_pretty\fR 4
+.IX Xref "pv_pretty"
+.IX Item "pv_pretty"
+Converts a string into something presentable, handling escaping via
+\&\f(CWpv_escape()\fR and supporting quoting and ellipses.
+.Sp
+If the \f(CW\*(C`PERL_PV_PRETTY_QUOTE\*(C'\fR flag is set then the result will be
+double quoted with any double quotes in the string escaped. Otherwise
+if the \f(CW\*(C`PERL_PV_PRETTY_LTGT\*(C'\fR flag is set then the result be wrapped in
+angle brackets.
+.Sp
+If the \f(CW\*(C`PERL_PV_PRETTY_ELLIPSES\*(C'\fR flag is set and not all characters in
+string were output then an ellipsis \f(CW\*(C`...\*(C'\fR will be appended to the
+string. Note that this happens AFTER it has been quoted.
+.Sp
+If \f(CW\*(C`start_color\*(C'\fR is non-null then it will be inserted after the opening
+quote (if there is one) but before the escaped text. If \f(CW\*(C`end_color\*(C'\fR
+is non-null then it will be inserted after the escaped text but before
+any quotes or ellipses.
+.Sp
+Returns a pointer to the prettified text as held by \f(CW\*(C`dsv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 4
+\& char * pv_pretty(SV *dsv, char const * const str,
+\& const STRLEN count, const STRLEN max,
+\& char const * const start_color,
+\& char const * const end_color, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vform""" 4
+.el .IP \f(CWvform\fR 4
+.IX Xref "vform"
+.IX Item "vform"
+Like \f(CW"form"\fR but but the arguments are an encapsulated argument list.
+.RS 4
+.Sp
+.Vb 1
+\& char * vform(const char *pat, va_list *args)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vmess""" 4
+.el .IP \f(CWvmess\fR 4
+.IX Xref "vmess"
+.IX Item "vmess"
+\&\f(CW\*(C`pat\*(C'\fR and \f(CW\*(C`args\*(C'\fR are a sprintf-style format pattern and encapsulated
+argument list, respectively. These are used to generate a string message. If
+the
+message does not end with a newline, then it will be extended with
+some indication of the current location in the code, as described for
+"mess_sv".
+.Sp
+Normally, the resulting message is returned in a new mortal SV.
+During global destruction a single SV may be shared between uses of
+this function.
+.RS 4
+.Sp
+.Vb 1
+\& SV * vmess(const char *pat, va_list *args)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Embedding, Threads, and Interpreter Cloning"
+.IX Xref "CV_NAME_NOTQUAL PADNAMEf_OUTER PERL_EXIT_ABORT PERL_EXIT_DESTRUCT_END PERL_EXIT_EXPECTED PERL_EXIT_WARN PERL_LOADMOD_DENY PERL_LOADMOD_IMPORT_OPS PERL_LOADMOD_NOIMPORT"
+.IX Header "Embedding, Threads, and Interpreter Cloning"
+.ie n .IP """call_atexit""" 4
+.el .IP \f(CWcall_atexit\fR 4
+.IX Xref "call_atexit"
+.IX Item "call_atexit"
+Add a function \f(CW\*(C`fn\*(C'\fR to the list of functions to be called at global
+destruction. \f(CW\*(C`ptr\*(C'\fR will be passed as an argument to \f(CW\*(C`fn\*(C'\fR; it can point to a
+\&\f(CW\*(C`struct\*(C'\fR so that you can pass anything you want.
+.Sp
+Note that under threads, \f(CW\*(C`fn\*(C'\fR may run multiple times. This is because the
+list is executed each time the current or any descendent thread terminates.
+.RS 4
+.Sp
+.Vb 1
+\& void call_atexit(ATEXIT_t fn, void *ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cv_clone""" 4
+.el .IP \f(CWcv_clone\fR 4
+.IX Xref "cv_clone"
+.IX Item "cv_clone"
+Clone a CV, making a lexical closure. \f(CW\*(C`proto\*(C'\fR supplies the prototype
+of the function: its code, pad structure, and other attributes.
+The prototype is combined with a capture of outer lexicals to which the
+code refers, which are taken from the currently-executing instance of
+the immediately surrounding code.
+.RS 4
+.Sp
+.Vb 1
+\& CV * cv_clone(CV *proto)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cv_name""" 4
+.el .IP \f(CWcv_name\fR 4
+.IX Xref "cv_name"
+.IX Item "cv_name"
+Returns an SV containing the name of the CV, mainly for use in error
+reporting. The CV may actually be a GV instead, in which case the returned
+SV holds the GV's name. Anything other than a GV or CV is treated as a
+string already holding the sub name, but this could change in the future.
+.Sp
+An SV may be passed as a second argument. If so, the name will be assigned
+to it and it will be returned. Otherwise the returned SV will be a new
+mortal.
+.Sp
+If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`CV_NAME_NOTQUAL\*(C'\fR bit set, then the package name will not be
+included. If the first argument is neither a CV nor a GV, this flag is
+ignored (subject to change).
+.RS 4
+.Sp
+.Vb 1
+\& SV * cv_name(CV *cv, SV *sv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cv_undef""" 4
+.el .IP \f(CWcv_undef\fR 4
+.IX Xref "cv_undef"
+.IX Item "cv_undef"
+Clear out all the active components of a CV. This can happen either
+by an explicit \f(CW\*(C`undef &foo\*(C'\fR, or by the reference count going to zero.
+In the former case, we keep the \f(CW\*(C`CvOUTSIDE\*(C'\fR pointer, so that any anonymous
+children can still follow the full lexical scope chain.
+.RS 4
+.Sp
+.Vb 1
+\& void cv_undef(CV *cv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """find_rundefsv""" 4
+.el .IP \f(CWfind_rundefsv\fR 4
+.IX Xref "find_rundefsv"
+.IX Item "find_rundefsv"
+Returns the global variable \f(CW$_\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * find_rundefsv()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """get_op_descs""" 4
+.el .IP \f(CWget_op_descs\fR 4
+.IX Xref "get_op_descs"
+.IX Item "get_op_descs"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`get_op_descs\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Return a pointer to the array of all the descriptions of the various OPs
+Given an opcode from the enum in \fIopcodes.h\fR, \f(CW\*(C`PL_op_desc[opcode]\*(C'\fR returns a
+pointer to a C language string giving its description.
+.RS 4
+.Sp
+.Vb 1
+\& char ** get_op_descs()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """get_op_names""" 4
+.el .IP \f(CWget_op_names\fR 4
+.IX Xref "get_op_names"
+.IX Item "get_op_names"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`get_op_names\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Return a pointer to the array of all the names of the various OPs
+Given an opcode from the enum in \fIopcodes.h\fR, \f(CW\*(C`PL_op_name[opcode]\*(C'\fR returns a
+pointer to a C language string giving its name.
+.RS 4
+.Sp
+.Vb 1
+\& char ** get_op_names()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HAS_SKIP_LOCALE_INIT""" 4
+.el .IP \f(CWHAS_SKIP_LOCALE_INIT\fR 4
+.IX Item "HAS_SKIP_LOCALE_INIT"
+Described in perlembed.
+.ie n .IP """intro_my""" 4
+.el .IP \f(CWintro_my\fR 4
+.IX Xref "intro_my"
+.IX Item "intro_my"
+"Introduce" \f(CW\*(C`my\*(C'\fR variables to visible status. This is called during parsing
+at the end of each statement to make lexical variables visible to subsequent
+statements.
+.RS 4
+.Sp
+.Vb 1
+\& U32 intro_my()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """load_module""" 4
+.el .IP \f(CWload_module\fR 4
+.IX Item "load_module"
+.PD 0
+.ie n .IP """load_module_nocontext""" 4
+.el .IP \f(CWload_module_nocontext\fR 4
+.IX Xref "load_module load_module_nocontext"
+.IX Item "load_module_nocontext"
+.PD
+These load the module whose name is pointed to by the string part of \f(CW\*(C`name\*(C'\fR.
+Note that the actual module name, not its filename, should be given.
+Eg, "Foo::Bar" instead of "Foo/Bar.pm". ver, if specified and not NULL,
+provides version semantics similar to \f(CW\*(C`use Foo::Bar VERSION\*(C'\fR. The optional
+trailing arguments can be used to specify arguments to the module's \f(CWimport()\fR
+method, similar to \f(CW\*(C`use Foo::Bar VERSION LIST\*(C'\fR; their precise handling depends
+on the flags. The flags argument is a bitwise-ORed collection of any of
+\&\f(CW\*(C`PERL_LOADMOD_DENY\*(C'\fR, \f(CW\*(C`PERL_LOADMOD_NOIMPORT\*(C'\fR, or \f(CW\*(C`PERL_LOADMOD_IMPORT_OPS\*(C'\fR
+(or 0 for no flags).
+.Sp
+If \f(CW\*(C`PERL_LOADMOD_NOIMPORT\*(C'\fR is set, the module is loaded as if with an empty
+import list, as in \f(CW\*(C`use Foo::Bar ()\*(C'\fR; this is the only circumstance in which
+the trailing optional arguments may be omitted entirely. Otherwise, if
+\&\f(CW\*(C`PERL_LOADMOD_IMPORT_OPS\*(C'\fR is set, the trailing arguments must consist of
+exactly one \f(CW\*(C`OP*\*(C'\fR, containing the op tree that produces the relevant import
+arguments. Otherwise, the trailing arguments must all be \f(CW\*(C`SV*\*(C'\fR values that
+will be used as import arguments; and the list must be terminated with \f(CW\*(C`(SV*)
+NULL\*(C'\fR. If neither \f(CW\*(C`PERL_LOADMOD_NOIMPORT\*(C'\fR nor \f(CW\*(C`PERL_LOADMOD_IMPORT_OPS\*(C'\fR is
+set, the trailing \f(CW\*(C`NULL\*(C'\fR pointer is needed even if no import arguments are
+desired. The reference count for each specified \f(CW\*(C`SV*\*(C'\fR argument is
+decremented. In addition, the \f(CW\*(C`name\*(C'\fR argument is modified.
+.Sp
+If \f(CW\*(C`PERL_LOADMOD_DENY\*(C'\fR is set, the module is loaded as if with \f(CW\*(C`no\*(C'\fR rather
+than \f(CW\*(C`use\*(C'\fR.
+.Sp
+\&\f(CW\*(C`load_module\*(C'\fR and \f(CW\*(C`load_module_nocontext\*(C'\fR have the same apparent signature,
+but the former hides the fact that it is accessing a thread context parameter.
+So use the latter when you get a compilation error about \f(CW\*(C`pTHX\*(C'\fR.
+.RS 4
+.Sp
+.Vb 2
+\& void load_module (U32 flags, SV *name, SV *ver, ...)
+\& void load_module_nocontext(U32 flags, SV *name, SV *ver, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_exit""" 4
+.el .IP \f(CWmy_exit\fR 4
+.IX Xref "my_exit"
+.IX Item "my_exit"
+A wrapper for the C library \fBexit\fR\|(3), honoring what "PL_exit_flags" in perlapi
+say to do.
+.RS 4
+.Sp
+.Vb 1
+\& void my_exit(U32 status)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_failure_exit""" 4
+.el .IP \f(CWmy_failure_exit\fR 4
+.IX Xref "my_failure_exit"
+.IX Item "my_failure_exit"
+Exit the running Perl process with an error.
+.Sp
+On non-VMS platforms, this is essentially equivalent to "\f(CW\*(C`my_exit\*(C'\fR", using
+\&\f(CW\*(C`errno\*(C'\fR, but forces an en error code of 255 if \f(CW\*(C`errno\*(C'\fR is 0.
+.Sp
+On VMS, it takes care to set the appropriate severity bits in the exit status.
+.RS 4
+.Sp
+.Vb 1
+\& void my_failure_exit()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_strlcat""" 4
+.el .IP \f(CWmy_strlcat\fR 4
+.IX Xref "my_strlcat"
+.IX Item "my_strlcat"
+The C library \f(CW\*(C`strlcat\*(C'\fR if available, or a Perl implementation of it.
+This operates on C \f(CW\*(C`NUL\*(C'\fR\-terminated strings.
+.Sp
+\&\f(CWmy_strlcat()\fR appends string \f(CW\*(C`src\*(C'\fR to the end of \f(CW\*(C`dst\*(C'\fR. It will append at
+most \f(CW\*(C`size\ \-\ strlen(dst)\ \-\ 1\*(C'\fR characters. It will then \f(CW\*(C`NUL\*(C'\fR\-terminate,
+unless \f(CW\*(C`size\*(C'\fR is 0 or the original \f(CW\*(C`dst\*(C'\fR string was longer than \f(CW\*(C`size\*(C'\fR (in
+practice this should not happen as it means that either \f(CW\*(C`size\*(C'\fR is incorrect or
+that \f(CW\*(C`dst\*(C'\fR is not a proper \f(CW\*(C`NUL\*(C'\fR\-terminated string).
+.Sp
+Note that \f(CW\*(C`size\*(C'\fR is the full size of the destination buffer and
+the result is guaranteed to be \f(CW\*(C`NUL\*(C'\fR\-terminated if there is room. Note that
+room for the \f(CW\*(C`NUL\*(C'\fR should be included in \f(CW\*(C`size\*(C'\fR.
+.Sp
+The return value is the total length that \f(CW\*(C`dst\*(C'\fR would have if \f(CW\*(C`size\*(C'\fR is
+sufficiently large. Thus it is the initial length of \f(CW\*(C`dst\*(C'\fR plus the length of
+\&\f(CW\*(C`src\*(C'\fR. If \f(CW\*(C`size\*(C'\fR is smaller than the return, the excess was not appended.
+.RS 4
+.Sp
+.Vb 1
+\& Size_t my_strlcat(char *dst, const char *src, Size_t size)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_strlcpy""" 4
+.el .IP \f(CWmy_strlcpy\fR 4
+.IX Xref "my_strlcpy"
+.IX Item "my_strlcpy"
+The C library \f(CW\*(C`strlcpy\*(C'\fR if available, or a Perl implementation of it.
+This operates on C \f(CW\*(C`NUL\*(C'\fR\-terminated strings.
+.Sp
+\&\f(CWmy_strlcpy()\fR copies up to \f(CW\*(C`size\ \-\ 1\*(C'\fR characters from the string \f(CW\*(C`src\*(C'\fR
+to \f(CW\*(C`dst\*(C'\fR, \f(CW\*(C`NUL\*(C'\fR\-terminating the result if \f(CW\*(C`size\*(C'\fR is not 0.
+.Sp
+The return value is the total length \f(CW\*(C`src\*(C'\fR would be if the copy completely
+succeeded. If it is larger than \f(CW\*(C`size\*(C'\fR, the excess was not copied.
+.RS 4
+.Sp
+.Vb 1
+\& Size_t my_strlcpy(char *dst, const char *src, Size_t size)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newPADNAMELIST""" 4
+.el .IP \f(CWnewPADNAMELIST\fR 4
+.IX Xref "newPADNAMELIST"
+.IX Item "newPADNAMELIST"
+NOTE: \f(CW\*(C`newPADNAMELIST\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Creates a new pad name list. \f(CW\*(C`max\*(C'\fR is the highest index for which space
+is allocated.
+.RS 4
+.Sp
+.Vb 1
+\& PADNAMELIST * newPADNAMELIST(size_t max)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newPADNAMEouter""" 4
+.el .IP \f(CWnewPADNAMEouter\fR 4
+.IX Xref "newPADNAMEouter"
+.IX Item "newPADNAMEouter"
+NOTE: \f(CW\*(C`newPADNAMEouter\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Constructs and returns a new pad name. Only use this function for names
+that refer to outer lexicals. (See also "newPADNAMEpvn".) \f(CW\*(C`outer\*(C'\fR is
+the outer pad name that this one mirrors. The returned pad name has the
+\&\f(CW\*(C`PADNAMEf_OUTER\*(C'\fR flag already set.
+.RS 4
+.Sp
+.Vb 1
+\& PADNAME * newPADNAMEouter(PADNAME *outer)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newPADNAMEpvn""" 4
+.el .IP \f(CWnewPADNAMEpvn\fR 4
+.IX Xref "newPADNAMEpvn"
+.IX Item "newPADNAMEpvn"
+NOTE: \f(CW\*(C`newPADNAMEpvn\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Constructs and returns a new pad name. \f(CW\*(C`s\*(C'\fR must be a UTF\-8 string. Do not
+use this for pad names that point to outer lexicals. See
+\&\f(CW"newPADNAMEouter"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& PADNAME * newPADNAMEpvn(const char *s, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """nothreadhook""" 4
+.el .IP \f(CWnothreadhook\fR 4
+.IX Xref "nothreadhook"
+.IX Item "nothreadhook"
+Stub that provides thread hook for perl_destruct when there are
+no threads.
+.RS 4
+.Sp
+.Vb 1
+\& int nothreadhook()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_add_anon""" 4
+.el .IP \f(CWpad_add_anon\fR 4
+.IX Xref "pad_add_anon"
+.IX Item "pad_add_anon"
+Allocates a place in the currently-compiling pad (via "pad_alloc")
+for an anonymous function that is lexically scoped inside the
+currently-compiling function.
+The function \f(CW\*(C`func\*(C'\fR is linked into the pad, and its \f(CW\*(C`CvOUTSIDE\*(C'\fR link
+to the outer scope is weakened to avoid a reference loop.
+.Sp
+One reference count is stolen, so you may need to do \f(CWSvREFCNT_inc(func)\fR.
+.Sp
+\&\f(CW\*(C`optype\*(C'\fR should be an opcode indicating the type of operation that the
+pad entry is to support. This doesn't affect operational semantics,
+but is used for debugging.
+.RS 4
+.Sp
+.Vb 1
+\& PADOFFSET pad_add_anon(CV *func, I32 optype)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_add_name_pv""" 4
+.el .IP \f(CWpad_add_name_pv\fR 4
+.IX Xref "pad_add_name_pv"
+.IX Item "pad_add_name_pv"
+Exactly like "pad_add_name_pvn", but takes a nul-terminated string
+instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 2
+\& PADOFFSET pad_add_name_pv(const char *name, const U32 flags,
+\& HV *typestash, HV *ourstash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_add_name_pvn""" 4
+.el .IP \f(CWpad_add_name_pvn\fR 4
+.IX Xref "pad_add_name_pvn"
+.IX Item "pad_add_name_pvn"
+Allocates a place in the currently-compiling pad for a named lexical
+variable. Stores the name and other metadata in the name part of the
+pad, and makes preparations to manage the variable's lexical scoping.
+Returns the offset of the allocated pad slot.
+.Sp
+\&\f(CW\*(C`namepv\*(C'\fR/\f(CW\*(C`namelen\*(C'\fR specify the variable's name, including leading sigil.
+If \f(CW\*(C`typestash\*(C'\fR is non-null, the name is for a typed lexical, and this
+identifies the type. If \f(CW\*(C`ourstash\*(C'\fR is non-null, it's a lexical reference
+to a package variable, and this identifies the package. The following
+flags can be OR'ed together:
+.Sp
+.Vb 4
+\& padadd_OUR redundantly specifies if it\*(Aqs a package var
+\& padadd_STATE variable will retain value persistently
+\& padadd_NO_DUP_CHECK skip check for lexical shadowing
+\& padadd_FIELD specifies that the lexical is a field for a class
+.Ve
+.RS 4
+.Sp
+.Vb 3
+\& PADOFFSET pad_add_name_pvn(const char *namepv, STRLEN namelen,
+\& U32 flags, HV *typestash,
+\& HV *ourstash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_add_name_sv""" 4
+.el .IP \f(CWpad_add_name_sv\fR 4
+.IX Xref "pad_add_name_sv"
+.IX Item "pad_add_name_sv"
+Exactly like "pad_add_name_pvn", but takes the name string in the form
+of an SV instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 2
+\& PADOFFSET pad_add_name_sv(SV *name, U32 flags, HV *typestash,
+\& HV *ourstash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_alloc""" 4
+.el .IP \f(CWpad_alloc\fR 4
+.IX Xref "pad_alloc"
+.IX Item "pad_alloc"
+NOTE: \f(CW\*(C`pad_alloc\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Allocates a place in the currently-compiling pad,
+returning the offset of the allocated pad slot.
+No name is initially attached to the pad slot.
+\&\f(CW\*(C`tmptype\*(C'\fR is a set of flags indicating the kind of pad entry required,
+which will be set in the value SV for the allocated pad entry:
+.Sp
+.Vb 3
+\& SVs_PADMY named lexical variable ("my", "our", "state")
+\& SVs_PADTMP unnamed temporary store
+\& SVf_READONLY constant shared between recursion levels
+.Ve
+.Sp
+\&\f(CW\*(C`SVf_READONLY\*(C'\fR has been supported here only since perl 5.20. To work with
+earlier versions as well, use \f(CW\*(C`SVf_READONLY|SVs_PADTMP\*(C'\fR. \f(CW\*(C`SVf_READONLY\*(C'\fR
+does not cause the SV in the pad slot to be marked read-only, but simply
+tells \f(CW\*(C`pad_alloc\*(C'\fR that it \fIwill\fR be made read-only (by the caller), or at
+least should be treated as such.
+.Sp
+\&\f(CW\*(C`optype\*(C'\fR should be an opcode indicating the type of operation that the
+pad entry is to support. This doesn't affect operational semantics,
+but is used for debugging.
+.RS 4
+.Sp
+.Vb 1
+\& PADOFFSET pad_alloc(I32 optype, U32 tmptype)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_findmy_pv""" 4
+.el .IP \f(CWpad_findmy_pv\fR 4
+.IX Xref "pad_findmy_pv"
+.IX Item "pad_findmy_pv"
+Exactly like "pad_findmy_pvn", but takes a nul-terminated string
+instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& PADOFFSET pad_findmy_pv(const char *name, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_findmy_pvn""" 4
+.el .IP \f(CWpad_findmy_pvn\fR 4
+.IX Xref "pad_findmy_pvn"
+.IX Item "pad_findmy_pvn"
+Given the name of a lexical variable, find its position in the
+currently-compiling pad.
+\&\f(CW\*(C`namepv\*(C'\fR/\f(CW\*(C`namelen\*(C'\fR specify the variable's name, including leading sigil.
+\&\f(CW\*(C`flags\*(C'\fR is reserved and must be zero.
+If it is not in the current pad but appears in the pad of any lexically
+enclosing scope, then a pseudo-entry for it is added in the current pad.
+Returns the offset in the current pad,
+or \f(CW\*(C`NOT_IN_PAD\*(C'\fR if no such lexical is in scope.
+.RS 4
+.Sp
+.Vb 2
+\& PADOFFSET pad_findmy_pvn(const char *namepv, STRLEN namelen,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_findmy_sv""" 4
+.el .IP \f(CWpad_findmy_sv\fR 4
+.IX Xref "pad_findmy_sv"
+.IX Item "pad_findmy_sv"
+Exactly like "pad_findmy_pvn", but takes the name string in the form
+of an SV instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& PADOFFSET pad_findmy_sv(SV *name, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """padnamelist_fetch""" 4
+.el .IP \f(CWpadnamelist_fetch\fR 4
+.IX Xref "padnamelist_fetch"
+.IX Item "padnamelist_fetch"
+NOTE: \f(CW\*(C`padnamelist_fetch\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Fetches the pad name from the given index.
+.RS 4
+.Sp
+.Vb 1
+\& PADNAME * padnamelist_fetch(PADNAMELIST *pnl, SSize_t key)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """padnamelist_store""" 4
+.el .IP \f(CWpadnamelist_store\fR 4
+.IX Xref "padnamelist_store"
+.IX Item "padnamelist_store"
+NOTE: \f(CW\*(C`padnamelist_store\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Stores the pad name (which may be null) at the given index, freeing any
+existing pad name in that slot.
+.RS 4
+.Sp
+.Vb 2
+\& PADNAME ** padnamelist_store(PADNAMELIST *pnl, SSize_t key,
+\& PADNAME *val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_tidy""" 4
+.el .IP \f(CWpad_tidy\fR 4
+.IX Xref "pad_tidy"
+.IX Item "pad_tidy"
+NOTE: \f(CW\*(C`pad_tidy\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Tidy up a pad at the end of compilation of the code to which it belongs.
+Jobs performed here are: remove most stuff from the pads of anonsub
+prototypes; give it a \f(CW@_\fR; mark temporaries as such. \f(CW\*(C`type\*(C'\fR indicates
+the kind of subroutine:
+.Sp
+.Vb 3
+\& padtidy_SUB ordinary subroutine
+\& padtidy_SUBCLONE prototype for lexical closure
+\& padtidy_FORMAT format
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& void pad_tidy(padtidy_type type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """perl_alloc""" 4
+.el .IP \f(CWperl_alloc\fR 4
+.IX Xref "perl_alloc"
+.IX Item "perl_alloc"
+Allocates a new Perl interpreter. See perlembed.
+.RS 4
+.Sp
+.Vb 1
+\& PerlInterpreter * perl_alloc()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_ASYNC_CHECK""" 4
+.el .IP \f(CWPERL_ASYNC_CHECK\fR 4
+.IX Item "PERL_ASYNC_CHECK"
+Described in perlinterp.
+.RS 4
+.Sp
+.Vb 1
+\& void PERL_ASYNC_CHECK()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """perl_clone""" 4
+.el .IP \f(CWperl_clone\fR 4
+.IX Xref "perl_clone"
+.IX Item "perl_clone"
+Create and return a new interpreter by cloning the current one.
+.Sp
+\&\f(CW\*(C`perl_clone\*(C'\fR takes these flags as parameters:
+.Sp
+\&\f(CW\*(C`CLONEf_COPY_STACKS\*(C'\fR \- is used to, well, copy the stacks also,
+without it we only clone the data and zero the stacks,
+with it we copy the stacks and the new perl interpreter is
+ready to run at the exact same point as the previous one.
+The pseudo-fork code uses \f(CW\*(C`COPY_STACKS\*(C'\fR while the
+threads\->create doesn't.
+.Sp
+\&\f(CW\*(C`CLONEf_KEEP_PTR_TABLE\*(C'\fR \-
+\&\f(CW\*(C`perl_clone\*(C'\fR keeps a ptr_table with the pointer of the old
+variable as a key and the new variable as a value,
+this allows it to check if something has been cloned and not
+clone it again, but rather just use the value and increase the
+refcount.
+If \f(CW\*(C`KEEP_PTR_TABLE\*(C'\fR is not set then \f(CW\*(C`perl_clone\*(C'\fR will kill the ptr_table
+using the function \f(CW\*(C`ptr_table_free(PL_ptr_table);\ PL_ptr_table\ =\ NULL;\*(C'\fR.
+A reason to keep it around is if you want to dup some of your own
+variables which are outside the graph that perl scans.
+.Sp
+\&\f(CW\*(C`CLONEf_CLONE_HOST\*(C'\fR \-
+This is a win32 thing, it is ignored on unix, it tells perl's
+win32host code (which is c++) to clone itself, this is needed on
+win32 if you want to run two threads at the same time,
+if you just want to do some stuff in a separate perl interpreter
+and then throw it away and return to the original one,
+you don't need to do anything.
+.RS 4
+.Sp
+.Vb 2
+\& PerlInterpreter * perl_clone(PerlInterpreter *proto_perl,
+\& UV flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """perl_construct""" 4
+.el .IP \f(CWperl_construct\fR 4
+.IX Xref "perl_construct"
+.IX Item "perl_construct"
+Initializes a new Perl interpreter. See perlembed.
+.RS 4
+.Sp
+.Vb 1
+\& void perl_construct(PerlInterpreter *my_perl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """perl_destruct""" 4
+.el .IP \f(CWperl_destruct\fR 4
+.IX Xref "perl_destruct"
+.IX Item "perl_destruct"
+Shuts down a Perl interpreter. See perlembed for a tutorial.
+.Sp
+\&\f(CW\*(C`my_perl\*(C'\fR points to the Perl interpreter. It must have been previously
+created through the use of "perl_alloc" and "perl_construct". It may
+have been initialised through "perl_parse", and may have been used
+through "perl_run" and other means. This function should be called for
+any Perl interpreter that has been constructed with "perl_construct",
+even if subsequent operations on it failed, for example if "perl_parse"
+returned a non-zero value.
+.Sp
+If the interpreter's \f(CW\*(C`PL_exit_flags\*(C'\fR word has the
+\&\f(CW\*(C`PERL_EXIT_DESTRUCT_END\*(C'\fR flag set, then this function will execute code
+in \f(CW\*(C`END\*(C'\fR blocks before performing the rest of destruction. If it is
+desired to make any use of the interpreter between "perl_parse" and
+"perl_destruct" other than just calling "perl_run", then this flag
+should be set early on. This matters if "perl_run" will not be called,
+or if anything else will be done in addition to calling "perl_run".
+.Sp
+Returns a value be a suitable value to pass to the C library function
+\&\f(CW\*(C`exit\*(C'\fR (or to return from \f(CW\*(C`main\*(C'\fR), to serve as an exit code indicating
+the nature of the way the interpreter terminated. This takes into account
+any failure of "perl_parse" and any early exit from "perl_run".
+The exit code is of the type required by the host operating system,
+so because of differing exit code conventions it is not portable to
+interpret specific numeric values as having specific meanings.
+.RS 4
+.Sp
+.Vb 1
+\& int perl_destruct(PerlInterpreter *my_perl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """perl_free""" 4
+.el .IP \f(CWperl_free\fR 4
+.IX Xref "perl_free"
+.IX Item "perl_free"
+Releases a Perl interpreter. See perlembed.
+.RS 4
+.Sp
+.Vb 1
+\& void perl_free(PerlInterpreter *my_perl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_GET_CONTEXT""" 4
+.el .IP \f(CWPERL_GET_CONTEXT\fR 4
+.IX Item "PERL_GET_CONTEXT"
+Described in perlguts.
+.ie n .IP """PerlInterpreter""" 4
+.el .IP \f(CWPerlInterpreter\fR 4
+.IX Item "PerlInterpreter"
+Described in perlembed.
+.ie n .IP """perl_parse""" 4
+.el .IP \f(CWperl_parse\fR 4
+.IX Xref "perl_parse"
+.IX Item "perl_parse"
+Tells a Perl interpreter to parse a Perl script. This performs most
+of the initialisation of a Perl interpreter. See perlembed for
+a tutorial.
+.Sp
+\&\f(CW\*(C`my_perl\*(C'\fR points to the Perl interpreter that is to parse the script.
+It must have been previously created through the use of "perl_alloc"
+and "perl_construct". \f(CW\*(C`xsinit\*(C'\fR points to a callback function that
+will be called to set up the ability for this Perl interpreter to load
+XS extensions, or may be null to perform no such setup.
+.Sp
+\&\f(CW\*(C`argc\*(C'\fR and \f(CW\*(C`argv\*(C'\fR supply a set of command-line arguments to the Perl
+interpreter, as would normally be passed to the \f(CW\*(C`main\*(C'\fR function of
+a C program. \f(CW\*(C`argv[argc]\*(C'\fR must be null. These arguments are where
+the script to parse is specified, either by naming a script file or by
+providing a script in a \f(CW\*(C`\-e\*(C'\fR option.
+If \f(CW$0\fR will be written to in the Perl interpreter, then
+the argument strings must be in writable memory, and so mustn't just be
+string constants.
+.Sp
+\&\f(CW\*(C`env\*(C'\fR specifies a set of environment variables that will be used by
+this Perl interpreter. If non-null, it must point to a null-terminated
+array of environment strings. If null, the Perl interpreter will use
+the environment supplied by the \f(CW\*(C`environ\*(C'\fR global variable.
+.Sp
+This function initialises the interpreter, and parses and compiles the
+script specified by the command-line arguments. This includes executing
+code in \f(CW\*(C`BEGIN\*(C'\fR, \f(CW\*(C`UNITCHECK\*(C'\fR, and \f(CW\*(C`CHECK\*(C'\fR blocks. It does not execute
+\&\f(CW\*(C`INIT\*(C'\fR blocks or the main program.
+.Sp
+Returns an integer of slightly tricky interpretation. The correct
+use of the return value is as a truth value indicating whether there
+was a failure in initialisation. If zero is returned, this indicates
+that initialisation was successful, and it is safe to proceed to call
+"perl_run" and make other use of it. If a non-zero value is returned,
+this indicates some problem that means the interpreter wants to terminate.
+The interpreter should not be just abandoned upon such failure; the caller
+should proceed to shut the interpreter down cleanly with "perl_destruct"
+and free it with "perl_free".
+.Sp
+For historical reasons, the non-zero return value also attempts to
+be a suitable value to pass to the C library function \f(CW\*(C`exit\*(C'\fR (or to
+return from \f(CW\*(C`main\*(C'\fR), to serve as an exit code indicating the nature
+of the way initialisation terminated. However, this isn't portable,
+due to differing exit code conventions. An attempt is made to return
+an exit code of the type required by the host operating system, but
+because it is constrained to be non-zero, it is not necessarily possible
+to indicate every type of exit. It is only reliable on Unix, where a
+zero exit code can be augmented with a set bit that will be ignored.
+In any case, this function is not the correct place to acquire an exit
+code: one should get that from "perl_destruct".
+.RS 4
+.Sp
+.Vb 2
+\& int perl_parse(PerlInterpreter *my_perl, XSINIT_t xsinit,
+\& int argc, char **argv, char **env)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """perl_run""" 4
+.el .IP \f(CWperl_run\fR 4
+.IX Xref "perl_run"
+.IX Item "perl_run"
+Tells a Perl interpreter to run its main program. See perlembed
+for a tutorial.
+.Sp
+\&\f(CW\*(C`my_perl\*(C'\fR points to the Perl interpreter. It must have been previously
+created through the use of "perl_alloc" and "perl_construct", and
+initialised through "perl_parse". This function should not be called
+if "perl_parse" returned a non-zero value, indicating a failure in
+initialisation or compilation.
+.Sp
+This function executes code in \f(CW\*(C`INIT\*(C'\fR blocks, and then executes the
+main program. The code to be executed is that established by the prior
+call to "perl_parse". If the interpreter's \f(CW\*(C`PL_exit_flags\*(C'\fR word
+does not have the \f(CW\*(C`PERL_EXIT_DESTRUCT_END\*(C'\fR flag set, then this function
+will also execute code in \f(CW\*(C`END\*(C'\fR blocks. If it is desired to make any
+further use of the interpreter after calling this function, then \f(CW\*(C`END\*(C'\fR
+blocks should be postponed to "perl_destruct" time by setting that flag.
+.Sp
+Returns an integer of slightly tricky interpretation. The correct use
+of the return value is as a truth value indicating whether the program
+terminated non-locally. If zero is returned, this indicates that
+the program ran to completion, and it is safe to make other use of the
+interpreter (provided that the \f(CW\*(C`PERL_EXIT_DESTRUCT_END\*(C'\fR flag was set as
+described above). If a non-zero value is returned, this indicates that
+the interpreter wants to terminate early. The interpreter should not be
+just abandoned because of this desire to terminate; the caller should
+proceed to shut the interpreter down cleanly with "perl_destruct"
+and free it with "perl_free".
+.Sp
+For historical reasons, the non-zero return value also attempts to
+be a suitable value to pass to the C library function \f(CW\*(C`exit\*(C'\fR (or to
+return from \f(CW\*(C`main\*(C'\fR), to serve as an exit code indicating the nature of
+the way the program terminated. However, this isn't portable, due to
+differing exit code conventions. An attempt is made to return an exit
+code of the type required by the host operating system, but because
+it is constrained to be non-zero, it is not necessarily possible to
+indicate every type of exit. It is only reliable on Unix, where a zero
+exit code can be augmented with a set bit that will be ignored. In any
+case, this function is not the correct place to acquire an exit code:
+one should get that from "perl_destruct".
+.RS 4
+.Sp
+.Vb 1
+\& int perl_run(PerlInterpreter *my_perl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_SET_CONTEXT""" 4
+.el .IP \f(CWPERL_SET_CONTEXT\fR 4
+.IX Item "PERL_SET_CONTEXT"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& void PERL_SET_CONTEXT(PerlInterpreter* i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_SYS_INIT""" 4
+.el .IP \f(CWPERL_SYS_INIT\fR 4
+.IX Item "PERL_SYS_INIT"
+.PD 0
+.ie n .IP """PERL_SYS_INIT3""" 4
+.el .IP \f(CWPERL_SYS_INIT3\fR 4
+.IX Xref "PERL_SYS_INIT PERL_SYS_INIT3"
+.IX Item "PERL_SYS_INIT3"
+.PD
+These provide system-specific tune up of the C runtime environment necessary to
+run Perl interpreters. Only one should be used, and it should be called only
+once, before creating any Perl interpreters.
+.Sp
+They differ in that \f(CW\*(C`PERL_SYS_INIT3\*(C'\fR also initializes \f(CW\*(C`env\*(C'\fR.
+.RS 4
+.Sp
+.Vb 2
+\& void PERL_SYS_INIT (int *argc, char*** argv)
+\& void PERL_SYS_INIT3(int *argc, char*** argv, char*** env)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_SYS_TERM""" 4
+.el .IP \f(CWPERL_SYS_TERM\fR 4
+.IX Xref "PERL_SYS_TERM"
+.IX Item "PERL_SYS_TERM"
+Provides system-specific clean up of the C runtime environment after
+running Perl interpreters. This should be called only once, after
+freeing any remaining Perl interpreters.
+.RS 4
+.Sp
+.Vb 1
+\& void PERL_SYS_TERM()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_exit_flags""" 4
+.el .IP \f(CWPL_exit_flags\fR 4
+.IX Xref "PL_exit_flags"
+.IX Item "PL_exit_flags"
+Contains flags controlling perl's behaviour on \fBexit()\fR:
+.RS 4
+.IP \(bu 4
+\&\f(CW\*(C`PERL_EXIT_DESTRUCT_END\*(C'\fR
+.Sp
+If set, END blocks are executed when the interpreter is destroyed.
+This is normally set by perl itself after the interpreter is
+constructed.
+.IP \(bu 4
+\&\f(CW\*(C`PERL_EXIT_ABORT\*(C'\fR
+.Sp
+Call \f(CWabort()\fR on exit. This is used internally by perl itself to
+abort if exit is called while processing exit.
+.IP \(bu 4
+\&\f(CW\*(C`PERL_EXIT_WARN\*(C'\fR
+.Sp
+Warn on exit.
+.IP \(bu 4
+\&\f(CW\*(C`PERL_EXIT_EXPECTED\*(C'\fR
+.Sp
+Set by the "exit" in perlfunc operator.
+.RE
+.RS 4
+.Sp
+.Vb 1
+\& U8 PL_exit_flags
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_origalen""" 4
+.el .IP \f(CWPL_origalen\fR 4
+.IX Item "PL_origalen"
+Described in perlembed.
+.ie n .IP """PL_perl_destruct_level""" 4
+.el .IP \f(CWPL_perl_destruct_level\fR 4
+.IX Xref "PL_perl_destruct_level"
+.IX Item "PL_perl_destruct_level"
+This value may be set when embedding for full cleanup.
+.Sp
+Possible values:
+.RS 4
+.IP \(bu 4
+0 \- none
+.IP \(bu 4
+1 \- full
+.IP \(bu 4
+2 or greater \- full with checks.
+.RE
+.RS 4
+.Sp
+If \f(CW$ENV{PERL_DESTRUCT_LEVEL}\fR is set to an integer greater than the
+value of \f(CW\*(C`PL_perl_destruct_level\*(C'\fR its value is used instead.
+.Sp
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+.Sp
+.Vb 1
+\& signed char PL_perl_destruct_level
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ptr_table_fetch""" 4
+.el .IP \f(CWptr_table_fetch\fR 4
+.IX Xref "ptr_table_fetch"
+.IX Item "ptr_table_fetch"
+Look for \f(CW\*(C`sv\*(C'\fR in the pointer-mapping table \f(CW\*(C`tbl\*(C'\fR, returning its value, or
+NULL if not found.
+.RS 4
+.Sp
+.Vb 2
+\& void * ptr_table_fetch(PTR_TBL_t * const tbl,
+\& const void * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ptr_table_free""" 4
+.el .IP \f(CWptr_table_free\fR 4
+.IX Xref "ptr_table_free"
+.IX Item "ptr_table_free"
+Clear and free a ptr table
+.RS 4
+.Sp
+.Vb 1
+\& void ptr_table_free(PTR_TBL_t * const tbl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ptr_table_new""" 4
+.el .IP \f(CWptr_table_new\fR 4
+.IX Xref "ptr_table_new"
+.IX Item "ptr_table_new"
+Create a new pointer-mapping table
+.RS 4
+.Sp
+.Vb 1
+\& PTR_TBL_t * ptr_table_new()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ptr_table_split""" 4
+.el .IP \f(CWptr_table_split\fR 4
+.IX Xref "ptr_table_split"
+.IX Item "ptr_table_split"
+Double the hash bucket size of an existing ptr table
+.RS 4
+.Sp
+.Vb 1
+\& void ptr_table_split(PTR_TBL_t * const tbl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ptr_table_store""" 4
+.el .IP \f(CWptr_table_store\fR 4
+.IX Xref "ptr_table_store"
+.IX Item "ptr_table_store"
+Add a new entry to a pointer-mapping table \f(CW\*(C`tbl\*(C'\fR.
+In hash terms, \f(CW\*(C`oldsv\*(C'\fR is the key; Cnewsv> is the value.
+.Sp
+The names "old" and "new" are specific to the core's typical use of ptr_tables
+in thread cloning.
+.RS 4
+.Sp
+.Vb 3
+\& void ptr_table_store(PTR_TBL_t * const tbl,
+\& const void * const oldsv,
+\& void * const newsv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """require_pv""" 4
+.el .IP \f(CWrequire_pv\fR 4
+.IX Xref "require_pv"
+.IX Item "require_pv"
+Tells Perl to \f(CW\*(C`require\*(C'\fR the file named by the string argument. It is
+analogous to the Perl code \f(CW\*(C`eval "require \*(Aq$file\*(Aq"\*(C'\fR. It's even
+implemented that way; consider using load_module instead.
+.Sp
+NOTE: the \f(CWperl_require_pv()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void require_pv(const char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vload_module""" 4
+.el .IP \f(CWvload_module\fR 4
+.IX Xref "vload_module"
+.IX Item "vload_module"
+Like \f(CW"load_module"\fR but the arguments are an encapsulated argument list.
+.RS 4
+.Sp
+.Vb 1
+\& void vload_module(U32 flags, SV *name, SV *ver, va_list *args)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Errno
+.IX Header "Errno"
+.ie n .IP """sv_string_from_errnum""" 4
+.el .IP \f(CWsv_string_from_errnum\fR 4
+.IX Xref "sv_string_from_errnum"
+.IX Item "sv_string_from_errnum"
+Generates the message string describing an OS error and returns it as
+an SV. \f(CW\*(C`errnum\*(C'\fR must be a value that \f(CW\*(C`errno\*(C'\fR could take, identifying
+the type of error.
+.Sp
+If \f(CW\*(C`tgtsv\*(C'\fR is non-null then the string will be written into that SV
+(overwriting existing content) and it will be returned. If \f(CW\*(C`tgtsv\*(C'\fR
+is a null pointer then the string will be written into a new mortal SV
+which will be returned.
+.Sp
+The message will be taken from whatever locale would be used by \f(CW$!\fR,
+and will be encoded in the SV in whatever manner would be used by \f(CW$!\fR.
+The details of this process are subject to future change. Currently,
+the message is taken from the C locale by default (usually producing an
+English message), and from the currently selected locale when in the scope
+of the \f(CW\*(C`use locale\*(C'\fR pragma. A heuristic attempt is made to decode the
+message from the locale's character encoding, but it will only be decoded
+as either UTF\-8 or ISO\-8859\-1. It is always correctly decoded in a UTF\-8
+locale, usually in an ISO\-8859\-1 locale, and never in any other locale.
+.Sp
+The SV is always returned containing an actual string, and with no other
+OK bits set. Unlike \f(CW$!\fR, a message is even yielded for \f(CW\*(C`errnum\*(C'\fR zero
+(meaning success), and if no useful message is available then a useless
+string (currently empty) is returned.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_string_from_errnum(int errnum, SV *tgtsv)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Exception Handling (simple) Macros"
+.IX Header "Exception Handling (simple) Macros"
+.ie n .IP """dXCPT""" 4
+.el .IP \f(CWdXCPT\fR 4
+.IX Xref "dXCPT"
+.IX Item "dXCPT"
+Set up necessary local variables for exception handling.
+See "Exception Handling" in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& dXCPT;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """JMPENV_JUMP""" 4
+.el .IP \f(CWJMPENV_JUMP\fR 4
+.IX Item "JMPENV_JUMP"
+Described in perlinterp.
+.RS 4
+.Sp
+.Vb 1
+\& void JMPENV_JUMP(int v)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """JMPENV_PUSH""" 4
+.el .IP \f(CWJMPENV_PUSH\fR 4
+.IX Item "JMPENV_PUSH"
+Described in perlinterp.
+.RS 4
+.Sp
+.Vb 1
+\& void JMPENV_PUSH(int v)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_restartop""" 4
+.el .IP \f(CWPL_restartop\fR 4
+.IX Item "PL_restartop"
+Described in perlinterp.
+.ie n .IP """XCPT_CATCH""" 4
+.el .IP \f(CWXCPT_CATCH\fR 4
+.IX Xref "XCPT_CATCH"
+.IX Item "XCPT_CATCH"
+Introduces a catch block. See "Exception Handling" in perlguts.
+.ie n .IP """XCPT_RETHROW""" 4
+.el .IP \f(CWXCPT_RETHROW\fR 4
+.IX Xref "XCPT_RETHROW"
+.IX Item "XCPT_RETHROW"
+Rethrows a previously caught exception. See "Exception Handling" in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& XCPT_RETHROW;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XCPT_TRY_END""" 4
+.el .IP \f(CWXCPT_TRY_END\fR 4
+.IX Xref "XCPT_TRY_END"
+.IX Item "XCPT_TRY_END"
+Ends a try block. See "Exception Handling" in perlguts.
+.ie n .IP """XCPT_TRY_START""" 4
+.el .IP \f(CWXCPT_TRY_START\fR 4
+.IX Xref "XCPT_TRY_START"
+.IX Item "XCPT_TRY_START"
+Starts a try block. See "Exception Handling" in perlguts.
+.SH "Filesystem configuration values"
+.IX Header "Filesystem configuration values"
+Also see "List of capability HAS_foo symbols".
+.ie n .IP """DIRNAMLEN""" 4
+.el .IP \f(CWDIRNAMLEN\fR 4
+.IX Xref "DIRNAMLEN"
+.IX Item "DIRNAMLEN"
+This symbol, if defined, indicates to the C program that the length
+of directory entry names is provided by a \f(CW\*(C`d_namlen\*(C'\fR field. Otherwise
+you need to do \f(CWstrlen()\fR on the \f(CW\*(C`d_name\*(C'\fR field.
+.ie n .IP """DOSUID""" 4
+.el .IP \f(CWDOSUID\fR 4
+.IX Xref "DOSUID"
+.IX Item "DOSUID"
+This symbol, if defined, indicates that the C program should
+check the script that it is executing for setuid/setgid bits, and
+attempt to emulate setuid/setgid on systems that have disabled
+setuid #! scripts because the kernel can't do it securely.
+It is up to the package designer to make sure that this emulation
+is done securely. Among other things, it should do an fstat on
+the script it just opened to make sure it really is a setuid/setgid
+script, it should make sure the arguments passed correspond exactly
+to the argument on the #! line, and it should not trust any
+subprocesses to which it must pass the filename rather than the
+file descriptor of the script to be executed.
+.ie n .IP """EOF_NONBLOCK""" 4
+.el .IP \f(CWEOF_NONBLOCK\fR 4
+.IX Xref "EOF_NONBLOCK"
+.IX Item "EOF_NONBLOCK"
+This symbol, if defined, indicates to the C program that a \f(CWread()\fR on
+a non-blocking file descriptor will return 0 on \f(CW\*(C`EOF\*(C'\fR, and not the value
+held in \f(CW\*(C`RD_NODATA\*(C'\fR (\-1 usually, in that case!).
+.ie n .IP """FCNTL_CAN_LOCK""" 4
+.el .IP \f(CWFCNTL_CAN_LOCK\fR 4
+.IX Xref "FCNTL_CAN_LOCK"
+.IX Item "FCNTL_CAN_LOCK"
+This symbol, if defined, indicates that \f(CWfcntl()\fR can be used
+for file locking. Normally on Unix systems this is defined.
+It may be undefined on \f(CW\*(C`VMS\*(C'\fR.
+.ie n .IP """FFLUSH_ALL""" 4
+.el .IP \f(CWFFLUSH_ALL\fR 4
+.IX Xref "FFLUSH_ALL"
+.IX Item "FFLUSH_ALL"
+This symbol, if defined, tells that to flush
+all pending stdio output one must loop through all
+the stdio file handles stored in an array and fflush them.
+Note that if \f(CW\*(C`fflushNULL\*(C'\fR is defined, fflushall will not
+even be probed for and will be left undefined.
+.ie n .IP """FFLUSH_NULL""" 4
+.el .IP \f(CWFFLUSH_NULL\fR 4
+.IX Xref "FFLUSH_NULL"
+.IX Item "FFLUSH_NULL"
+This symbol, if defined, tells that \f(CWfflush(NULL)\fR correctly
+flushes all pending stdio output without side effects. In
+particular, on some platforms calling \f(CWfflush(NULL)\fR *still*
+corrupts \f(CW\*(C`STDIN\*(C'\fR if it is a pipe.
+.ie n .IP """FILE_base""" 4
+.el .IP \f(CWFILE_base\fR 4
+.IX Xref "FILE_base"
+.IX Item "FILE_base"
+This macro is used to access the \f(CW\*(C`_base\*(C'\fR field (or equivalent) of the
+\&\f(CW\*(C`FILE\*(C'\fR structure pointed to by its argument. This macro will always be
+defined if \f(CW\*(C`USE_STDIO_BASE\*(C'\fR is defined.
+.RS 4
+.Sp
+.Vb 1
+\& void * FILE_base(FILE * f)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """FILE_bufsiz""" 4
+.el .IP \f(CWFILE_bufsiz\fR 4
+.IX Xref "FILE_bufsiz"
+.IX Item "FILE_bufsiz"
+This macro is used to determine the number of bytes in the I/O
+buffer pointed to by \f(CW\*(C`_base\*(C'\fR field (or equivalent) of the \f(CW\*(C`FILE\*(C'\fR
+structure pointed to its argument. This macro will always be defined
+if \f(CW\*(C`USE_STDIO_BASE\*(C'\fR is defined.
+.RS 4
+.Sp
+.Vb 1
+\& Size_t FILE_bufsiz(FILE *f)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """FILE_cnt""" 4
+.el .IP \f(CWFILE_cnt\fR 4
+.IX Xref "FILE_cnt"
+.IX Item "FILE_cnt"
+This macro is used to access the \f(CW\*(C`_cnt\*(C'\fR field (or equivalent) of the
+\&\f(CW\*(C`FILE\*(C'\fR structure pointed to by its argument. This macro will always be
+defined if \f(CW\*(C`USE_STDIO_PTR\*(C'\fR is defined.
+.RS 4
+.Sp
+.Vb 1
+\& Size_t FILE_cnt(FILE * f)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """FILE_ptr""" 4
+.el .IP \f(CWFILE_ptr\fR 4
+.IX Xref "FILE_ptr"
+.IX Item "FILE_ptr"
+This macro is used to access the \f(CW\*(C`_ptr\*(C'\fR field (or equivalent) of the
+\&\f(CW\*(C`FILE\*(C'\fR structure pointed to by its argument. This macro will always be
+defined if \f(CW\*(C`USE_STDIO_PTR\*(C'\fR is defined.
+.RS 4
+.Sp
+.Vb 1
+\& void * FILE_ptr(FILE * f)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """FLEXFILENAMES""" 4
+.el .IP \f(CWFLEXFILENAMES\fR 4
+.IX Xref "FLEXFILENAMES"
+.IX Item "FLEXFILENAMES"
+This symbol, if defined, indicates that the system supports filenames
+longer than 14 characters.
+.ie n .IP """HAS_DIR_DD_FD""" 4
+.el .IP \f(CWHAS_DIR_DD_FD\fR 4
+.IX Xref "HAS_DIR_DD_FD"
+.IX Item "HAS_DIR_DD_FD"
+This symbol, if defined, indicates that the \f(CW\*(C`DIR\*(C'\fR* dirstream
+structure contains a member variable named \f(CW\*(C`dd_fd\*(C'\fR.
+.ie n .IP """HAS_DUP2""" 4
+.el .IP \f(CWHAS_DUP2\fR 4
+.IX Xref "HAS_DUP2"
+.IX Item "HAS_DUP2"
+This symbol, if defined, indicates that the \f(CW\*(C`dup2\*(C'\fR routine is
+available to duplicate file descriptors.
+.ie n .IP """HAS_DUP3""" 4
+.el .IP \f(CWHAS_DUP3\fR 4
+.IX Xref "HAS_DUP3"
+.IX Item "HAS_DUP3"
+This symbol, if defined, indicates that the \f(CW\*(C`dup3\*(C'\fR routine is
+available to duplicate file descriptors.
+.ie n .IP """HAS_FAST_STDIO""" 4
+.el .IP \f(CWHAS_FAST_STDIO\fR 4
+.IX Xref "HAS_FAST_STDIO"
+.IX Item "HAS_FAST_STDIO"
+This symbol, if defined, indicates that the "fast stdio"
+is available to manipulate the stdio buffers directly.
+.ie n .IP """HAS_FCHDIR""" 4
+.el .IP \f(CWHAS_FCHDIR\fR 4
+.IX Xref "HAS_FCHDIR"
+.IX Item "HAS_FCHDIR"
+This symbol, if defined, indicates that the \f(CW\*(C`fchdir\*(C'\fR routine is
+available to change directory using a file descriptor.
+.ie n .IP """HAS_FCNTL""" 4
+.el .IP \f(CWHAS_FCNTL\fR 4
+.IX Xref "HAS_FCNTL"
+.IX Item "HAS_FCNTL"
+This symbol, if defined, indicates to the C program that
+the \f(CWfcntl()\fR function exists.
+.ie n .IP """HAS_FDCLOSE""" 4
+.el .IP \f(CWHAS_FDCLOSE\fR 4
+.IX Xref "HAS_FDCLOSE"
+.IX Item "HAS_FDCLOSE"
+This symbol, if defined, indicates that the \f(CW\*(C`fdclose\*(C'\fR routine is
+available to free a \f(CW\*(C`FILE\*(C'\fR structure without closing the underlying
+file descriptor. This function appeared in \f(CW\*(C`FreeBSD\*(C'\fR 10.2.
+.ie n .IP """HAS_FPATHCONF""" 4
+.el .IP \f(CWHAS_FPATHCONF\fR 4
+.IX Xref "HAS_FPATHCONF"
+.IX Item "HAS_FPATHCONF"
+This symbol, if defined, indicates that \f(CWpathconf()\fR is available
+to determine file-system related limits and options associated
+with a given open file descriptor.
+.ie n .IP """HAS_FPOS64_T""" 4
+.el .IP \f(CWHAS_FPOS64_T\fR 4
+.IX Xref "HAS_FPOS64_T"
+.IX Item "HAS_FPOS64_T"
+This symbol will be defined if the C compiler supports \f(CW\*(C`fpos64_t\*(C'\fR.
+.ie n .IP """HAS_FSTATFS""" 4
+.el .IP \f(CWHAS_FSTATFS\fR 4
+.IX Xref "HAS_FSTATFS"
+.IX Item "HAS_FSTATFS"
+This symbol, if defined, indicates that the \f(CW\*(C`fstatfs\*(C'\fR routine is
+available to stat filesystems by file descriptors.
+.ie n .IP """HAS_FSTATVFS""" 4
+.el .IP \f(CWHAS_FSTATVFS\fR 4
+.IX Xref "HAS_FSTATVFS"
+.IX Item "HAS_FSTATVFS"
+This symbol, if defined, indicates that the \f(CW\*(C`fstatvfs\*(C'\fR routine is
+available to stat filesystems by file descriptors.
+.ie n .IP """HAS_GETFSSTAT""" 4
+.el .IP \f(CWHAS_GETFSSTAT\fR 4
+.IX Xref "HAS_GETFSSTAT"
+.IX Item "HAS_GETFSSTAT"
+This symbol, if defined, indicates that the \f(CW\*(C`getfsstat\*(C'\fR routine is
+available to stat filesystems in bulk.
+.ie n .IP """HAS_GETMNT""" 4
+.el .IP \f(CWHAS_GETMNT\fR 4
+.IX Xref "HAS_GETMNT"
+.IX Item "HAS_GETMNT"
+This symbol, if defined, indicates that the \f(CW\*(C`getmnt\*(C'\fR routine is
+available to get filesystem mount info by filename.
+.ie n .IP """HAS_GETMNTENT""" 4
+.el .IP \f(CWHAS_GETMNTENT\fR 4
+.IX Xref "HAS_GETMNTENT"
+.IX Item "HAS_GETMNTENT"
+This symbol, if defined, indicates that the \f(CW\*(C`getmntent\*(C'\fR routine is
+available to iterate through mounted file systems to get their info.
+.ie n .IP """HAS_HASMNTOPT""" 4
+.el .IP \f(CWHAS_HASMNTOPT\fR 4
+.IX Xref "HAS_HASMNTOPT"
+.IX Item "HAS_HASMNTOPT"
+This symbol, if defined, indicates that the \f(CW\*(C`hasmntopt\*(C'\fR routine is
+available to query the mount options of file systems.
+.ie n .IP """HAS_LSEEK_PROTO""" 4
+.el .IP \f(CWHAS_LSEEK_PROTO\fR 4
+.IX Xref "HAS_LSEEK_PROTO"
+.IX Item "HAS_LSEEK_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWlseek()\fR function. Otherwise, it is up
+to the program to supply one. A good guess is
+.Sp
+.Vb 1
+\& extern off_t lseek(int, off_t, int);
+.Ve
+.ie n .IP """HAS_MKDIR""" 4
+.el .IP \f(CWHAS_MKDIR\fR 4
+.IX Xref "HAS_MKDIR"
+.IX Item "HAS_MKDIR"
+This symbol, if defined, indicates that the \f(CW\*(C`mkdir\*(C'\fR routine is available
+to create directories. Otherwise you should fork off a new process to
+exec \fI/bin/mkdir\fR.
+.ie n .IP """HAS_OFF64_T""" 4
+.el .IP \f(CWHAS_OFF64_T\fR 4
+.IX Xref "HAS_OFF64_T"
+.IX Item "HAS_OFF64_T"
+This symbol will be defined if the C compiler supports \f(CW\*(C`off64_t\*(C'\fR.
+.ie n .IP """HAS_OPENAT""" 4
+.el .IP \f(CWHAS_OPENAT\fR 4
+.IX Xref "HAS_OPENAT"
+.IX Item "HAS_OPENAT"
+This symbol is defined if the \f(CWopenat()\fR routine is available.
+.ie n .IP """HAS_OPEN3""" 4
+.el .IP \f(CWHAS_OPEN3\fR 4
+.IX Xref "HAS_OPEN3"
+.IX Item "HAS_OPEN3"
+This manifest constant lets the C program know that the three
+argument form of \f(CWopen(2)\fR is available.
+.ie n .IP """HAS_POLL""" 4
+.el .IP \f(CWHAS_POLL\fR 4
+.IX Xref "HAS_POLL"
+.IX Item "HAS_POLL"
+This symbol, if defined, indicates that the \f(CW\*(C`poll\*(C'\fR routine is
+available to \f(CW\*(C`poll\*(C'\fR active file descriptors. Please check \f(CW\*(C`I_POLL\*(C'\fR and
+\&\f(CW\*(C`I_SYS_POLL\*(C'\fR to know which header should be included as well.
+.ie n .IP """HAS_READDIR""" 4
+.el .IP \f(CWHAS_READDIR\fR 4
+.IX Xref "HAS_READDIR"
+.IX Item "HAS_READDIR"
+This symbol, if defined, indicates that the \f(CW\*(C`readdir\*(C'\fR routine is
+available to read directory entries. You may have to include
+\&\fIdirent.h\fR. See \f(CW"I_DIRENT"\fR.
+.ie n .IP """HAS_READDIR64_R""" 4
+.el .IP \f(CWHAS_READDIR64_R\fR 4
+.IX Xref "HAS_READDIR64_R"
+.IX Item "HAS_READDIR64_R"
+This symbol, if defined, indicates that the \f(CW\*(C`readdir64_r\*(C'\fR routine
+is available to readdir64 re-entrantly.
+.ie n .IP """HAS_REWINDDIR""" 4
+.el .IP \f(CWHAS_REWINDDIR\fR 4
+.IX Xref "HAS_REWINDDIR"
+.IX Item "HAS_REWINDDIR"
+This symbol, if defined, indicates that the \f(CW\*(C`rewinddir\*(C'\fR routine is
+available. You may have to include \fIdirent.h\fR. See \f(CW"I_DIRENT"\fR.
+.ie n .IP """HAS_RMDIR""" 4
+.el .IP \f(CWHAS_RMDIR\fR 4
+.IX Xref "HAS_RMDIR"
+.IX Item "HAS_RMDIR"
+This symbol, if defined, indicates that the \f(CW\*(C`rmdir\*(C'\fR routine is
+available to remove directories. Otherwise you should fork off a
+new process to exec \fI/bin/rmdir\fR.
+.ie n .IP """HAS_SEEKDIR""" 4
+.el .IP \f(CWHAS_SEEKDIR\fR 4
+.IX Xref "HAS_SEEKDIR"
+.IX Item "HAS_SEEKDIR"
+This symbol, if defined, indicates that the \f(CW\*(C`seekdir\*(C'\fR routine is
+available. You may have to include \fIdirent.h\fR. See \f(CW"I_DIRENT"\fR.
+.ie n .IP """HAS_SELECT""" 4
+.el .IP \f(CWHAS_SELECT\fR 4
+.IX Xref "HAS_SELECT"
+.IX Item "HAS_SELECT"
+This symbol, if defined, indicates that the \f(CW\*(C`select\*(C'\fR routine is
+available to \f(CW\*(C`select\*(C'\fR active file descriptors. If the timeout field
+is used, \fIsys/time.h\fR may need to be included.
+.ie n .IP """HAS_SETVBUF""" 4
+.el .IP \f(CWHAS_SETVBUF\fR 4
+.IX Xref "HAS_SETVBUF"
+.IX Item "HAS_SETVBUF"
+This symbol, if defined, indicates that the \f(CW\*(C`setvbuf\*(C'\fR routine is
+available to change buffering on an open stdio stream.
+to a line-buffered mode.
+.ie n .IP """HAS_STDIO_STREAM_ARRAY""" 4
+.el .IP \f(CWHAS_STDIO_STREAM_ARRAY\fR 4
+.IX Xref "HAS_STDIO_STREAM_ARRAY"
+.IX Item "HAS_STDIO_STREAM_ARRAY"
+This symbol, if defined, tells that there is an array
+holding the stdio streams.
+.ie n .IP """HAS_STRUCT_FS_DATA""" 4
+.el .IP \f(CWHAS_STRUCT_FS_DATA\fR 4
+.IX Xref "HAS_STRUCT_FS_DATA"
+.IX Item "HAS_STRUCT_FS_DATA"
+This symbol, if defined, indicates that the \f(CW\*(C`struct fs_data\*(C'\fR
+to do \f(CWstatfs()\fR is supported.
+.ie n .IP """HAS_STRUCT_STATFS""" 4
+.el .IP \f(CWHAS_STRUCT_STATFS\fR 4
+.IX Xref "HAS_STRUCT_STATFS"
+.IX Item "HAS_STRUCT_STATFS"
+This symbol, if defined, indicates that the \f(CW\*(C`struct statfs\*(C'\fR
+to do \f(CWstatfs()\fR is supported.
+.ie n .IP """HAS_STRUCT_STATFS_F_FLAGS""" 4
+.el .IP \f(CWHAS_STRUCT_STATFS_F_FLAGS\fR 4
+.IX Xref "HAS_STRUCT_STATFS_F_FLAGS"
+.IX Item "HAS_STRUCT_STATFS_F_FLAGS"
+This symbol, if defined, indicates that the \f(CW\*(C`struct statfs\*(C'\fR
+does have the \f(CW\*(C`f_flags\*(C'\fR member containing the mount flags of
+the filesystem containing the file.
+This kind of \f(CW\*(C`struct statfs\*(C'\fR is coming from \fIsys/mount.h\fR (\f(CW\*(C`BSD\*(C'\fR 4.3),
+not from \fIsys/statfs.h\fR (\f(CW\*(C`SYSV\*(C'\fR). Older \f(CW\*(C`BSDs\*(C'\fR (like Ultrix) do not
+have \f(CWstatfs()\fR and \f(CW\*(C`struct statfs\*(C'\fR, they have \f(CWustat()\fR and \f(CWgetmnt()\fR
+with \f(CW\*(C`struct ustat\*(C'\fR and \f(CW\*(C`struct fs_data\*(C'\fR.
+.ie n .IP """HAS_TELLDIR""" 4
+.el .IP \f(CWHAS_TELLDIR\fR 4
+.IX Xref "HAS_TELLDIR"
+.IX Item "HAS_TELLDIR"
+This symbol, if defined, indicates that the \f(CW\*(C`telldir\*(C'\fR routine is
+available. You may have to include \fIdirent.h\fR. See \f(CW"I_DIRENT"\fR.
+.ie n .IP """HAS_USTAT""" 4
+.el .IP \f(CWHAS_USTAT\fR 4
+.IX Xref "HAS_USTAT"
+.IX Item "HAS_USTAT"
+This symbol, if defined, indicates that the \f(CW\*(C`ustat\*(C'\fR system call is
+available to query file system statistics by \f(CW\*(C`dev_t\*(C'\fR.
+.ie n .IP """I_FCNTL""" 4
+.el .IP \f(CWI_FCNTL\fR 4
+.IX Xref "I_FCNTL"
+.IX Item "I_FCNTL"
+This manifest constant tells the C program to include \fIfcntl.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_FCNTL
+\& #include <fcntl.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_SYS_DIR""" 4
+.el .IP \f(CWI_SYS_DIR\fR 4
+.IX Xref "I_SYS_DIR"
+.IX Item "I_SYS_DIR"
+This symbol, if defined, indicates to the C program that it should
+include \fIsys/dir.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_SYS_DIR
+\& #include <sys_dir.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_SYS_FILE""" 4
+.el .IP \f(CWI_SYS_FILE\fR 4
+.IX Xref "I_SYS_FILE"
+.IX Item "I_SYS_FILE"
+This symbol, if defined, indicates to the C program that it should
+include \fIsys/file.h\fR to get definition of \f(CW\*(C`R_OK\*(C'\fR and friends.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_SYS_FILE
+\& #include <sys_file.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_SYS_NDIR""" 4
+.el .IP \f(CWI_SYS_NDIR\fR 4
+.IX Xref "I_SYS_NDIR"
+.IX Item "I_SYS_NDIR"
+This symbol, if defined, indicates to the C program that it should
+include \fIsys/ndir.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_SYS_NDIR
+\& #include <sys_ndir.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_SYS_STATFS""" 4
+.el .IP \f(CWI_SYS_STATFS\fR 4
+.IX Xref "I_SYS_STATFS"
+.IX Item "I_SYS_STATFS"
+This symbol, if defined, indicates that \fIsys/statfs.h\fR exists.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_SYS_STATFS
+\& #include <sys_statfs.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LSEEKSIZE""" 4
+.el .IP \f(CWLSEEKSIZE\fR 4
+.IX Xref "LSEEKSIZE"
+.IX Item "LSEEKSIZE"
+This symbol holds the number of bytes used by the \f(CW\*(C`Off_t\*(C'\fR.
+.ie n .IP """RD_NODATA""" 4
+.el .IP \f(CWRD_NODATA\fR 4
+.IX Xref "RD_NODATA"
+.IX Item "RD_NODATA"
+This symbol holds the return code from \f(CWread()\fR when no data is present
+on the non-blocking file descriptor. Be careful! If \f(CW\*(C`EOF_NONBLOCK\*(C'\fR is
+not defined, then you can't distinguish between no data and \f(CW\*(C`EOF\*(C'\fR by
+issuing a \f(CWread()\fR. You'll have to find another way to tell for sure!
+.ie n .IP """READDIR64_R_PROTO""" 4
+.el .IP \f(CWREADDIR64_R_PROTO\fR 4
+.IX Xref "READDIR64_R_PROTO"
+.IX Item "READDIR64_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`readdir64_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_readdir64_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_readdir64_r\*(C'\fR
+is defined.
+.ie n .IP """STDCHAR""" 4
+.el .IP \f(CWSTDCHAR\fR 4
+.IX Xref "STDCHAR"
+.IX Item "STDCHAR"
+This symbol is defined to be the type of char used in \fIstdio.h\fR.
+It has the values "unsigned char" or "char".
+.ie n .IP """STDIO_CNT_LVALUE""" 4
+.el .IP \f(CWSTDIO_CNT_LVALUE\fR 4
+.IX Xref "STDIO_CNT_LVALUE"
+.IX Item "STDIO_CNT_LVALUE"
+This symbol is defined if the \f(CW\*(C`FILE_cnt\*(C'\fR macro can be used as an
+lvalue.
+.ie n .IP """STDIO_PTR_LVAL_NOCHANGE_CNT""" 4
+.el .IP \f(CWSTDIO_PTR_LVAL_NOCHANGE_CNT\fR 4
+.IX Xref "STDIO_PTR_LVAL_NOCHANGE_CNT"
+.IX Item "STDIO_PTR_LVAL_NOCHANGE_CNT"
+This symbol is defined if using the \f(CW\*(C`FILE_ptr\*(C'\fR macro as an lvalue
+to increase the pointer by n leaves \f(CWFile_cnt(fp)\fR unchanged.
+.ie n .IP """STDIO_PTR_LVAL_SETS_CNT""" 4
+.el .IP \f(CWSTDIO_PTR_LVAL_SETS_CNT\fR 4
+.IX Xref "STDIO_PTR_LVAL_SETS_CNT"
+.IX Item "STDIO_PTR_LVAL_SETS_CNT"
+This symbol is defined if using the \f(CW\*(C`FILE_ptr\*(C'\fR macro as an lvalue
+to increase the pointer by n has the side effect of decreasing the
+value of \f(CWFile_cnt(fp)\fR by n.
+.ie n .IP """STDIO_PTR_LVALUE""" 4
+.el .IP \f(CWSTDIO_PTR_LVALUE\fR 4
+.IX Xref "STDIO_PTR_LVALUE"
+.IX Item "STDIO_PTR_LVALUE"
+This symbol is defined if the \f(CW\*(C`FILE_ptr\*(C'\fR macro can be used as an
+lvalue.
+.ie n .IP """STDIO_STREAM_ARRAY""" 4
+.el .IP \f(CWSTDIO_STREAM_ARRAY\fR 4
+.IX Xref "STDIO_STREAM_ARRAY"
+.IX Item "STDIO_STREAM_ARRAY"
+This symbol tells the name of the array holding the stdio streams.
+Usual values include \f(CW\*(C`_iob\*(C'\fR, \f(CW\*(C`_\|_iob\*(C'\fR, and \f(CW\*(C`_\|_sF\*(C'\fR.
+.ie n .IP """ST_INO_SIGN""" 4
+.el .IP \f(CWST_INO_SIGN\fR 4
+.IX Xref "ST_INO_SIGN"
+.IX Item "ST_INO_SIGN"
+This symbol holds the signedness of \f(CW\*(C`struct stat\*(C'\fR's \f(CW\*(C`st_ino\*(C'\fR.
+1 for unsigned, \-1 for signed.
+.ie n .IP """ST_INO_SIZE""" 4
+.el .IP \f(CWST_INO_SIZE\fR 4
+.IX Xref "ST_INO_SIZE"
+.IX Item "ST_INO_SIZE"
+This variable contains the size of \f(CW\*(C`struct stat\*(C'\fR's \f(CW\*(C`st_ino\*(C'\fR in bytes.
+.ie n .IP """VAL_EAGAIN""" 4
+.el .IP \f(CWVAL_EAGAIN\fR 4
+.IX Xref "VAL_EAGAIN"
+.IX Item "VAL_EAGAIN"
+This symbol holds the errno error code set by \f(CWread()\fR when no data was
+present on the non-blocking file descriptor.
+.ie n .IP """VAL_O_NONBLOCK""" 4
+.el .IP \f(CWVAL_O_NONBLOCK\fR 4
+.IX Xref "VAL_O_NONBLOCK"
+.IX Item "VAL_O_NONBLOCK"
+This symbol is to be used during \f(CWopen()\fR or \f(CWfcntl(F_SETFL)\fR to turn on
+non-blocking I/O for the file descriptor. Note that there is no way
+back, i.e. you cannot turn it blocking again this way. If you wish to
+alternatively switch between blocking and non-blocking, use the
+\&\f(CWioctl(FIOSNBIO)\fR call instead, but that is not supported by all devices.
+.ie n .IP """VOID_CLOSEDIR""" 4
+.el .IP \f(CWVOID_CLOSEDIR\fR 4
+.IX Xref "VOID_CLOSEDIR"
+.IX Item "VOID_CLOSEDIR"
+This symbol, if defined, indicates that the \f(CWclosedir()\fR routine
+does not return a value.
+.SH "Floating point"
+.IX Header "Floating point"
+Also "List of capability HAS_foo symbols" lists capabilities
+that arent in this section. For example \f(CW\*(C`HAS_ASINH\*(C'\fR, for the
+hyperbolic sine function.
+.ie n .IP """CASTFLAGS""" 4
+.el .IP \f(CWCASTFLAGS\fR 4
+.IX Xref "CASTFLAGS"
+.IX Item "CASTFLAGS"
+This symbol contains flags that say what difficulties the compiler
+has casting odd floating values to unsigned long:
+.Sp
+.Vb 4
+\& 0 = ok
+\& 1 = couldn\*(Aqt cast < 0
+\& 2 = couldn\*(Aqt cast >= 0x80000000
+\& 4 = couldn\*(Aqt cast in argument expression list
+.Ve
+.ie n .IP """CASTNEGFLOAT""" 4
+.el .IP \f(CWCASTNEGFLOAT\fR 4
+.IX Xref "CASTNEGFLOAT"
+.IX Item "CASTNEGFLOAT"
+This symbol is defined if the C compiler can cast negative
+numbers to unsigned longs, ints and shorts.
+.ie n .IP """DOUBLE_HAS_INF""" 4
+.el .IP \f(CWDOUBLE_HAS_INF\fR 4
+.IX Xref "DOUBLE_HAS_INF"
+.IX Item "DOUBLE_HAS_INF"
+This symbol, if defined, indicates that the double has
+the infinity.
+.ie n .IP """DOUBLE_HAS_NAN""" 4
+.el .IP \f(CWDOUBLE_HAS_NAN\fR 4
+.IX Xref "DOUBLE_HAS_NAN"
+.IX Item "DOUBLE_HAS_NAN"
+This symbol, if defined, indicates that the double has
+the not-a-number.
+.ie n .IP """DOUBLE_HAS_NEGATIVE_ZERO""" 4
+.el .IP \f(CWDOUBLE_HAS_NEGATIVE_ZERO\fR 4
+.IX Xref "DOUBLE_HAS_NEGATIVE_ZERO"
+.IX Item "DOUBLE_HAS_NEGATIVE_ZERO"
+This symbol, if defined, indicates that the double has
+the \f(CW\*(C`negative_zero\*(C'\fR.
+.ie n .IP """DOUBLE_HAS_SUBNORMALS""" 4
+.el .IP \f(CWDOUBLE_HAS_SUBNORMALS\fR 4
+.IX Xref "DOUBLE_HAS_SUBNORMALS"
+.IX Item "DOUBLE_HAS_SUBNORMALS"
+This symbol, if defined, indicates that the double has
+the subnormals (denormals).
+.ie n .IP """DOUBLEINFBYTES""" 4
+.el .IP \f(CWDOUBLEINFBYTES\fR 4
+.IX Xref "DOUBLEINFBYTES"
+.IX Item "DOUBLEINFBYTES"
+This symbol, if defined, is a comma-separated list of
+hexadecimal bytes for the double precision infinity.
+.ie n .IP """DOUBLEKIND""" 4
+.el .IP \f(CWDOUBLEKIND\fR 4
+.IX Xref "DOUBLEKIND"
+.IX Item "DOUBLEKIND"
+\&\f(CW\*(C`DOUBLEKIND\*(C'\fR will be one of
+\&\f(CW\*(C`DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_VAX_F_FLOAT\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_VAX_D_FLOAT\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_VAX_G_FLOAT\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IBM_SINGLE_32_BIT\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_IBM_DOUBLE_64_BIT\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_CRAY_SINGLE_64_BIT\*(C'\fR
+\&\f(CW\*(C`DOUBLE_IS_UNKNOWN_FORMAT\*(C'\fR
+.ie n .IP """DOUBLEMANTBITS""" 4
+.el .IP \f(CWDOUBLEMANTBITS\fR 4
+.IX Xref "DOUBLEMANTBITS"
+.IX Item "DOUBLEMANTBITS"
+This symbol, if defined, tells how many mantissa bits
+there are in double precision floating point format.
+Note that this is usually \f(CW\*(C`DBL_MANT_DIG\*(C'\fR minus one, since
+with the standard \f(CW\*(C`IEEE\*(C'\fR 754 formats \f(CW\*(C`DBL_MANT_DIG\*(C'\fR includes
+the implicit bit, which doesn't really exist.
+.ie n .IP """DOUBLENANBYTES""" 4
+.el .IP \f(CWDOUBLENANBYTES\fR 4
+.IX Xref "DOUBLENANBYTES"
+.IX Item "DOUBLENANBYTES"
+This symbol, if defined, is a comma-separated list of
+hexadecimal bytes (0xHH) for the double precision not-a-number.
+.ie n .IP """DOUBLESIZE""" 4
+.el .IP \f(CWDOUBLESIZE\fR 4
+.IX Xref "DOUBLESIZE"
+.IX Item "DOUBLESIZE"
+This symbol contains the size of a double, so that the C preprocessor
+can make decisions based on it.
+.ie n .IP """DOUBLE_STYLE_CRAY""" 4
+.el .IP \f(CWDOUBLE_STYLE_CRAY\fR 4
+.IX Xref "DOUBLE_STYLE_CRAY"
+.IX Item "DOUBLE_STYLE_CRAY"
+This symbol, if defined, indicates that the double is
+the 64\-bit \f(CW\*(C`CRAY\*(C'\fR mainframe format.
+.ie n .IP """DOUBLE_STYLE_IBM""" 4
+.el .IP \f(CWDOUBLE_STYLE_IBM\fR 4
+.IX Xref "DOUBLE_STYLE_IBM"
+.IX Item "DOUBLE_STYLE_IBM"
+This symbol, if defined, indicates that the double is
+the 64\-bit \f(CW\*(C`IBM\*(C'\fR mainframe format.
+.ie n .IP """DOUBLE_STYLE_IEEE""" 4
+.el .IP \f(CWDOUBLE_STYLE_IEEE\fR 4
+.IX Xref "DOUBLE_STYLE_IEEE"
+.IX Item "DOUBLE_STYLE_IEEE"
+This symbol, if defined, indicates that the double is
+the 64\-bit \f(CW\*(C`IEEE\*(C'\fR 754.
+.ie n .IP """DOUBLE_STYLE_VAX""" 4
+.el .IP \f(CWDOUBLE_STYLE_VAX\fR 4
+.IX Xref "DOUBLE_STYLE_VAX"
+.IX Item "DOUBLE_STYLE_VAX"
+This symbol, if defined, indicates that the double is
+the 64\-bit \f(CW\*(C`VAX\*(C'\fR format D or G.
+.ie n .IP """HAS_ATOLF""" 4
+.el .IP \f(CWHAS_ATOLF\fR 4
+.IX Xref "HAS_ATOLF"
+.IX Item "HAS_ATOLF"
+This symbol, if defined, indicates that the \f(CW\*(C`atolf\*(C'\fR routine is
+available to convert strings into long doubles.
+.ie n .IP """HAS_CLASS""" 4
+.el .IP \f(CWHAS_CLASS\fR 4
+.IX Xref "HAS_CLASS"
+.IX Item "HAS_CLASS"
+This symbol, if defined, indicates that the \f(CW\*(C`class\*(C'\fR routine is
+available to classify doubles. Available for example in \f(CW\*(C`AIX\*(C'\fR.
+The returned values are defined in \fIfloat.h\fR and are:
+.Sp
+.Vb 10
+\& FP_PLUS_NORM Positive normalized, nonzero
+\& FP_MINUS_NORM Negative normalized, nonzero
+\& FP_PLUS_DENORM Positive denormalized, nonzero
+\& FP_MINUS_DENORM Negative denormalized, nonzero
+\& FP_PLUS_ZERO +0.0
+\& FP_MINUS_ZERO \-0.0
+\& FP_PLUS_INF +INF
+\& FP_MINUS_INF \-INF
+\& FP_NANS Signaling Not a Number (NaNS)
+\& FP_NANQ Quiet Not a Number (NaNQ)
+.Ve
+.ie n .IP """HAS_FINITE""" 4
+.el .IP \f(CWHAS_FINITE\fR 4
+.IX Xref "HAS_FINITE"
+.IX Item "HAS_FINITE"
+This symbol, if defined, indicates that the \f(CW\*(C`finite\*(C'\fR routine is
+available to check whether a double is \f(CW\*(C`finite\*(C'\fR (non-infinity non-NaN).
+.ie n .IP """HAS_FINITEL""" 4
+.el .IP \f(CWHAS_FINITEL\fR 4
+.IX Xref "HAS_FINITEL"
+.IX Item "HAS_FINITEL"
+This symbol, if defined, indicates that the \f(CW\*(C`finitel\*(C'\fR routine is
+available to check whether a long double is finite
+(non-infinity non-NaN).
+.ie n .IP """HAS_FPCLASS""" 4
+.el .IP \f(CWHAS_FPCLASS\fR 4
+.IX Xref "HAS_FPCLASS"
+.IX Item "HAS_FPCLASS"
+This symbol, if defined, indicates that the \f(CW\*(C`fpclass\*(C'\fR routine is
+available to classify doubles. Available for example in Solaris/\f(CW\*(C`SVR4\*(C'\fR.
+The returned values are defined in \fIieeefp.h\fR and are:
+.Sp
+.Vb 10
+\& FP_SNAN signaling NaN
+\& FP_QNAN quiet NaN
+\& FP_NINF negative infinity
+\& FP_PINF positive infinity
+\& FP_NDENORM negative denormalized non\-zero
+\& FP_PDENORM positive denormalized non\-zero
+\& FP_NZERO negative zero
+\& FP_PZERO positive zero
+\& FP_NNORM negative normalized non\-zero
+\& FP_PNORM positive normalized non\-zero
+.Ve
+.ie n .IP """HAS_FP_CLASS""" 4
+.el .IP \f(CWHAS_FP_CLASS\fR 4
+.IX Xref "HAS_FP_CLASS"
+.IX Item "HAS_FP_CLASS"
+This symbol, if defined, indicates that the \f(CW\*(C`fp_class\*(C'\fR routine is
+available to classify doubles. Available for example in Digital \f(CW\*(C`UNIX\*(C'\fR.
+The returned values are defined in \fImath.h\fR and are:
+.Sp
+.Vb 10
+\& FP_SNAN Signaling NaN (Not\-a\-Number)
+\& FP_QNAN Quiet NaN (Not\-a\-Number)
+\& FP_POS_INF +infinity
+\& FP_NEG_INF \-infinity
+\& FP_POS_NORM Positive normalized
+\& FP_NEG_NORM Negative normalized
+\& FP_POS_DENORM Positive denormalized
+\& FP_NEG_DENORM Negative denormalized
+\& FP_POS_ZERO +0.0 (positive zero)
+\& FP_NEG_ZERO \-0.0 (negative zero)
+.Ve
+.ie n .IP """HAS_FPCLASSIFY""" 4
+.el .IP \f(CWHAS_FPCLASSIFY\fR 4
+.IX Xref "HAS_FPCLASSIFY"
+.IX Item "HAS_FPCLASSIFY"
+This symbol, if defined, indicates that the \f(CW\*(C`fpclassify\*(C'\fR routine is
+available to classify doubles. Available for example in HP-UX.
+The returned values are defined in \fImath.h\fR and are
+.Sp
+.Vb 5
+\& FP_NORMAL Normalized
+\& FP_ZERO Zero
+\& FP_INFINITE Infinity
+\& FP_SUBNORMAL Denormalized
+\& FP_NAN NaN
+.Ve
+.ie n .IP """HAS_FP_CLASSIFY""" 4
+.el .IP \f(CWHAS_FP_CLASSIFY\fR 4
+.IX Xref "HAS_FP_CLASSIFY"
+.IX Item "HAS_FP_CLASSIFY"
+This symbol, if defined, indicates that the \f(CW\*(C`fp_classify\*(C'\fR routine is
+available to classify doubles. The values are defined in \fImath.h\fR
+.Sp
+.Vb 5
+\& FP_NORMAL Normalized
+\& FP_ZERO Zero
+\& FP_INFINITE Infinity
+\& FP_SUBNORMAL Denormalized
+\& FP_NAN NaN
+.Ve
+.ie n .IP """HAS_FPCLASSL""" 4
+.el .IP \f(CWHAS_FPCLASSL\fR 4
+.IX Xref "HAS_FPCLASSL"
+.IX Item "HAS_FPCLASSL"
+This symbol, if defined, indicates that the \f(CW\*(C`fpclassl\*(C'\fR routine is
+available to classify long doubles. Available for example in \f(CW\*(C`IRIX\*(C'\fR.
+The returned values are defined in \fIieeefp.h\fR and are:
+.Sp
+.Vb 10
+\& FP_SNAN signaling NaN
+\& FP_QNAN quiet NaN
+\& FP_NINF negative infinity
+\& FP_PINF positive infinity
+\& FP_NDENORM negative denormalized non\-zero
+\& FP_PDENORM positive denormalized non\-zero
+\& FP_NZERO negative zero
+\& FP_PZERO positive zero
+\& FP_NNORM negative normalized non\-zero
+\& FP_PNORM positive normalized non\-zero
+.Ve
+.ie n .IP """HAS_FP_CLASSL""" 4
+.el .IP \f(CWHAS_FP_CLASSL\fR 4
+.IX Xref "HAS_FP_CLASSL"
+.IX Item "HAS_FP_CLASSL"
+This symbol, if defined, indicates that the \f(CW\*(C`fp_classl\*(C'\fR routine is
+available to classify long doubles. Available for example in
+Digital \f(CW\*(C`UNIX\*(C'\fR. See for possible values \f(CW\*(C`HAS_FP_CLASS\*(C'\fR.
+.ie n .IP """HAS_FPGETROUND""" 4
+.el .IP \f(CWHAS_FPGETROUND\fR 4
+.IX Xref "HAS_FPGETROUND"
+.IX Item "HAS_FPGETROUND"
+This symbol, if defined, indicates that the \f(CW\*(C`fpgetround\*(C'\fR routine is
+available to get the floating point rounding mode.
+.ie n .IP """HAS_FREXPL""" 4
+.el .IP \f(CWHAS_FREXPL\fR 4
+.IX Xref "HAS_FREXPL"
+.IX Item "HAS_FREXPL"
+This symbol, if defined, indicates that the \f(CW\*(C`frexpl\*(C'\fR routine is
+available to break a long double floating-point number into
+a normalized fraction and an integral power of 2.
+.ie n .IP """HAS_ILOGB""" 4
+.el .IP \f(CWHAS_ILOGB\fR 4
+.IX Xref "HAS_ILOGB"
+.IX Item "HAS_ILOGB"
+This symbol, if defined, indicates that the \f(CW\*(C`ilogb\*(C'\fR routine is
+available to get integer exponent of a floating-point value.
+.ie n .IP """HAS_ISFINITE""" 4
+.el .IP \f(CWHAS_ISFINITE\fR 4
+.IX Xref "HAS_ISFINITE"
+.IX Item "HAS_ISFINITE"
+This symbol, if defined, indicates that the \f(CW\*(C`isfinite\*(C'\fR routine is
+available to check whether a double is finite (non-infinity non-NaN).
+.ie n .IP """HAS_ISFINITEL""" 4
+.el .IP \f(CWHAS_ISFINITEL\fR 4
+.IX Xref "HAS_ISFINITEL"
+.IX Item "HAS_ISFINITEL"
+This symbol, if defined, indicates that the \f(CW\*(C`isfinitel\*(C'\fR routine is
+available to check whether a long double is finite.
+(non-infinity non-NaN).
+.ie n .IP """HAS_ISINF""" 4
+.el .IP \f(CWHAS_ISINF\fR 4
+.IX Xref "HAS_ISINF"
+.IX Item "HAS_ISINF"
+This symbol, if defined, indicates that the \f(CW\*(C`isinf\*(C'\fR routine is
+available to check whether a double is an infinity.
+.ie n .IP """HAS_ISINFL""" 4
+.el .IP \f(CWHAS_ISINFL\fR 4
+.IX Xref "HAS_ISINFL"
+.IX Item "HAS_ISINFL"
+This symbol, if defined, indicates that the \f(CW\*(C`isinfl\*(C'\fR routine is
+available to check whether a long double is an infinity.
+.ie n .IP """HAS_ISNAN""" 4
+.el .IP \f(CWHAS_ISNAN\fR 4
+.IX Xref "HAS_ISNAN"
+.IX Item "HAS_ISNAN"
+This symbol, if defined, indicates that the \f(CW\*(C`isnan\*(C'\fR routine is
+available to check whether a double is a NaN.
+.ie n .IP """HAS_ISNANL""" 4
+.el .IP \f(CWHAS_ISNANL\fR 4
+.IX Xref "HAS_ISNANL"
+.IX Item "HAS_ISNANL"
+This symbol, if defined, indicates that the \f(CW\*(C`isnanl\*(C'\fR routine is
+available to check whether a long double is a NaN.
+.ie n .IP """HAS_ISNORMAL""" 4
+.el .IP \f(CWHAS_ISNORMAL\fR 4
+.IX Xref "HAS_ISNORMAL"
+.IX Item "HAS_ISNORMAL"
+This symbol, if defined, indicates that the \f(CW\*(C`isnormal\*(C'\fR routine is
+available to check whether a double is normal (non-zero normalized).
+.ie n .IP """HAS_J0L""" 4
+.el .IP \f(CWHAS_J0L\fR 4
+.IX Xref "HAS_J0L"
+.IX Item "HAS_J0L"
+This symbol, if defined, indicates to the C program that the
+\&\f(CWj0l()\fR function is available for Bessel functions of the first
+kind of the order zero, for long doubles.
+.ie n .IP """HAS_J0""" 4
+.el .IP \f(CWHAS_J0\fR 4
+.IX Xref "HAS_J0"
+.IX Item "HAS_J0"
+This symbol, if defined, indicates to the C program that the
+\&\f(CWj0()\fR function is available for Bessel functions of the first
+kind of the order zero, for doubles.
+.ie n .IP """HAS_LDBL_DIG""" 4
+.el .IP \f(CWHAS_LDBL_DIG\fR 4
+.IX Xref "HAS_LDBL_DIG"
+.IX Item "HAS_LDBL_DIG"
+This symbol, if defined, indicates that this system's \fIfloat.h\fR
+or \fIlimits.h\fR defines the symbol \f(CW\*(C`LDBL_DIG\*(C'\fR, which is the number
+of significant digits in a long double precision number. Unlike
+for \f(CW\*(C`DBL_DIG\*(C'\fR, there's no good guess for \f(CW\*(C`LDBL_DIG\*(C'\fR if it is undefined.
+.ie n .IP """HAS_LDEXPL""" 4
+.el .IP \f(CWHAS_LDEXPL\fR 4
+.IX Xref "HAS_LDEXPL"
+.IX Item "HAS_LDEXPL"
+This symbol, if defined, indicates that the \f(CW\*(C`ldexpl\*(C'\fR routine is
+available to shift a long double floating-point number
+by an integral power of 2.
+.ie n .IP """HAS_LLRINT""" 4
+.el .IP \f(CWHAS_LLRINT\fR 4
+.IX Xref "HAS_LLRINT"
+.IX Item "HAS_LLRINT"
+This symbol, if defined, indicates that the \f(CW\*(C`llrint\*(C'\fR routine is
+available to return the long long value closest to a double
+(according to the current rounding mode).
+.ie n .IP """HAS_LLRINTL""" 4
+.el .IP \f(CWHAS_LLRINTL\fR 4
+.IX Xref "HAS_LLRINTL"
+.IX Item "HAS_LLRINTL"
+This symbol, if defined, indicates that the \f(CW\*(C`llrintl\*(C'\fR routine is
+available to return the long long value closest to a long double
+(according to the current rounding mode).
+.ie n .IP """HAS_LLROUNDL""" 4
+.el .IP \f(CWHAS_LLROUNDL\fR 4
+.IX Xref "HAS_LLROUNDL"
+.IX Item "HAS_LLROUNDL"
+This symbol, if defined, indicates that the \f(CW\*(C`llroundl\*(C'\fR routine is
+available to return the nearest long long value away from zero of
+the long double argument value.
+.ie n .IP """HAS_LONG_DOUBLE""" 4
+.el .IP \f(CWHAS_LONG_DOUBLE\fR 4
+.IX Xref "HAS_LONG_DOUBLE"
+.IX Item "HAS_LONG_DOUBLE"
+This symbol will be defined if the C compiler supports long
+doubles.
+.ie n .IP """HAS_LRINT""" 4
+.el .IP \f(CWHAS_LRINT\fR 4
+.IX Xref "HAS_LRINT"
+.IX Item "HAS_LRINT"
+This symbol, if defined, indicates that the \f(CW\*(C`lrint\*(C'\fR routine is
+available to return the integral value closest to a double
+(according to the current rounding mode).
+.ie n .IP """HAS_LRINTL""" 4
+.el .IP \f(CWHAS_LRINTL\fR 4
+.IX Xref "HAS_LRINTL"
+.IX Item "HAS_LRINTL"
+This symbol, if defined, indicates that the \f(CW\*(C`lrintl\*(C'\fR routine is
+available to return the integral value closest to a long double
+(according to the current rounding mode).
+.ie n .IP """HAS_LROUNDL""" 4
+.el .IP \f(CWHAS_LROUNDL\fR 4
+.IX Xref "HAS_LROUNDL"
+.IX Item "HAS_LROUNDL"
+This symbol, if defined, indicates that the \f(CW\*(C`lroundl\*(C'\fR routine is
+available to return the nearest integral value away from zero of
+the long double argument value.
+.ie n .IP """HAS_MODFL""" 4
+.el .IP \f(CWHAS_MODFL\fR 4
+.IX Xref "HAS_MODFL"
+.IX Item "HAS_MODFL"
+This symbol, if defined, indicates that the \f(CW\*(C`modfl\*(C'\fR routine is
+available to split a long double x into a fractional part f and
+an integer part i such that |f| < 1.0 and (f + i) = x.
+.ie n .IP """HAS_NAN""" 4
+.el .IP \f(CWHAS_NAN\fR 4
+.IX Xref "HAS_NAN"
+.IX Item "HAS_NAN"
+This symbol, if defined, indicates that the \f(CW\*(C`nan\*(C'\fR routine is
+available to generate NaN.
+.ie n .IP """HAS_NEXTTOWARD""" 4
+.el .IP \f(CWHAS_NEXTTOWARD\fR 4
+.IX Xref "HAS_NEXTTOWARD"
+.IX Item "HAS_NEXTTOWARD"
+This symbol, if defined, indicates that the \f(CW\*(C`nexttoward\*(C'\fR routine is
+available to return the next machine representable long double from
+x in direction y.
+.ie n .IP """HAS_REMAINDER""" 4
+.el .IP \f(CWHAS_REMAINDER\fR 4
+.IX Xref "HAS_REMAINDER"
+.IX Item "HAS_REMAINDER"
+This symbol, if defined, indicates that the \f(CW\*(C`remainder\*(C'\fR routine is
+available to return the floating-point \f(CW\*(C`remainder\*(C'\fR.
+.ie n .IP """HAS_SCALBN""" 4
+.el .IP \f(CWHAS_SCALBN\fR 4
+.IX Xref "HAS_SCALBN"
+.IX Item "HAS_SCALBN"
+This symbol, if defined, indicates that the \f(CW\*(C`scalbn\*(C'\fR routine is
+available to multiply floating-point number by integral power
+of radix.
+.ie n .IP """HAS_SIGNBIT""" 4
+.el .IP \f(CWHAS_SIGNBIT\fR 4
+.IX Xref "HAS_SIGNBIT"
+.IX Item "HAS_SIGNBIT"
+This symbol, if defined, indicates that the \f(CW\*(C`signbit\*(C'\fR routine is
+available to check if the given number has the sign bit set.
+This should include correct testing of \-0.0. This will only be set
+if the \f(CWsignbit()\fR routine is safe to use with the NV type used internally
+in perl. Users should call \f(CWPerl_signbit()\fR, which will be #defined to
+the system's \f(CWsignbit()\fR function or macro if this symbol is defined.
+.ie n .IP """HAS_SQRTL""" 4
+.el .IP \f(CWHAS_SQRTL\fR 4
+.IX Xref "HAS_SQRTL"
+.IX Item "HAS_SQRTL"
+This symbol, if defined, indicates that the \f(CW\*(C`sqrtl\*(C'\fR routine is
+available to do long double square roots.
+.ie n .IP """HAS_STRTOD_L""" 4
+.el .IP \f(CWHAS_STRTOD_L\fR 4
+.IX Xref "HAS_STRTOD_L"
+.IX Item "HAS_STRTOD_L"
+This symbol, if defined, indicates that the \f(CW\*(C`strtod_l\*(C'\fR routine is
+available to convert strings to long doubles.
+.ie n .IP """HAS_STRTOLD""" 4
+.el .IP \f(CWHAS_STRTOLD\fR 4
+.IX Xref "HAS_STRTOLD"
+.IX Item "HAS_STRTOLD"
+This symbol, if defined, indicates that the \f(CW\*(C`strtold\*(C'\fR routine is
+available to convert strings to long doubles.
+.ie n .IP """HAS_STRTOLD_L""" 4
+.el .IP \f(CWHAS_STRTOLD_L\fR 4
+.IX Xref "HAS_STRTOLD_L"
+.IX Item "HAS_STRTOLD_L"
+This symbol, if defined, indicates that the \f(CW\*(C`strtold_l\*(C'\fR routine is
+available to convert strings to long doubles.
+.ie n .IP """HAS_TRUNC""" 4
+.el .IP \f(CWHAS_TRUNC\fR 4
+.IX Xref "HAS_TRUNC"
+.IX Item "HAS_TRUNC"
+This symbol, if defined, indicates that the \f(CW\*(C`trunc\*(C'\fR routine is
+available to round doubles towards zero.
+.ie n .IP """HAS_UNORDERED""" 4
+.el .IP \f(CWHAS_UNORDERED\fR 4
+.IX Xref "HAS_UNORDERED"
+.IX Item "HAS_UNORDERED"
+This symbol, if defined, indicates that the \f(CW\*(C`unordered\*(C'\fR routine is
+available to check whether two doubles are \f(CW\*(C`unordered\*(C'\fR
+(effectively: whether either of them is NaN)
+.ie n .IP """I_FENV""" 4
+.el .IP \f(CWI_FENV\fR 4
+.IX Xref "I_FENV"
+.IX Item "I_FENV"
+This symbol, if defined, indicates to the C program that it should
+include \fIfenv.h\fR to get the floating point environment definitions.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_FENV
+\& #include <fenv.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_QUADMATH""" 4
+.el .IP \f(CWI_QUADMATH\fR 4
+.IX Xref "I_QUADMATH"
+.IX Item "I_QUADMATH"
+This symbol, if defined, indicates that \fIquadmath.h\fR exists and
+should be included.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_QUADMATH
+\& #include <quadmath.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LONGDBLINFBYTES""" 4
+.el .IP \f(CWLONGDBLINFBYTES\fR 4
+.IX Xref "LONGDBLINFBYTES"
+.IX Item "LONGDBLINFBYTES"
+This symbol, if defined, is a comma-separated list of
+hexadecimal bytes for the long double precision infinity.
+.ie n .IP """LONGDBLMANTBITS""" 4
+.el .IP \f(CWLONGDBLMANTBITS\fR 4
+.IX Xref "LONGDBLMANTBITS"
+.IX Item "LONGDBLMANTBITS"
+This symbol, if defined, tells how many mantissa bits
+there are in long double precision floating point format.
+Note that this can be \f(CW\*(C`LDBL_MANT_DIG\*(C'\fR minus one,
+since \f(CW\*(C`LDBL_MANT_DIG\*(C'\fR can include the \f(CW\*(C`IEEE\*(C'\fR 754 implicit bit.
+The common x86\-style 80\-bit long double does not have
+an implicit bit.
+.ie n .IP """LONGDBLNANBYTES""" 4
+.el .IP \f(CWLONGDBLNANBYTES\fR 4
+.IX Xref "LONGDBLNANBYTES"
+.IX Item "LONGDBLNANBYTES"
+This symbol, if defined, is a comma-separated list of
+hexadecimal bytes (0xHH) for the long double precision not-a-number.
+.ie n .IP """LONG_DOUBLEKIND""" 4
+.el .IP \f(CWLONG_DOUBLEKIND\fR 4
+.IX Xref "LONG_DOUBLEKIND"
+.IX Item "LONG_DOUBLEKIND"
+\&\f(CW\*(C`LONG_DOUBLEKIND\*(C'\fR will be one of
+\&\f(CW\*(C`LONG_DOUBLE_IS_DOUBLE\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_VAX_H_FLOAT\*(C'\fR
+\&\f(CW\*(C`LONG_DOUBLE_IS_UNKNOWN_FORMAT\*(C'\fR
+It is only defined if the system supports long doubles.
+.ie n .IP """LONG_DOUBLESIZE""" 4
+.el .IP \f(CWLONG_DOUBLESIZE\fR 4
+.IX Xref "LONG_DOUBLESIZE"
+.IX Item "LONG_DOUBLESIZE"
+This symbol contains the size of a long double, so that the
+C preprocessor can make decisions based on it. It is only
+defined if the system supports long doubles. Note that this
+is \f(CW\*(C`sizeof(long double)\*(C'\fR, which may include unused bytes.
+.ie n .IP """LONG_DOUBLE_STYLE_IEEE""" 4
+.el .IP \f(CWLONG_DOUBLE_STYLE_IEEE\fR 4
+.IX Xref "LONG_DOUBLE_STYLE_IEEE"
+.IX Item "LONG_DOUBLE_STYLE_IEEE"
+This symbol, if defined, indicates that the long double
+is any of the \f(CW\*(C`IEEE\*(C'\fR 754 style long doubles:
+\&\f(CW\*(C`LONG_DOUBLE_STYLE_IEEE_STD\*(C'\fR, \f(CW\*(C`LONG_DOUBLE_STYLE_IEEE_EXTENDED\*(C'\fR,
+\&\f(CW\*(C`LONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE\*(C'\fR.
+.ie n .IP """LONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE""" 4
+.el .IP \f(CWLONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE\fR 4
+.IX Xref "LONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE"
+.IX Item "LONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE"
+This symbol, if defined, indicates that the long double is
+the 128\-bit double-double.
+.ie n .IP """LONG_DOUBLE_STYLE_IEEE_EXTENDED""" 4
+.el .IP \f(CWLONG_DOUBLE_STYLE_IEEE_EXTENDED\fR 4
+.IX Xref "LONG_DOUBLE_STYLE_IEEE_EXTENDED"
+.IX Item "LONG_DOUBLE_STYLE_IEEE_EXTENDED"
+This symbol, if defined, indicates that the long double is
+the 80\-bit \f(CW\*(C`IEEE\*(C'\fR 754. Note that despite the 'extended' this
+is less than the 'std', since this is an extension of
+the double precision.
+.ie n .IP """LONG_DOUBLE_STYLE_IEEE_STD""" 4
+.el .IP \f(CWLONG_DOUBLE_STYLE_IEEE_STD\fR 4
+.IX Xref "LONG_DOUBLE_STYLE_IEEE_STD"
+.IX Item "LONG_DOUBLE_STYLE_IEEE_STD"
+This symbol, if defined, indicates that the long double is
+the 128\-bit \f(CW\*(C`IEEE\*(C'\fR 754.
+.ie n .IP """LONG_DOUBLE_STYLE_VAX""" 4
+.el .IP \f(CWLONG_DOUBLE_STYLE_VAX\fR 4
+.IX Xref "LONG_DOUBLE_STYLE_VAX"
+.IX Item "LONG_DOUBLE_STYLE_VAX"
+This symbol, if defined, indicates that the long double is
+the 128\-bit \f(CW\*(C`VAX\*(C'\fR format H.
+.ie n .IP """NV""" 4
+.el .IP \f(CWNV\fR 4
+.IX Item "NV"
+Described in perlguts.
+.ie n .IP """NVMANTBITS""" 4
+.el .IP \f(CWNVMANTBITS\fR 4
+.IX Xref "NVMANTBITS"
+.IX Item "NVMANTBITS"
+This symbol, if defined, tells how many mantissa bits
+(not including implicit bit) there are in a Perl NV.
+This depends on which floating point type was chosen.
+.ie n .IP """NV_OVERFLOWS_INTEGERS_AT""" 4
+.el .IP \f(CWNV_OVERFLOWS_INTEGERS_AT\fR 4
+.IX Xref "NV_OVERFLOWS_INTEGERS_AT"
+.IX Item "NV_OVERFLOWS_INTEGERS_AT"
+This symbol gives the largest integer value that NVs can hold. This
+value + 1.0 cannot be stored accurately. It is expressed as constant
+floating point expression to reduce the chance of decimal/binary
+conversion issues. If it can not be determined, the value 0 is given.
+.ie n .IP """NV_PRESERVES_UV""" 4
+.el .IP \f(CWNV_PRESERVES_UV\fR 4
+.IX Xref "NV_PRESERVES_UV"
+.IX Item "NV_PRESERVES_UV"
+This symbol, if defined, indicates that a variable of type \f(CW\*(C`NVTYPE\*(C'\fR
+can preserve all the bits of a variable of type \f(CW\*(C`UVTYPE\*(C'\fR.
+.ie n .IP """NV_PRESERVES_UV_BITS""" 4
+.el .IP \f(CWNV_PRESERVES_UV_BITS\fR 4
+.IX Xref "NV_PRESERVES_UV_BITS"
+.IX Item "NV_PRESERVES_UV_BITS"
+This symbol contains the number of bits a variable of type \f(CW\*(C`NVTYPE\*(C'\fR
+can preserve of a variable of type \f(CW\*(C`UVTYPE\*(C'\fR.
+.ie n .IP """NVSIZE""" 4
+.el .IP \f(CWNVSIZE\fR 4
+.IX Xref "NVSIZE"
+.IX Item "NVSIZE"
+This symbol contains the \f(CWsizeof(NV)\fR.
+Note that some floating point formats have unused bytes.
+The most notable example is the x86* 80\-bit extended precision
+which comes in byte sizes of 12 and 16 (for 32 and 64 bit
+platforms, respectively), but which only uses 10 bytes.
+Perl compiled with \f(CW\*(C`\-Duselongdouble\*(C'\fR on x86* is like this.
+.ie n .IP """NVTYPE""" 4
+.el .IP \f(CWNVTYPE\fR 4
+.IX Xref "NVTYPE"
+.IX Item "NVTYPE"
+This symbol defines the C type used for Perl's NV.
+.ie n .IP """NV_ZERO_IS_ALLBITS_ZERO""" 4
+.el .IP \f(CWNV_ZERO_IS_ALLBITS_ZERO\fR 4
+.IX Xref "NV_ZERO_IS_ALLBITS_ZERO"
+.IX Item "NV_ZERO_IS_ALLBITS_ZERO"
+This symbol, if defined, indicates that a variable of type \f(CW\*(C`NVTYPE\*(C'\fR
+stores 0.0 in memory as all bits zero.
+.SH "General Configuration"
+.IX Xref "PERL_GCC_BRACE_GROUPS_FORBIDDEN"
+.IX Header "General Configuration"
+This section contains configuration information not otherwise
+found in the more specialized sections of this document. At the
+end is a list of \f(CW\*(C`#defines\*(C'\fR whose name should be enough to tell
+you what they do, and a list of #defines which tell you if you
+need to \f(CW\*(C`#include\*(C'\fR files to get the corresponding functionality.
+.ie n .IP """ASCIIish""" 4
+.el .IP \f(CWASCIIish\fR 4
+.IX Xref "ASCIIish"
+.IX Item "ASCIIish"
+A preprocessor symbol that is defined iff the system is an ASCII platform; this
+symbol would not be defined on \f(CW"EBCDIC"\fR platforms.
+.RS 4
+.Sp
+.Vb 1
+\& #ifdef ASCIIish
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """BYTEORDER""" 4
+.el .IP \f(CWBYTEORDER\fR 4
+.IX Xref "BYTEORDER"
+.IX Item "BYTEORDER"
+This symbol holds the hexadecimal constant defined in byteorder,
+in a UV, i.e. 0x1234 or 0x4321 or 0x12345678, etc...
+If the compiler supports cross-compiling or multiple-architecture
+binaries, use compiler-defined macros to
+determine the byte order.
+.ie n .IP """CHARBITS""" 4
+.el .IP \f(CWCHARBITS\fR 4
+.IX Xref "CHARBITS"
+.IX Item "CHARBITS"
+This symbol contains the size of a char, so that the C preprocessor
+can make decisions based on it.
+.ie n .IP """DB_VERSION_MAJOR_CFG""" 4
+.el .IP \f(CWDB_VERSION_MAJOR_CFG\fR 4
+.IX Xref "DB_VERSION_MAJOR_CFG"
+.IX Item "DB_VERSION_MAJOR_CFG"
+This symbol, if defined, defines the major version number of
+Berkeley DB found in the \fIdb.h\fR header when Perl was configured.
+.ie n .IP """DB_VERSION_MINOR_CFG""" 4
+.el .IP \f(CWDB_VERSION_MINOR_CFG\fR 4
+.IX Xref "DB_VERSION_MINOR_CFG"
+.IX Item "DB_VERSION_MINOR_CFG"
+This symbol, if defined, defines the minor version number of
+Berkeley DB found in the \fIdb.h\fR header when Perl was configured.
+For DB version 1 this is always 0.
+.ie n .IP """DB_VERSION_PATCH_CFG""" 4
+.el .IP \f(CWDB_VERSION_PATCH_CFG\fR 4
+.IX Xref "DB_VERSION_PATCH_CFG"
+.IX Item "DB_VERSION_PATCH_CFG"
+This symbol, if defined, defines the patch version number of
+Berkeley DB found in the \fIdb.h\fR header when Perl was configured.
+For DB version 1 this is always 0.
+.ie n .IP """DEFAULT_INC_EXCLUDES_DOT""" 4
+.el .IP \f(CWDEFAULT_INC_EXCLUDES_DOT\fR 4
+.IX Xref "DEFAULT_INC_EXCLUDES_DOT"
+.IX Item "DEFAULT_INC_EXCLUDES_DOT"
+This symbol, if defined, removes the legacy default behavior of
+including '.' at the end of @\f(CW\*(C`INC\*(C'\fR.
+.ie n .IP """DLSYM_NEEDS_UNDERSCORE""" 4
+.el .IP \f(CWDLSYM_NEEDS_UNDERSCORE\fR 4
+.IX Xref "DLSYM_NEEDS_UNDERSCORE"
+.IX Item "DLSYM_NEEDS_UNDERSCORE"
+This symbol, if defined, indicates that we need to prepend an
+underscore to the symbol name before calling \f(CWdlsym()\fR. This only
+makes sense if you *have* dlsym, which we will presume is the
+case if you're using \fIdl_dlopen.xs\fR.
+.ie n .IP """EBCDIC""" 4
+.el .IP \f(CWEBCDIC\fR 4
+.IX Xref "EBCDIC"
+.IX Item "EBCDIC"
+This symbol, if defined, indicates that this system uses
+\&\f(CW\*(C`EBCDIC\*(C'\fR encoding.
+.ie n .IP """HAS_CSH""" 4
+.el .IP \f(CWHAS_CSH\fR 4
+.IX Xref "HAS_CSH"
+.IX Item "HAS_CSH"
+This symbol, if defined, indicates that the C\-shell exists.
+.ie n .IP """HAS_GETHOSTNAME""" 4
+.el .IP \f(CWHAS_GETHOSTNAME\fR 4
+.IX Xref "HAS_GETHOSTNAME"
+.IX Item "HAS_GETHOSTNAME"
+This symbol, if defined, indicates that the C program may use the
+\&\f(CWgethostname()\fR routine to derive the host name. See also \f(CW"HAS_UNAME"\fR
+and \f(CW"PHOSTNAME"\fR.
+.ie n .IP """HAS_GNULIBC""" 4
+.el .IP \f(CWHAS_GNULIBC\fR 4
+.IX Xref "HAS_GNULIBC"
+.IX Item "HAS_GNULIBC"
+This symbol, if defined, indicates to the C program that
+the \f(CW\*(C`GNU\*(C'\fR C library is being used. A better check is to use
+the \f(CW\*(C`_\|_GLIBC_\|_\*(C'\fR and \f(CW\*(C`_\|_GLIBC_MINOR_\|_\*(C'\fR symbols supplied with glibc.
+.ie n .IP """HAS_LGAMMA""" 4
+.el .IP \f(CWHAS_LGAMMA\fR 4
+.IX Xref "HAS_LGAMMA"
+.IX Item "HAS_LGAMMA"
+This symbol, if defined, indicates that the \f(CW\*(C`lgamma\*(C'\fR routine is
+available to do the log gamma function. See also \f(CW"HAS_TGAMMA"\fR and
+\&\f(CW"HAS_LGAMMA_R"\fR.
+.ie n .IP """HAS_LGAMMA_R""" 4
+.el .IP \f(CWHAS_LGAMMA_R\fR 4
+.IX Xref "HAS_LGAMMA_R"
+.IX Item "HAS_LGAMMA_R"
+This symbol, if defined, indicates that the \f(CW\*(C`lgamma_r\*(C'\fR routine is
+available to do the log gamma function without using the global
+signgam variable.
+.ie n .IP """HAS_NON_INT_BITFIELDS""" 4
+.el .IP \f(CWHAS_NON_INT_BITFIELDS\fR 4
+.IX Xref "HAS_NON_INT_BITFIELDS"
+.IX Item "HAS_NON_INT_BITFIELDS"
+This symbol, if defined, indicates that the C compiler accepts, without
+error or warning, \f(CW\*(C`struct bitfields\*(C'\fR that are declared with sizes other
+than plain 'int'; for example 'unsigned char' is accepted.
+.ie n .IP """HAS_PRCTL_SET_NAME""" 4
+.el .IP \f(CWHAS_PRCTL_SET_NAME\fR 4
+.IX Xref "HAS_PRCTL_SET_NAME"
+.IX Item "HAS_PRCTL_SET_NAME"
+This symbol, if defined, indicates that the prctl routine is
+available to set process title and supports \f(CW\*(C`PR_SET_NAME\*(C'\fR.
+.ie n .IP """HAS_PROCSELFEXE""" 4
+.el .IP \f(CWHAS_PROCSELFEXE\fR 4
+.IX Xref "HAS_PROCSELFEXE"
+.IX Item "HAS_PROCSELFEXE"
+This symbol is defined if \f(CW\*(C`PROCSELFEXE_PATH\*(C'\fR is a symlink
+to the absolute pathname of the executing program.
+.ie n .IP """HAS_PSEUDOFORK""" 4
+.el .IP \f(CWHAS_PSEUDOFORK\fR 4
+.IX Xref "HAS_PSEUDOFORK"
+.IX Item "HAS_PSEUDOFORK"
+This symbol, if defined, indicates that an emulation of the
+fork routine is available.
+.ie n .IP """HAS_REGCOMP""" 4
+.el .IP \f(CWHAS_REGCOMP\fR 4
+.IX Xref "HAS_REGCOMP"
+.IX Item "HAS_REGCOMP"
+This symbol, if defined, indicates that the \f(CWregcomp()\fR routine is
+available to do some regular pattern matching (usually on \f(CW\*(C`POSIX\*(C'\fR.2
+conforming systems).
+.ie n .IP """HAS_SETPGID""" 4
+.el .IP \f(CWHAS_SETPGID\fR 4
+.IX Xref "HAS_SETPGID"
+.IX Item "HAS_SETPGID"
+This symbol, if defined, indicates that the \f(CW\*(C`setpgid(pid, gpid)\*(C'\fR
+routine is available to set process group ID.
+.ie n .IP """HAS_SIGSETJMP""" 4
+.el .IP \f(CWHAS_SIGSETJMP\fR 4
+.IX Xref "HAS_SIGSETJMP"
+.IX Item "HAS_SIGSETJMP"
+This variable indicates to the C program that the \f(CWsigsetjmp()\fR
+routine is available to save the calling process's registers
+and stack environment for later use by \f(CWsiglongjmp()\fR, and
+to optionally save the process's signal mask. See
+\&\f(CW"Sigjmp_buf"\fR, \f(CW"Sigsetjmp"\fR, and \f(CW"Siglongjmp"\fR.
+.ie n .IP """HAS_STRUCT_CMSGHDR""" 4
+.el .IP \f(CWHAS_STRUCT_CMSGHDR\fR 4
+.IX Xref "HAS_STRUCT_CMSGHDR"
+.IX Item "HAS_STRUCT_CMSGHDR"
+This symbol, if defined, indicates that the \f(CW\*(C`struct cmsghdr\*(C'\fR
+is supported.
+.ie n .IP """HAS_STRUCT_MSGHDR""" 4
+.el .IP \f(CWHAS_STRUCT_MSGHDR\fR 4
+.IX Xref "HAS_STRUCT_MSGHDR"
+.IX Item "HAS_STRUCT_MSGHDR"
+This symbol, if defined, indicates that the \f(CW\*(C`struct msghdr\*(C'\fR
+is supported.
+.ie n .IP """HAS_TGAMMA""" 4
+.el .IP \f(CWHAS_TGAMMA\fR 4
+.IX Xref "HAS_TGAMMA"
+.IX Item "HAS_TGAMMA"
+This symbol, if defined, indicates that the \f(CW\*(C`tgamma\*(C'\fR routine is
+available to do the gamma function. See also \f(CW"HAS_LGAMMA"\fR.
+.ie n .IP """HAS_UNAME""" 4
+.el .IP \f(CWHAS_UNAME\fR 4
+.IX Xref "HAS_UNAME"
+.IX Item "HAS_UNAME"
+This symbol, if defined, indicates that the C program may use the
+\&\f(CWuname()\fR routine to derive the host name. See also \f(CW"HAS_GETHOSTNAME"\fR
+and \f(CW"PHOSTNAME"\fR.
+.ie n .IP """HAS_UNION_SEMUN""" 4
+.el .IP \f(CWHAS_UNION_SEMUN\fR 4
+.IX Xref "HAS_UNION_SEMUN"
+.IX Item "HAS_UNION_SEMUN"
+This symbol, if defined, indicates that the \f(CW\*(C`union semun\*(C'\fR is
+defined by including \fIsys/sem.h\fR. If not, the user code
+probably needs to define it as:
+.Sp
+.Vb 5
+\& union semun {
+\& int val;
+\& struct semid_ds *buf;
+\& unsigned short *array;
+\& }
+.Ve
+.ie n .IP """I_DIRENT""" 4
+.el .IP \f(CWI_DIRENT\fR 4
+.IX Xref "I_DIRENT"
+.IX Item "I_DIRENT"
+This symbol, if defined, indicates to the C program that it should
+include \fIdirent.h\fR. Using this symbol also triggers the definition
+of the \f(CW\*(C`Direntry_t\*(C'\fR define which ends up being '\f(CW\*(C`struct dirent\*(C'\fR' or
+\&'\f(CW\*(C`struct direct\*(C'\fR' depending on the availability of \fIdirent.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_DIRENT
+\& #include <dirent.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_POLL""" 4
+.el .IP \f(CWI_POLL\fR 4
+.IX Xref "I_POLL"
+.IX Item "I_POLL"
+This symbol, if defined, indicates that \fIpoll.h\fR exists and
+should be included. (see also \f(CW"HAS_POLL"\fR)
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_POLL
+\& #include <poll.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_SYS_RESOURCE""" 4
+.el .IP \f(CWI_SYS_RESOURCE\fR 4
+.IX Xref "I_SYS_RESOURCE"
+.IX Item "I_SYS_RESOURCE"
+This symbol, if defined, indicates to the C program that it should
+include \fIsys/resource.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_SYS_RESOURCE
+\& #include <sys_resource.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LIBM_LIB_VERSION""" 4
+.el .IP \f(CWLIBM_LIB_VERSION\fR 4
+.IX Xref "LIBM_LIB_VERSION"
+.IX Item "LIBM_LIB_VERSION"
+This symbol, if defined, indicates that libm exports \f(CW\*(C`_LIB_VERSION\*(C'\fR
+and that \fImath.h\fR defines the enum to manipulate it.
+.ie n .IP """NEED_VA_COPY""" 4
+.el .IP \f(CWNEED_VA_COPY\fR 4
+.IX Item "NEED_VA_COPY"
+This symbol, if defined, indicates that the system stores
+the variable argument list datatype, \f(CW\*(C`va_list\*(C'\fR, in a format
+that cannot be copied by simple assignment, so that some
+other means must be used when copying is required.
+As such systems vary in their provision (or non-provision)
+of copying mechanisms, \fIhandy.h\fR defines a platform\-
+independent macro, \f(CW\*(C`Perl_va_copy(src, dst)\*(C'\fR, to do the job.
+.ie n .IP """OSNAME""" 4
+.el .IP \f(CWOSNAME\fR 4
+.IX Xref "OSNAME"
+.IX Item "OSNAME"
+This symbol contains the name of the operating system, as determined
+by Configure. You shouldn't rely on it too much; the specific
+feature tests from Configure are generally more reliable.
+.ie n .IP """OSVERS""" 4
+.el .IP \f(CWOSVERS\fR 4
+.IX Xref "OSVERS"
+.IX Item "OSVERS"
+This symbol contains the version of the operating system, as determined
+by Configure. You shouldn't rely on it too much; the specific
+feature tests from Configure are generally more reliable.
+.ie n .IP """PERL_USE_GCC_BRACE_GROUPS""" 4
+.el .IP \f(CWPERL_USE_GCC_BRACE_GROUPS\fR 4
+.IX Xref "PERL_USE_GCC_BRACE_GROUPS"
+.IX Item "PERL_USE_GCC_BRACE_GROUPS"
+This C pre-processor value, if defined, indicates that it is permissible to use
+the GCC brace groups extension. However, use of this extension is DISCOURAGED.
+Use a \f(CW\*(C`static inline\*(C'\fR function instead.
+.Sp
+The extension, of the form
+.Sp
+.Vb 1
+\& ({ statement ... })
+.Ve
+.Sp
+turns the block consisting of \fIstatement ...\fR into an expression with a
+value, unlike plain C language blocks. This can present optimization
+possibilities, \fBBUT\fR, unless you know for sure that this will never be
+compiled without this extension being available and not forbidden, you need to
+specify an alternative. Thus two code paths have to be maintained, which can
+get out-of-sync. All these issues are solved by using a \f(CW\*(C`static inline\*(C'\fR
+function instead.
+.Sp
+Perl can be configured to not use this feature by passing the parameter
+\&\f(CW\*(C`\-Accflags=\-DPERL_GCC_BRACE_GROUPS_FORBIDDEN\*(C'\fR to \fIConfigure\fR.
+.RS 4
+.Sp
+.Vb 1
+\& #ifdef PERL_USE_GCC_BRACE_GROUPS
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PHOSTNAME""" 4
+.el .IP \f(CWPHOSTNAME\fR 4
+.IX Xref "PHOSTNAME"
+.IX Item "PHOSTNAME"
+This symbol, if defined, indicates the command to feed to the
+\&\f(CWpopen()\fR routine to derive the host name. See also \f(CW"HAS_GETHOSTNAME"\fR
+and \f(CW"HAS_UNAME"\fR. Note that the command uses a fully qualified path,
+so that it is safe even if used by a process with super-user
+privileges.
+.ie n .IP """PROCSELFEXE_PATH""" 4
+.el .IP \f(CWPROCSELFEXE_PATH\fR 4
+.IX Xref "PROCSELFEXE_PATH"
+.IX Item "PROCSELFEXE_PATH"
+If \f(CW\*(C`HAS_PROCSELFEXE\*(C'\fR is defined this symbol is the filename
+of the symbolic link pointing to the absolute pathname of
+the executing program.
+.ie n .IP """PTRSIZE""" 4
+.el .IP \f(CWPTRSIZE\fR 4
+.IX Xref "PTRSIZE"
+.IX Item "PTRSIZE"
+This symbol contains the size of a pointer, so that the C preprocessor
+can make decisions based on it. It will be \f(CW\*(C`sizeof(void *)\*(C'\fR if
+the compiler supports (void *); otherwise it will be
+\&\f(CW\*(C`sizeof(char *)\*(C'\fR.
+.ie n .IP """RANDBITS""" 4
+.el .IP \f(CWRANDBITS\fR 4
+.IX Xref "RANDBITS"
+.IX Item "RANDBITS"
+This symbol indicates how many bits are produced by the
+function used to generate normalized random numbers.
+Values include 15, 16, 31, and 48.
+.ie n .IP """SELECT_MIN_BITS""" 4
+.el .IP \f(CWSELECT_MIN_BITS\fR 4
+.IX Xref "SELECT_MIN_BITS"
+.IX Item "SELECT_MIN_BITS"
+This symbol holds the minimum number of bits operated by select.
+That is, if you do \f(CW\*(C`select(n, ...)\*(C'\fR, how many bits at least will be
+cleared in the masks if some activity is detected. Usually this
+is either n or 32*\f(CWceil(n/32)\fR, especially many little-endians do
+the latter. This is only useful if you have \f(CWselect()\fR, naturally.
+.ie n .IP """SETUID_SCRIPTS_ARE_SECURE_NOW""" 4
+.el .IP \f(CWSETUID_SCRIPTS_ARE_SECURE_NOW\fR 4
+.IX Xref "SETUID_SCRIPTS_ARE_SECURE_NOW"
+.IX Item "SETUID_SCRIPTS_ARE_SECURE_NOW"
+This symbol, if defined, indicates that the bug that prevents
+setuid scripts from being secure is not present in this kernel.
+.ie n .IP """ST_DEV_SIGN""" 4
+.el .IP \f(CWST_DEV_SIGN\fR 4
+.IX Xref "ST_DEV_SIGN"
+.IX Item "ST_DEV_SIGN"
+This symbol holds the signedness of \f(CW\*(C`struct stat\*(C'\fR's \f(CW\*(C`st_dev\*(C'\fR.
+1 for unsigned, \-1 for signed.
+.ie n .IP """ST_DEV_SIZE""" 4
+.el .IP \f(CWST_DEV_SIZE\fR 4
+.IX Xref "ST_DEV_SIZE"
+.IX Item "ST_DEV_SIZE"
+This variable contains the size of \f(CW\*(C`struct stat\*(C'\fR's \f(CW\*(C`st_dev\*(C'\fR in bytes.
+.ie n .SS "List of capability ""HAS_\fIfoo\fP"" symbols"
+.el .SS "List of capability \f(CWHAS_\fP\f(CIfoo\fP\f(CW\fP symbols"
+.IX Subsection "List of capability HAS_foo symbols"
+This is a list of those symbols that dont appear elsewhere in ths
+document that indicate if the current platform has a certain
+capability. Their names all begin with \f(CW\*(C`HAS_\*(C'\fR. Only those
+symbols whose capability is directly derived from the name are
+listed here. All others have their meaning expanded out elsewhere
+in this document. This (relatively) compact list is because we
+think that the expansion would add little or no value and take up
+a lot of space (because there are so many). If you think certain
+ones should be expanded, send email to
+perl5\-porters@perl.org <mailto:perl5-porters@perl.org>.
+.PP
+Each symbol here will be \f(CW\*(C`#define\*(C'\fRd if and only if the platform
+has the capability. If you need more detail, see the
+corresponding entry in \fIconfig.h\fR. For convenience, the list is
+split so that the ones that indicate there is a reentrant version
+of a capability are listed separately
+.PP
+\&\f(CW\*(C`HAS_ACCEPT4\*(C'\fR,\ \f(CW\*(C`HAS_ACCESS\*(C'\fR,\ \f(CW\*(C`HAS_ACCESSX\*(C'\fR,\ \f(CW\*(C`HAS_ACOSH\*(C'\fR,\ \f(CW\*(C`HAS_AINTL\*(C'\fR,\ \f(CW\*(C`HAS_ALARM\*(C'\fR,\ \f(CW\*(C`HAS_ASINH\*(C'\fR,\ \f(CW\*(C`HAS_ATANH\*(C'\fR,\ \f(CW\*(C`HAS_ATOLL\*(C'\fR,\ \f(CW\*(C`HAS_CBRT\*(C'\fR,\ \f(CW\*(C`HAS_CHOWN\*(C'\fR,\ \f(CW\*(C`HAS_CHROOT\*(C'\fR,\ \f(CW\*(C`HAS_CHSIZE\*(C'\fR,\ \f(CW\*(C`HAS_CLEARENV\*(C'\fR,\ \f(CW\*(C`HAS_COPYSIGN\*(C'\fR,\ \f(CW\*(C`HAS_COPYSIGNL\*(C'\fR,\ \f(CW\*(C`HAS_CRYPT\*(C'\fR,\ \f(CW\*(C`HAS_CTERMID\*(C'\fR,\ \f(CW\*(C`HAS_CUSERID\*(C'\fR,\ \f(CW\*(C`HAS_DIRFD\*(C'\fR,\ \f(CW\*(C`HAS_DLADDR\*(C'\fR,\ \f(CW\*(C`HAS_DLERROR\*(C'\fR,\ \f(CW\*(C`HAS_EACCESS\*(C'\fR,\ \f(CW\*(C`HAS_ENDHOSTENT\*(C'\fR,\ \f(CW\*(C`HAS_ENDNETENT\*(C'\fR,\ \f(CW\*(C`HAS_ENDPROTOENT\*(C'\fR,\ \f(CW\*(C`HAS_ENDSERVENT\*(C'\fR,\ \f(CW\*(C`HAS_ERF\*(C'\fR,\ \f(CW\*(C`HAS_ERFC\*(C'\fR,\ \f(CW\*(C`HAS_EXPM1\*(C'\fR,\ \f(CW\*(C`HAS_EXP2\*(C'\fR,\ \f(CW\*(C`HAS_FCHMOD\*(C'\fR,\ \f(CW\*(C`HAS_FCHMODAT\*(C'\fR,\ \f(CW\*(C`HAS_FCHOWN\*(C'\fR,\ \f(CW\*(C`HAS_FDIM\*(C'\fR,\ \f(CW\*(C`HAS_FD_SET\*(C'\fR,\ \f(CW\*(C`HAS_FEGETROUND\*(C'\fR,\ \f(CW\*(C`HAS_FFS\*(C'\fR,\ \f(CW\*(C`HAS_FFSL\*(C'\fR,\ \f(CW\*(C`HAS_FGETPOS\*(C'\fR,\ \f(CW\*(C`HAS_FLOCK\*(C'\fR,\ \f(CW\*(C`HAS_FMA\*(C'\fR,\ \f(CW\*(C`HAS_FMAX\*(C'\fR,\ \f(CW\*(C`HAS_FMIN\*(C'\fR,\ \f(CW\*(C`HAS_FORK\*(C'\fR,\ \f(CW\*(C`HAS_FSEEKO\*(C'\fR,\ \f(CW\*(C`HAS_FSETPOS\*(C'\fR,\ \f(CW\*(C`HAS_FSYNC\*(C'\fR,\ \f(CW\*(C`HAS_FTELLO\*(C'\fR,\ \f(CW\*(C`HAS_\|_FWALK\*(C'\fR,\ \f(CW\*(C`HAS_GAI_STRERROR\*(C'\fR,\ \f(CW\*(C`HAS_GETADDRINFO\*(C'\fR,\ \f(CW\*(C`HAS_GETCWD\*(C'\fR,\ \f(CW\*(C`HAS_GETESPWNAM\*(C'\fR,\ \f(CW\*(C`HAS_GETGROUPS\*(C'\fR,\ \f(CW\*(C`HAS_GETHOSTBYADDR\*(C'\fR,\ \f(CW\*(C`HAS_GETHOSTBYNAME\*(C'\fR,\ \f(CW\*(C`HAS_GETHOSTENT\*(C'\fR,\ \f(CW\*(C`HAS_GETLOGIN\*(C'\fR,\ \f(CW\*(C`HAS_GETNAMEINFO\*(C'\fR,\ \f(CW\*(C`HAS_GETNETBYADDR\*(C'\fR,\ \f(CW\*(C`HAS_GETNETBYNAME\*(C'\fR,\ \f(CW\*(C`HAS_GETNETENT\*(C'\fR,\ \f(CW\*(C`HAS_GETPAGESIZE\*(C'\fR,\ \f(CW\*(C`HAS_GETPGID\*(C'\fR,\ \f(CW\*(C`HAS_GETPGRP\*(C'\fR,\ \f(CW\*(C`HAS_GETPGRP2\*(C'\fR,\ \f(CW\*(C`HAS_GETPPID\*(C'\fR,\ \f(CW\*(C`HAS_GETPRIORITY\*(C'\fR,\ \f(CW\*(C`HAS_GETPROTOBYNAME\*(C'\fR,\ \f(CW\*(C`HAS_GETPROTOBYNUMBER\*(C'\fR,\ \f(CW\*(C`HAS_GETPROTOENT\*(C'\fR,\ \f(CW\*(C`HAS_GETPRPWNAM\*(C'\fR,\ \f(CW\*(C`HAS_GETSERVBYNAME\*(C'\fR,\ \f(CW\*(C`HAS_GETSERVBYPORT\*(C'\fR,\ \f(CW\*(C`HAS_GETSERVENT\*(C'\fR,\ \f(CW\*(C`HAS_GETSPNAM\*(C'\fR,\ \f(CW\*(C`HAS_HTONL\*(C'\fR,\ \f(CW\*(C`HAS_HTONS\*(C'\fR,\ \f(CW\*(C`HAS_HYPOT\*(C'\fR,\ \f(CW\*(C`HAS_ILOGBL\*(C'\fR,\ \f(CW\*(C`HAS_INET_ATON\*(C'\fR,\ \f(CW\*(C`HAS_INETNTOP\*(C'\fR,\ \f(CW\*(C`HAS_INETPTON\*(C'\fR,\ \f(CW\*(C`HAS_IP_MREQ\*(C'\fR,\ \f(CW\*(C`HAS_IP_MREQ_SOURCE\*(C'\fR,\ \f(CW\*(C`HAS_IPV6_MREQ\*(C'\fR,\ \f(CW\*(C`HAS_IPV6_MREQ_SOURCE\*(C'\fR,\ \f(CW\*(C`HAS_ISASCII\*(C'\fR,\ \f(CW\*(C`HAS_ISBLANK\*(C'\fR,\ \f(CW\*(C`HAS_ISLESS\*(C'\fR,\ \f(CW\*(C`HAS_KILLPG\*(C'\fR,\ \f(CW\*(C`HAS_LCHOWN\*(C'\fR,\ \f(CW\*(C`HAS_LINK\*(C'\fR,\ \f(CW\*(C`HAS_LINKAT\*(C'\fR,\ \f(CW\*(C`HAS_LLROUND\*(C'\fR,\ \f(CW\*(C`HAS_LOCKF\*(C'\fR,\ \f(CW\*(C`HAS_LOGB\*(C'\fR,\ \f(CW\*(C`HAS_LOG1P\*(C'\fR,\ \f(CW\*(C`HAS_LOG2\*(C'\fR,\ \f(CW\*(C`HAS_LROUND\*(C'\fR,\ \f(CW\*(C`HAS_LSTAT\*(C'\fR,\ \f(CW\*(C`HAS_MADVISE\*(C'\fR,\ \f(CW\*(C`HAS_MBLEN\*(C'\fR,\ \f(CW\*(C`HAS_MBRLEN\*(C'\fR,\ \f(CW\*(C`HAS_MBRTOWC\*(C'\fR,\ \f(CW\*(C`HAS_MBSTOWCS\*(C'\fR,\ \f(CW\*(C`HAS_MBTOWC\*(C'\fR,\ \f(CW\*(C`HAS_MEMMEM\*(C'\fR,\ \f(CW\*(C`HAS_MEMRCHR\*(C'\fR,\ \f(CW\*(C`HAS_MKDTEMP\*(C'\fR,\ \f(CW\*(C`HAS_MKFIFO\*(C'\fR,\ \f(CW\*(C`HAS_MKOSTEMP\*(C'\fR,\ \f(CW\*(C`HAS_MKSTEMP\*(C'\fR,\ \f(CW\*(C`HAS_MKSTEMPS\*(C'\fR,\ \f(CW\*(C`HAS_MMAP\*(C'\fR,\ \f(CW\*(C`HAS_MPROTECT\*(C'\fR,\ \f(CW\*(C`HAS_MSG\*(C'\fR,\ \f(CW\*(C`HAS_MSYNC\*(C'\fR,\ \f(CW\*(C`HAS_MUNMAP\*(C'\fR,\ \f(CW\*(C`HAS_NEARBYINT\*(C'\fR,\ \f(CW\*(C`HAS_NEXTAFTER\*(C'\fR,\ \f(CW\*(C`HAS_NICE\*(C'\fR,\ \f(CW\*(C`HAS_NTOHL\*(C'\fR,\ \f(CW\*(C`HAS_NTOHS\*(C'\fR,\ \f(CW\*(C`HAS_PATHCONF\*(C'\fR,\ \f(CW\*(C`HAS_PAUSE\*(C'\fR,\ \f(CW\*(C`HAS_PHOSTNAME\*(C'\fR,\ \f(CW\*(C`HAS_PIPE\*(C'\fR,\ \f(CW\*(C`HAS_PIPE2\*(C'\fR,\ \f(CW\*(C`HAS_PRCTL\*(C'\fR,\ \f(CW\*(C`HAS_PTRDIFF_T\*(C'\fR,\ \f(CW\*(C`HAS_READLINK\*(C'\fR,\ \f(CW\*(C`HAS_READV\*(C'\fR,\ \f(CW\*(C`HAS_RECVMSG\*(C'\fR,\ \f(CW\*(C`HAS_REMQUO\*(C'\fR,\ \f(CW\*(C`HAS_RENAME\*(C'\fR,\ \f(CW\*(C`HAS_RENAMEAT\*(C'\fR,\ \f(CW\*(C`HAS_RINT\*(C'\fR,\ \f(CW\*(C`HAS_ROUND\*(C'\fR,\ \f(CW\*(C`HAS_SCALBNL\*(C'\fR,\ \f(CW\*(C`HAS_SEM\*(C'\fR,\ \f(CW\*(C`HAS_SENDMSG\*(C'\fR,\ \f(CW\*(C`HAS_SETEGID\*(C'\fR,\ \f(CW\*(C`HAS_SETENV\*(C'\fR,\ \f(CW\*(C`HAS_SETEUID\*(C'\fR,\ \f(CW\*(C`HAS_SETGROUPS\*(C'\fR,\ \f(CW\*(C`HAS_SETHOSTENT\*(C'\fR,\ \f(CW\*(C`HAS_SETLINEBUF\*(C'\fR,\ \f(CW\*(C`HAS_SETNETENT\*(C'\fR,\ \f(CW\*(C`HAS_SETPGRP\*(C'\fR,\ \f(CW\*(C`HAS_SETPGRP2\*(C'\fR,\ \f(CW\*(C`HAS_SETPRIORITY\*(C'\fR,\ \f(CW\*(C`HAS_SETPROCTITLE\*(C'\fR,\ \f(CW\*(C`HAS_SETPROTOENT\*(C'\fR,\ \f(CW\*(C`HAS_SETREGID\*(C'\fR,\ \f(CW\*(C`HAS_SETRESGID\*(C'\fR,\ \f(CW\*(C`HAS_SETRESUID\*(C'\fR,\ \f(CW\*(C`HAS_SETREUID\*(C'\fR,\ \f(CW\*(C`HAS_SETRGID\*(C'\fR,\ \f(CW\*(C`HAS_SETRUID\*(C'\fR,\ \f(CW\*(C`HAS_SETSERVENT\*(C'\fR,\ \f(CW\*(C`HAS_SETSID\*(C'\fR,\ \f(CW\*(C`HAS_SHM\*(C'\fR,\ \f(CW\*(C`HAS_SIGACTION\*(C'\fR,\ \f(CW\*(C`HAS_SIGPROCMASK\*(C'\fR,\ \f(CW\*(C`HAS_SIN6_SCOPE_ID\*(C'\fR,\ \f(CW\*(C`HAS_SNPRINTF\*(C'\fR,\ \f(CW\*(C`HAS_STAT\*(C'\fR,\ \f(CW\*(C`HAS_STRCOLL\*(C'\fR,\ \f(CW\*(C`HAS_STRERROR_L\*(C'\fR,\ \f(CW\*(C`HAS_STRLCAT\*(C'\fR,\ \f(CW\*(C`HAS_STRLCPY\*(C'\fR,\ \f(CW\*(C`HAS_STRNLEN\*(C'\fR,\ \f(CW\*(C`HAS_STRTOD\*(C'\fR,\ \f(CW\*(C`HAS_STRTOL\*(C'\fR,\ \f(CW\*(C`HAS_STRTOLL\*(C'\fR,\ \f(CW\*(C`HAS_STRTOQ\*(C'\fR,\ \f(CW\*(C`HAS_STRTOUL\*(C'\fR,\ \f(CW\*(C`HAS_STRTOULL\*(C'\fR,\ \f(CW\*(C`HAS_STRTOUQ\*(C'\fR,\ \f(CW\*(C`HAS_STRXFRM\*(C'\fR,\ \f(CW\*(C`HAS_STRXFRM_L\*(C'\fR,\ \f(CW\*(C`HAS_SYMLINK\*(C'\fR,\ \f(CW\*(C`HAS_SYSCALL\*(C'\fR,\ \f(CW\*(C`HAS_SYSCONF\*(C'\fR,\ \f(CW\*(C`HAS_SYS_ERRLIST\*(C'\fR,\ \f(CW\*(C`HAS_SYSTEM\*(C'\fR,\ \f(CW\*(C`HAS_TCGETPGRP\*(C'\fR,\ \f(CW\*(C`HAS_TCSETPGRP\*(C'\fR,\ \f(CW\*(C`HAS_TOWLOWER\*(C'\fR,\ \f(CW\*(C`HAS_TOWUPPER\*(C'\fR,\ \f(CW\*(C`HAS_TRUNCATE\*(C'\fR,\ \f(CW\*(C`HAS_TRUNCL\*(C'\fR,\ \f(CW\*(C`HAS_UALARM\*(C'\fR,\ \f(CW\*(C`HAS_UMASK\*(C'\fR,\ \f(CW\*(C`HAS_UNLINKAT\*(C'\fR,\ \f(CW\*(C`HAS_UNSETENV\*(C'\fR,\ \f(CW\*(C`HAS_VFORK\*(C'\fR,\ \f(CW\*(C`HAS_VSNPRINTF\*(C'\fR,\ \f(CW\*(C`HAS_WAITPID\*(C'\fR,\ \f(CW\*(C`HAS_WAIT4\*(C'\fR,\ \f(CW\*(C`HAS_WCRTOMB\*(C'\fR,\ \f(CW\*(C`HAS_WCSCMP\*(C'\fR,\ \f(CW\*(C`HAS_WCSTOMBS\*(C'\fR,\ \f(CW\*(C`HAS_WCSXFRM\*(C'\fR,\ \f(CW\*(C`HAS_WCTOMB\*(C'\fR,\ \f(CW\*(C`HAS_WRITEV\*(C'\fR
+.PP
+And, the reentrant capabilities:
+.PP
+\&\f(CW\*(C`HAS_CRYPT_R\*(C'\fR,\ \f(CW\*(C`HAS_CTERMID_R\*(C'\fR,\ \f(CW\*(C`HAS_DRAND48_R\*(C'\fR,\ \f(CW\*(C`HAS_ENDHOSTENT_R\*(C'\fR,\ \f(CW\*(C`HAS_ENDNETENT_R\*(C'\fR,\ \f(CW\*(C`HAS_ENDPROTOENT_R\*(C'\fR,\ \f(CW\*(C`HAS_ENDSERVENT_R\*(C'\fR,\ \f(CW\*(C`HAS_GETGRGID_R\*(C'\fR,\ \f(CW\*(C`HAS_GETGRNAM_R\*(C'\fR,\ \f(CW\*(C`HAS_GETHOSTBYADDR_R\*(C'\fR,\ \f(CW\*(C`HAS_GETHOSTBYNAME_R\*(C'\fR,\ \f(CW\*(C`HAS_GETHOSTENT_R\*(C'\fR,\ \f(CW\*(C`HAS_GETLOGIN_R\*(C'\fR,\ \f(CW\*(C`HAS_GETNETBYADDR_R\*(C'\fR,\ \f(CW\*(C`HAS_GETNETBYNAME_R\*(C'\fR,\ \f(CW\*(C`HAS_GETNETENT_R\*(C'\fR,\ \f(CW\*(C`HAS_GETPROTOBYNAME_R\*(C'\fR,\ \f(CW\*(C`HAS_GETPROTOBYNUMBER_R\*(C'\fR,\ \f(CW\*(C`HAS_GETPROTOENT_R\*(C'\fR,\ \f(CW\*(C`HAS_GETPWNAM_R\*(C'\fR,\ \f(CW\*(C`HAS_GETPWUID_R\*(C'\fR,\ \f(CW\*(C`HAS_GETSERVBYNAME_R\*(C'\fR,\ \f(CW\*(C`HAS_GETSERVBYPORT_R\*(C'\fR,\ \f(CW\*(C`HAS_GETSERVENT_R\*(C'\fR,\ \f(CW\*(C`HAS_GETSPNAM_R\*(C'\fR,\ \f(CW\*(C`HAS_RANDOM_R\*(C'\fR,\ \f(CW\*(C`HAS_READDIR_R\*(C'\fR,\ \f(CW\*(C`HAS_SETHOSTENT_R\*(C'\fR,\ \f(CW\*(C`HAS_SETNETENT_R\*(C'\fR,\ \f(CW\*(C`HAS_SETPROTOENT_R\*(C'\fR,\ \f(CW\*(C`HAS_SETSERVENT_R\*(C'\fR,\ \f(CW\*(C`HAS_SRANDOM_R\*(C'\fR,\ \f(CW\*(C`HAS_SRAND48_R\*(C'\fR,\ \f(CW\*(C`HAS_STRERROR_R\*(C'\fR,\ \f(CW\*(C`HAS_TMPNAM_R\*(C'\fR,\ \f(CW\*(C`HAS_TTYNAME_R\*(C'\fR
+.PP
+Example usage:
+.Sp
+.Vb 5
+\& #ifdef HAS_STRNLEN
+\& use strnlen()
+\& #else
+\& use an alternative implementation
+\& #endif
+.Ve
+.ie n .SS "List of ""#include"" needed symbols"
+.el .SS "List of \f(CW#include\fP needed symbols"
+.IX Subsection "List of #include needed symbols"
+This list contains symbols that indicate if certain \f(CW\*(C`#include\*(C'\fR
+files are present on the platform. If your code accesses the
+functionality that one of these is for, you will need to
+\&\f(CW\*(C`#include\*(C'\fR it if the symbol on this list is \f(CW\*(C`#define\*(C'\fRd. For
+more detail, see the corresponding entry in \fIconfig.h\fR.
+.PP
+\&\f(CW\*(C`I_ARPA_INET\*(C'\fR,\ \f(CW\*(C`I_BFD\*(C'\fR,\ \f(CW\*(C`I_CRYPT\*(C'\fR,\ \f(CW\*(C`I_DBM\*(C'\fR,\ \f(CW\*(C`I_DLFCN\*(C'\fR,\ \f(CW\*(C`I_EXECINFO\*(C'\fR,\ \f(CW\*(C`I_FP\*(C'\fR,\ \f(CW\*(C`I_FP_CLASS\*(C'\fR,\ \f(CW\*(C`I_GDBM\*(C'\fR,\ \f(CW\*(C`I_GDBMNDBM\*(C'\fR,\ \f(CW\*(C`I_GDBM_NDBM\*(C'\fR,\ \f(CW\*(C`I_GRP\*(C'\fR,\ \f(CW\*(C`I_IEEEFP\*(C'\fR,\ \f(CW\*(C`I_INTTYPES\*(C'\fR,\ \f(CW\*(C`I_LIBUTIL\*(C'\fR,\ \f(CW\*(C`I_MNTENT\*(C'\fR,\ \f(CW\*(C`I_NDBM\*(C'\fR,\ \f(CW\*(C`I_NETDB\*(C'\fR,\ \f(CW\*(C`I_NET_ERRNO\*(C'\fR,\ \f(CW\*(C`I_NETINET_IN\*(C'\fR,\ \f(CW\*(C`I_NETINET_TCP\*(C'\fR,\ \f(CW\*(C`I_PROT\*(C'\fR,\ \f(CW\*(C`I_PWD\*(C'\fR,\ \f(CW\*(C`I_RPCSVC_DBM\*(C'\fR,\ \f(CW\*(C`I_SGTTY\*(C'\fR,\ \f(CW\*(C`I_SHADOW\*(C'\fR,\ \f(CW\*(C`I_STDBOOL\*(C'\fR,\ \f(CW\*(C`I_STDINT\*(C'\fR,\ \f(CW\*(C`I_SUNMATH\*(C'\fR,\ \f(CW\*(C`I_SYS_ACCESS\*(C'\fR,\ \f(CW\*(C`I_SYS_IOCTL\*(C'\fR,\ \f(CW\*(C`I_SYSLOG\*(C'\fR,\ \f(CW\*(C`I_SYSMODE\*(C'\fR,\ \f(CW\*(C`I_SYS_MOUNT\*(C'\fR,\ \f(CW\*(C`I_SYS_PARAM\*(C'\fR,\ \f(CW\*(C`I_SYS_POLL\*(C'\fR,\ \f(CW\*(C`I_SYS_SECURITY\*(C'\fR,\ \f(CW\*(C`I_SYS_SELECT\*(C'\fR,\ \f(CW\*(C`I_SYS_STAT\*(C'\fR,\ \f(CW\*(C`I_SYS_STATVFS\*(C'\fR,\ \f(CW\*(C`I_SYS_SYSCALL\*(C'\fR,\ \f(CW\*(C`I_SYS_TIME\*(C'\fR,\ \f(CW\*(C`I_SYS_TIME_KERNEL\*(C'\fR,\ \f(CW\*(C`I_SYS_TIMES\*(C'\fR,\ \f(CW\*(C`I_SYS_TYPES\*(C'\fR,\ \f(CW\*(C`I_SYSUIO\*(C'\fR,\ \f(CW\*(C`I_SYS_UN\*(C'\fR,\ \f(CW\*(C`I_SYSUTSNAME\*(C'\fR,\ \f(CW\*(C`I_SYS_VFS\*(C'\fR,\ \f(CW\*(C`I_SYS_WAIT\*(C'\fR,\ \f(CW\*(C`I_TERMIO\*(C'\fR,\ \f(CW\*(C`I_TERMIOS\*(C'\fR,\ \f(CW\*(C`I_UNISTD\*(C'\fR,\ \f(CW\*(C`I_USTAT\*(C'\fR,\ \f(CW\*(C`I_VFORK\*(C'\fR,\ \f(CW\*(C`I_WCHAR\*(C'\fR,\ \f(CW\*(C`I_WCTYPE\*(C'\fR
+.PP
+Example usage:
+.Sp
+.Vb 3
+\& #ifdef I_WCHAR
+\& #include <wchar.h>
+\& #endif
+.Ve
+.SH "Global Variables"
+.IX Header "Global Variables"
+These variables are global to an entire process. They are shared between
+all interpreters and all threads in a process. Any variables not documented
+here may be changed or removed without notice, so don't use them!
+If you feel you really do need to use an unlisted variable, first send email to
+perl5\-porters@perl.org <mailto:perl5-porters@perl.org>. It may be that
+someone there will point out a way to accomplish what you need without using an
+internal variable. But if not, you should get a go-ahead to document and then
+use the variable.
+.ie n .IP """PL_check""" 4
+.el .IP \f(CWPL_check\fR 4
+.IX Xref "PL_check"
+.IX Item "PL_check"
+Array, indexed by opcode, of functions that will be called for the "check"
+phase of optree building during compilation of Perl code. For most (but
+not all) types of op, once the op has been initially built and populated
+with child ops it will be filtered through the check function referenced
+by the appropriate element of this array. The new op is passed in as the
+sole argument to the check function, and the check function returns the
+completed op. The check function may (as the name suggests) check the op
+for validity and signal errors. It may also initialise or modify parts of
+the ops, or perform more radical surgery such as adding or removing child
+ops, or even throw the op away and return a different op in its place.
+.Sp
+This array of function pointers is a convenient place to hook into the
+compilation process. An XS module can put its own custom check function
+in place of any of the standard ones, to influence the compilation of a
+particular type of op. However, a custom check function must never fully
+replace a standard check function (or even a custom check function from
+another module). A module modifying checking must instead \fBwrap\fR the
+preexisting check function. A custom check function must be selective
+about when to apply its custom behaviour. In the usual case where
+it decides not to do anything special with an op, it must chain the
+preexisting op function. Check functions are thus linked in a chain,
+with the core's base checker at the end.
+.Sp
+For thread safety, modules should not write directly to this array.
+Instead, use the function "wrap_op_checker".
+.ie n .IP """PL_infix_plugin""" 4
+.el .IP \f(CWPL_infix_plugin\fR 4
+.IX Xref "PL_infix_plugin"
+.IX Item "PL_infix_plugin"
+NOTE: \f(CW\*(C`PL_infix_plugin\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+\&\fBNOTE:\fR This API exists entirely for the purpose of making the CPAN module
+\&\f(CW\*(C`XS::Parse::Infix\*(C'\fR work. It is not expected that additional modules will make
+use of it; rather, that they should use \f(CW\*(C`XS::Parse::Infix\*(C'\fR to provide parsing
+of new infix operators.
+.Sp
+Function pointer, pointing at a function used to handle extended infix
+operators. The function should be declared as
+.Sp
+.Vb 3
+\& int infix_plugin_function(pTHX_
+\& char *opname, STRLEN oplen,
+\& struct Perl_custom_infix **infix_ptr)
+.Ve
+.Sp
+The function is called from the tokenizer whenever a possible infix operator
+is seen. \f(CW\*(C`opname\*(C'\fR points to the operator name in the parser's input buffer,
+and \f(CW\*(C`oplen\*(C'\fR gives the \fImaximum\fR number of bytes of it that should be
+consumed; it is not null-terminated. The function is expected to examine the
+operator name and possibly other state such as %^H, to
+determine whether it wants to handle the operator name.
+.Sp
+As compared to the single stage of \f(CW\*(C`PL_keyword_plugin\*(C'\fR, parsing of additional
+infix operators occurs in three separate stages. This is because of the more
+complex interactions it has with the parser, to ensure that operator
+precedence rules work correctly. These stages are co-ordinated by the use of
+an additional information structure.
+.Sp
+If the function wants to handle the infix operator, it must set the variable
+pointed to by \f(CW\*(C`infix_ptr\*(C'\fR to the address of a structure that provides this
+additional information about the subsequent parsing stages. If it does not,
+it should make a call to the next function in the chain.
+.Sp
+This structure has the following definition:
+.Sp
+.Vb 7
+\& struct Perl_custom_infix {
+\& enum Perl_custom_infix_precedence prec;
+\& void (*parse)(pTHX_ SV **opdata,
+\& struct Perl_custom_infix *);
+\& OP *(*build_op)(pTHX_ SV **opdata, OP *lhs, OP *rhs,
+\& struct Perl_custom_infix *);
+\& };
+.Ve
+.Sp
+The function must then return an integer giving the number of bytes consumed
+by the name of this operator. In the case of an operator whose name is
+composed of identifier characters, this must be equal to \f(CW\*(C`oplen\*(C'\fR. In the case
+of an operator named by non-identifier characters, this is permitted to be
+shorter than \f(CW\*(C`oplen\*(C'\fR, and any additional characters after it will not be
+claimed by the infix operator but instead will be consumed by the tokenizer
+and parser as normal.
+.Sp
+If the optional \f(CW\*(C`parse\*(C'\fR function is provided, it is called immediately by the
+parser to let the operator's definition consume any additional syntax from the
+source code. This should \fInot\fR be used for normal operand parsing, but it may
+be useful when implementing things like parametric operators or meta-operators
+that consume more syntax themselves. This function may use the variable
+pointed to by \f(CW\*(C`opdata\*(C'\fR to provide an SV containing additional data to be
+passed into the \f(CW\*(C`build_op\*(C'\fR function later on.
+.Sp
+The information structure gives the operator precedence level in the \f(CW\*(C`prec\*(C'\fR
+field. This is used to tell the parser how much of the surrounding syntax
+before and after should be considered as operands to the operator.
+.Sp
+The tokenizer and parser will then continue to operate as normal until enough
+additional input has been parsed to form both the left\- and right-hand side
+operands to the operator, according to the precedence level. At this point the
+\&\f(CW\*(C`build_op\*(C'\fR function is called, being passed the left\- and right-hand operands
+as optree fragments. It is expected to combine them into the resulting optree
+fragment, which it should return.
+.Sp
+After the \f(CW\*(C`build_op\*(C'\fR function has returned, if the variable pointed to by
+\&\f(CW\*(C`opdata\*(C'\fR was set to a non\-\f(CW\*(C`NULL\*(C'\fR value, it will then be destroyed by calling
+\&\f(CWSvREFCNT_dec()\fR.
+.Sp
+For thread safety, modules should not set this variable directly.
+Instead, use the function "wrap_infix_plugin".
+.Sp
+However, that all said, the introductory note above still applies. This
+variable is provided in core perl only for the benefit of the
+\&\f(CW\*(C`XS::Parse::Infix\*(C'\fR module. That module acts as a central registry for infix
+operators, automatically handling things like deparse support and
+discovery/reflection, and these abilities only work because it knows all the
+registered operators. Other modules should not use this interpreter variable
+directly to implement them because then those central features would no longer
+work properly.
+.Sp
+Furthermore, it is likely that this (experimental) API will be replaced in a
+future Perl version by a more complete API that fully implements the central
+registry and other semantics currently provided by \f(CW\*(C`XS::Parse::Infix\*(C'\fR, once
+the module has had sufficient experimental testing time. This current
+mechanism exists only as an interim measure to get to that stage.
+.ie n .IP """PL_keyword_plugin""" 4
+.el .IP \f(CWPL_keyword_plugin\fR 4
+.IX Xref "PL_keyword_plugin"
+.IX Item "PL_keyword_plugin"
+NOTE: \f(CW\*(C`PL_keyword_plugin\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Function pointer, pointing at a function used to handle extended keywords.
+The function should be declared as
+.Sp
+.Vb 3
+\& int keyword_plugin_function(pTHX_
+\& char *keyword_ptr, STRLEN keyword_len,
+\& OP **op_ptr)
+.Ve
+.Sp
+The function is called from the tokeniser, whenever a possible keyword
+is seen. \f(CW\*(C`keyword_ptr\*(C'\fR points at the word in the parser's input
+buffer, and \f(CW\*(C`keyword_len\*(C'\fR gives its length; it is not null-terminated.
+The function is expected to examine the word, and possibly other state
+such as %^H, to decide whether it wants to handle it
+as an extended keyword. If it does not, the function should return
+\&\f(CW\*(C`KEYWORD_PLUGIN_DECLINE\*(C'\fR, and the normal parser process will continue.
+.Sp
+If the function wants to handle the keyword, it first must
+parse anything following the keyword that is part of the syntax
+introduced by the keyword. See "Lexer interface" for details.
+.Sp
+When a keyword is being handled, the plugin function must build
+a tree of \f(CW\*(C`OP\*(C'\fR structures, representing the code that was parsed.
+The root of the tree must be stored in \f(CW*op_ptr\fR. The function then
+returns a constant indicating the syntactic role of the construct that
+it has parsed: \f(CW\*(C`KEYWORD_PLUGIN_STMT\*(C'\fR if it is a complete statement, or
+\&\f(CW\*(C`KEYWORD_PLUGIN_EXPR\*(C'\fR if it is an expression. Note that a statement
+construct cannot be used inside an expression (except via \f(CW\*(C`do BLOCK\*(C'\fR
+and similar), and an expression is not a complete statement (it requires
+at least a terminating semicolon).
+.Sp
+When a keyword is handled, the plugin function may also have
+(compile-time) side effects. It may modify \f(CW\*(C`%^H\*(C'\fR, define functions, and
+so on. Typically, if side effects are the main purpose of a handler,
+it does not wish to generate any ops to be included in the normal
+compilation. In this case it is still required to supply an op tree,
+but it suffices to generate a single null op.
+.Sp
+That's how the \f(CW*PL_keyword_plugin\fR function needs to behave overall.
+Conventionally, however, one does not completely replace the existing
+handler function. Instead, take a copy of \f(CW\*(C`PL_keyword_plugin\*(C'\fR before
+assigning your own function pointer to it. Your handler function should
+look for keywords that it is interested in and handle those. Where it
+is not interested, it should call the saved plugin function, passing on
+the arguments it received. Thus \f(CW\*(C`PL_keyword_plugin\*(C'\fR actually points
+at a chain of handler functions, all of which have an opportunity to
+handle keywords, and only the last function in the chain (built into
+the Perl core) will normally return \f(CW\*(C`KEYWORD_PLUGIN_DECLINE\*(C'\fR.
+.Sp
+For thread safety, modules should not set this variable directly.
+Instead, use the function "wrap_keyword_plugin".
+.ie n .IP """PL_phase""" 4
+.el .IP \f(CWPL_phase\fR 4
+.IX Xref "PL_phase"
+.IX Item "PL_phase"
+A value that indicates the current Perl interpreter's phase. Possible values
+include \f(CW\*(C`PERL_PHASE_CONSTRUCT\*(C'\fR, \f(CW\*(C`PERL_PHASE_START\*(C'\fR, \f(CW\*(C`PERL_PHASE_CHECK\*(C'\fR,
+\&\f(CW\*(C`PERL_PHASE_INIT\*(C'\fR, \f(CW\*(C`PERL_PHASE_RUN\*(C'\fR, \f(CW\*(C`PERL_PHASE_END\*(C'\fR, and
+\&\f(CW\*(C`PERL_PHASE_DESTRUCT\*(C'\fR.
+.Sp
+For example, the following determines whether the interpreter is in
+global destruction:
+.Sp
+.Vb 3
+\& if (PL_phase == PERL_PHASE_DESTRUCT) {
+\& // we are in global destruction
+\& }
+.Ve
+.Sp
+\&\f(CW\*(C`PL_phase\*(C'\fR was introduced in Perl 5.14; in prior perls you can use
+\&\f(CW\*(C`PL_dirty\*(C'\fR (boolean) to determine whether the interpreter is in global
+destruction. (Use of \f(CW\*(C`PL_dirty\*(C'\fR is discouraged since 5.14.)
+.RS 4
+.Sp
+.Vb 1
+\& enum perl_phase PL_phase
+.Ve
+.RE
+.RS 4
+.RE
+.SH "GV Handling and Stashes"
+.IX Xref "GV GV_ADD GV_ADDMG GV_ADDMULTI GV_ADDWARN GV_NOADD_NOINIT GV_NOEXPAND GV_NOINIT GV_NOTQUAL GV_NO_SVGMAGIC GV_SUPER SVf_UTF8"
+.IX Header "GV Handling and Stashes"
+A GV is a structure which corresponds to to a Perl typeglob, ie *foo.
+It is a structure that holds a pointer to a scalar, an array, a hash etc,
+corresponding to \f(CW$foo\fR, \f(CW@foo\fR, \f(CW%foo\fR.
+.PP
+GVs are usually found as values in stashes (symbol table hashes) where
+Perl stores its global variables.
+.PP
+A \fBstash\fR is a hash that contains all variables that are defined
+within a package. See "Stashes and Globs" in perlguts
+.ie n .IP """amagic_call""" 4
+.el .IP \f(CWamagic_call\fR 4
+.IX Xref "amagic_call"
+.IX Item "amagic_call"
+Perform the overloaded (active magic) operation given by \f(CW\*(C`method\*(C'\fR.
+\&\f(CW\*(C`method\*(C'\fR is one of the values found in \fIoverload.h\fR.
+.Sp
+\&\f(CW\*(C`flags\*(C'\fR affects how the operation is performed, as follows:
+.RS 4
+.ie n .IP """AMGf_noleft""" 4
+.el .IP \f(CWAMGf_noleft\fR 4
+.IX Item "AMGf_noleft"
+\&\f(CW\*(C`left\*(C'\fR is not to be used in this operation.
+.ie n .IP """AMGf_noright""" 4
+.el .IP \f(CWAMGf_noright\fR 4
+.IX Item "AMGf_noright"
+\&\f(CW\*(C`right\*(C'\fR is not to be used in this operation.
+.ie n .IP """AMGf_unary""" 4
+.el .IP \f(CWAMGf_unary\fR 4
+.IX Item "AMGf_unary"
+The operation is done only on just one operand.
+.ie n .IP """AMGf_assign""" 4
+.el .IP \f(CWAMGf_assign\fR 4
+.IX Item "AMGf_assign"
+The operation changes one of the operands, e.g., \f(CW$x\fR += 1
+.RE
+.RS 4
+.Sp
+.Vb 1
+\& SV * amagic_call(SV *left, SV *right, int method, int dir)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """amagic_deref_call""" 4
+.el .IP \f(CWamagic_deref_call\fR 4
+.IX Xref "amagic_deref_call"
+.IX Item "amagic_deref_call"
+Perform \f(CW\*(C`method\*(C'\fR overloading dereferencing on \f(CW\*(C`ref\*(C'\fR, returning the
+dereferenced result. \f(CW\*(C`method\*(C'\fR must be one of the dereference operations given
+in \fIoverload.h\fR.
+.Sp
+If overloading is inactive on \f(CW\*(C`ref\*(C'\fR, returns \f(CW\*(C`ref\*(C'\fR itself.
+.RS 4
+.Sp
+.Vb 1
+\& SV * amagic_deref_call(SV *ref, int method)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_add_by_type""" 4
+.el .IP \f(CWgv_add_by_type\fR 4
+.IX Xref "gv_add_by_type"
+.IX Item "gv_add_by_type"
+Make sure there is a slot of type \f(CW\*(C`type\*(C'\fR in the GV \f(CW\*(C`gv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& GV * gv_add_by_type(GV *gv, svtype type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Gv_AMupdate""" 4
+.el .IP \f(CWGv_AMupdate\fR 4
+.IX Xref "Gv_AMupdate"
+.IX Item "Gv_AMupdate"
+Recalculates overload magic in the package given by \f(CW\*(C`stash\*(C'\fR.
+.Sp
+Returns:
+.RS 4
+.IP "1 on success and there is some overload" 4
+.IX Item "1 on success and there is some overload"
+.PD 0
+.IP "0 if there is no overload" 4
+.IX Item "0 if there is no overload"
+.ie n .IP "\-1 if some error occurred and it couldn't croak (because ""destructing"" is true)." 4
+.el .IP "\-1 if some error occurred and it couldn't croak (because \f(CWdestructing\fR is true)." 4
+.IX Item "-1 if some error occurred and it couldn't croak (because destructing is true)."
+.RE
+.RS 4
+.PD
+.Sp
+.Vb 1
+\& int Gv_AMupdate(HV *stash, bool destructing)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_autoload_pv""" 4
+.el .IP \f(CWgv_autoload_pv\fR 4
+.IX Item "gv_autoload_pv"
+.PD 0
+.ie n .IP """gv_autoload_pvn""" 4
+.el .IP \f(CWgv_autoload_pvn\fR 4
+.IX Item "gv_autoload_pvn"
+.ie n .IP """gv_autoload_sv""" 4
+.el .IP \f(CWgv_autoload_sv\fR 4
+.IX Xref "gv_autoload_pv gv_autoload_pvn gv_autoload_sv"
+.IX Item "gv_autoload_sv"
+.PD
+These each search for an \f(CW\*(C`AUTOLOAD\*(C'\fR method, returning NULL if not found, or
+else returning a pointer to its GV, while setting the package
+\&\f(CW$AUTOLOAD\fR variable to \f(CW\*(C`name\*(C'\fR (fully qualified). Also,
+if found and the GV's CV is an XSUB, the CV's PV will be set to \f(CW\*(C`name\*(C'\fR, and
+its stash will be set to the stash of the GV.
+.Sp
+Searching is done in \f(CW\*(C`MRO\*(C'\fR order, as specified in
+"\f(CW\*(C`gv_fetchmeth\*(C'\fR", beginning with \f(CW\*(C`stash\*(C'\fR if it isn't NULL.
+.Sp
+The forms differ only in how \f(CW\*(C`name\*(C'\fR is specified.
+.Sp
+In \f(CW\*(C`gv_autoload_pv\*(C'\fR, \f(CW\*(C`namepv\*(C'\fR is a C language NUL-terminated string.
+.Sp
+In \f(CW\*(C`gv_autoload_pvn\*(C'\fR, \f(CW\*(C`name\*(C'\fR points to the first byte of the name, and an
+additional parameter, \f(CW\*(C`len\*(C'\fR, specifies its length in bytes. Hence, \f(CW*name\fR
+may contain embedded-NUL characters.
+.Sp
+In \f(CW\*(C`gv_autoload_sv\*(C'\fR, \f(CW*namesv\fR is an SV, and the name is the PV extracted
+from that using "\f(CW\*(C`SvPV\*(C'\fR". If the SV is marked as being in UTF\-8, the
+extracted PV will also be.
+.RS 4
+.Sp
+.Vb 4
+\& GV * gv_autoload_pv (HV *stash, const char *namepv, U32 flags)
+\& GV * gv_autoload_pvn(HV *stash, const char *name, STRLEN len,
+\& U32 flags)
+\& GV * gv_autoload_sv (HV *stash, SV *namesv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_autoload4""" 4
+.el .IP \f(CWgv_autoload4\fR 4
+.IX Xref "gv_autoload4"
+.IX Item "gv_autoload4"
+Equivalent to \f(CW"gv_autoload_pvn"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& GV * gv_autoload4(HV *stash, const char *name, STRLEN len,
+\& I32 method)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """GvAV""" 4
+.el .IP \f(CWGvAV\fR 4
+.IX Xref "GvAV"
+.IX Item "GvAV"
+Return the AV from the GV.
+.RS 4
+.Sp
+.Vb 1
+\& AV* GvAV(GV* gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_AVadd""" 4
+.el .IP \f(CWgv_AVadd\fR 4
+.IX Item "gv_AVadd"
+.PD 0
+.ie n .IP """gv_HVadd""" 4
+.el .IP \f(CWgv_HVadd\fR 4
+.IX Item "gv_HVadd"
+.ie n .IP """gv_IOadd""" 4
+.el .IP \f(CWgv_IOadd\fR 4
+.IX Item "gv_IOadd"
+.ie n .IP """gv_SVadd""" 4
+.el .IP \f(CWgv_SVadd\fR 4
+.IX Xref "gv_AVadd gv_HVadd gv_IOadd gv_SVadd"
+.IX Item "gv_SVadd"
+.PD
+Make sure there is a slot of the given type (AV, HV, IO, SV) in the GV \f(CW\*(C`gv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& GV * gv_AVadd(GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_const_sv""" 4
+.el .IP \f(CWgv_const_sv\fR 4
+.IX Xref "gv_const_sv"
+.IX Item "gv_const_sv"
+If \f(CW\*(C`gv\*(C'\fR is a typeglob whose subroutine entry is a constant sub eligible for
+inlining, or \f(CW\*(C`gv\*(C'\fR is a placeholder reference that would be promoted to such
+a typeglob, then returns the value returned by the sub. Otherwise, returns
+\&\f(CW\*(C`NULL\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * gv_const_sv(GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """GvCV""" 4
+.el .IP \f(CWGvCV\fR 4
+.IX Xref "GvCV"
+.IX Item "GvCV"
+Return the CV from the GV.
+.RS 4
+.Sp
+.Vb 1
+\& CV* GvCV(GV* gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_efullname3""" 4
+.el .IP \f(CWgv_efullname3\fR 4
+.IX Item "gv_efullname3"
+.PD 0
+.ie n .IP """gv_efullname4""" 4
+.el .IP \f(CWgv_efullname4\fR 4
+.IX Item "gv_efullname4"
+.ie n .IP """gv_fullname3""" 4
+.el .IP \f(CWgv_fullname3\fR 4
+.IX Item "gv_fullname3"
+.ie n .IP """gv_fullname4""" 4
+.el .IP \f(CWgv_fullname4\fR 4
+.IX Xref "gv_efullname3 gv_efullname4 gv_fullname3 gv_fullname4"
+.IX Item "gv_fullname4"
+.PD
+Place the full package name of \f(CW\*(C`gv\*(C'\fR into \f(CW\*(C`sv\*(C'\fR. The \f(CW\*(C`gv_e*\*(C'\fR forms return
+instead the effective package name (see "HvENAME").
+.Sp
+If \f(CW\*(C`prefix\*(C'\fR is non-NULL, it is considered to be a C language NUL-terminated
+string, and the stored name will be prefaced with it.
+.Sp
+The other difference between the functions is that the \f(CW*4\fR forms have an
+extra parameter, \f(CW\*(C`keepmain\*(C'\fR. If \f(CW\*(C`true\*(C'\fR an initial \f(CW\*(C`main::\*(C'\fR in the name is
+kept; if \f(CW\*(C`false\*(C'\fR it is stripped. With the \f(CW*3\fR forms, it is always kept.
+.RS 4
+.Sp
+.Vb 6
+\& void gv_efullname3(SV *sv, const GV *gv, const char *prefix)
+\& void gv_efullname4(SV *sv, const GV *gv, const char *prefix,
+\& bool keepmain)
+\& void gv_fullname3 (SV *sv, const GV *gv, const char *prefix)
+\& void gv_fullname4 (SV *sv, const GV *gv, const char *prefix,
+\& bool keepmain)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchfile""" 4
+.el .IP \f(CWgv_fetchfile\fR 4
+.IX Item "gv_fetchfile"
+.PD 0
+.ie n .IP """gv_fetchfile_flags""" 4
+.el .IP \f(CWgv_fetchfile_flags\fR 4
+.IX Xref "gv_fetchfile gv_fetchfile_flags"
+.IX Item "gv_fetchfile_flags"
+.PD
+These return the debugger glob for the file (compiled by Perl) whose name is
+given by the \f(CW\*(C`name\*(C'\fR parameter.
+.Sp
+There are currently exactly two differences between these functions.
+.Sp
+The \f(CW\*(C`name\*(C'\fR parameter to \f(CW\*(C`gv_fetchfile\*(C'\fR is a C string, meaning it is
+\&\f(CW\*(C`NUL\*(C'\fR\-terminated; whereas the \f(CW\*(C`name\*(C'\fR parameter to \f(CW\*(C`gv_fetchfile_flags\*(C'\fR is a
+Perl string, whose length (in bytes) is passed in via the \f(CW\*(C`namelen\*(C'\fR parameter
+This means the name may contain embedded \f(CW\*(C`NUL\*(C'\fR characters.
+\&\f(CW\*(C`namelen\*(C'\fR doesn't exist in plain \f(CW\*(C`gv_fetchfile\*(C'\fR).
+.Sp
+The other difference is that \f(CW\*(C`gv_fetchfile_flags\*(C'\fR has an extra \f(CW\*(C`flags\*(C'\fR
+parameter, which is currently completely ignored, but allows for possible
+future extensions.
+.RS 4
+.Sp
+.Vb 3
+\& GV * gv_fetchfile (const char *name)
+\& GV * gv_fetchfile_flags(const char * const name,
+\& const STRLEN len, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchmeth""" 4
+.el .IP \f(CWgv_fetchmeth\fR 4
+.IX Item "gv_fetchmeth"
+.PD 0
+.ie n .IP """gv_fetchmeth_pv""" 4
+.el .IP \f(CWgv_fetchmeth_pv\fR 4
+.IX Item "gv_fetchmeth_pv"
+.ie n .IP """gv_fetchmeth_pvn""" 4
+.el .IP \f(CWgv_fetchmeth_pvn\fR 4
+.IX Item "gv_fetchmeth_pvn"
+.ie n .IP """gv_fetchmeth_sv""" 4
+.el .IP \f(CWgv_fetchmeth_sv\fR 4
+.IX Xref "gv_fetchmeth gv_fetchmeth_pv gv_fetchmeth_pvn gv_fetchmeth_sv"
+.IX Item "gv_fetchmeth_sv"
+.PD
+These each look for a glob with name \f(CW\*(C`name\*(C'\fR, containing a defined subroutine,
+returning the GV of that glob if found, or \f(CW\*(C`NULL\*(C'\fR if not.
+.Sp
+\&\f(CW\*(C`stash\*(C'\fR is always searched (first), unless it is \f(CW\*(C`NULL\*(C'\fR.
+.Sp
+If \f(CW\*(C`stash\*(C'\fR is NULL, or was searched but nothing was found in it, and the
+\&\f(CW\*(C`GV_SUPER\*(C'\fR bit is set in \f(CW\*(C`flags\*(C'\fR, stashes accessible via \f(CW@ISA\fR are searched
+next. Searching is conducted according to \f(CW\*(C`MRO\*(C'\fR order.
+.Sp
+Finally, if no matches were found so far, and the \f(CW\*(C`GV_NOUNIVERSAL\*(C'\fR flag in
+\&\f(CW\*(C`flags\*(C'\fR is not set, \f(CW\*(C`UNIVERSAL::\*(C'\fR is searched.
+.Sp
+The argument \f(CW\*(C`level\*(C'\fR should be either 0 or \-1. If \-1, the function will
+return without any side effects or caching. If 0, the function makes sure
+there is a glob named \f(CW\*(C`name\*(C'\fR in \f(CW\*(C`stash\*(C'\fR, creating one if necessary.
+The subroutine slot in the glob will be set to any subroutine found in the
+\&\f(CW\*(C`stash\*(C'\fR and \f(CW\*(C`SUPER::\*(C'\fR search, hence caching any \f(CW\*(C`SUPER::\*(C'\fR result. Note that
+subroutines found in \f(CW\*(C`UNIVERSAL::\*(C'\fR are not cached.
+.Sp
+The GV returned from these may be a method cache entry, which is not visible to
+Perl code. So when calling \f(CW\*(C`call_sv\*(C'\fR, you should not use the GV directly;
+instead, you should use the method's CV, which can be obtained from the GV with
+the \f(CW\*(C`GvCV\*(C'\fR macro.
+.Sp
+The only other significant value for \f(CW\*(C`flags\*(C'\fR is \f(CW\*(C`SVf_UTF8\*(C'\fR, indicating that
+\&\f(CW\*(C`name\*(C'\fR is to be treated as being encoded in UTF\-8.
+.Sp
+Plain \f(CW\*(C`gv_fetchmeth\*(C'\fR lacks a \f(CW\*(C`flags\*(C'\fR parameter, hence always searches in
+\&\f(CW\*(C`stash\*(C'\fR, then \f(CW\*(C`UNIVERSAL::\*(C'\fR, and \f(CW\*(C`name\*(C'\fR is never UTF\-8. Otherwise it is
+exactly like \f(CW\*(C`gv_fetchmeth_pvn\*(C'\fR.
+.Sp
+The other forms do have a \f(CW\*(C`flags\*(C'\fR parameter, and differ only in how the glob
+name is specified.
+.Sp
+In \f(CW\*(C`gv_fetchmeth_pv\*(C'\fR, \f(CW\*(C`name\*(C'\fR is a C language NUL-terminated string.
+.Sp
+In \f(CW\*(C`gv_fetchmeth_pvn\*(C'\fR, \f(CW\*(C`name\*(C'\fR points to the first byte of the name, and an
+additional parameter, \f(CW\*(C`len\*(C'\fR, specifies its length in bytes. Hence, the name
+may contain embedded-NUL characters.
+.Sp
+In \f(CW\*(C`gv_fetchmeth_sv\*(C'\fR, \f(CW*name\fR is an SV, and the name is the PV extracted from
+that, using "\f(CW\*(C`SvPV\*(C'\fR". If the SV is marked as being in UTF\-8, the extracted
+PV will also be.
+.RS 4
+.Sp
+.Vb 8
+\& GV * gv_fetchmeth (HV *stash, const char *name, STRLEN len,
+\& I32 level)
+\& GV * gv_fetchmeth_pv (HV *stash, const char *name, I32 level,
+\& U32 flags)
+\& GV * gv_fetchmeth_pvn(HV *stash, const char *name, STRLEN len,
+\& I32 level, U32 flags)
+\& GV * gv_fetchmeth_sv (HV *stash, SV *namesv, I32 level,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchmeth_autoload""" 4
+.el .IP \f(CWgv_fetchmeth_autoload\fR 4
+.IX Xref "gv_fetchmeth_autoload"
+.IX Item "gv_fetchmeth_autoload"
+This is the old form of "gv_fetchmeth_pvn_autoload", which has no flags
+parameter.
+.RS 4
+.Sp
+.Vb 2
+\& GV * gv_fetchmeth_autoload(HV *stash, const char *name,
+\& STRLEN len, I32 level)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchmethod""" 4
+.el .IP \f(CWgv_fetchmethod\fR 4
+.IX Xref "gv_fetchmethod"
+.IX Item "gv_fetchmethod"
+See "gv_fetchmethod_autoload".
+.RS 4
+.Sp
+.Vb 1
+\& GV * gv_fetchmethod(HV *stash, const char *name)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchmethod_autoload""" 4
+.el .IP \f(CWgv_fetchmethod_autoload\fR 4
+.IX Xref "gv_fetchmethod_autoload"
+.IX Item "gv_fetchmethod_autoload"
+Returns the glob which contains the subroutine to call to invoke the method
+on the \f(CW\*(C`stash\*(C'\fR. In fact in the presence of autoloading this may be the
+glob for "AUTOLOAD". In this case the corresponding variable \f(CW$AUTOLOAD\fR is
+already setup.
+.Sp
+The third parameter of \f(CW\*(C`gv_fetchmethod_autoload\*(C'\fR determines whether
+AUTOLOAD lookup is performed if the given method is not present: non-zero
+means yes, look for AUTOLOAD; zero means no, don't look for AUTOLOAD.
+Calling \f(CW\*(C`gv_fetchmethod\*(C'\fR is equivalent to calling \f(CW\*(C`gv_fetchmethod_autoload\*(C'\fR
+with a non-zero \f(CW\*(C`autoload\*(C'\fR parameter.
+.Sp
+These functions grant \f(CW"SUPER"\fR token
+as a prefix of the method name. Note
+that if you want to keep the returned glob for a long time, you need to
+check for it being "AUTOLOAD", since at the later time the call may load a
+different subroutine due to \f(CW$AUTOLOAD\fR changing its value. Use the glob
+created as a side effect to do this.
+.Sp
+These functions have the same side-effects as \f(CW\*(C`gv_fetchmeth\*(C'\fR with
+\&\f(CW\*(C`level==0\*(C'\fR. The warning against passing the GV returned by
+\&\f(CW\*(C`gv_fetchmeth\*(C'\fR to \f(CW\*(C`call_sv\*(C'\fR applies equally to these functions.
+.RS 4
+.Sp
+.Vb 2
+\& GV * gv_fetchmethod_autoload(HV *stash, const char *name,
+\& I32 autoload)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchmeth_pv_autoload""" 4
+.el .IP \f(CWgv_fetchmeth_pv_autoload\fR 4
+.IX Xref "gv_fetchmeth_pv_autoload"
+.IX Item "gv_fetchmeth_pv_autoload"
+Exactly like "gv_fetchmeth_pvn_autoload", but takes a nul-terminated string
+instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 2
+\& GV * gv_fetchmeth_pv_autoload(HV *stash, const char *name,
+\& I32 level, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchmeth_pvn_autoload""" 4
+.el .IP \f(CWgv_fetchmeth_pvn_autoload\fR 4
+.IX Xref "gv_fetchmeth_pvn_autoload"
+.IX Item "gv_fetchmeth_pvn_autoload"
+Same as \f(CWgv_fetchmeth_pvn()\fR, but looks for autoloaded subroutines too.
+Returns a glob for the subroutine.
+.Sp
+For an autoloaded subroutine without a GV, will create a GV even
+if \f(CW\*(C`level < 0\*(C'\fR. For an autoloaded subroutine without a stub, \f(CWGvCV()\fR
+of the result may be zero.
+.Sp
+Currently, the only significant value for \f(CW\*(C`flags\*(C'\fR is \f(CW\*(C`SVf_UTF8\*(C'\fR.
+.RS 4
+.Sp
+.Vb 2
+\& GV * gv_fetchmeth_pvn_autoload(HV *stash, const char *name,
+\& STRLEN len, I32 level, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchmeth_sv_autoload""" 4
+.el .IP \f(CWgv_fetchmeth_sv_autoload\fR 4
+.IX Xref "gv_fetchmeth_sv_autoload"
+.IX Item "gv_fetchmeth_sv_autoload"
+Exactly like "gv_fetchmeth_pvn_autoload", but takes the name string in the form
+of an SV instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 2
+\& GV * gv_fetchmeth_sv_autoload(HV *stash, SV *namesv, I32 level,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_fetchpv""" 4
+.el .IP \f(CWgv_fetchpv\fR 4
+.IX Item "gv_fetchpv"
+.PD 0
+.ie n .IP """gv_fetchpvn""" 4
+.el .IP \f(CWgv_fetchpvn\fR 4
+.IX Item "gv_fetchpvn"
+.ie n .IP """gv_fetchpvn_flags""" 4
+.el .IP \f(CWgv_fetchpvn_flags\fR 4
+.IX Item "gv_fetchpvn_flags"
+.ie n .IP """gv_fetchpvs""" 4
+.el .IP \f(CWgv_fetchpvs\fR 4
+.IX Item "gv_fetchpvs"
+.ie n .IP """gv_fetchsv""" 4
+.el .IP \f(CWgv_fetchsv\fR 4
+.IX Item "gv_fetchsv"
+.ie n .IP """gv_fetchsv_nomg""" 4
+.el .IP \f(CWgv_fetchsv_nomg\fR 4
+.IX Xref "gv_fetchpv gv_fetchpvn gv_fetchpvn_flags gv_fetchpvs gv_fetchsv gv_fetchsv_nomg"
+.IX Item "gv_fetchsv_nomg"
+.PD
+These all return the GV of type \f(CW\*(C`sv_type\*(C'\fR whose name is given by the inputs,
+or NULL if no GV of that name and type could be found. See "Stashes
+and Globs" in perlguts.
+.Sp
+The only differences are how the input name is specified, and if 'get' magic is
+normally used in getting that name.
+.Sp
+Don't be fooled by the fact that only one form has \f(CW\*(C`flags\*(C'\fR in its name. They
+all have a \f(CW\*(C`flags\*(C'\fR parameter in fact, and all the flag bits have the same
+meanings for all
+.Sp
+If any of the flags \f(CW\*(C`GV_ADD\*(C'\fR, \f(CW\*(C`GV_ADDMG\*(C'\fR, \f(CW\*(C`GV_ADDWARN\*(C'\fR, \f(CW\*(C`GV_ADDMULTI\*(C'\fR, or
+\&\f(CW\*(C`GV_NOINIT\*(C'\fR is set, a GV is created if none already exists for the input name
+and type. However, \f(CW\*(C`GV_ADDMG\*(C'\fR will only do the creation for magical GV's.
+For all of these flags except \f(CW\*(C`GV_NOINIT\*(C'\fR, \f(CW"gv_init_pvn"\fR is called after
+the addition. \f(CW\*(C`GV_ADDWARN\*(C'\fR is used when the caller expects that adding won't
+be necessary because the symbol should already exist; but if not, add it
+anyway, with a warning that it was unexpectedly absent. The \f(CW\*(C`GV_ADDMULTI\*(C'\fR
+flag means to pretend that the GV has been seen before (\fIi.e.\fR, suppress "Used
+once" warnings).
+.Sp
+The flag \f(CW\*(C`GV_NOADD_NOINIT\*(C'\fR causes \f(CW"gv_init_pvn"\fR not be to called if the
+GV existed but isn't PVGV.
+.Sp
+If the \f(CW\*(C`SVf_UTF8\*(C'\fR bit is set, the name is treated as being encoded in UTF\-8;
+otherwise the name won't be considered to be UTF\-8 in the \f(CW\*(C`pv\*(C'\fR\-named forms,
+and the UTF\-8ness of the underlying SVs will be used in the \f(CW\*(C`sv\*(C'\fR forms.
+.Sp
+If the flag \f(CW\*(C`GV_NOTQUAL\*(C'\fR is set, the caller warrants that the input name is a
+plain symbol name, not qualified with a package, otherwise the name is checked
+for being a qualified one.
+.Sp
+In \f(CW\*(C`gv_fetchpv\*(C'\fR, \f(CW\*(C`nambeg\*(C'\fR is a C string, NUL-terminated with no intermediate
+NULs.
+.Sp
+In \f(CW\*(C`gv_fetchpvs\*(C'\fR, \f(CW\*(C`name\*(C'\fR is a literal C string, hence is enclosed in
+double quotes.
+.Sp
+\&\f(CW\*(C`gv_fetchpvn\*(C'\fR and \f(CW\*(C`gv_fetchpvn_flags\*(C'\fR are identical. In these, <nambeg> is
+a Perl string whose byte length is given by \f(CW\*(C`full_len\*(C'\fR, and may contain
+embedded NULs.
+.Sp
+In \f(CW\*(C`gv_fetchsv\*(C'\fR and \f(CW\*(C`gv_fetchsv_nomg\*(C'\fR, the name is extracted from the PV of
+the input \f(CW\*(C`name\*(C'\fR SV. The only difference between these two forms is that
+\&'get' magic is normally done on \f(CW\*(C`name\*(C'\fR in \f(CW\*(C`gv_fetchsv\*(C'\fR, and always skipped
+with \f(CW\*(C`gv_fetchsv_nomg\*(C'\fR. Including \f(CW\*(C`GV_NO_SVGMAGIC\*(C'\fR in the \f(CW\*(C`flags\*(C'\fR parameter
+to \f(CW\*(C`gv_fetchsv\*(C'\fR makes it behave identically to \f(CW\*(C`gv_fetchsv_nomg\*(C'\fR.
+.RS 4
+.Sp
+.Vb 9
+\& GV * gv_fetchpv (const char *nambeg, I32 flags,
+\& const svtype sv_type)
+\& GV * gv_fetchpvn (const char * nambeg, STRLEN full_len,
+\& I32 flags, const svtype sv_type)
+\& GV * gv_fetchpvn_flags(const char *name, STRLEN len, I32 flags,
+\& const svtype sv_type)
+\& GV * gv_fetchpvs ("name", I32 flags, const svtype sv_type)
+\& GV * gv_fetchsv (SV *name, I32 flags, const svtype sv_type)
+\& GV * gv_fetchsv_nomg (SV *name, I32 flags, const svtype sv_type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """GvHV""" 4
+.el .IP \f(CWGvHV\fR 4
+.IX Xref "GvHV"
+.IX Item "GvHV"
+Return the HV from the GV.
+.RS 4
+.Sp
+.Vb 1
+\& HV* GvHV(GV* gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_init""" 4
+.el .IP \f(CWgv_init\fR 4
+.IX Xref "gv_init"
+.IX Item "gv_init"
+The old form of \f(CWgv_init_pvn()\fR. It does not work with UTF\-8 strings, as it
+has no flags parameter. If the \f(CW\*(C`multi\*(C'\fR parameter is set, the
+\&\f(CW\*(C`GV_ADDMULTI\*(C'\fR flag will be passed to \f(CWgv_init_pvn()\fR.
+.RS 4
+.Sp
+.Vb 2
+\& void gv_init(GV *gv, HV *stash, const char *name, STRLEN len,
+\& int multi)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_init_pv""" 4
+.el .IP \f(CWgv_init_pv\fR 4
+.IX Xref "gv_init_pv"
+.IX Item "gv_init_pv"
+Same as \f(CWgv_init_pvn()\fR, but takes a nul-terminated string for the name
+instead of separate char * and length parameters.
+.RS 4
+.Sp
+.Vb 1
+\& void gv_init_pv(GV *gv, HV *stash, const char *name, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_init_pvn""" 4
+.el .IP \f(CWgv_init_pvn\fR 4
+.IX Xref "gv_init_pvn"
+.IX Item "gv_init_pvn"
+Converts a scalar into a typeglob. This is an incoercible typeglob;
+assigning a reference to it will assign to one of its slots, instead of
+overwriting it as happens with typeglobs created by \f(CW\*(C`SvSetSV\*(C'\fR. Converting
+any scalar that is \f(CWSvOK()\fR may produce unpredictable results and is reserved
+for perl's internal use.
+.Sp
+\&\f(CW\*(C`gv\*(C'\fR is the scalar to be converted.
+.Sp
+\&\f(CW\*(C`stash\*(C'\fR is the parent stash/package, if any.
+.Sp
+\&\f(CW\*(C`name\*(C'\fR and \f(CW\*(C`len\*(C'\fR give the name. The name must be unqualified;
+that is, it must not include the package name. If \f(CW\*(C`gv\*(C'\fR is a
+stash element, it is the caller's responsibility to ensure that the name
+passed to this function matches the name of the element. If it does not
+match, perl's internal bookkeeping will get out of sync.
+.Sp
+\&\f(CW\*(C`flags\*(C'\fR can be set to \f(CW\*(C`SVf_UTF8\*(C'\fR if \f(CW\*(C`name\*(C'\fR is a UTF\-8 string, or
+the return value of SvUTF8(sv). It can also take the
+\&\f(CW\*(C`GV_ADDMULTI\*(C'\fR flag, which means to pretend that the GV has been
+seen before (i.e., suppress "Used once" warnings).
+.RS 4
+.Sp
+.Vb 2
+\& void gv_init_pvn(GV *gv, HV *stash, const char *name, STRLEN len,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_init_sv""" 4
+.el .IP \f(CWgv_init_sv\fR 4
+.IX Xref "gv_init_sv"
+.IX Item "gv_init_sv"
+Same as \f(CWgv_init_pvn()\fR, but takes an SV * for the name instead of separate
+char * and length parameters. \f(CW\*(C`flags\*(C'\fR is currently unused.
+.RS 4
+.Sp
+.Vb 1
+\& void gv_init_sv(GV *gv, HV *stash, SV *namesv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_name_set""" 4
+.el .IP \f(CWgv_name_set\fR 4
+.IX Xref "gv_name_set"
+.IX Item "gv_name_set"
+Set the name for GV \f(CW\*(C`gv\*(C'\fR to \f(CW\*(C`name\*(C'\fR which is \f(CW\*(C`len\*(C'\fR bytes long. Thus it may
+contain embedded NUL characters.
+.Sp
+If \f(CW\*(C`flags\*(C'\fR contains \f(CW\*(C`SVf_UTF8\*(C'\fR, the name is treated as being encoded in
+UTF\-8; otherwise not.
+.RS 4
+.Sp
+.Vb 1
+\& void gv_name_set(GV *gv, const char *name, U32 len, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_stashpv""" 4
+.el .IP \f(CWgv_stashpv\fR 4
+.IX Xref "gv_stashpv"
+.IX Item "gv_stashpv"
+Returns a pointer to the stash for a specified package. Uses \f(CW\*(C`strlen\*(C'\fR to
+determine the length of \f(CW\*(C`name\*(C'\fR, then calls \f(CWgv_stashpvn()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& HV * gv_stashpv(const char *name, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_stashpvn""" 4
+.el .IP \f(CWgv_stashpvn\fR 4
+.IX Xref "gv_stashpvn"
+.IX Item "gv_stashpvn"
+Returns a pointer to the stash for a specified package. The \f(CW\*(C`namelen\*(C'\fR
+parameter indicates the length of the \f(CW\*(C`name\*(C'\fR, in bytes. \f(CW\*(C`flags\*(C'\fR is passed
+to \f(CWgv_fetchpvn_flags()\fR, so if set to \f(CW\*(C`GV_ADD\*(C'\fR then the package will be
+created if it does not already exist. If the package does not exist and
+\&\f(CW\*(C`flags\*(C'\fR is 0 (or any other setting that does not create packages) then \f(CW\*(C`NULL\*(C'\fR
+is returned.
+.Sp
+Flags may be one of:
+.Sp
+.Vb 7
+\& GV_ADD Create and initialize the package if doesn\*(Aqt
+\& already exist
+\& GV_NOADD_NOINIT Don\*(Aqt create the package,
+\& GV_ADDMG GV_ADD iff the GV is magical
+\& GV_NOINIT GV_ADD, but don\*(Aqt initialize
+\& GV_NOEXPAND Don\*(Aqt expand SvOK() entries to PVGV
+\& SVf_UTF8 The name is in UTF\-8
+.Ve
+.Sp
+The most important of which are probably \f(CW\*(C`GV_ADD\*(C'\fR and \f(CW\*(C`SVf_UTF8\*(C'\fR.
+.Sp
+Note, use of \f(CW\*(C`gv_stashsv\*(C'\fR instead of \f(CW\*(C`gv_stashpvn\*(C'\fR where possible is strongly
+recommended for performance reasons.
+.RS 4
+.Sp
+.Vb 1
+\& HV * gv_stashpvn(const char *name, U32 namelen, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_stashpvs""" 4
+.el .IP \f(CWgv_stashpvs\fR 4
+.IX Xref "gv_stashpvs"
+.IX Item "gv_stashpvs"
+Like \f(CW\*(C`gv_stashpvn\*(C'\fR, but takes a literal string instead of a
+string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& HV* gv_stashpvs("name", I32 create)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """gv_stashsv""" 4
+.el .IP \f(CWgv_stashsv\fR 4
+.IX Xref "gv_stashsv"
+.IX Item "gv_stashsv"
+Returns a pointer to the stash for a specified package. See
+\&\f(CW"gv_stashpvn"\fR.
+.Sp
+Note this interface is strongly preferred over \f(CW\*(C`gv_stashpvn\*(C'\fR for performance
+reasons.
+.RS 4
+.Sp
+.Vb 1
+\& HV * gv_stashsv(SV *sv, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """GvSV""" 4
+.el .IP \f(CWGvSV\fR 4
+.IX Xref "GvSV"
+.IX Item "GvSV"
+Return the SV from the GV.
+.Sp
+Prior to Perl v5.9.3, this would add a scalar if none existed. Nowadays, use
+\&\f(CW"GvSVn"\fR for that, or compile perl with \f(CW\*(C`\-DPERL_CREATE_GVSV\*(C'\fR. See
+perl5100delta.
+.RS 4
+.Sp
+.Vb 1
+\& SV* GvSV(GV* gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """GvSVn""" 4
+.el .IP \f(CWGvSVn\fR 4
+.IX Xref "GvSVn"
+.IX Item "GvSVn"
+Like \f(CW"GvSV"\fR, but creates an empty scalar if none already exists.
+.RS 4
+.Sp
+.Vb 1
+\& SV* GvSVn(GV* gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newGVgen""" 4
+.el .IP \f(CWnewGVgen\fR 4
+.IX Item "newGVgen"
+.PD 0
+.ie n .IP """newGVgen_flags""" 4
+.el .IP \f(CWnewGVgen_flags\fR 4
+.IX Xref "newGVgen newGVgen_flags"
+.IX Item "newGVgen_flags"
+.PD
+Create a new, guaranteed to be unique, GV in the package given by the
+NUL-terminated C language string \f(CW\*(C`pack\*(C'\fR, and return a pointer to it.
+.Sp
+For \f(CW\*(C`newGVgen\*(C'\fR or if \f(CW\*(C`flags\*(C'\fR in \f(CW\*(C`newGVgen_flags\*(C'\fR is 0, \f(CW\*(C`pack\*(C'\fR is to be
+considered to be encoded in Latin\-1. The only other legal \f(CW\*(C`flags\*(C'\fR value is
+\&\f(CW\*(C`SVf_UTF8\*(C'\fR, which indicates \f(CW\*(C`pack\*(C'\fR is to be considered to be encoded in
+UTF\-8.
+.RS 4
+.Sp
+.Vb 2
+\& GV * newGVgen (const char *pack)
+\& GV * newGVgen_flags(const char *pack, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_curstash""" 4
+.el .IP \f(CWPL_curstash\fR 4
+.IX Xref "PL_curstash"
+.IX Item "PL_curstash"
+The stash for the package code will be compiled into.
+.Sp
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+.RS 4
+.Sp
+.Vb 1
+\& HV* PL_curstash
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_defgv""" 4
+.el .IP \f(CWPL_defgv\fR 4
+.IX Xref "PL_defgv"
+.IX Item "PL_defgv"
+The GV representing \f(CW*_\fR. Useful for access to \f(CW$_\fR.
+.Sp
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+.RS 4
+.Sp
+.Vb 1
+\& GV * PL_defgv
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_defoutgv""" 4
+.el .IP \f(CWPL_defoutgv\fR 4
+.IX Xref "PL_defoutgv"
+.IX Item "PL_defoutgv"
+See \f(CW"setdefout"\fR.
+.ie n .IP """PL_defstash""" 4
+.el .IP \f(CWPL_defstash\fR 4
+.IX Item "PL_defstash"
+Described in perlguts.
+.ie n .IP """save_gp""" 4
+.el .IP \f(CWsave_gp\fR 4
+.IX Xref "save_gp"
+.IX Item "save_gp"
+Saves the current GP of gv on the save stack to be restored on scope exit.
+.Sp
+If \f(CW\*(C`empty\*(C'\fR is true, replace the GP with a new GP.
+.Sp
+If \f(CW\*(C`empty\*(C'\fR is false, mark \f(CW\*(C`gv\*(C'\fR with \f(CW\*(C`GVf_INTRO\*(C'\fR so the next reference
+assigned is localized, which is how \f(CW\*(C`\ local\ *foo\ =\ $someref;\ \*(C'\fR works.
+.RS 4
+.Sp
+.Vb 1
+\& void save_gp(GV *gv, I32 empty)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """setdefout""" 4
+.el .IP \f(CWsetdefout\fR 4
+.IX Xref "setdefout"
+.IX Item "setdefout"
+Sets \f(CW\*(C`PL_defoutgv\*(C'\fR, the default file handle for output, to the passed in
+typeglob. As \f(CW\*(C`PL_defoutgv\*(C'\fR "owns" a reference on its typeglob, the reference
+count of the passed in typeglob is increased by one, and the reference count
+of the typeglob that \f(CW\*(C`PL_defoutgv\*(C'\fR points to is decreased by one.
+.RS 4
+.Sp
+.Vb 1
+\& void setdefout(GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Hook manipulation"
+.IX Header "Hook manipulation"
+These functions provide convenient and thread-safe means of manipulating
+hook variables.
+.ie n .IP """rcpv_copy""" 4
+.el .IP \f(CWrcpv_copy\fR 4
+.IX Xref "rcpv_copy"
+.IX Item "rcpv_copy"
+refcount increment a shared memory refcounted string, and when
+the refcount goes to 0 free it using \fBPerlMemShared_free()\fR.
+.Sp
+It is the callers responsibility to ensure that the pv is the
+result of a \fBrcpv_new()\fR call.
+.Sp
+Returns the same pointer that was passed in.
+.Sp
+.Vb 1
+\& new = rcpv_copy(pv);
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& char * rcpv_copy(char * const pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """rcpv_free""" 4
+.el .IP \f(CWrcpv_free\fR 4
+.IX Xref "rcpv_free"
+.IX Item "rcpv_free"
+refcount decrement a shared memory refcounted string, and when
+the refcount goes to 0 free it using \fBperlmemshared_free()\fR.
+.Sp
+it is the callers responsibility to ensure that the pv is the
+result of a \fBrcpv_new()\fR call.
+.Sp
+Always returns NULL so it can be used like this:
+.Sp
+.Vb 1
+\& thing = rcpv_free(thing);
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& char * rcpv_free(char * const pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """rcpv_new""" 4
+.el .IP \f(CWrcpv_new\fR 4
+.IX Xref "rcpv_new"
+.IX Item "rcpv_new"
+Create a new shared memory refcounted string with the requested size, and
+with the requested initialization and a refcount of 1. The actual space
+allocated will be 1 byte more than requested and \fBrcpv_new()\fR will ensure that
+the extra byte is a null regardless of any flags settings.
+.Sp
+If the RCPVf_NO_COPY flag is set then the pv argument will be
+ignored, otherwise the contents of the pv pointer will be copied into
+the new buffer or if it is NULL the function will do nothing and return NULL.
+.Sp
+If the RCPVf_USE_STRLEN flag is set then the len argument is ignored and
+recomputed using \f(CWstrlen(pv)\fR. It is an error to combine RCPVf_USE_STRLEN
+and RCPVf_NO_COPY at the same time.
+.Sp
+Under DEBUGGING \fBrcpv_new()\fR will \fBassert()\fR if it is asked to create a 0 length
+shared string unless the RCPVf_ALLOW_EMPTY flag is set.
+.Sp
+The return value from the function is suitable for passing into \fBrcpv_copy()\fR and
+\&\fBrcpv_free()\fR. To access the RCPV * from the returned value use the \fBRCPVx()\fR macro.
+The 'len' member of the RCPV struct stores the allocated length (including the
+extra byte), but the \fBRCPV_LEN()\fR macro returns the requested length (not
+including the extra byte).
+.Sp
+Note that \fBrcpv_new()\fR does NOT use a hash table or anything like that to
+dedupe inputs given the same text content. Each call with a non-null pv
+parameter will produce a distinct pointer with its own refcount regardless of
+the input content.
+.RS 4
+.Sp
+.Vb 1
+\& char * rcpv_new(const char * const pv, STRLEN len, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """wrap_op_checker""" 4
+.el .IP \f(CWwrap_op_checker\fR 4
+.IX Xref "wrap_op_checker"
+.IX Item "wrap_op_checker"
+Puts a C function into the chain of check functions for a specified op
+type. This is the preferred way to manipulate the "PL_check" array.
+\&\f(CW\*(C`opcode\*(C'\fR specifies which type of op is to be affected. \f(CW\*(C`new_checker\*(C'\fR
+is a pointer to the C function that is to be added to that opcode's
+check chain, and \f(CW\*(C`old_checker_p\*(C'\fR points to the storage location where a
+pointer to the next function in the chain will be stored. The value of
+\&\f(CW\*(C`new_checker\*(C'\fR is written into the "PL_check" array, while the value
+previously stored there is written to \f(CW*old_checker_p\fR.
+.Sp
+"PL_check" is global to an entire process, and a module wishing to
+hook op checking may find itself invoked more than once per process,
+typically in different threads. To handle that situation, this function
+is idempotent. The location \f(CW*old_checker_p\fR must initially (once
+per process) contain a null pointer. A C variable of static duration
+(declared at file scope, typically also marked \f(CW\*(C`static\*(C'\fR to give
+it internal linkage) will be implicitly initialised appropriately,
+if it does not have an explicit initialiser. This function will only
+actually modify the check chain if it finds \f(CW*old_checker_p\fR to be null.
+This function is also thread safe on the small scale. It uses appropriate
+locking to avoid race conditions in accessing "PL_check".
+.Sp
+When this function is called, the function referenced by \f(CW\*(C`new_checker\*(C'\fR
+must be ready to be called, except for \f(CW*old_checker_p\fR being unfilled.
+In a threading situation, \f(CW\*(C`new_checker\*(C'\fR may be called immediately,
+even before this function has returned. \f(CW*old_checker_p\fR will always
+be appropriately set before \f(CW\*(C`new_checker\*(C'\fR is called. If \f(CW\*(C`new_checker\*(C'\fR
+decides not to do anything special with an op that it is given (which
+is the usual case for most uses of op check hooking), it must chain the
+check function referenced by \f(CW*old_checker_p\fR.
+.Sp
+Taken all together, XS code to hook an op checker should typically look
+something like this:
+.Sp
+.Vb 9
+\& static Perl_check_t nxck_frob;
+\& static OP *myck_frob(pTHX_ OP *op) {
+\& ...
+\& op = nxck_frob(aTHX_ op);
+\& ...
+\& return op;
+\& }
+\& BOOT:
+\& wrap_op_checker(OP_FROB, myck_frob, &nxck_frob);
+.Ve
+.Sp
+If you want to influence compilation of calls to a specific subroutine,
+then use "cv_set_call_checker_flags" rather than hooking checking of
+all \f(CW\*(C`entersub\*(C'\fR ops.
+.RS 4
+.Sp
+.Vb 2
+\& void wrap_op_checker(Optype opcode, Perl_check_t new_checker,
+\& Perl_check_t *old_checker_p)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "HV Handling"
+.IX Xref "HV_ITERNEXT_WANTPLACEHOLDERS HV_NAME_SETALL HvNAMELEN_get"
+.IX Header "HV Handling"
+A HV structure represents a Perl hash. It consists mainly of an array
+of pointers, each of which points to a linked list of HE structures. The
+array is indexed by the hash function of the key, so each linked list
+represents all the hash entries with the same hash value. Each HE contains
+a pointer to the actual value, plus a pointer to a HEK structure which
+holds the key and hash value.
+.ie n .IP """get_hv""" 4
+.el .IP \f(CWget_hv\fR 4
+.IX Xref "get_hv"
+.IX Item "get_hv"
+Returns the HV of the specified Perl hash. \f(CW\*(C`flags\*(C'\fR are passed to
+\&\f(CW\*(C`gv_fetchpv\*(C'\fR. If \f(CW\*(C`GV_ADD\*(C'\fR is set and the
+Perl variable does not exist then it will be created. If \f(CW\*(C`flags\*(C'\fR is zero
+(ignoring \f(CW\*(C`SVf_UTF8\*(C'\fR) and the variable does not exist then \f(CW\*(C`NULL\*(C'\fR is
+returned.
+.Sp
+NOTE: the \f(CWperl_get_hv()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& HV * get_hv(const char *name, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HE""" 4
+.el .IP \f(CWHE\fR 4
+.IX Item "HE"
+Described in perlguts.
+.ie n .IP """HEf_SVKEY""" 4
+.el .IP \f(CWHEf_SVKEY\fR 4
+.IX Xref "HEf_SVKEY"
+.IX Item "HEf_SVKEY"
+This flag, used in the length slot of hash entries and magic structures,
+specifies the structure contains an \f(CW\*(C`SV*\*(C'\fR pointer where a \f(CW\*(C`char*\*(C'\fR pointer
+is to be expected. (For information only\-\-not to be used).
+.ie n .IP """HeHASH""" 4
+.el .IP \f(CWHeHASH\fR 4
+.IX Xref "HeHASH"
+.IX Item "HeHASH"
+Returns the computed hash stored in the hash entry.
+.RS 4
+.Sp
+.Vb 1
+\& U32 HeHASH(HE* he)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HeKEY""" 4
+.el .IP \f(CWHeKEY\fR 4
+.IX Xref "HeKEY"
+.IX Item "HeKEY"
+Returns the actual pointer stored in the key slot of the hash entry. The
+pointer may be either \f(CW\*(C`char*\*(C'\fR or \f(CW\*(C`SV*\*(C'\fR, depending on the value of
+\&\f(CWHeKLEN()\fR. Can be assigned to. The \f(CWHePV()\fR or \f(CWHeSVKEY()\fR macros are
+usually preferable for finding the value of a key.
+.RS 4
+.Sp
+.Vb 1
+\& void* HeKEY(HE* he)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HeKLEN""" 4
+.el .IP \f(CWHeKLEN\fR 4
+.IX Xref "HeKLEN"
+.IX Item "HeKLEN"
+If this is negative, and amounts to \f(CW\*(C`HEf_SVKEY\*(C'\fR, it indicates the entry
+holds an \f(CW\*(C`SV*\*(C'\fR key. Otherwise, holds the actual length of the key. Can
+be assigned to. The \f(CWHePV()\fR macro is usually preferable for finding key
+lengths.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN HeKLEN(HE* he)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HePV""" 4
+.el .IP \f(CWHePV\fR 4
+.IX Xref "HePV"
+.IX Item "HePV"
+Returns the key slot of the hash entry as a \f(CW\*(C`char*\*(C'\fR value, doing any
+necessary dereferencing of possibly \f(CW\*(C`SV*\*(C'\fR keys. The length of the string
+is placed in \f(CW\*(C`len\*(C'\fR (this is a macro, so do \fInot\fR use \f(CW&len\fR). If you do
+not care about what the length of the key is, you may use the global
+variable \f(CW\*(C`PL_na\*(C'\fR, though this is rather less efficient than using a local
+variable. Remember though, that hash keys in perl are free to contain
+embedded nulls, so using \f(CWstrlen()\fR or similar is not a good way to find
+the length of hash keys. This is very similar to the \f(CWSvPV()\fR macro
+described elsewhere in this document. See also \f(CW"HeUTF8"\fR.
+.Sp
+If you are using \f(CW\*(C`HePV\*(C'\fR to get values to pass to \f(CWnewSVpvn()\fR to create a
+new SV, you should consider using \f(CW\*(C`newSVhek(HeKEY_hek(he))\*(C'\fR as it is more
+efficient.
+.RS 4
+.Sp
+.Vb 1
+\& char* HePV(HE* he, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HeSVKEY""" 4
+.el .IP \f(CWHeSVKEY\fR 4
+.IX Xref "HeSVKEY"
+.IX Item "HeSVKEY"
+Returns the key as an \f(CW\*(C`SV*\*(C'\fR, or \f(CW\*(C`NULL\*(C'\fR if the hash entry does not
+contain an \f(CW\*(C`SV*\*(C'\fR key.
+.RS 4
+.Sp
+.Vb 1
+\& SV* HeSVKEY(HE* he)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HeSVKEY_force""" 4
+.el .IP \f(CWHeSVKEY_force\fR 4
+.IX Xref "HeSVKEY_force"
+.IX Item "HeSVKEY_force"
+Returns the key as an \f(CW\*(C`SV*\*(C'\fR. Will create and return a temporary mortal
+\&\f(CW\*(C`SV*\*(C'\fR if the hash entry contains only a \f(CW\*(C`char*\*(C'\fR key.
+.RS 4
+.Sp
+.Vb 1
+\& SV* HeSVKEY_force(HE* he)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HeSVKEY_set""" 4
+.el .IP \f(CWHeSVKEY_set\fR 4
+.IX Xref "HeSVKEY_set"
+.IX Item "HeSVKEY_set"
+Sets the key to a given \f(CW\*(C`SV*\*(C'\fR, taking care to set the appropriate flags to
+indicate the presence of an \f(CW\*(C`SV*\*(C'\fR key, and returns the same
+\&\f(CW\*(C`SV*\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV* HeSVKEY_set(HE* he, SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HeUTF8""" 4
+.el .IP \f(CWHeUTF8\fR 4
+.IX Xref "HeUTF8"
+.IX Item "HeUTF8"
+Returns whether the \f(CW\*(C`char *\*(C'\fR value returned by \f(CW\*(C`HePV\*(C'\fR is encoded in UTF\-8,
+doing any necessary dereferencing of possibly \f(CW\*(C`SV*\*(C'\fR keys. The value returned
+will be 0 or non\-0, not necessarily 1 (or even a value with any low bits set),
+so \fBdo not\fR blindly assign this to a \f(CW\*(C`bool\*(C'\fR variable, as \f(CW\*(C`bool\*(C'\fR may be a
+typedef for \f(CW\*(C`char\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& U32 HeUTF8(HE* he)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HeVAL""" 4
+.el .IP \f(CWHeVAL\fR 4
+.IX Xref "HeVAL"
+.IX Item "HeVAL"
+Returns the value slot (type \f(CW\*(C`SV*\*(C'\fR)
+stored in the hash entry. Can be assigned
+to.
+.Sp
+.Vb 2
+\& SV *foo= HeVAL(hv);
+\& HeVAL(hv)= sv;
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& SV* HeVAL(HE* he)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HV""" 4
+.el .IP \f(CWHV\fR 4
+.IX Item "HV"
+Described in perlguts.
+.ie n .IP """hv_assert""" 4
+.el .IP \f(CWhv_assert\fR 4
+.IX Xref "hv_assert"
+.IX Item "hv_assert"
+Check that a hash is in an internally consistent state.
+.Sp
+NOTE: \f(CW\*(C`hv_assert\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_hv_assert\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 1
+\& void Perl_hv_assert(pTHX_ HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_bucket_ratio""" 4
+.el .IP \f(CWhv_bucket_ratio\fR 4
+.IX Xref "hv_bucket_ratio"
+.IX Item "hv_bucket_ratio"
+NOTE: \f(CW\*(C`hv_bucket_ratio\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+If the hash is tied dispatches through to the SCALAR tied method,
+otherwise if the hash contains no keys returns 0, otherwise returns
+a mortal sv containing a string specifying the number of used buckets,
+followed by a slash, followed by the number of available buckets.
+.Sp
+This function is expensive, it must scan all of the buckets
+to determine which are used, and the count is NOT cached.
+In a large hash this could be a lot of buckets.
+.RS 4
+.Sp
+.Vb 1
+\& SV * hv_bucket_ratio(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_clear""" 4
+.el .IP \f(CWhv_clear\fR 4
+.IX Xref "hv_clear"
+.IX Item "hv_clear"
+Frees all the elements of a hash, leaving it empty.
+The XS equivalent of \f(CW\*(C`%hash = ()\*(C'\fR. See also "hv_undef".
+.Sp
+See "av_clear" for a note about the hash possibly being invalid on
+return.
+.RS 4
+.Sp
+.Vb 1
+\& void hv_clear(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_clear_placeholders""" 4
+.el .IP \f(CWhv_clear_placeholders\fR 4
+.IX Xref "hv_clear_placeholders"
+.IX Item "hv_clear_placeholders"
+Clears any placeholders from a hash. If a restricted hash has any of its keys
+marked as readonly and the key is subsequently deleted, the key is not actually
+deleted but is marked by assigning it a value of \f(CW&PL_sv_placeholder\fR. This tags
+it so it will be ignored by future operations such as iterating over the hash,
+but will still allow the hash to have a value reassigned to the key at some
+future point. This function clears any such placeholder keys from the hash.
+See \f(CWHash::Util::lock_keys()\fR for an example of its
+use.
+.RS 4
+.Sp
+.Vb 1
+\& void hv_clear_placeholders(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_copy_hints_hv""" 4
+.el .IP \f(CWhv_copy_hints_hv\fR 4
+.IX Xref "hv_copy_hints_hv"
+.IX Item "hv_copy_hints_hv"
+A specialised version of "newHVhv" for copying \f(CW\*(C`%^H\*(C'\fR. \f(CW\*(C`ohv\*(C'\fR must be
+a pointer to a hash (which may have \f(CW\*(C`%^H\*(C'\fR magic, but should be generally
+non-magical), or \f(CW\*(C`NULL\*(C'\fR (interpreted as an empty hash). The content
+of \f(CW\*(C`ohv\*(C'\fR is copied to a new hash, which has the \f(CW\*(C`%^H\*(C'\fR\-specific magic
+added to it. A pointer to the new hash is returned.
+.RS 4
+.Sp
+.Vb 1
+\& HV * hv_copy_hints_hv(HV * const ohv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_delete""" 4
+.el .IP \f(CWhv_delete\fR 4
+.IX Xref "hv_delete"
+.IX Item "hv_delete"
+Deletes a key/value pair in the hash. The value's SV is removed from
+the hash, made mortal, and returned to the caller. The absolute
+value of \f(CW\*(C`klen\*(C'\fR is the length of the key. If \f(CW\*(C`klen\*(C'\fR is negative the
+key is assumed to be in UTF\-8\-encoded Unicode. The \f(CW\*(C`flags\*(C'\fR value
+will normally be zero; if set to \f(CW\*(C`G_DISCARD\*(C'\fR then \f(CW\*(C`NULL\*(C'\fR will be returned.
+\&\f(CW\*(C`NULL\*(C'\fR will also be returned if the key is not found.
+.RS 4
+.Sp
+.Vb 1
+\& SV * hv_delete(HV *hv, const char *key, I32 klen, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_delete_ent""" 4
+.el .IP \f(CWhv_delete_ent\fR 4
+.IX Xref "hv_delete_ent"
+.IX Item "hv_delete_ent"
+Deletes a key/value pair in the hash. The value SV is removed from the hash,
+made mortal, and returned to the caller. The \f(CW\*(C`flags\*(C'\fR value will normally be
+zero; if set to \f(CW\*(C`G_DISCARD\*(C'\fR then \f(CW\*(C`NULL\*(C'\fR will be returned. \f(CW\*(C`NULL\*(C'\fR will also
+be returned if the key is not found. \f(CW\*(C`hash\*(C'\fR can be a valid precomputed hash
+value, or 0 to ask for it to be computed.
+.RS 4
+.Sp
+.Vb 1
+\& SV * hv_delete_ent(HV *hv, SV *keysv, I32 flags, U32 hash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HvENAME""" 4
+.el .IP \f(CWHvENAME\fR 4
+.IX Xref "HvENAME"
+.IX Item "HvENAME"
+Returns the effective name of a stash, or NULL if there is none. The
+effective name represents a location in the symbol table where this stash
+resides. It is updated automatically when packages are aliased or deleted.
+A stash that is no longer in the symbol table has no effective name. This
+name is preferable to \f(CW\*(C`HvNAME\*(C'\fR for use in MRO linearisations and isa
+caches.
+.RS 4
+.Sp
+.Vb 1
+\& char* HvENAME(HV* stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HvENAMELEN""" 4
+.el .IP \f(CWHvENAMELEN\fR 4
+.IX Xref "HvENAMELEN"
+.IX Item "HvENAMELEN"
+Returns the length of the stash's effective name.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN HvENAMELEN(HV *stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HvENAMEUTF8""" 4
+.el .IP \f(CWHvENAMEUTF8\fR 4
+.IX Xref "HvENAMEUTF8"
+.IX Item "HvENAMEUTF8"
+Returns true if the effective name is in UTF\-8 encoding.
+.RS 4
+.Sp
+.Vb 1
+\& unsigned char HvENAMEUTF8(HV *stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_exists""" 4
+.el .IP \f(CWhv_exists\fR 4
+.IX Xref "hv_exists"
+.IX Item "hv_exists"
+Returns a boolean indicating whether the specified hash key exists. The
+absolute value of \f(CW\*(C`klen\*(C'\fR is the length of the key. If \f(CW\*(C`klen\*(C'\fR is
+negative the key is assumed to be in UTF\-8\-encoded Unicode.
+.RS 4
+.Sp
+.Vb 1
+\& bool hv_exists(HV *hv, const char *key, I32 klen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_exists_ent""" 4
+.el .IP \f(CWhv_exists_ent\fR 4
+.IX Xref "hv_exists_ent"
+.IX Item "hv_exists_ent"
+Returns a boolean indicating whether
+the specified hash key exists. \f(CW\*(C`hash\*(C'\fR
+can be a valid precomputed hash value, or 0 to ask for it to be
+computed.
+.RS 4
+.Sp
+.Vb 1
+\& bool hv_exists_ent(HV *hv, SV *keysv, U32 hash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_fetch""" 4
+.el .IP \f(CWhv_fetch\fR 4
+.IX Xref "hv_fetch"
+.IX Item "hv_fetch"
+Returns the SV which corresponds to the specified key in the hash.
+The absolute value of \f(CW\*(C`klen\*(C'\fR is the length of the key. If \f(CW\*(C`klen\*(C'\fR is
+negative the key is assumed to be in UTF\-8\-encoded Unicode. If
+\&\f(CW\*(C`lval\*(C'\fR is set then the fetch will be part of a store. This means that if
+there is no value in the hash associated with the given key, then one is
+created and a pointer to it is returned. The \f(CW\*(C`SV*\*(C'\fR it points to can be
+assigned to. But always check that the
+return value is non-null before dereferencing it to an \f(CW\*(C`SV*\*(C'\fR.
+.Sp
+See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for more
+information on how to use this function on tied hashes.
+.RS 4
+.Sp
+.Vb 1
+\& SV ** hv_fetch(HV *hv, const char *key, I32 klen, I32 lval)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_fetch_ent""" 4
+.el .IP \f(CWhv_fetch_ent\fR 4
+.IX Xref "hv_fetch_ent"
+.IX Item "hv_fetch_ent"
+Returns the hash entry which corresponds to the specified key in the hash.
+\&\f(CW\*(C`hash\*(C'\fR must be a valid precomputed hash number for the given \f(CW\*(C`key\*(C'\fR, or 0
+if you want the function to compute it. IF \f(CW\*(C`lval\*(C'\fR is set then the fetch
+will be part of a store. Make sure the return value is non-null before
+accessing it. The return value when \f(CW\*(C`hv\*(C'\fR is a tied hash is a pointer to a
+static location, so be sure to make a copy of the structure if you need to
+store it somewhere.
+.Sp
+See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for more
+information on how to use this function on tied hashes.
+.RS 4
+.Sp
+.Vb 1
+\& HE * hv_fetch_ent(HV *hv, SV *keysv, I32 lval, U32 hash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_fetchs""" 4
+.el .IP \f(CWhv_fetchs\fR 4
+.IX Xref "hv_fetchs"
+.IX Item "hv_fetchs"
+Like \f(CW\*(C`hv_fetch\*(C'\fR, but takes a literal string instead of a
+string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& SV** hv_fetchs(HV* tb, "key", I32 lval)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HvFILL""" 4
+.el .IP \f(CWHvFILL\fR 4
+.IX Xref "HvFILL"
+.IX Item "HvFILL"
+Returns the number of hash buckets that happen to be in use.
+.Sp
+As of perl 5.25 this function is used only for debugging
+purposes, and the number of used hash buckets is not
+in any way cached, thus this function can be costly
+to execute as it must iterate over all the buckets in the
+hash.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN HvFILL(HV *const hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HvHasAUX""" 4
+.el .IP \f(CWHvHasAUX\fR 4
+.IX Xref "HvHasAUX"
+.IX Item "HvHasAUX"
+Returns true if the HV has a \f(CW\*(C`struct xpvhv_aux\*(C'\fR extension. Use this to check
+whether it is valid to call \f(CWHvAUX()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool HvHasAUX(HV *const hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_iterinit""" 4
+.el .IP \f(CWhv_iterinit\fR 4
+.IX Xref "hv_iterinit"
+.IX Item "hv_iterinit"
+Prepares a starting point to traverse a hash table. Returns the number of
+keys in the hash, including placeholders (i.e. the same as \f(CWHvTOTALKEYS(hv)\fR).
+The return value is currently only meaningful for hashes without tie magic.
+.Sp
+NOTE: Before version 5.004_65, \f(CW\*(C`hv_iterinit\*(C'\fR used to return the number of
+hash buckets that happen to be in use. If you still need that esoteric
+value, you can get it through the macro \f(CWHvFILL(hv)\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 hv_iterinit(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_iterkey""" 4
+.el .IP \f(CWhv_iterkey\fR 4
+.IX Xref "hv_iterkey"
+.IX Item "hv_iterkey"
+Returns the key from the current position of the hash iterator. See
+\&\f(CW"hv_iterinit"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& char * hv_iterkey(HE *entry, I32 *retlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_iterkeysv""" 4
+.el .IP \f(CWhv_iterkeysv\fR 4
+.IX Xref "hv_iterkeysv"
+.IX Item "hv_iterkeysv"
+Returns the key as an \f(CW\*(C`SV*\*(C'\fR from the current position of the hash
+iterator. The return value will always be a mortal copy of the key. Also
+see \f(CW"hv_iterinit"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * hv_iterkeysv(HE *entry)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_iternext""" 4
+.el .IP \f(CWhv_iternext\fR 4
+.IX Xref "hv_iternext"
+.IX Item "hv_iternext"
+Returns entries from a hash iterator. See \f(CW"hv_iterinit"\fR.
+.Sp
+You may call \f(CW\*(C`hv_delete\*(C'\fR or \f(CW\*(C`hv_delete_ent\*(C'\fR on the hash entry that the
+iterator currently points to, without losing your place or invalidating your
+iterator. Note that in this case the current entry is deleted from the hash
+with your iterator holding the last reference to it. Your iterator is flagged
+to free the entry on the next call to \f(CW\*(C`hv_iternext\*(C'\fR, so you must not discard
+your iterator immediately else the entry will leak \- call \f(CW\*(C`hv_iternext\*(C'\fR to
+trigger the resource deallocation.
+.RS 4
+.Sp
+.Vb 1
+\& HE * hv_iternext(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_iternext_flags""" 4
+.el .IP \f(CWhv_iternext_flags\fR 4
+.IX Xref "hv_iternext_flags"
+.IX Item "hv_iternext_flags"
+NOTE: \f(CW\*(C`hv_iternext_flags\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Returns entries from a hash iterator. See \f(CW"hv_iterinit"\fR and
+\&\f(CW"hv_iternext"\fR.
+The \f(CW\*(C`flags\*(C'\fR value will normally be zero; if \f(CW\*(C`HV_ITERNEXT_WANTPLACEHOLDERS\*(C'\fR is
+set the placeholders keys (for restricted hashes) will be returned in addition
+to normal keys. By default placeholders are automatically skipped over.
+Currently a placeholder is implemented with a value that is
+\&\f(CW&PL_sv_placeholder\fR. Note that the implementation of placeholders and
+restricted hashes may change, and the implementation currently is
+insufficiently abstracted for any change to be tidy.
+.RS 4
+.Sp
+.Vb 1
+\& HE * hv_iternext_flags(HV *hv, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_iternextsv""" 4
+.el .IP \f(CWhv_iternextsv\fR 4
+.IX Xref "hv_iternextsv"
+.IX Item "hv_iternextsv"
+Performs an \f(CW\*(C`hv_iternext\*(C'\fR, \f(CW\*(C`hv_iterkey\*(C'\fR, and \f(CW\*(C`hv_iterval\*(C'\fR in one
+operation.
+.RS 4
+.Sp
+.Vb 1
+\& SV * hv_iternextsv(HV *hv, char **key, I32 *retlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_iterval""" 4
+.el .IP \f(CWhv_iterval\fR 4
+.IX Xref "hv_iterval"
+.IX Item "hv_iterval"
+Returns the value from the current position of the hash iterator. See
+\&\f(CW"hv_iterkey"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * hv_iterval(HV *hv, HE *entry)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_ksplit""" 4
+.el .IP \f(CWhv_ksplit\fR 4
+.IX Xref "hv_ksplit"
+.IX Item "hv_ksplit"
+Attempt to grow the hash \f(CW\*(C`hv\*(C'\fR so it has at least \f(CW\*(C`newmax\*(C'\fR buckets available.
+Perl chooses the actual number for its convenience.
+.Sp
+This is the same as doing the following in Perl code:
+.Sp
+.Vb 1
+\& keys %hv = newmax;
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& void hv_ksplit(HV *hv, IV newmax)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_magic""" 4
+.el .IP \f(CWhv_magic\fR 4
+.IX Xref "hv_magic"
+.IX Item "hv_magic"
+Adds magic to a hash. See \f(CW"sv_magic"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void hv_magic(HV *hv, GV *gv, int how)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HvNAME""" 4
+.el .IP \f(CWHvNAME\fR 4
+.IX Xref "HvNAME"
+.IX Item "HvNAME"
+Returns the package name of a stash, or \f(CW\*(C`NULL\*(C'\fR if \f(CW\*(C`stash\*(C'\fR isn't a stash.
+See \f(CW"SvSTASH"\fR, \f(CW"CvSTASH"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& char* HvNAME(HV* stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HvNAMELEN""" 4
+.el .IP \f(CWHvNAMELEN\fR 4
+.IX Xref "HvNAMELEN"
+.IX Item "HvNAMELEN"
+Returns the length of the stash's name.
+.Sp
+Disfavored forms of HvNAME and HvNAMELEN; suppress mention of them
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN HvNAMELEN(HV *stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_name_set""" 4
+.el .IP \f(CWhv_name_set\fR 4
+.IX Item "hv_name_set"
+.PD 0
+.ie n .IP """hv_name_sets""" 4
+.el .IP \f(CWhv_name_sets\fR 4
+.IX Xref "hv_name_set hv_name_sets"
+.IX Item "hv_name_sets"
+.PD
+These each set the name of stash \f(CW\*(C`hv\*(C'\fR to the specified name.
+.Sp
+They differ only in how the name is specified.
+.Sp
+In \f(CW\*(C`hv_name_sets\*(C'\fR, the name is a literal C string, enclosed in double quotes.
+.Sp
+In \f(CW\*(C`hv_name_set\*(C'\fR, \f(CW\*(C`name\*(C'\fR points to the first byte of the name, and an
+additional parameter, \f(CW\*(C`len\*(C'\fR, specifies its length in bytes. Hence, the name
+may contain embedded-NUL characters.
+.Sp
+If \f(CW\*(C`SVf_UTF8\*(C'\fR is set in \f(CW\*(C`flags\*(C'\fR, the name is treated as being in UTF\-8;
+otherwise not.
+.Sp
+If \f(CW\*(C`HV_NAME_SETALL\*(C'\fR is set in \f(CW\*(C`flags\*(C'\fR, both the name and the effective name
+are set.
+.RS 4
+.Sp
+.Vb 2
+\& void hv_name_set (HV *hv, const char *name, U32 len, U32 flags)
+\& void hv_name_sets(HV *hv, "name", U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HvNAMEUTF8""" 4
+.el .IP \f(CWHvNAMEUTF8\fR 4
+.IX Xref "HvNAMEUTF8"
+.IX Item "HvNAMEUTF8"
+Returns true if the name is in UTF\-8 encoding.
+.RS 4
+.Sp
+.Vb 1
+\& unsigned char HvNAMEUTF8(HV *stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_scalar""" 4
+.el .IP \f(CWhv_scalar\fR 4
+.IX Xref "hv_scalar"
+.IX Item "hv_scalar"
+Evaluates the hash in scalar context and returns the result.
+.Sp
+When the hash is tied dispatches through to the SCALAR method,
+otherwise returns a mortal SV containing the number of keys
+in the hash.
+.Sp
+Note, prior to 5.25 this function returned what is now
+returned by the \fBhv_bucket_ratio()\fR function.
+.RS 4
+.Sp
+.Vb 1
+\& SV * hv_scalar(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_store""" 4
+.el .IP \f(CWhv_store\fR 4
+.IX Item "hv_store"
+.PD 0
+.ie n .IP """hv_stores""" 4
+.el .IP \f(CWhv_stores\fR 4
+.IX Xref "hv_store hv_stores"
+.IX Item "hv_stores"
+.PD
+These each store SV \f(CW\*(C`val\*(C'\fR with the specified key in hash \f(CW\*(C`hv\*(C'\fR, returning NULL
+if the operation failed or if the value did not need to be actually stored
+within the hash (as in the case of tied hashes). Otherwise it can be
+dereferenced to get the original \f(CW\*(C`SV*\*(C'\fR.
+.Sp
+They differ only in how the hash key is specified.
+.Sp
+In \f(CW\*(C`hv_stores\*(C'\fR, the key is a C language string literal, enclosed in double
+quotes. It is never treated as being in UTF\-8.
+.Sp
+In \f(CW\*(C`hv_store\*(C'\fR, \f(CW\*(C`key\*(C'\fR is either NULL or points to the first byte of the string
+specifying the key, and its length in bytes is given by the absolute value of
+an additional parameter, \f(CW\*(C`klen\*(C'\fR. A NULL key indicates the key is to be
+treated as \f(CW\*(C`undef\*(C'\fR, and \f(CW\*(C`klen\*(C'\fR is ignored; otherwise the key string may
+contain embedded-NUL bytes. If \f(CW\*(C`klen\*(C'\fR is negative, the string is treated as
+being encoded in UTF\-8; otherwise not.
+.Sp
+\&\f(CW\*(C`hv_store\*(C'\fR has another extra parameter, \f(CW\*(C`hash\*(C'\fR, a precomputed hash of the key
+string, or zero if it has not been precomputed. This parameter is omitted from
+\&\f(CW\*(C`hv_stores\*(C'\fR, as it is computed automatically at compile time.
+.Sp
+If <hv> is NULL, NULL is returned and no action is taken.
+.Sp
+If \f(CW\*(C`val\*(C'\fR is NULL, it is treated as being \f(CW\*(C`undef\*(C'\fR; otherwise the caller is
+responsible for suitably incrementing the reference count of \f(CW\*(C`val\*(C'\fR before
+the call, and decrementing it if the function returned \f(CW\*(C`NULL\*(C'\fR. Effectively
+a successful \f(CW\*(C`hv_store\*(C'\fR takes ownership of one reference to \f(CW\*(C`val\*(C'\fR. This is
+usually what you want; a newly created SV has a reference count of one, so
+if all your code does is create SVs then store them in a hash, \f(CW\*(C`hv_store\*(C'\fR
+will own the only reference to the new SV, and your code doesn't need to do
+anything further to tidy up.
+.Sp
+\&\f(CW\*(C`hv_store\*(C'\fR is not implemented as a call to "\f(CW\*(C`hv_store_ent\*(C'\fR", and does not
+create a temporary SV for the key, so if your key data is not already in SV
+form then use \f(CW\*(C`hv_store\*(C'\fR in preference to \f(CW\*(C`hv_store_ent\*(C'\fR.
+.Sp
+See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for more
+information on how to use this function on tied hashes.
+.RS 4
+.Sp
+.Vb 3
+\& SV ** hv_store (HV *hv, const char *key, I32 klen, SV *val,
+\& U32 hash)
+\& SV ** hv_stores(HV *hv, "key", SV *val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_store_ent""" 4
+.el .IP \f(CWhv_store_ent\fR 4
+.IX Xref "hv_store_ent"
+.IX Item "hv_store_ent"
+Stores \f(CW\*(C`val\*(C'\fR in a hash. The hash key is specified as \f(CW\*(C`key\*(C'\fR. The \f(CW\*(C`hash\*(C'\fR
+parameter is the precomputed hash value; if it is zero then Perl will
+compute it. The return value is the new hash entry so created. It will be
+\&\f(CW\*(C`NULL\*(C'\fR if the operation failed or if the value did not need to be actually
+stored within the hash (as in the case of tied hashes). Otherwise the
+contents of the return value can be accessed using the \f(CW\*(C`He?\*(C'\fR macros
+described here. Note that the caller is responsible for suitably
+incrementing the reference count of \f(CW\*(C`val\*(C'\fR before the call, and
+decrementing it if the function returned NULL. Effectively a successful
+\&\f(CW\*(C`hv_store_ent\*(C'\fR takes ownership of one reference to \f(CW\*(C`val\*(C'\fR. This is
+usually what you want; a newly created SV has a reference count of one, so
+if all your code does is create SVs then store them in a hash, \f(CW\*(C`hv_store\*(C'\fR
+will own the only reference to the new SV, and your code doesn't need to do
+anything further to tidy up. Note that \f(CW\*(C`hv_store_ent\*(C'\fR only reads the \f(CW\*(C`key\*(C'\fR;
+unlike \f(CW\*(C`val\*(C'\fR it does not take ownership of it, so maintaining the correct
+reference count on \f(CW\*(C`key\*(C'\fR is entirely the caller's responsibility. The reason
+it does not take ownership, is that \f(CW\*(C`key\*(C'\fR is not used after this function
+returns, and so can be freed immediately. \f(CW\*(C`hv_store\*(C'\fR
+is not implemented as a call to \f(CW\*(C`hv_store_ent\*(C'\fR, and does not create a temporary
+SV for the key, so if your key data is not already in SV form then use
+\&\f(CW\*(C`hv_store\*(C'\fR in preference to \f(CW\*(C`hv_store_ent\*(C'\fR.
+.Sp
+See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for more
+information on how to use this function on tied hashes.
+.RS 4
+.Sp
+.Vb 1
+\& HE * hv_store_ent(HV *hv, SV *key, SV *val, U32 hash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """hv_undef""" 4
+.el .IP \f(CWhv_undef\fR 4
+.IX Xref "hv_undef"
+.IX Item "hv_undef"
+Undefines the hash. The XS equivalent of \f(CWundef(%hash)\fR.
+.Sp
+As well as freeing all the elements of the hash (like \f(CWhv_clear()\fR), this
+also frees any auxiliary data and storage associated with the hash.
+.Sp
+See "av_clear" for a note about the hash possibly being invalid on
+return.
+.RS 4
+.Sp
+.Vb 1
+\& void hv_undef(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newHV""" 4
+.el .IP \f(CWnewHV\fR 4
+.IX Xref "newHV"
+.IX Item "newHV"
+Creates a new HV. The reference count is set to 1.
+.RS 4
+.Sp
+.Vb 1
+\& HV * newHV()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newHVhv""" 4
+.el .IP \f(CWnewHVhv\fR 4
+.IX Xref "newHVhv"
+.IX Item "newHVhv"
+The content of \f(CW\*(C`ohv\*(C'\fR is copied to a new hash. A pointer to the new hash is
+returned.
+.RS 4
+.Sp
+.Vb 1
+\& HV * newHVhv(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Nullhv""" 4
+.el .IP \f(CWNullhv\fR 4
+.IX Xref "Nullhv"
+.IX Item "Nullhv"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`Nullhv\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Null HV pointer.
+.Sp
+(deprecated \- use \f(CW\*(C`(HV *)NULL\*(C'\fR instead)
+.ie n .IP """PERL_HASH""" 4
+.el .IP \f(CWPERL_HASH\fR 4
+.IX Item "PERL_HASH"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& void PERL_HASH(U32 hash, char *key, STRLEN klen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_modglobal""" 4
+.el .IP \f(CWPL_modglobal\fR 4
+.IX Xref "PL_modglobal"
+.IX Item "PL_modglobal"
+\&\f(CW\*(C`PL_modglobal\*(C'\fR is a general purpose, interpreter global HV for use by
+extensions that need to keep information on a per-interpreter basis.
+In a pinch, it can also be used as a symbol table for extensions
+to share data among each other. It is a good idea to use keys
+prefixed by the package name of the extension that owns the data.
+.Sp
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+.RS 4
+.Sp
+.Vb 1
+\& HV* PL_modglobal
+.Ve
+.RE
+.RS 4
+.RE
+.SH Input/Output
+.IX Header "Input/Output"
+.ie n .IP """do_close""" 4
+.el .IP \f(CWdo_close\fR 4
+.IX Xref "do_close"
+.IX Item "do_close"
+Close an I/O stream. This implements Perl "\f(CW\*(C`close\*(C'\fR" in perlfunc.
+.Sp
+\&\f(CW\*(C`gv\*(C'\fR is the glob associated with the stream.
+.Sp
+\&\f(CW\*(C`is_explict\*(C'\fR is \f(CW\*(C`true\*(C'\fR if this is an explicit close of the stream; \f(CW\*(C`false\*(C'\fR
+if it is part of another operation, such as closing a pipe (which involves
+implicitly closing both ends).
+.Sp
+Returns \f(CW\*(C`true\*(C'\fR if successful; otherwise returns \f(CW\*(C`false\*(C'\fR and sets \f(CW\*(C`errno\*(C'\fR to
+indicate the cause.
+.RS 4
+.Sp
+.Vb 1
+\& bool do_close(GV *gv, bool is_explicit)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoDIRP""" 4
+.el .IP \f(CWIoDIRP\fR 4
+.IX Item "IoDIRP"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& DIR * IoDIRP(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IOf_FLUSH""" 4
+.el .IP \f(CWIOf_FLUSH\fR 4
+.IX Item "IOf_FLUSH"
+Described in perlguts.
+.ie n .IP """IoFLAGS""" 4
+.el .IP \f(CWIoFLAGS\fR 4
+.IX Item "IoFLAGS"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& U8 IoFLAGS(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IOf_UNTAINT""" 4
+.el .IP \f(CWIOf_UNTAINT\fR 4
+.IX Item "IOf_UNTAINT"
+Described in perlguts.
+.ie n .IP """IoIFP""" 4
+.el .IP \f(CWIoIFP\fR 4
+.IX Item "IoIFP"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& PerlIO * IoIFP(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoOFP""" 4
+.el .IP \f(CWIoOFP\fR 4
+.IX Item "IoOFP"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& PerlIO * IoOFP(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoTYPE""" 4
+.el .IP \f(CWIoTYPE\fR 4
+.IX Item "IoTYPE"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& char IoTYPE(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_chsize""" 4
+.el .IP \f(CWmy_chsize\fR 4
+.IX Xref "my_chsize"
+.IX Item "my_chsize"
+The C library \fBchsize\fR\|(3) if available, or a Perl implementation of it.
+.RS 4
+.Sp
+.Vb 1
+\& I32 my_chsize(int fd, Off_t length)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_dirfd""" 4
+.el .IP \f(CWmy_dirfd\fR 4
+.IX Xref "my_dirfd"
+.IX Item "my_dirfd"
+The C library \f(CWdirfd(3)\fR if available, or a Perl implementation of it, or die
+if not easily emulatable.
+.RS 4
+.Sp
+.Vb 1
+\& int my_dirfd(DIR *dir)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_pclose""" 4
+.el .IP \f(CWmy_pclose\fR 4
+.IX Xref "my_pclose"
+.IX Item "my_pclose"
+A wrapper for the C library \fBpclose\fR\|(3). Don't use the latter, as the Perl
+version knows things that interact with the rest of the perl interpreter.
+.RS 4
+.Sp
+.Vb 1
+\& I32 my_pclose(PerlIO *ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_popen""" 4
+.el .IP \f(CWmy_popen\fR 4
+.IX Xref "my_popen"
+.IX Item "my_popen"
+A wrapper for the C library \fBpopen\fR\|(3). Don't use the latter, as the Perl
+version knows things that interact with the rest of the perl interpreter.
+.RS 4
+.Sp
+.Vb 1
+\& PerlIO * my_popen(const char *cmd, const char *mode)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newIO""" 4
+.el .IP \f(CWnewIO\fR 4
+.IX Xref "newIO"
+.IX Item "newIO"
+Create a new IO, setting the reference count to 1.
+.RS 4
+.Sp
+.Vb 1
+\& IO * newIO()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_FLUSHALL_FOR_CHILD""" 4
+.el .IP \f(CWPERL_FLUSHALL_FOR_CHILD\fR 4
+.IX Xref "PERL_FLUSHALL_FOR_CHILD"
+.IX Item "PERL_FLUSHALL_FOR_CHILD"
+This defines a way to flush all output buffers. This may be a
+performance issue, so we allow people to disable it. Also, if
+we are using stdio, there are broken implementations of fflush(NULL)
+out there, Solaris being the most prominent.
+.RS 4
+.Sp
+.Vb 1
+\& void PERL_FLUSHALL_FOR_CHILD
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PerlIO_apply_layers""" 4
+.el .IP \f(CWPerlIO_apply_layers\fR 4
+.IX Item "PerlIO_apply_layers"
+.PD 0
+.ie n .IP """PerlIO_binmode""" 4
+.el .IP \f(CWPerlIO_binmode\fR 4
+.IX Item "PerlIO_binmode"
+.ie n .IP """PerlIO_canset_cnt""" 4
+.el .IP \f(CWPerlIO_canset_cnt\fR 4
+.IX Item "PerlIO_canset_cnt"
+.ie n .IP """PerlIO_clearerr""" 4
+.el .IP \f(CWPerlIO_clearerr\fR 4
+.IX Item "PerlIO_clearerr"
+.ie n .IP """PerlIO_close""" 4
+.el .IP \f(CWPerlIO_close\fR 4
+.IX Item "PerlIO_close"
+.ie n .IP """PerlIO_debug""" 4
+.el .IP \f(CWPerlIO_debug\fR 4
+.IX Item "PerlIO_debug"
+.ie n .IP """PerlIO_eof""" 4
+.el .IP \f(CWPerlIO_eof\fR 4
+.IX Item "PerlIO_eof"
+.ie n .IP """PerlIO_error""" 4
+.el .IP \f(CWPerlIO_error\fR 4
+.IX Item "PerlIO_error"
+.ie n .IP """PerlIO_exportFILE""" 4
+.el .IP \f(CWPerlIO_exportFILE\fR 4
+.IX Item "PerlIO_exportFILE"
+.ie n .IP """PerlIO_fast_gets""" 4
+.el .IP \f(CWPerlIO_fast_gets\fR 4
+.IX Item "PerlIO_fast_gets"
+.ie n .IP """PerlIO_fdopen""" 4
+.el .IP \f(CWPerlIO_fdopen\fR 4
+.IX Item "PerlIO_fdopen"
+.ie n .IP """PerlIO_fileno""" 4
+.el .IP \f(CWPerlIO_fileno\fR 4
+.IX Item "PerlIO_fileno"
+.ie n .IP """PerlIO_fill""" 4
+.el .IP \f(CWPerlIO_fill\fR 4
+.IX Item "PerlIO_fill"
+.ie n .IP """PerlIO_findFILE""" 4
+.el .IP \f(CWPerlIO_findFILE\fR 4
+.IX Item "PerlIO_findFILE"
+.ie n .IP """PerlIO_flush""" 4
+.el .IP \f(CWPerlIO_flush\fR 4
+.IX Item "PerlIO_flush"
+.ie n .IP """PerlIO_get_base""" 4
+.el .IP \f(CWPerlIO_get_base\fR 4
+.IX Item "PerlIO_get_base"
+.ie n .IP """PerlIO_get_bufsiz""" 4
+.el .IP \f(CWPerlIO_get_bufsiz\fR 4
+.IX Item "PerlIO_get_bufsiz"
+.ie n .IP """PerlIO_get_cnt""" 4
+.el .IP \f(CWPerlIO_get_cnt\fR 4
+.IX Item "PerlIO_get_cnt"
+.ie n .IP """PerlIO_get_ptr""" 4
+.el .IP \f(CWPerlIO_get_ptr\fR 4
+.IX Item "PerlIO_get_ptr"
+.ie n .IP """PerlIO_getc""" 4
+.el .IP \f(CWPerlIO_getc\fR 4
+.IX Item "PerlIO_getc"
+.ie n .IP """PerlIO_getpos""" 4
+.el .IP \f(CWPerlIO_getpos\fR 4
+.IX Item "PerlIO_getpos"
+.ie n .IP """PerlIO_has_base""" 4
+.el .IP \f(CWPerlIO_has_base\fR 4
+.IX Item "PerlIO_has_base"
+.ie n .IP """PerlIO_has_cntptr""" 4
+.el .IP \f(CWPerlIO_has_cntptr\fR 4
+.IX Item "PerlIO_has_cntptr"
+.ie n .IP """PerlIO_importFILE""" 4
+.el .IP \f(CWPerlIO_importFILE\fR 4
+.IX Item "PerlIO_importFILE"
+.ie n .IP """PerlIO_open""" 4
+.el .IP \f(CWPerlIO_open\fR 4
+.IX Item "PerlIO_open"
+.ie n .IP """PerlIO_printf""" 4
+.el .IP \f(CWPerlIO_printf\fR 4
+.IX Item "PerlIO_printf"
+.ie n .IP """PerlIO_putc""" 4
+.el .IP \f(CWPerlIO_putc\fR 4
+.IX Item "PerlIO_putc"
+.ie n .IP """PerlIO_puts""" 4
+.el .IP \f(CWPerlIO_puts\fR 4
+.IX Item "PerlIO_puts"
+.ie n .IP """PerlIO_read""" 4
+.el .IP \f(CWPerlIO_read\fR 4
+.IX Item "PerlIO_read"
+.ie n .IP """PerlIO_releaseFILE""" 4
+.el .IP \f(CWPerlIO_releaseFILE\fR 4
+.IX Item "PerlIO_releaseFILE"
+.ie n .IP """PerlIO_reopen""" 4
+.el .IP \f(CWPerlIO_reopen\fR 4
+.IX Item "PerlIO_reopen"
+.ie n .IP """PerlIO_rewind""" 4
+.el .IP \f(CWPerlIO_rewind\fR 4
+.IX Item "PerlIO_rewind"
+.ie n .IP """PerlIO_seek""" 4
+.el .IP \f(CWPerlIO_seek\fR 4
+.IX Item "PerlIO_seek"
+.ie n .IP """PerlIO_set_cnt""" 4
+.el .IP \f(CWPerlIO_set_cnt\fR 4
+.IX Item "PerlIO_set_cnt"
+.ie n .IP """PerlIO_set_ptrcnt""" 4
+.el .IP \f(CWPerlIO_set_ptrcnt\fR 4
+.IX Item "PerlIO_set_ptrcnt"
+.ie n .IP """PerlIO_setlinebuf""" 4
+.el .IP \f(CWPerlIO_setlinebuf\fR 4
+.IX Item "PerlIO_setlinebuf"
+.ie n .IP """PerlIO_setpos""" 4
+.el .IP \f(CWPerlIO_setpos\fR 4
+.IX Item "PerlIO_setpos"
+.ie n .IP """PerlIO_stderr""" 4
+.el .IP \f(CWPerlIO_stderr\fR 4
+.IX Item "PerlIO_stderr"
+.ie n .IP """PerlIO_stdin""" 4
+.el .IP \f(CWPerlIO_stdin\fR 4
+.IX Item "PerlIO_stdin"
+.ie n .IP """PerlIO_stdout""" 4
+.el .IP \f(CWPerlIO_stdout\fR 4
+.IX Item "PerlIO_stdout"
+.ie n .IP """PerlIO_stdoutf""" 4
+.el .IP \f(CWPerlIO_stdoutf\fR 4
+.IX Item "PerlIO_stdoutf"
+.ie n .IP """PerlIO_tell""" 4
+.el .IP \f(CWPerlIO_tell\fR 4
+.IX Item "PerlIO_tell"
+.ie n .IP """PerlIO_ungetc""" 4
+.el .IP \f(CWPerlIO_ungetc\fR 4
+.IX Item "PerlIO_ungetc"
+.ie n .IP """PerlIO_unread""" 4
+.el .IP \f(CWPerlIO_unread\fR 4
+.IX Item "PerlIO_unread"
+.ie n .IP """PerlIO_vprintf""" 4
+.el .IP \f(CWPerlIO_vprintf\fR 4
+.IX Item "PerlIO_vprintf"
+.ie n .IP """PerlIO_write""" 4
+.el .IP \f(CWPerlIO_write\fR 4
+.IX Item "PerlIO_write"
+.PD
+Described in perlapio.
+.RS 4
+.Sp
+.Vb 10
+\& int PerlIO_apply_layers(PerlIO *f, const char *mode,
+\& const char *layers)
+\& int PerlIO_binmode (PerlIO *f, int ptype, int imode,
+\& const char *layers)
+\& int PerlIO_canset_cnt (PerlIO *f)
+\& void PerlIO_clearerr (PerlIO *f)
+\& int PerlIO_close (PerlIO *f)
+\& void PerlIO_debug (const char *fmt, ...)
+\& int PerlIO_eof (PerlIO *f)
+\& int PerlIO_error (PerlIO *f)
+\& FILE * PerlIO_exportFILE (PerlIO *f, const char *mode)
+\& int PerlIO_fast_gets (PerlIO *f)
+\& PerlIO * PerlIO_fdopen (int fd, const char *mode)
+\& int PerlIO_fileno (PerlIO *f)
+\& int PerlIO_fill (PerlIO *f)
+\& FILE * PerlIO_findFILE (PerlIO *f)
+\& int PerlIO_flush (PerlIO *f)
+\& STDCHAR * PerlIO_get_base (PerlIO *f)
+\& SSize_t PerlIO_get_bufsiz (PerlIO *f)
+\& SSize_t PerlIO_get_cnt (PerlIO *f)
+\& STDCHAR * PerlIO_get_ptr (PerlIO *f)
+\& int PerlIO_getc (PerlIO *d)
+\& int PerlIO_getpos (PerlIO *f, SV *save)
+\& int PerlIO_has_base (PerlIO *f)
+\& int PerlIO_has_cntptr (PerlIO *f)
+\& PerlIO * PerlIO_importFILE (FILE *stdio, const char *mode)
+\& PerlIO * PerlIO_open (const char *path, const char *mode)
+\& int PerlIO_printf (PerlIO *f, const char *fmt, ...)
+\& int PerlIO_putc (PerlIO *f, int ch)
+\& int PerlIO_puts (PerlIO *f, const char *string)
+\& SSize_t PerlIO_read (PerlIO *f, void *vbuf,
+\& Size_t count)
+\& void PerlIO_releaseFILE (PerlIO *f, FILE *stdio)
+\& PerlIO * PerlIO_reopen (const char *path, const char *mode,
+\& PerlIO *old)
+\& void PerlIO_rewind (PerlIO *f)
+\& int PerlIO_seek (PerlIO *f, Off_t offset,
+\& int whence)
+\& void PerlIO_set_cnt (PerlIO *f, SSize_t cnt)
+\& void PerlIO_set_ptrcnt (PerlIO *f, STDCHAR *ptr,
+\& SSize_t cnt)
+\& void PerlIO_setlinebuf (PerlIO *f)
+\& int PerlIO_setpos (PerlIO *f, SV *saved)
+\& PerlIO * PerlIO_stderr (PerlIO *f, const char *mode,
+\& const char *layers)
+\& PerlIO * PerlIO_stdin (PerlIO *f, const char *mode,
+\& const char *layers)
+\& PerlIO * PerlIO_stdout (PerlIO *f, const char *mode,
+\& const char *layers)
+\& int PerlIO_stdoutf (const char *fmt, ...)
+\& Off_t PerlIO_tell (PerlIO *f)
+\& int PerlIO_ungetc (PerlIO *f, int ch)
+\& SSize_t PerlIO_unread (PerlIO *f, const void *vbuf,
+\& Size_t count)
+\& int PerlIO_vprintf (PerlIO *f, const char *fmt,
+\& va_list args)
+\& SSize_t PerlIO_write (PerlIO *f, const void *vbuf,
+\& Size_t count)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERLIO_F_APPEND""" 4
+.el .IP \f(CWPERLIO_F_APPEND\fR 4
+.IX Item "PERLIO_F_APPEND"
+.PD 0
+.ie n .IP """PERLIO_F_CANREAD""" 4
+.el .IP \f(CWPERLIO_F_CANREAD\fR 4
+.IX Item "PERLIO_F_CANREAD"
+.ie n .IP """PERLIO_F_CANWRITE""" 4
+.el .IP \f(CWPERLIO_F_CANWRITE\fR 4
+.IX Item "PERLIO_F_CANWRITE"
+.ie n .IP """PERLIO_F_CRLF""" 4
+.el .IP \f(CWPERLIO_F_CRLF\fR 4
+.IX Item "PERLIO_F_CRLF"
+.ie n .IP """PERLIO_F_EOF""" 4
+.el .IP \f(CWPERLIO_F_EOF\fR 4
+.IX Item "PERLIO_F_EOF"
+.ie n .IP """PERLIO_F_ERROR""" 4
+.el .IP \f(CWPERLIO_F_ERROR\fR 4
+.IX Item "PERLIO_F_ERROR"
+.ie n .IP """PERLIO_F_FASTGETS""" 4
+.el .IP \f(CWPERLIO_F_FASTGETS\fR 4
+.IX Item "PERLIO_F_FASTGETS"
+.ie n .IP """PERLIO_F_LINEBUF""" 4
+.el .IP \f(CWPERLIO_F_LINEBUF\fR 4
+.IX Item "PERLIO_F_LINEBUF"
+.ie n .IP """PERLIO_F_OPEN""" 4
+.el .IP \f(CWPERLIO_F_OPEN\fR 4
+.IX Item "PERLIO_F_OPEN"
+.ie n .IP """PERLIO_F_RDBUF""" 4
+.el .IP \f(CWPERLIO_F_RDBUF\fR 4
+.IX Item "PERLIO_F_RDBUF"
+.ie n .IP """PERLIO_F_TEMP""" 4
+.el .IP \f(CWPERLIO_F_TEMP\fR 4
+.IX Item "PERLIO_F_TEMP"
+.ie n .IP """PERLIO_F_TRUNCATE""" 4
+.el .IP \f(CWPERLIO_F_TRUNCATE\fR 4
+.IX Item "PERLIO_F_TRUNCATE"
+.ie n .IP """PERLIO_F_UNBUF""" 4
+.el .IP \f(CWPERLIO_F_UNBUF\fR 4
+.IX Item "PERLIO_F_UNBUF"
+.ie n .IP """PERLIO_F_UTF8""" 4
+.el .IP \f(CWPERLIO_F_UTF8\fR 4
+.IX Item "PERLIO_F_UTF8"
+.ie n .IP """PERLIO_F_WRBUF""" 4
+.el .IP \f(CWPERLIO_F_WRBUF\fR 4
+.IX Item "PERLIO_F_WRBUF"
+.PD
+Described in perliol.
+.ie n .IP """PERLIO_FUNCS_CAST""" 4
+.el .IP \f(CWPERLIO_FUNCS_CAST\fR 4
+.IX Xref "PERLIO_FUNCS_CAST"
+.IX Item "PERLIO_FUNCS_CAST"
+Cast the pointer \f(CW\*(C`func\*(C'\fR to be of type \f(CW\*(C`PerlIO_funcs\ *\*(C'\fR.
+.ie n .IP """PERLIO_FUNCS_DECL""" 4
+.el .IP \f(CWPERLIO_FUNCS_DECL\fR 4
+.IX Xref "PERLIO_FUNCS_DECL"
+.IX Item "PERLIO_FUNCS_DECL"
+Declare \f(CW\*(C`ftab\*(C'\fR to be a PerlIO function table, that is, of type
+\&\f(CW\*(C`PerlIO_funcs\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& PERLIO_FUNCS_DECL(PerlIO * ftab)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERLIO_K_BUFFERED""" 4
+.el .IP \f(CWPERLIO_K_BUFFERED\fR 4
+.IX Item "PERLIO_K_BUFFERED"
+.PD 0
+.ie n .IP """PERLIO_K_CANCRLF""" 4
+.el .IP \f(CWPERLIO_K_CANCRLF\fR 4
+.IX Item "PERLIO_K_CANCRLF"
+.ie n .IP """PERLIO_K_FASTGETS""" 4
+.el .IP \f(CWPERLIO_K_FASTGETS\fR 4
+.IX Item "PERLIO_K_FASTGETS"
+.ie n .IP """PERLIO_K_MULTIARG""" 4
+.el .IP \f(CWPERLIO_K_MULTIARG\fR 4
+.IX Item "PERLIO_K_MULTIARG"
+.ie n .IP """PERLIO_K_RAW""" 4
+.el .IP \f(CWPERLIO_K_RAW\fR 4
+.IX Item "PERLIO_K_RAW"
+.PD
+Described in perliol.
+.ie n .IP """PERLIO_NOT_STDIO""" 4
+.el .IP \f(CWPERLIO_NOT_STDIO\fR 4
+.IX Item "PERLIO_NOT_STDIO"
+Described in perlapio.
+.ie n .IP """PL_maxsysfd""" 4
+.el .IP \f(CWPL_maxsysfd\fR 4
+.IX Item "PL_maxsysfd"
+Described in perliol.
+.ie n .IP """repeatcpy""" 4
+.el .IP \f(CWrepeatcpy\fR 4
+.IX Xref "repeatcpy"
+.IX Item "repeatcpy"
+Make \f(CW\*(C`count\*(C'\fR copies of the \f(CW\*(C`len\*(C'\fR bytes beginning at \f(CW\*(C`from\*(C'\fR, placing them
+into memory beginning at \f(CW\*(C`to\*(C'\fR, which must be big enough to accommodate them
+all.
+.RS 4
+.Sp
+.Vb 1
+\& void repeatcpy(char *to, const char *from, I32 len, IV count)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """USE_STDIO""" 4
+.el .IP \f(CWUSE_STDIO\fR 4
+.IX Item "USE_STDIO"
+Described in perlapio.
+.SH Integer
+.IX Header "Integer"
+.ie n .IP """CASTI32""" 4
+.el .IP \f(CWCASTI32\fR 4
+.IX Xref "CASTI32"
+.IX Item "CASTI32"
+This symbol is defined if the C compiler can cast negative
+or large floating point numbers to 32\-bit ints.
+.ie n .IP """HAS_INT64_T""" 4
+.el .IP \f(CWHAS_INT64_T\fR 4
+.IX Xref "HAS_INT64_T"
+.IX Item "HAS_INT64_T"
+This symbol will defined if the C compiler supports \f(CW\*(C`int64_t\*(C'\fR.
+Usually the \fIinttypes.h\fR needs to be included, but sometimes
+\&\fIsys/types.h\fR is enough.
+.ie n .IP """HAS_LONG_LONG""" 4
+.el .IP \f(CWHAS_LONG_LONG\fR 4
+.IX Xref "HAS_LONG_LONG"
+.IX Item "HAS_LONG_LONG"
+This symbol will be defined if the C compiler supports long long.
+.ie n .IP """HAS_QUAD""" 4
+.el .IP \f(CWHAS_QUAD\fR 4
+.IX Xref "HAS_QUAD"
+.IX Item "HAS_QUAD"
+This symbol, if defined, tells that there's a 64\-bit integer type,
+\&\f(CW\*(C`Quad_t\*(C'\fR, and its unsigned counterpart, \f(CW\*(C`Uquad_t\*(C'\fR. \f(CW\*(C`QUADKIND\*(C'\fR will be one
+of \f(CW\*(C`QUAD_IS_INT\*(C'\fR, \f(CW\*(C`QUAD_IS_LONG\*(C'\fR, \f(CW\*(C`QUAD_IS_LONG_LONG\*(C'\fR, \f(CW\*(C`QUAD_IS_INT64_T\*(C'\fR,
+or \f(CW\*(C`QUAD_IS_\|_\|_INT64\*(C'\fR.
+.ie n .IP """I32df""" 4
+.el .IP \f(CWI32df\fR 4
+.IX Xref "I32df"
+.IX Item "I32df"
+This symbol defines the format string used for printing a Perl I32
+as a signed decimal integer.
+.ie n .IP """INT16_C""" 4
+.el .IP \f(CWINT16_C\fR 4
+.IX Item "INT16_C"
+.PD 0
+.ie n .IP """INT32_C""" 4
+.el .IP \f(CWINT32_C\fR 4
+.IX Item "INT32_C"
+.ie n .IP """INT64_C""" 4
+.el .IP \f(CWINT64_C\fR 4
+.IX Xref "INT16_C INT32_C INT64_C"
+.IX Item "INT64_C"
+.PD
+Returns a token the C compiler recognizes for the constant \f(CW\*(C`number\*(C'\fR of the
+corresponding integer type on the machine.
+.Sp
+If the machine does not have a 64\-bit type, \f(CW\*(C`INT64_C\*(C'\fR is undefined.
+Use \f(CW"INTMAX_C"\fR to get the largest type available on the platform.
+.RS 4
+.Sp
+.Vb 3
+\& I16 INT16_C(number)
+\& I32 INT32_C(number)
+\& I64 INT64_C(number)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """INTMAX_C""" 4
+.el .IP \f(CWINTMAX_C\fR 4
+.IX Xref "INTMAX_C"
+.IX Item "INTMAX_C"
+Returns a token the C compiler recognizes for the constant \f(CW\*(C`number\*(C'\fR of the
+widest integer type on the machine. For example, if the machine has \f(CW\*(C`long
+long\*(C'\fRs, \f(CWINTMAX_C(\-1)\fR would yield
+.Sp
+.Vb 1
+\& \-1LL
+.Ve
+.Sp
+See also, for example, \f(CW"INT32_C"\fR.
+.Sp
+Use "IV" to declare variables of the maximum usable size on this platform.
+.RS 4
+.Sp
+.Vb 1
+\& INTMAX_C(number)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """INTSIZE""" 4
+.el .IP \f(CWINTSIZE\fR 4
+.IX Xref "INTSIZE"
+.IX Item "INTSIZE"
+This symbol contains the value of \f(CWsizeof(int)\fR so that the C
+preprocessor can make decisions based on it.
+.ie n .IP """I8SIZE""" 4
+.el .IP \f(CWI8SIZE\fR 4
+.IX Xref "I8SIZE"
+.IX Item "I8SIZE"
+This symbol contains the \f(CWsizeof(I8)\fR.
+.ie n .IP """I16SIZE""" 4
+.el .IP \f(CWI16SIZE\fR 4
+.IX Xref "I16SIZE"
+.IX Item "I16SIZE"
+This symbol contains the \f(CWsizeof(I16)\fR.
+.ie n .IP """I32SIZE""" 4
+.el .IP \f(CWI32SIZE\fR 4
+.IX Xref "I32SIZE"
+.IX Item "I32SIZE"
+This symbol contains the \f(CWsizeof(I32)\fR.
+.ie n .IP """I64SIZE""" 4
+.el .IP \f(CWI64SIZE\fR 4
+.IX Xref "I64SIZE"
+.IX Item "I64SIZE"
+This symbol contains the \f(CWsizeof(I64)\fR.
+.ie n .IP """I8TYPE""" 4
+.el .IP \f(CWI8TYPE\fR 4
+.IX Xref "I8TYPE"
+.IX Item "I8TYPE"
+This symbol defines the C type used for Perl's I8.
+.ie n .IP """I16TYPE""" 4
+.el .IP \f(CWI16TYPE\fR 4
+.IX Xref "I16TYPE"
+.IX Item "I16TYPE"
+This symbol defines the C type used for Perl's I16.
+.ie n .IP """I32TYPE""" 4
+.el .IP \f(CWI32TYPE\fR 4
+.IX Xref "I32TYPE"
+.IX Item "I32TYPE"
+This symbol defines the C type used for Perl's I32.
+.ie n .IP """I64TYPE""" 4
+.el .IP \f(CWI64TYPE\fR 4
+.IX Xref "I64TYPE"
+.IX Item "I64TYPE"
+This symbol defines the C type used for Perl's I64.
+.ie n .IP """IV""" 4
+.el .IP \f(CWIV\fR 4
+.IX Item "IV"
+.PD 0
+.ie n .IP """I8""" 4
+.el .IP \f(CWI8\fR 4
+.IX Item "I8"
+.ie n .IP """I16""" 4
+.el .IP \f(CWI16\fR 4
+.IX Item "I16"
+.ie n .IP """I32""" 4
+.el .IP \f(CWI32\fR 4
+.IX Item "I32"
+.ie n .IP """I64""" 4
+.el .IP \f(CWI64\fR 4
+.IX Item "I64"
+.PD
+Described in perlguts.
+.ie n .IP """IV_MAX""" 4
+.el .IP \f(CWIV_MAX\fR 4
+.IX Xref "IV_MAX"
+.IX Item "IV_MAX"
+The largest signed integer that fits in an IV on this platform.
+.RS 4
+.Sp
+.Vb 1
+\& IV IV_MAX
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IV_MIN""" 4
+.el .IP \f(CWIV_MIN\fR 4
+.IX Xref "IV_MIN"
+.IX Item "IV_MIN"
+The negative signed integer furthest away from 0 that fits in an IV on this
+platform.
+.RS 4
+.Sp
+.Vb 1
+\& IV IV_MIN
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IVSIZE""" 4
+.el .IP \f(CWIVSIZE\fR 4
+.IX Xref "IVSIZE"
+.IX Item "IVSIZE"
+This symbol contains the \f(CWsizeof(IV)\fR.
+.ie n .IP """IVTYPE""" 4
+.el .IP \f(CWIVTYPE\fR 4
+.IX Xref "IVTYPE"
+.IX Item "IVTYPE"
+This symbol defines the C type used for Perl's IV.
+.ie n .IP """line_t""" 4
+.el .IP \f(CWline_t\fR 4
+.IX Xref "line_t"
+.IX Item "line_t"
+The typedef to use to declare variables that are to hold line numbers.
+.ie n .IP """LONGLONGSIZE""" 4
+.el .IP \f(CWLONGLONGSIZE\fR 4
+.IX Xref "LONGLONGSIZE"
+.IX Item "LONGLONGSIZE"
+This symbol contains the size of a long long, so that the
+C preprocessor can make decisions based on it. It is only
+defined if the system supports long long.
+.ie n .IP """LONGSIZE""" 4
+.el .IP \f(CWLONGSIZE\fR 4
+.IX Xref "LONGSIZE"
+.IX Item "LONGSIZE"
+This symbol contains the value of \f(CWsizeof(long)\fR so that the C
+preprocessor can make decisions based on it.
+.ie n .IP """memzero""" 4
+.el .IP \f(CWmemzero\fR 4
+.IX Xref "memzero"
+.IX Item "memzero"
+Set the \f(CW\*(C`l\*(C'\fR bytes starting at \f(CW*d\fR to all zeroes.
+.RS 4
+.Sp
+.Vb 1
+\& void memzero(void * d, Size_t l)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_INT_FAST8_T""" 4
+.el .IP \f(CWPERL_INT_FAST8_T\fR 4
+.IX Item "PERL_INT_FAST8_T"
+.PD 0
+.ie n .IP """PERL_INT_FAST16_T""" 4
+.el .IP \f(CWPERL_INT_FAST16_T\fR 4
+.IX Item "PERL_INT_FAST16_T"
+.ie n .IP """PERL_UINT_FAST8_T""" 4
+.el .IP \f(CWPERL_UINT_FAST8_T\fR 4
+.IX Item "PERL_UINT_FAST8_T"
+.ie n .IP """PERL_UINT_FAST16_T""" 4
+.el .IP \f(CWPERL_UINT_FAST16_T\fR 4
+.IX Xref "PERL_INT_FAST8_T PERL_INT_FAST16_T PERL_UINT_FAST8_T PERL_UINT_FAST16_T"
+.IX Item "PERL_UINT_FAST16_T"
+.PD
+These are equivalent to the correspondingly-named C99 typedefs on platforms
+that have those; they evaluate to \f(CW\*(C`int\*(C'\fR and \f(CW\*(C`unsigned int\*(C'\fR on platforms that
+don't, so that you can portably take advantage of this C99 feature.
+.ie n .IP """PERL_INT_MAX""" 4
+.el .IP \f(CWPERL_INT_MAX\fR 4
+.IX Item "PERL_INT_MAX"
+.PD 0
+.ie n .IP """PERL_INT_MIN""" 4
+.el .IP \f(CWPERL_INT_MIN\fR 4
+.IX Item "PERL_INT_MIN"
+.ie n .IP """PERL_LONG_MAX""" 4
+.el .IP \f(CWPERL_LONG_MAX\fR 4
+.IX Item "PERL_LONG_MAX"
+.ie n .IP """PERL_LONG_MIN""" 4
+.el .IP \f(CWPERL_LONG_MIN\fR 4
+.IX Item "PERL_LONG_MIN"
+.ie n .IP """PERL_QUAD_MAX""" 4
+.el .IP \f(CWPERL_QUAD_MAX\fR 4
+.IX Item "PERL_QUAD_MAX"
+.ie n .IP """PERL_QUAD_MIN""" 4
+.el .IP \f(CWPERL_QUAD_MIN\fR 4
+.IX Item "PERL_QUAD_MIN"
+.ie n .IP """PERL_SHORT_MAX""" 4
+.el .IP \f(CWPERL_SHORT_MAX\fR 4
+.IX Item "PERL_SHORT_MAX"
+.ie n .IP """PERL_SHORT_MIN""" 4
+.el .IP \f(CWPERL_SHORT_MIN\fR 4
+.IX Item "PERL_SHORT_MIN"
+.ie n .IP """PERL_UCHAR_MAX""" 4
+.el .IP \f(CWPERL_UCHAR_MAX\fR 4
+.IX Item "PERL_UCHAR_MAX"
+.ie n .IP """PERL_UCHAR_MIN""" 4
+.el .IP \f(CWPERL_UCHAR_MIN\fR 4
+.IX Item "PERL_UCHAR_MIN"
+.ie n .IP """PERL_UINT_MAX""" 4
+.el .IP \f(CWPERL_UINT_MAX\fR 4
+.IX Item "PERL_UINT_MAX"
+.ie n .IP """PERL_UINT_MIN""" 4
+.el .IP \f(CWPERL_UINT_MIN\fR 4
+.IX Item "PERL_UINT_MIN"
+.ie n .IP """PERL_ULONG_MAX""" 4
+.el .IP \f(CWPERL_ULONG_MAX\fR 4
+.IX Item "PERL_ULONG_MAX"
+.ie n .IP """PERL_ULONG_MIN""" 4
+.el .IP \f(CWPERL_ULONG_MIN\fR 4
+.IX Item "PERL_ULONG_MIN"
+.ie n .IP """PERL_UQUAD_MAX""" 4
+.el .IP \f(CWPERL_UQUAD_MAX\fR 4
+.IX Item "PERL_UQUAD_MAX"
+.ie n .IP """PERL_UQUAD_MIN""" 4
+.el .IP \f(CWPERL_UQUAD_MIN\fR 4
+.IX Item "PERL_UQUAD_MIN"
+.ie n .IP """PERL_USHORT_MAX""" 4
+.el .IP \f(CWPERL_USHORT_MAX\fR 4
+.IX Item "PERL_USHORT_MAX"
+.ie n .IP """PERL_USHORT_MIN""" 4
+.el .IP \f(CWPERL_USHORT_MIN\fR 4
+.IX Xref "PERL_INT_MAX PERL_INT_MIN PERL_LONG_MAX PERL_LONG_MIN PERL_QUAD_MAX PERL_QUAD_MIN PERL_SHORT_MAX PERL_SHORT_MIN PERL_UCHAR_MAX PERL_UCHAR_MIN PERL_UINT_MAX PERL_UINT_MIN PERL_ULONG_MAX PERL_ULONG_MIN PERL_UQUAD_MAX PERL_UQUAD_MIN PERL_USHORT_MAX PERL_USHORT_MIN"
+.IX Item "PERL_USHORT_MIN"
+.PD
+These give the largest and smallest number representable in the current
+platform in variables of the corresponding types.
+.Sp
+For signed types, the smallest representable number is the most negative
+number, the one furthest away from zero.
+.Sp
+For C99 and later compilers, these correspond to things like \f(CW\*(C`INT_MAX\*(C'\fR, which
+are available to the C code. But these constants, furnished by Perl,
+allow code compiled on earlier compilers to portably have access to the same
+constants.
+.RS 4
+.Sp
+.Vb 10
+\& int PERL_INT_MAX
+\& int PERL_INT_MIN
+\& long PERL_LONG_MAX
+\& long PERL_LONG_MIN
+\& IV PERL_QUAD_MAX
+\& IV PERL_QUAD_MIN
+\& short PERL_SHORT_MAX
+\& short PERL_SHORT_MIN
+\& U8 PERL_UCHAR_MAX
+\& U8 PERL_UCHAR_MIN
+\& unsigned int PERL_UINT_MAX
+\& unsigned int PERL_UINT_MIN
+\& unsigned long PERL_ULONG_MAX
+\& unsigned long PERL_ULONG_MIN
+\& UV PERL_UQUAD_MAX
+\& UV PERL_UQUAD_MIN
+\& unsigned short PERL_USHORT_MAX
+\& unsigned short PERL_USHORT_MIN
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SHORTSIZE""" 4
+.el .IP \f(CWSHORTSIZE\fR 4
+.IX Xref "SHORTSIZE"
+.IX Item "SHORTSIZE"
+This symbol contains the value of \f(CWsizeof(short)\fR so that the C
+preprocessor can make decisions based on it.
+.ie n .IP """UINT16_C""" 4
+.el .IP \f(CWUINT16_C\fR 4
+.IX Item "UINT16_C"
+.PD 0
+.ie n .IP """UINT32_C""" 4
+.el .IP \f(CWUINT32_C\fR 4
+.IX Item "UINT32_C"
+.ie n .IP """UINT64_C""" 4
+.el .IP \f(CWUINT64_C\fR 4
+.IX Xref "UINT16_C UINT32_C UINT64_C"
+.IX Item "UINT64_C"
+.PD
+Returns a token the C compiler recognizes for the constant \f(CW\*(C`number\*(C'\fR of the
+corresponding unsigned integer type on the machine.
+.Sp
+If the machine does not have a 64\-bit type, \f(CW\*(C`UINT64_C\*(C'\fR is undefined.
+Use \f(CW"UINTMAX_C"\fR to get the largest type available on the platform.
+.RS 4
+.Sp
+.Vb 3
+\& U16 UINT16_C(number)
+\& U32 UINT32_C(number)
+\& U64 UINT64_C(number)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UINTMAX_C""" 4
+.el .IP \f(CWUINTMAX_C\fR 4
+.IX Xref "UINTMAX_C"
+.IX Item "UINTMAX_C"
+Returns a token the C compiler recognizes for the constant \f(CW\*(C`number\*(C'\fR of the
+widest unsigned integer type on the machine. For example, if the machine has
+\&\f(CW\*(C`long\*(C'\fRs, \f(CWUINTMAX_C(1)\fR would yield
+.Sp
+.Vb 1
+\& 1UL
+.Ve
+.Sp
+See also, for example, \f(CW"UINT32_C"\fR.
+.Sp
+Use "UV" to declare variables of the maximum usable size on this platform.
+.RS 4
+.Sp
+.Vb 1
+\& UINTMAX_C(number)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """U32of""" 4
+.el .IP \f(CWU32of\fR 4
+.IX Xref "U32of"
+.IX Item "U32of"
+This symbol defines the format string used for printing a Perl U32
+as an unsigned octal integer.
+.ie n .IP """U8SIZE""" 4
+.el .IP \f(CWU8SIZE\fR 4
+.IX Xref "U8SIZE"
+.IX Item "U8SIZE"
+This symbol contains the \f(CWsizeof(U8)\fR.
+.ie n .IP """U16SIZE""" 4
+.el .IP \f(CWU16SIZE\fR 4
+.IX Xref "U16SIZE"
+.IX Item "U16SIZE"
+This symbol contains the \f(CWsizeof(U16)\fR.
+.ie n .IP """U32SIZE""" 4
+.el .IP \f(CWU32SIZE\fR 4
+.IX Xref "U32SIZE"
+.IX Item "U32SIZE"
+This symbol contains the \f(CWsizeof(U32)\fR.
+.ie n .IP """U64SIZE""" 4
+.el .IP \f(CWU64SIZE\fR 4
+.IX Xref "U64SIZE"
+.IX Item "U64SIZE"
+This symbol contains the \f(CWsizeof(U64)\fR.
+.ie n .IP """U8TYPE""" 4
+.el .IP \f(CWU8TYPE\fR 4
+.IX Xref "U8TYPE"
+.IX Item "U8TYPE"
+This symbol defines the C type used for Perl's U8.
+.ie n .IP """U16TYPE""" 4
+.el .IP \f(CWU16TYPE\fR 4
+.IX Xref "U16TYPE"
+.IX Item "U16TYPE"
+This symbol defines the C type used for Perl's U16.
+.ie n .IP """U32TYPE""" 4
+.el .IP \f(CWU32TYPE\fR 4
+.IX Xref "U32TYPE"
+.IX Item "U32TYPE"
+This symbol defines the C type used for Perl's U32.
+.ie n .IP """U64TYPE""" 4
+.el .IP \f(CWU64TYPE\fR 4
+.IX Xref "U64TYPE"
+.IX Item "U64TYPE"
+This symbol defines the C type used for Perl's U64.
+.ie n .IP """U32uf""" 4
+.el .IP \f(CWU32uf\fR 4
+.IX Xref "U32uf"
+.IX Item "U32uf"
+This symbol defines the format string used for printing a Perl U32
+as an unsigned decimal integer.
+.ie n .IP """UV""" 4
+.el .IP \f(CWUV\fR 4
+.IX Item "UV"
+.PD 0
+.ie n .IP """U8""" 4
+.el .IP \f(CWU8\fR 4
+.IX Item "U8"
+.ie n .IP """U16""" 4
+.el .IP \f(CWU16\fR 4
+.IX Item "U16"
+.ie n .IP """U32""" 4
+.el .IP \f(CWU32\fR 4
+.IX Item "U32"
+.ie n .IP """U64""" 4
+.el .IP \f(CWU64\fR 4
+.IX Item "U64"
+.PD
+Described in perlguts.
+.ie n .IP """UV_MAX""" 4
+.el .IP \f(CWUV_MAX\fR 4
+.IX Xref "UV_MAX"
+.IX Item "UV_MAX"
+The largest unsigned integer that fits in a UV on this platform.
+.RS 4
+.Sp
+.Vb 1
+\& UV UV_MAX
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UV_MIN""" 4
+.el .IP \f(CWUV_MIN\fR 4
+.IX Xref "UV_MIN"
+.IX Item "UV_MIN"
+The smallest unsigned integer that fits in a UV on this platform. It should
+equal zero.
+.RS 4
+.Sp
+.Vb 1
+\& UV UV_MIN
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UVSIZE""" 4
+.el .IP \f(CWUVSIZE\fR 4
+.IX Xref "UVSIZE"
+.IX Item "UVSIZE"
+This symbol contains the \f(CWsizeof(UV)\fR.
+.ie n .IP """UVTYPE""" 4
+.el .IP \f(CWUVTYPE\fR 4
+.IX Xref "UVTYPE"
+.IX Item "UVTYPE"
+This symbol defines the C type used for Perl's UV.
+.ie n .IP """U32Xf""" 4
+.el .IP \f(CWU32Xf\fR 4
+.IX Xref "U32Xf"
+.IX Item "U32Xf"
+This symbol defines the format string used for printing a Perl U32
+as an unsigned hexadecimal integer in uppercase \f(CW\*(C`ABCDEF\*(C'\fR.
+.ie n .IP """U32xf""" 4
+.el .IP \f(CWU32xf\fR 4
+.IX Xref "U32xf"
+.IX Item "U32xf"
+This symbol defines the format string used for printing a Perl U32
+as an unsigned hexadecimal integer in lowercase abcdef.
+.ie n .IP """WIDEST_UTYPE""" 4
+.el .IP \f(CWWIDEST_UTYPE\fR 4
+.IX Xref "WIDEST_UTYPE"
+.IX Item "WIDEST_UTYPE"
+Yields the widest unsigned integer type on the platform, currently either
+\&\f(CW\*(C`U32\*(C'\fR or \f(CW\*(C`U64\*(C'\fR. This can be used in declarations such as
+.Sp
+.Vb 1
+\& WIDEST_UTYPE my_uv;
+.Ve
+.Sp
+or casts
+.Sp
+.Vb 1
+\& my_uv = (WIDEST_UTYPE) val;
+.Ve
+.SH "I/O Formats"
+.IX Header "I/O Formats"
+These are used for formatting the corresponding type For example,
+instead of saying
+.PP
+.Vb 1
+\& Perl_newSVpvf(pTHX_ "Create an SV with a %d in it\en", iv);
+.Ve
+.PP
+use
+.PP
+.Vb 1
+\& Perl_newSVpvf(pTHX_ "Create an SV with a " IVdf " in it\en", iv);
+.Ve
+.PP
+This keeps you from having to know if, say an IV, needs to be
+printed as \f(CW%d\fR, \f(CW%ld\fR, or something else.
+.ie n .IP """HvNAMEf""" 4
+.el .IP \f(CWHvNAMEf\fR 4
+.IX Item "HvNAMEf"
+Described in perlguts.
+.ie n .IP """HvNAMEf_QUOTEDPREFIX""" 4
+.el .IP \f(CWHvNAMEf_QUOTEDPREFIX\fR 4
+.IX Item "HvNAMEf_QUOTEDPREFIX"
+Described in perlguts.
+.ie n .IP """IVdf""" 4
+.el .IP \f(CWIVdf\fR 4
+.IX Xref "IVdf"
+.IX Item "IVdf"
+This symbol defines the format string used for printing a Perl IV
+as a signed decimal integer.
+.ie n .IP """NVef""" 4
+.el .IP \f(CWNVef\fR 4
+.IX Xref "NVef"
+.IX Item "NVef"
+This symbol defines the format string used for printing a Perl NV
+using \f(CW%e\fR\-ish floating point format.
+.ie n .IP """NVff""" 4
+.el .IP \f(CWNVff\fR 4
+.IX Xref "NVff"
+.IX Item "NVff"
+This symbol defines the format string used for printing a Perl NV
+using \f(CW%f\fR\-ish floating point format.
+.ie n .IP """NVgf""" 4
+.el .IP \f(CWNVgf\fR 4
+.IX Xref "NVgf"
+.IX Item "NVgf"
+This symbol defines the format string used for printing a Perl NV
+using \f(CW%g\fR\-ish floating point format.
+.ie n .IP """PERL_PRIeldbl""" 4
+.el .IP \f(CWPERL_PRIeldbl\fR 4
+.IX Xref "PERL_PRIeldbl"
+.IX Item "PERL_PRIeldbl"
+This symbol, if defined, contains the string used by stdio to
+format long doubles (format 'e') for output.
+.ie n .IP """PERL_PRIfldbl""" 4
+.el .IP \f(CWPERL_PRIfldbl\fR 4
+.IX Xref "PERL_PRIfldbl"
+.IX Item "PERL_PRIfldbl"
+This symbol, if defined, contains the string used by stdio to
+format long doubles (format 'f') for output.
+.ie n .IP """PERL_PRIgldbl""" 4
+.el .IP \f(CWPERL_PRIgldbl\fR 4
+.IX Xref "PERL_PRIgldbl"
+.IX Item "PERL_PRIgldbl"
+This symbol, if defined, contains the string used by stdio to
+format long doubles (format 'g') for output.
+.ie n .IP """PERL_SCNfldbl""" 4
+.el .IP \f(CWPERL_SCNfldbl\fR 4
+.IX Xref "PERL_SCNfldbl"
+.IX Item "PERL_SCNfldbl"
+This symbol, if defined, contains the string used by stdio to
+format long doubles (format 'f') for input.
+.ie n .IP """PRINTF_FORMAT_NULL_OK""" 4
+.el .IP \f(CWPRINTF_FORMAT_NULL_OK\fR 4
+.IX Xref "PRINTF_FORMAT_NULL_OK"
+.IX Item "PRINTF_FORMAT_NULL_OK"
+Allows \f(CW\*(C`_\|_printf_\|_\*(C'\fR format to be null when checking printf-style
+.ie n .IP """SVf""" 4
+.el .IP \f(CWSVf\fR 4
+.IX Item "SVf"
+Described in perlguts.
+.ie n .IP """SVfARG""" 4
+.el .IP \f(CWSVfARG\fR 4
+.IX Item "SVfARG"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& SVfARG(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SVf_QUOTEDPREFIX""" 4
+.el .IP \f(CWSVf_QUOTEDPREFIX\fR 4
+.IX Item "SVf_QUOTEDPREFIX"
+Described in perlguts.
+.ie n .IP """UTF8f""" 4
+.el .IP \f(CWUTF8f\fR 4
+.IX Item "UTF8f"
+Described in perlguts.
+.ie n .IP """UTF8fARG""" 4
+.el .IP \f(CWUTF8fARG\fR 4
+.IX Item "UTF8fARG"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& UTF8fARG(bool is_utf8, Size_t byte_len, char *str)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8f_QUOTEDPREFIX""" 4
+.el .IP \f(CWUTF8f_QUOTEDPREFIX\fR 4
+.IX Item "UTF8f_QUOTEDPREFIX"
+Described in perlguts.
+.ie n .IP """UVf""" 4
+.el .IP \f(CWUVf\fR 4
+.IX Xref "UVf"
+.IX Item "UVf"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`UVf\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Obsolete form of \f(CW\*(C`UVuf\*(C'\fR, which you should convert to instead use
+.RS 4
+.Sp
+.Vb 1
+\& const char * UVf
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UVof""" 4
+.el .IP \f(CWUVof\fR 4
+.IX Xref "UVof"
+.IX Item "UVof"
+This symbol defines the format string used for printing a Perl UV
+as an unsigned octal integer.
+.ie n .IP """UVuf""" 4
+.el .IP \f(CWUVuf\fR 4
+.IX Xref "UVuf"
+.IX Item "UVuf"
+This symbol defines the format string used for printing a Perl UV
+as an unsigned decimal integer.
+.ie n .IP """UVXf""" 4
+.el .IP \f(CWUVXf\fR 4
+.IX Xref "UVXf"
+.IX Item "UVXf"
+This symbol defines the format string used for printing a Perl UV
+as an unsigned hexadecimal integer in uppercase \f(CW\*(C`ABCDEF\*(C'\fR.
+.ie n .IP """UVxf""" 4
+.el .IP \f(CWUVxf\fR 4
+.IX Xref "UVxf"
+.IX Item "UVxf"
+This symbol defines the format string used for printing a Perl UV
+as an unsigned hexadecimal integer in lowercase abcdef.
+.SH "Lexer interface"
+.IX Xref "LEX_KEEP_PREVIOUS LEX_STUFF_UTF8 PARSE_OPTIONAL"
+.IX Header "Lexer interface"
+This is the lower layer of the Perl parser, managing characters and tokens.
+.ie n .IP """BHK""" 4
+.el .IP \f(CWBHK\fR 4
+.IX Item "BHK"
+Described in perlguts.
+.ie n .IP """lex_bufutf8""" 4
+.el .IP \f(CWlex_bufutf8\fR 4
+.IX Xref "lex_bufutf8"
+.IX Item "lex_bufutf8"
+NOTE: \f(CW\*(C`lex_bufutf8\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Indicates whether the octets in the lexer buffer
+("PL_parser\->linestr") should be interpreted as the UTF\-8 encoding
+of Unicode characters. If not, they should be interpreted as Latin\-1
+characters. This is analogous to the \f(CW\*(C`SvUTF8\*(C'\fR flag for scalars.
+.Sp
+In UTF\-8 mode, it is not guaranteed that the lexer buffer actually
+contains valid UTF\-8. Lexing code must be robust in the face of invalid
+encoding.
+.Sp
+The actual \f(CW\*(C`SvUTF8\*(C'\fR flag of the "PL_parser\->linestr" scalar
+is significant, but not the whole story regarding the input character
+encoding. Normally, when a file is being read, the scalar contains octets
+and its \f(CW\*(C`SvUTF8\*(C'\fR flag is off, but the octets should be interpreted as
+UTF\-8 if the \f(CW\*(C`use utf8\*(C'\fR pragma is in effect. During a string eval,
+however, the scalar may have the \f(CW\*(C`SvUTF8\*(C'\fR flag on, and in this case its
+octets should be interpreted as UTF\-8 unless the \f(CW\*(C`use bytes\*(C'\fR pragma
+is in effect. This logic may change in the future; use this function
+instead of implementing the logic yourself.
+.RS 4
+.Sp
+.Vb 1
+\& bool lex_bufutf8()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_discard_to""" 4
+.el .IP \f(CWlex_discard_to\fR 4
+.IX Xref "lex_discard_to"
+.IX Item "lex_discard_to"
+NOTE: \f(CW\*(C`lex_discard_to\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Discards the first part of the "PL_parser\->linestr" buffer,
+up to \f(CW\*(C`ptr\*(C'\fR. The remaining content of the buffer will be moved, and
+all pointers into the buffer updated appropriately. \f(CW\*(C`ptr\*(C'\fR must not
+be later in the buffer than the position of "PL_parser\->bufptr":
+it is not permitted to discard text that has yet to be lexed.
+.Sp
+Normally it is not necessarily to do this directly, because it suffices to
+use the implicit discarding behaviour of "lex_next_chunk" and things
+based on it. However, if a token stretches across multiple lines,
+and the lexing code has kept multiple lines of text in the buffer for
+that purpose, then after completion of the token it would be wise to
+explicitly discard the now-unneeded earlier lines, to avoid future
+multi-line tokens growing the buffer without bound.
+.RS 4
+.Sp
+.Vb 1
+\& void lex_discard_to(char *ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_grow_linestr""" 4
+.el .IP \f(CWlex_grow_linestr\fR 4
+.IX Xref "lex_grow_linestr"
+.IX Item "lex_grow_linestr"
+NOTE: \f(CW\*(C`lex_grow_linestr\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Reallocates the lexer buffer ("PL_parser\->linestr") to accommodate
+at least \f(CW\*(C`len\*(C'\fR octets (including terminating \f(CW\*(C`NUL\*(C'\fR). Returns a
+pointer to the reallocated buffer. This is necessary before making
+any direct modification of the buffer that would increase its length.
+"lex_stuff_pvn" provides a more convenient way to insert text into
+the buffer.
+.Sp
+Do not use \f(CW\*(C`SvGROW\*(C'\fR or \f(CW\*(C`sv_grow\*(C'\fR directly on \f(CW\*(C`PL_parser\->linestr\*(C'\fR;
+this function updates all of the lexer's variables that point directly
+into the buffer.
+.RS 4
+.Sp
+.Vb 1
+\& char * lex_grow_linestr(STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_next_chunk""" 4
+.el .IP \f(CWlex_next_chunk\fR 4
+.IX Xref "lex_next_chunk"
+.IX Item "lex_next_chunk"
+NOTE: \f(CW\*(C`lex_next_chunk\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Reads in the next chunk of text to be lexed, appending it to
+"PL_parser\->linestr". This should be called when lexing code has
+looked to the end of the current chunk and wants to know more. It is
+usual, but not necessary, for lexing to have consumed the entirety of
+the current chunk at this time.
+.Sp
+If "PL_parser\->bufptr" is pointing to the very end of the current
+chunk (i.e., the current chunk has been entirely consumed), normally the
+current chunk will be discarded at the same time that the new chunk is
+read in. If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`LEX_KEEP_PREVIOUS\*(C'\fR bit set, the current chunk
+will not be discarded. If the current chunk has not been entirely
+consumed, then it will not be discarded regardless of the flag.
+.Sp
+Returns true if some new text was added to the buffer, or false if the
+buffer has reached the end of the input text.
+.RS 4
+.Sp
+.Vb 1
+\& bool lex_next_chunk(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_peek_unichar""" 4
+.el .IP \f(CWlex_peek_unichar\fR 4
+.IX Xref "lex_peek_unichar"
+.IX Item "lex_peek_unichar"
+NOTE: \f(CW\*(C`lex_peek_unichar\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Looks ahead one (Unicode) character in the text currently being lexed.
+Returns the codepoint (unsigned integer value) of the next character,
+or \-1 if lexing has reached the end of the input text. To consume the
+peeked character, use "lex_read_unichar".
+.Sp
+If the next character is in (or extends into) the next chunk of input
+text, the next chunk will be read in. Normally the current chunk will be
+discarded at the same time, but if \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`LEX_KEEP_PREVIOUS\*(C'\fR
+bit set, then the current chunk will not be discarded.
+.Sp
+If the input is being interpreted as UTF\-8 and a UTF\-8 encoding error
+is encountered, an exception is generated.
+.RS 4
+.Sp
+.Vb 1
+\& I32 lex_peek_unichar(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_read_space""" 4
+.el .IP \f(CWlex_read_space\fR 4
+.IX Xref "lex_read_space"
+.IX Item "lex_read_space"
+NOTE: \f(CW\*(C`lex_read_space\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Reads optional spaces, in Perl style, in the text currently being
+lexed. The spaces may include ordinary whitespace characters and
+Perl-style comments. \f(CW\*(C`#line\*(C'\fR directives are processed if encountered.
+"PL_parser\->bufptr" is moved past the spaces, so that it points
+at a non-space character (or the end of the input text).
+.Sp
+If spaces extend into the next chunk of input text, the next chunk will
+be read in. Normally the current chunk will be discarded at the same
+time, but if \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`LEX_KEEP_PREVIOUS\*(C'\fR bit set, then the current
+chunk will not be discarded.
+.RS 4
+.Sp
+.Vb 1
+\& void lex_read_space(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_read_to""" 4
+.el .IP \f(CWlex_read_to\fR 4
+.IX Xref "lex_read_to"
+.IX Item "lex_read_to"
+NOTE: \f(CW\*(C`lex_read_to\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Consume text in the lexer buffer, from "PL_parser\->bufptr" up
+to \f(CW\*(C`ptr\*(C'\fR. This advances "PL_parser\->bufptr" to match \f(CW\*(C`ptr\*(C'\fR,
+performing the correct bookkeeping whenever a newline character is passed.
+This is the normal way to consume lexed text.
+.Sp
+Interpretation of the buffer's octets can be abstracted out by
+using the slightly higher-level functions "lex_peek_unichar" and
+"lex_read_unichar".
+.RS 4
+.Sp
+.Vb 1
+\& void lex_read_to(char *ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_read_unichar""" 4
+.el .IP \f(CWlex_read_unichar\fR 4
+.IX Xref "lex_read_unichar"
+.IX Item "lex_read_unichar"
+NOTE: \f(CW\*(C`lex_read_unichar\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Reads the next (Unicode) character in the text currently being lexed.
+Returns the codepoint (unsigned integer value) of the character read,
+and moves "PL_parser\->bufptr" past the character, or returns \-1
+if lexing has reached the end of the input text. To non-destructively
+examine the next character, use "lex_peek_unichar" instead.
+.Sp
+If the next character is in (or extends into) the next chunk of input
+text, the next chunk will be read in. Normally the current chunk will be
+discarded at the same time, but if \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`LEX_KEEP_PREVIOUS\*(C'\fR
+bit set, then the current chunk will not be discarded.
+.Sp
+If the input is being interpreted as UTF\-8 and a UTF\-8 encoding error
+is encountered, an exception is generated.
+.RS 4
+.Sp
+.Vb 1
+\& I32 lex_read_unichar(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_start""" 4
+.el .IP \f(CWlex_start\fR 4
+.IX Xref "lex_start"
+.IX Item "lex_start"
+NOTE: \f(CW\*(C`lex_start\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Creates and initialises a new lexer/parser state object, supplying
+a context in which to lex and parse from a new source of Perl code.
+A pointer to the new state object is placed in "PL_parser". An entry
+is made on the save stack so that upon unwinding, the new state object
+will be destroyed and the former value of "PL_parser" will be restored.
+Nothing else need be done to clean up the parsing context.
+.Sp
+The code to be parsed comes from \f(CW\*(C`line\*(C'\fR and \f(CW\*(C`rsfp\*(C'\fR. \f(CW\*(C`line\*(C'\fR, if
+non-null, provides a string (in SV form) containing code to be parsed.
+A copy of the string is made, so subsequent modification of \f(CW\*(C`line\*(C'\fR
+does not affect parsing. \f(CW\*(C`rsfp\*(C'\fR, if non-null, provides an input stream
+from which code will be read to be parsed. If both are non-null, the
+code in \f(CW\*(C`line\*(C'\fR comes first and must consist of complete lines of input,
+and \f(CW\*(C`rsfp\*(C'\fR supplies the remainder of the source.
+.Sp
+The \f(CW\*(C`flags\*(C'\fR parameter is reserved for future use. Currently it is only
+used by perl internally, so extensions should always pass zero.
+.RS 4
+.Sp
+.Vb 1
+\& void lex_start(SV *line, PerlIO *rsfp, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_stuff_pv""" 4
+.el .IP \f(CWlex_stuff_pv\fR 4
+.IX Xref "lex_stuff_pv"
+.IX Item "lex_stuff_pv"
+NOTE: \f(CW\*(C`lex_stuff_pv\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Insert characters into the lexer buffer ("PL_parser\->linestr"),
+immediately after the current lexing point ("PL_parser\->bufptr"),
+reallocating the buffer if necessary. This means that lexing code that
+runs later will see the characters as if they had appeared in the input.
+It is not recommended to do this as part of normal parsing, and most
+uses of this facility run the risk of the inserted characters being
+interpreted in an unintended manner.
+.Sp
+The string to be inserted is represented by octets starting at \f(CW\*(C`pv\*(C'\fR
+and continuing to the first nul. These octets are interpreted as either
+UTF\-8 or Latin\-1, according to whether the \f(CW\*(C`LEX_STUFF_UTF8\*(C'\fR flag is set
+in \f(CW\*(C`flags\*(C'\fR. The characters are recoded for the lexer buffer, according
+to how the buffer is currently being interpreted ("lex_bufutf8").
+If it is not convenient to nul-terminate a string to be inserted, the
+"lex_stuff_pvn" function is more appropriate.
+.RS 4
+.Sp
+.Vb 1
+\& void lex_stuff_pv(const char *pv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_stuff_pvn""" 4
+.el .IP \f(CWlex_stuff_pvn\fR 4
+.IX Xref "lex_stuff_pvn"
+.IX Item "lex_stuff_pvn"
+NOTE: \f(CW\*(C`lex_stuff_pvn\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Insert characters into the lexer buffer ("PL_parser\->linestr"),
+immediately after the current lexing point ("PL_parser\->bufptr"),
+reallocating the buffer if necessary. This means that lexing code that
+runs later will see the characters as if they had appeared in the input.
+It is not recommended to do this as part of normal parsing, and most
+uses of this facility run the risk of the inserted characters being
+interpreted in an unintended manner.
+.Sp
+The string to be inserted is represented by \f(CW\*(C`len\*(C'\fR octets starting
+at \f(CW\*(C`pv\*(C'\fR. These octets are interpreted as either UTF\-8 or Latin\-1,
+according to whether the \f(CW\*(C`LEX_STUFF_UTF8\*(C'\fR flag is set in \f(CW\*(C`flags\*(C'\fR.
+The characters are recoded for the lexer buffer, according to how the
+buffer is currently being interpreted ("lex_bufutf8"). If a string
+to be inserted is available as a Perl scalar, the "lex_stuff_sv"
+function is more convenient.
+.RS 4
+.Sp
+.Vb 1
+\& void lex_stuff_pvn(const char *pv, STRLEN len, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_stuff_pvs""" 4
+.el .IP \f(CWlex_stuff_pvs\fR 4
+.IX Xref "lex_stuff_pvs"
+.IX Item "lex_stuff_pvs"
+NOTE: \f(CW\*(C`lex_stuff_pvs\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Like "lex_stuff_pvn", but takes a literal string instead of
+a string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& void lex_stuff_pvs("pv", U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_stuff_sv""" 4
+.el .IP \f(CWlex_stuff_sv\fR 4
+.IX Xref "lex_stuff_sv"
+.IX Item "lex_stuff_sv"
+NOTE: \f(CW\*(C`lex_stuff_sv\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Insert characters into the lexer buffer ("PL_parser\->linestr"),
+immediately after the current lexing point ("PL_parser\->bufptr"),
+reallocating the buffer if necessary. This means that lexing code that
+runs later will see the characters as if they had appeared in the input.
+It is not recommended to do this as part of normal parsing, and most
+uses of this facility run the risk of the inserted characters being
+interpreted in an unintended manner.
+.Sp
+The string to be inserted is the string value of \f(CW\*(C`sv\*(C'\fR. The characters
+are recoded for the lexer buffer, according to how the buffer is currently
+being interpreted ("lex_bufutf8"). If a string to be inserted is
+not already a Perl scalar, the "lex_stuff_pvn" function avoids the
+need to construct a scalar.
+.RS 4
+.Sp
+.Vb 1
+\& void lex_stuff_sv(SV *sv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """lex_unstuff""" 4
+.el .IP \f(CWlex_unstuff\fR 4
+.IX Xref "lex_unstuff"
+.IX Item "lex_unstuff"
+NOTE: \f(CW\*(C`lex_unstuff\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Discards text about to be lexed, from "PL_parser\->bufptr" up to
+\&\f(CW\*(C`ptr\*(C'\fR. Text following \f(CW\*(C`ptr\*(C'\fR will be moved, and the buffer shortened.
+This hides the discarded text from any lexing code that runs later,
+as if the text had never appeared.
+.Sp
+This is not the normal way to consume lexed text. For that, use
+"lex_read_to".
+.RS 4
+.Sp
+.Vb 1
+\& void lex_unstuff(char *ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_arithexpr""" 4
+.el .IP \f(CWparse_arithexpr\fR 4
+.IX Xref "parse_arithexpr"
+.IX Item "parse_arithexpr"
+NOTE: \f(CW\*(C`parse_arithexpr\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a Perl arithmetic expression. This may contain operators of precedence
+down to the bit shift operators. The expression must be followed (and thus
+terminated) either by a comparison or lower-precedence operator or by
+something that would normally terminate an expression such as semicolon.
+If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`PARSE_OPTIONAL\*(C'\fR bit set, then the expression is optional,
+otherwise it is mandatory. It is up to the caller to ensure that the
+dynamic parser state ("PL_parser" et al) is correctly set to reflect
+the source of the code to be parsed and the lexical context for the
+expression.
+.Sp
+The op tree representing the expression is returned. If an optional
+expression is absent, a null pointer is returned, otherwise the pointer
+will be non-null.
+.Sp
+If an error occurs in parsing or compilation, in most cases a valid op
+tree is returned anyway. The error is reflected in the parser state,
+normally resulting in a single exception at the top level of parsing
+which covers all the compilation errors that occurred. Some compilation
+errors, however, will throw an exception immediately.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_arithexpr(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_barestmt""" 4
+.el .IP \f(CWparse_barestmt\fR 4
+.IX Xref "parse_barestmt"
+.IX Item "parse_barestmt"
+NOTE: \f(CW\*(C`parse_barestmt\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a single unadorned Perl statement. This may be a normal imperative
+statement or a declaration that has compile-time effect. It does not
+include any label or other affixture. It is up to the caller to ensure
+that the dynamic parser state ("PL_parser" et al) is correctly set to
+reflect the source of the code to be parsed and the lexical context for
+the statement.
+.Sp
+The op tree representing the statement is returned. This may be a
+null pointer if the statement is null, for example if it was actually
+a subroutine definition (which has compile-time side effects). If not
+null, it will be ops directly implementing the statement, suitable to
+pass to "newSTATEOP". It will not normally include a \f(CW\*(C`nextstate\*(C'\fR or
+equivalent op (except for those embedded in a scope contained entirely
+within the statement).
+.Sp
+If an error occurs in parsing or compilation, in most cases a valid op
+tree (most likely null) is returned anyway. The error is reflected in
+the parser state, normally resulting in a single exception at the top
+level of parsing which covers all the compilation errors that occurred.
+Some compilation errors, however, will throw an exception immediately.
+.Sp
+The \f(CW\*(C`flags\*(C'\fR parameter is reserved for future use, and must always
+be zero.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_barestmt(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_block""" 4
+.el .IP \f(CWparse_block\fR 4
+.IX Xref "parse_block"
+.IX Item "parse_block"
+NOTE: \f(CW\*(C`parse_block\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a single complete Perl code block. This consists of an opening
+brace, a sequence of statements, and a closing brace. The block
+constitutes a lexical scope, so \f(CW\*(C`my\*(C'\fR variables and various compile-time
+effects can be contained within it. It is up to the caller to ensure
+that the dynamic parser state ("PL_parser" et al) is correctly set to
+reflect the source of the code to be parsed and the lexical context for
+the statement.
+.Sp
+The op tree representing the code block is returned. This is always a
+real op, never a null pointer. It will normally be a \f(CW\*(C`lineseq\*(C'\fR list,
+including \f(CW\*(C`nextstate\*(C'\fR or equivalent ops. No ops to construct any kind
+of runtime scope are included by virtue of it being a block.
+.Sp
+If an error occurs in parsing or compilation, in most cases a valid op
+tree (most likely null) is returned anyway. The error is reflected in
+the parser state, normally resulting in a single exception at the top
+level of parsing which covers all the compilation errors that occurred.
+Some compilation errors, however, will throw an exception immediately.
+.Sp
+The \f(CW\*(C`flags\*(C'\fR parameter is reserved for future use, and must always
+be zero.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_block(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_fullexpr""" 4
+.el .IP \f(CWparse_fullexpr\fR 4
+.IX Xref "parse_fullexpr"
+.IX Item "parse_fullexpr"
+NOTE: \f(CW\*(C`parse_fullexpr\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a single complete Perl expression. This allows the full
+expression grammar, including the lowest-precedence operators such
+as \f(CW\*(C`or\*(C'\fR. The expression must be followed (and thus terminated) by a
+token that an expression would normally be terminated by: end-of-file,
+closing bracketing punctuation, semicolon, or one of the keywords that
+signals a postfix expression-statement modifier. If \f(CW\*(C`flags\*(C'\fR has the
+\&\f(CW\*(C`PARSE_OPTIONAL\*(C'\fR bit set, then the expression is optional, otherwise it is
+mandatory. It is up to the caller to ensure that the dynamic parser
+state ("PL_parser" et al) is correctly set to reflect the source of
+the code to be parsed and the lexical context for the expression.
+.Sp
+The op tree representing the expression is returned. If an optional
+expression is absent, a null pointer is returned, otherwise the pointer
+will be non-null.
+.Sp
+If an error occurs in parsing or compilation, in most cases a valid op
+tree is returned anyway. The error is reflected in the parser state,
+normally resulting in a single exception at the top level of parsing
+which covers all the compilation errors that occurred. Some compilation
+errors, however, will throw an exception immediately.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_fullexpr(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_fullstmt""" 4
+.el .IP \f(CWparse_fullstmt\fR 4
+.IX Xref "parse_fullstmt"
+.IX Item "parse_fullstmt"
+NOTE: \f(CW\*(C`parse_fullstmt\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a single complete Perl statement. This may be a normal imperative
+statement or a declaration that has compile-time effect, and may include
+optional labels. It is up to the caller to ensure that the dynamic
+parser state ("PL_parser" et al) is correctly set to reflect the source
+of the code to be parsed and the lexical context for the statement.
+.Sp
+The op tree representing the statement is returned. This may be a
+null pointer if the statement is null, for example if it was actually
+a subroutine definition (which has compile-time side effects). If not
+null, it will be the result of a "newSTATEOP" call, normally including
+a \f(CW\*(C`nextstate\*(C'\fR or equivalent op.
+.Sp
+If an error occurs in parsing or compilation, in most cases a valid op
+tree (most likely null) is returned anyway. The error is reflected in
+the parser state, normally resulting in a single exception at the top
+level of parsing which covers all the compilation errors that occurred.
+Some compilation errors, however, will throw an exception immediately.
+.Sp
+The \f(CW\*(C`flags\*(C'\fR parameter is reserved for future use, and must always
+be zero.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_fullstmt(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_label""" 4
+.el .IP \f(CWparse_label\fR 4
+.IX Xref "parse_label"
+.IX Item "parse_label"
+NOTE: \f(CW\*(C`parse_label\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a single label, possibly optional, of the type that may prefix a
+Perl statement. It is up to the caller to ensure that the dynamic parser
+state ("PL_parser" et al) is correctly set to reflect the source of
+the code to be parsed. If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`PARSE_OPTIONAL\*(C'\fR bit set, then the
+label is optional, otherwise it is mandatory.
+.Sp
+The name of the label is returned in the form of a fresh scalar. If an
+optional label is absent, a null pointer is returned.
+.Sp
+If an error occurs in parsing, which can only occur if the label is
+mandatory, a valid label is returned anyway. The error is reflected in
+the parser state, normally resulting in a single exception at the top
+level of parsing which covers all the compilation errors that occurred.
+.RS 4
+.Sp
+.Vb 1
+\& SV * parse_label(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_listexpr""" 4
+.el .IP \f(CWparse_listexpr\fR 4
+.IX Xref "parse_listexpr"
+.IX Item "parse_listexpr"
+NOTE: \f(CW\*(C`parse_listexpr\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a Perl list expression. This may contain operators of precedence
+down to the comma operator. The expression must be followed (and thus
+terminated) either by a low-precedence logic operator such as \f(CW\*(C`or\*(C'\fR or by
+something that would normally terminate an expression such as semicolon.
+If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`PARSE_OPTIONAL\*(C'\fR bit set, then the expression is optional,
+otherwise it is mandatory. It is up to the caller to ensure that the
+dynamic parser state ("PL_parser" et al) is correctly set to reflect
+the source of the code to be parsed and the lexical context for the
+expression.
+.Sp
+The op tree representing the expression is returned. If an optional
+expression is absent, a null pointer is returned, otherwise the pointer
+will be non-null.
+.Sp
+If an error occurs in parsing or compilation, in most cases a valid op
+tree is returned anyway. The error is reflected in the parser state,
+normally resulting in a single exception at the top level of parsing
+which covers all the compilation errors that occurred. Some compilation
+errors, however, will throw an exception immediately.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_listexpr(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_stmtseq""" 4
+.el .IP \f(CWparse_stmtseq\fR 4
+.IX Xref "parse_stmtseq"
+.IX Item "parse_stmtseq"
+NOTE: \f(CW\*(C`parse_stmtseq\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a sequence of zero or more Perl statements. These may be normal
+imperative statements, including optional labels, or declarations
+that have compile-time effect, or any mixture thereof. The statement
+sequence ends when a closing brace or end-of-file is encountered in a
+place where a new statement could have validly started. It is up to
+the caller to ensure that the dynamic parser state ("PL_parser" et al)
+is correctly set to reflect the source of the code to be parsed and the
+lexical context for the statements.
+.Sp
+The op tree representing the statement sequence is returned. This may
+be a null pointer if the statements were all null, for example if there
+were no statements or if there were only subroutine definitions (which
+have compile-time side effects). If not null, it will be a \f(CW\*(C`lineseq\*(C'\fR
+list, normally including \f(CW\*(C`nextstate\*(C'\fR or equivalent ops.
+.Sp
+If an error occurs in parsing or compilation, in most cases a valid op
+tree is returned anyway. The error is reflected in the parser state,
+normally resulting in a single exception at the top level of parsing
+which covers all the compilation errors that occurred. Some compilation
+errors, however, will throw an exception immediately.
+.Sp
+The \f(CW\*(C`flags\*(C'\fR parameter is reserved for future use, and must always
+be zero.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_stmtseq(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_subsignature""" 4
+.el .IP \f(CWparse_subsignature\fR 4
+.IX Xref "parse_subsignature"
+.IX Item "parse_subsignature"
+NOTE: \f(CW\*(C`parse_subsignature\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a subroutine signature declaration. This is the contents of the
+parentheses following a named or anonymous subroutine declaration when the
+\&\f(CW\*(C`signatures\*(C'\fR feature is enabled. Note that this function neither expects
+nor consumes the opening and closing parentheses around the signature; it
+is the caller's job to handle these.
+.Sp
+This function must only be called during parsing of a subroutine; after
+"start_subparse" has been called. It might allocate lexical variables on
+the pad for the current subroutine.
+.Sp
+The op tree to unpack the arguments from the stack at runtime is returned.
+This op tree should appear at the beginning of the compiled function. The
+caller may wish to use "op_append_list" to build their function body
+after it, or splice it together with the body before calling "newATTRSUB".
+.Sp
+The \f(CW\*(C`flags\*(C'\fR parameter is reserved for future use, and must always
+be zero.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_subsignature(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """parse_termexpr""" 4
+.el .IP \f(CWparse_termexpr\fR 4
+.IX Xref "parse_termexpr"
+.IX Item "parse_termexpr"
+NOTE: \f(CW\*(C`parse_termexpr\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Parse a Perl term expression. This may contain operators of precedence
+down to the assignment operators. The expression must be followed (and thus
+terminated) either by a comma or lower-precedence operator or by
+something that would normally terminate an expression such as semicolon.
+If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`PARSE_OPTIONAL\*(C'\fR bit set, then the expression is optional,
+otherwise it is mandatory. It is up to the caller to ensure that the
+dynamic parser state ("PL_parser" et al) is correctly set to reflect
+the source of the code to be parsed and the lexical context for the
+expression.
+.Sp
+The op tree representing the expression is returned. If an optional
+expression is absent, a null pointer is returned, otherwise the pointer
+will be non-null.
+.Sp
+If an error occurs in parsing or compilation, in most cases a valid op
+tree is returned anyway. The error is reflected in the parser state,
+normally resulting in a single exception at the top level of parsing
+which covers all the compilation errors that occurred. Some compilation
+errors, however, will throw an exception immediately.
+.RS 4
+.Sp
+.Vb 1
+\& OP * parse_termexpr(U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_parser""" 4
+.el .IP \f(CWPL_parser\fR 4
+.IX Xref "PL_parser"
+.IX Item "PL_parser"
+Pointer to a structure encapsulating the state of the parsing operation
+currently in progress. The pointer can be locally changed to perform
+a nested parse without interfering with the state of an outer parse.
+Individual members of \f(CW\*(C`PL_parser\*(C'\fR have their own documentation.
+.ie n .IP """PL_parser\->bufend""" 4
+.el .IP \f(CWPL_parser\->bufend\fR 4
+.IX Xref "PL_parser->bufend"
+.IX Item "PL_parser->bufend"
+NOTE: \f(CW\*(C`PL_parser\->bufend\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Direct pointer to the end of the chunk of text currently being lexed, the
+end of the lexer buffer. This is equal to \f(CW\*(C`SvPVX(PL_parser\->linestr)
++ SvCUR(PL_parser\->linestr)\*(C'\fR. A \f(CW\*(C`NUL\*(C'\fR character (zero octet) is
+always located at the end of the buffer, and does not count as part of
+the buffer's contents.
+.ie n .IP """PL_parser\->bufptr""" 4
+.el .IP \f(CWPL_parser\->bufptr\fR 4
+.IX Xref "PL_parser->bufptr"
+.IX Item "PL_parser->bufptr"
+NOTE: \f(CW\*(C`PL_parser\->bufptr\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Points to the current position of lexing inside the lexer buffer.
+Characters around this point may be freely examined, within
+the range delimited by \f(CWSvPVX("PL_parser\->linestr")\fR and
+"PL_parser\->bufend". The octets of the buffer may be intended to be
+interpreted as either UTF\-8 or Latin\-1, as indicated by "lex_bufutf8".
+.Sp
+Lexing code (whether in the Perl core or not) moves this pointer past
+the characters that it consumes. It is also expected to perform some
+bookkeeping whenever a newline character is consumed. This movement
+can be more conveniently performed by the function "lex_read_to",
+which handles newlines appropriately.
+.Sp
+Interpretation of the buffer's octets can be abstracted out by
+using the slightly higher-level functions "lex_peek_unichar" and
+"lex_read_unichar".
+.ie n .IP """PL_parser\->linestart""" 4
+.el .IP \f(CWPL_parser\->linestart\fR 4
+.IX Xref "PL_parser->linestart"
+.IX Item "PL_parser->linestart"
+NOTE: \f(CW\*(C`PL_parser\->linestart\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Points to the start of the current line inside the lexer buffer.
+This is useful for indicating at which column an error occurred, and
+not much else. This must be updated by any lexing code that consumes
+a newline; the function "lex_read_to" handles this detail.
+.ie n .IP """PL_parser\->linestr""" 4
+.el .IP \f(CWPL_parser\->linestr\fR 4
+.IX Xref "PL_parser->linestr"
+.IX Item "PL_parser->linestr"
+NOTE: \f(CW\*(C`PL_parser\->linestr\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Buffer scalar containing the chunk currently under consideration of the
+text currently being lexed. This is always a plain string scalar (for
+which \f(CW\*(C`SvPOK\*(C'\fR is true). It is not intended to be used as a scalar by
+normal scalar means; instead refer to the buffer directly by the pointer
+variables described below.
+.Sp
+The lexer maintains various \f(CW\*(C`char*\*(C'\fR pointers to things in the
+\&\f(CW\*(C`PL_parser\->linestr\*(C'\fR buffer. If \f(CW\*(C`PL_parser\->linestr\*(C'\fR is ever
+reallocated, all of these pointers must be updated. Don't attempt to
+do this manually, but rather use "lex_grow_linestr" if you need to
+reallocate the buffer.
+.Sp
+The content of the text chunk in the buffer is commonly exactly one
+complete line of input, up to and including a newline terminator,
+but there are situations where it is otherwise. The octets of the
+buffer may be intended to be interpreted as either UTF\-8 or Latin\-1.
+The function "lex_bufutf8" tells you which. Do not use the \f(CW\*(C`SvUTF8\*(C'\fR
+flag on this scalar, which may disagree with it.
+.Sp
+For direct examination of the buffer, the variable
+"PL_parser\->bufend" points to the end of the buffer. The current
+lexing position is pointed to by "PL_parser\->bufptr". Direct use
+of these pointers is usually preferable to examination of the scalar
+through normal scalar means.
+.ie n .IP """suspend_compcv""" 4
+.el .IP \f(CWsuspend_compcv\fR 4
+.IX Xref "suspend_compcv"
+.IX Item "suspend_compcv"
+Implements part of the concept of a "suspended compilation CV", which can be
+used to pause the parser and compiler during parsing a CV in order to come
+back to it later on.
+.Sp
+This function saves the current state of the subroutine under compilation
+(\f(CW\*(C`PL_compcv\*(C'\fR) into the supplied buffer. This should be used initially to
+create the state in the buffer, as the final thing before a \f(CW\*(C`LEAVE\*(C'\fR within a
+block.
+.Sp
+.Vb 3
+\& ENTER;
+\& start_subparse(0);
+\& ...
+\&
+\& suspend_compcv(&buffer);
+\& LEAVE;
+.Ve
+.Sp
+Once suspended, the \f(CW\*(C`resume_compcv\*(C'\fR or \f(CW\*(C`resume_compcv_and_save\*(C'\fR function can
+later be used to continue the parsing from the point this stopped.
+.RS 4
+.Sp
+.Vb 1
+\& void suspend_compcv(struct suspended_compcv *buffer)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """wrap_infix_plugin""" 4
+.el .IP \f(CWwrap_infix_plugin\fR 4
+.IX Xref "wrap_infix_plugin"
+.IX Item "wrap_infix_plugin"
+NOTE: \f(CW\*(C`wrap_infix_plugin\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+\&\fBNOTE:\fR This API exists entirely for the purpose of making the CPAN module
+\&\f(CW\*(C`XS::Parse::Infix\*(C'\fR work. It is not expected that additional modules will make
+use of it; rather, that they should use \f(CW\*(C`XS::Parse::Infix\*(C'\fR to provide parsing
+of new infix operators.
+.Sp
+Puts a C function into the chain of infix plugins. This is the preferred
+way to manipulate the "PL_infix_plugin" variable. \f(CW\*(C`new_plugin\*(C'\fR is a
+pointer to the C function that is to be added to the infix plugin chain, and
+\&\f(CW\*(C`old_plugin_p\*(C'\fR points to a storage location where a pointer to the next
+function in the chain will be stored. The value of \f(CW\*(C`new_plugin\*(C'\fR is written
+into the "PL_infix_plugin" variable, while the value previously stored there
+is written to \f(CW*old_plugin_p\fR.
+.Sp
+Direct access to "PL_infix_plugin" should be avoided.
+.RS 4
+.Sp
+.Vb 2
+\& void wrap_infix_plugin(Perl_infix_plugin_t new_plugin,
+\& Perl_infix_plugin_t *old_plugin_p)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """wrap_keyword_plugin""" 4
+.el .IP \f(CWwrap_keyword_plugin\fR 4
+.IX Xref "wrap_keyword_plugin"
+.IX Item "wrap_keyword_plugin"
+NOTE: \f(CW\*(C`wrap_keyword_plugin\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Puts a C function into the chain of keyword plugins. This is the
+preferred way to manipulate the "PL_keyword_plugin" variable.
+\&\f(CW\*(C`new_plugin\*(C'\fR is a pointer to the C function that is to be added to the
+keyword plugin chain, and \f(CW\*(C`old_plugin_p\*(C'\fR points to the storage location
+where a pointer to the next function in the chain will be stored. The
+value of \f(CW\*(C`new_plugin\*(C'\fR is written into the "PL_keyword_plugin" variable,
+while the value previously stored there is written to \f(CW*old_plugin_p\fR.
+.Sp
+"PL_keyword_plugin" is global to an entire process, and a module wishing
+to hook keyword parsing may find itself invoked more than once per
+process, typically in different threads. To handle that situation, this
+function is idempotent. The location \f(CW*old_plugin_p\fR must initially
+(once per process) contain a null pointer. A C variable of static
+duration (declared at file scope, typically also marked \f(CW\*(C`static\*(C'\fR to give
+it internal linkage) will be implicitly initialised appropriately, if it
+does not have an explicit initialiser. This function will only actually
+modify the plugin chain if it finds \f(CW*old_plugin_p\fR to be null. This
+function is also thread safe on the small scale. It uses appropriate
+locking to avoid race conditions in accessing "PL_keyword_plugin".
+.Sp
+When this function is called, the function referenced by \f(CW\*(C`new_plugin\*(C'\fR
+must be ready to be called, except for \f(CW*old_plugin_p\fR being unfilled.
+In a threading situation, \f(CW\*(C`new_plugin\*(C'\fR may be called immediately, even
+before this function has returned. \f(CW*old_plugin_p\fR will always be
+appropriately set before \f(CW\*(C`new_plugin\*(C'\fR is called. If \f(CW\*(C`new_plugin\*(C'\fR
+decides not to do anything special with the identifier that it is given
+(which is the usual case for most calls to a keyword plugin), it must
+chain the plugin function referenced by \f(CW*old_plugin_p\fR.
+.Sp
+Taken all together, XS code to install a keyword plugin should typically
+look something like this:
+.Sp
+.Vb 10
+\& static Perl_keyword_plugin_t next_keyword_plugin;
+\& static OP *my_keyword_plugin(pTHX_
+\& char *keyword_ptr, STRLEN keyword_len, OP **op_ptr)
+\& {
+\& if (memEQs(keyword_ptr, keyword_len,
+\& "my_new_keyword")) {
+\& ...
+\& } else {
+\& return next_keyword_plugin(aTHX_
+\& keyword_ptr, keyword_len, op_ptr);
+\& }
+\& }
+\& BOOT:
+\& wrap_keyword_plugin(my_keyword_plugin,
+\& &next_keyword_plugin);
+.Ve
+.Sp
+Direct access to "PL_keyword_plugin" should be avoided.
+.RS 4
+.Sp
+.Vb 2
+\& void wrap_keyword_plugin(Perl_keyword_plugin_t new_plugin,
+\& Perl_keyword_plugin_t *old_plugin_p)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Locales
+.IX Header "Locales"
+.ie n .IP """DECLARATION_FOR_LC_NUMERIC_MANIPULATION""" 4
+.el .IP \f(CWDECLARATION_FOR_LC_NUMERIC_MANIPULATION\fR 4
+.IX Xref "DECLARATION_FOR_LC_NUMERIC_MANIPULATION"
+.IX Item "DECLARATION_FOR_LC_NUMERIC_MANIPULATION"
+This macro should be used as a statement. It declares a private variable
+(whose name begins with an underscore) that is needed by the other macros in
+this section. Failing to include this correctly should lead to a syntax error.
+For compatibility with C89 C compilers it should be placed in a block before
+any executable statements.
+.RS 4
+.Sp
+.Vb 1
+\& void DECLARATION_FOR_LC_NUMERIC_MANIPULATION
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """foldEQ_locale""" 4
+.el .IP \f(CWfoldEQ_locale\fR 4
+.IX Xref "foldEQ_locale"
+.IX Item "foldEQ_locale"
+Returns true if the leading \f(CW\*(C`len\*(C'\fR bytes of the strings \f(CW\*(C`s1\*(C'\fR and \f(CW\*(C`s2\*(C'\fR are the
+same case-insensitively in the current locale; false otherwise.
+.RS 4
+.Sp
+.Vb 1
+\& I32 foldEQ_locale(const char *a, const char *b, I32 len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HAS_DUPLOCALE""" 4
+.el .IP \f(CWHAS_DUPLOCALE\fR 4
+.IX Xref "HAS_DUPLOCALE"
+.IX Item "HAS_DUPLOCALE"
+This symbol, if defined, indicates that the \f(CW\*(C`duplocale\*(C'\fR routine is
+available to duplicate a locale object.
+.ie n .IP """HAS_FREELOCALE""" 4
+.el .IP \f(CWHAS_FREELOCALE\fR 4
+.IX Xref "HAS_FREELOCALE"
+.IX Item "HAS_FREELOCALE"
+This symbol, if defined, indicates that the \f(CW\*(C`freelocale\*(C'\fR routine is
+available to deallocates the resources associated with a locale object.
+.ie n .IP """HAS_LC_MONETARY_2008""" 4
+.el .IP \f(CWHAS_LC_MONETARY_2008\fR 4
+.IX Xref "HAS_LC_MONETARY_2008"
+.IX Item "HAS_LC_MONETARY_2008"
+This symbol, if defined, indicates that the localeconv routine is
+available and has the additional members added in \f(CW\*(C`POSIX\*(C'\fR 1003.1\-2008.
+.ie n .IP """HAS_LOCALECONV""" 4
+.el .IP \f(CWHAS_LOCALECONV\fR 4
+.IX Xref "HAS_LOCALECONV"
+.IX Item "HAS_LOCALECONV"
+This symbol, if defined, indicates that the \f(CW\*(C`localeconv\*(C'\fR routine is
+available for numeric and monetary formatting conventions.
+.ie n .IP """HAS_LOCALECONV_L""" 4
+.el .IP \f(CWHAS_LOCALECONV_L\fR 4
+.IX Xref "HAS_LOCALECONV_L"
+.IX Item "HAS_LOCALECONV_L"
+This symbol, if defined, indicates that the \f(CW\*(C`localeconv_l\*(C'\fR routine is
+available to query certain information about a locale.
+.ie n .IP """HAS_NEWLOCALE""" 4
+.el .IP \f(CWHAS_NEWLOCALE\fR 4
+.IX Xref "HAS_NEWLOCALE"
+.IX Item "HAS_NEWLOCALE"
+This symbol, if defined, indicates that the \f(CW\*(C`newlocale\*(C'\fR routine is
+available to return a new locale object or modify an existing
+locale object.
+.ie n .IP """HAS_NL_LANGINFO""" 4
+.el .IP \f(CWHAS_NL_LANGINFO\fR 4
+.IX Xref "HAS_NL_LANGINFO"
+.IX Item "HAS_NL_LANGINFO"
+This symbol, if defined, indicates that the \f(CW\*(C`nl_langinfo\*(C'\fR routine is
+available to return local data. You will also need \fIlanginfo.h\fR
+and therefore \f(CW\*(C`I_LANGINFO\*(C'\fR.
+.ie n .IP """HAS_NL_LANGINFO_L""" 4
+.el .IP \f(CWHAS_NL_LANGINFO_L\fR 4
+.IX Xref "HAS_NL_LANGINFO_L"
+.IX Item "HAS_NL_LANGINFO_L"
+This symbol, when defined, indicates presence of the \f(CWnl_langinfo_l()\fR
+function
+.ie n .IP """HAS_QUERYLOCALE""" 4
+.el .IP \f(CWHAS_QUERYLOCALE\fR 4
+.IX Xref "HAS_QUERYLOCALE"
+.IX Item "HAS_QUERYLOCALE"
+This symbol, if defined, indicates that the \f(CW\*(C`querylocale\*(C'\fR routine is
+available to return the name of the locale for a category mask.
+.ie n .IP """HAS_SETLOCALE""" 4
+.el .IP \f(CWHAS_SETLOCALE\fR 4
+.IX Xref "HAS_SETLOCALE"
+.IX Item "HAS_SETLOCALE"
+This symbol, if defined, indicates that the \f(CW\*(C`setlocale\*(C'\fR routine is
+available to handle locale-specific ctype implementations.
+.ie n .IP """HAS_SETLOCALE_R""" 4
+.el .IP \f(CWHAS_SETLOCALE_R\fR 4
+.IX Xref "HAS_SETLOCALE_R"
+.IX Item "HAS_SETLOCALE_R"
+This symbol, if defined, indicates that the \f(CW\*(C`setlocale_r\*(C'\fR routine
+is available to setlocale re-entrantly.
+.ie n .IP """HAS_THREAD_SAFE_NL_LANGINFO_L""" 4
+.el .IP \f(CWHAS_THREAD_SAFE_NL_LANGINFO_L\fR 4
+.IX Xref "HAS_THREAD_SAFE_NL_LANGINFO_L"
+.IX Item "HAS_THREAD_SAFE_NL_LANGINFO_L"
+This symbol, when defined, indicates presence of the \f(CWnl_langinfo_l()\fR
+function, and that it is thread-safe.
+.ie n .IP """HAS_USELOCALE""" 4
+.el .IP \f(CWHAS_USELOCALE\fR 4
+.IX Xref "HAS_USELOCALE"
+.IX Item "HAS_USELOCALE"
+This symbol, if defined, indicates that the \f(CW\*(C`uselocale\*(C'\fR routine is
+available to set the current locale for the calling thread.
+.ie n .IP """I_LANGINFO""" 4
+.el .IP \f(CWI_LANGINFO\fR 4
+.IX Xref "I_LANGINFO"
+.IX Item "I_LANGINFO"
+This symbol, if defined, indicates that \fIlanginfo.h\fR exists and
+should be included.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_LANGINFO
+\& #include <langinfo.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_LOCALE""" 4
+.el .IP \f(CWI_LOCALE\fR 4
+.IX Xref "I_LOCALE"
+.IX Item "I_LOCALE"
+This symbol, if defined, indicates to the C program that it should
+include \fIlocale.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_LOCALE
+\& #include <locale.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IN_LOCALE""" 4
+.el .IP \f(CWIN_LOCALE\fR 4
+.IX Xref "IN_LOCALE"
+.IX Item "IN_LOCALE"
+Evaluates to TRUE if the plain locale pragma without a parameter (\f(CW\*(C`use\ locale\*(C'\fR) is in effect.
+.RS 4
+.Sp
+.Vb 1
+\& bool IN_LOCALE
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IN_LOCALE_COMPILETIME""" 4
+.el .IP \f(CWIN_LOCALE_COMPILETIME\fR 4
+.IX Xref "IN_LOCALE_COMPILETIME"
+.IX Item "IN_LOCALE_COMPILETIME"
+Evaluates to TRUE if, when compiling a perl program (including an \f(CW\*(C`eval\*(C'\fR) if
+the plain locale pragma without a parameter (\f(CW\*(C`use\ locale\*(C'\fR) is in effect.
+.RS 4
+.Sp
+.Vb 1
+\& bool IN_LOCALE_COMPILETIME
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IN_LOCALE_RUNTIME""" 4
+.el .IP \f(CWIN_LOCALE_RUNTIME\fR 4
+.IX Xref "IN_LOCALE_RUNTIME"
+.IX Item "IN_LOCALE_RUNTIME"
+Evaluates to TRUE if, when executing a perl program (including an \f(CW\*(C`eval\*(C'\fR) if
+the plain locale pragma without a parameter (\f(CW\*(C`use\ locale\*(C'\fR) is in effect.
+.RS 4
+.Sp
+.Vb 1
+\& bool IN_LOCALE_RUNTIME
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_XLOCALE""" 4
+.el .IP \f(CWI_XLOCALE\fR 4
+.IX Xref "I_XLOCALE"
+.IX Item "I_XLOCALE"
+This symbol, if defined, indicates to the C program that the
+header \fIxlocale.h\fR is available. See also \f(CW"NEED_XLOCALE_H"\fR
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_XLOCALE
+\& #include <xlocale.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """NEED_XLOCALE_H""" 4
+.el .IP \f(CWNEED_XLOCALE_H\fR 4
+.IX Xref "NEED_XLOCALE_H"
+.IX Item "NEED_XLOCALE_H"
+This symbol, if defined, indicates that the C program should
+include \fIxlocale.h\fR to get \f(CWnewlocale()\fR and its friends.
+.ie n .IP """Perl_langinfo""" 4
+.el .IP \f(CWPerl_langinfo\fR 4
+.IX Item "Perl_langinfo"
+.PD 0
+.ie n .IP """Perl_langinfo8""" 4
+.el .IP \f(CWPerl_langinfo8\fR 4
+.IX Xref "Perl_langinfo Perl_langinfo8"
+.IX Item "Perl_langinfo8"
+.PD
+\&\f(CW\*(C`Perl_langinfo\*(C'\fR is an (almost) drop-in replacement for the system
+\&\f(CWnl_langinfo(3)\fR, taking the same \f(CW\*(C`item\*(C'\fR parameter values, and returning
+the same information. But it is more thread-safe than regular
+\&\f(CWnl_langinfo()\fR, and hides the quirks of Perl's locale handling from your
+code, and can be used on systems that lack a native \f(CW\*(C`nl_langinfo\*(C'\fR.
+.Sp
+However, you should instead use the improved version of this:
+"Perl_langinfo8", which behaves identically except for an additional
+parameter, a pointer to a variable declared as "\f(CW\*(C`utf8ness_t\*(C'\fR", into which it
+returns to you how you should treat the returned string with regards to it
+being encoded in UTF\-8 or not.
+.Sp
+Concerning the differences between these and plain \f(CWnl_langinfo()\fR:
+.RS 4
+.IP a. 4
+.IX Item "a."
+\&\f(CW\*(C`Perl_langinfo8\*(C'\fR has an extra parameter, described above. Besides this, the
+other reason they aren't quite a drop-in replacement is actually an advantage.
+The \f(CW\*(C`const\*(C'\fRness of the return allows the compiler to catch attempts to write
+into the returned buffer, which is illegal and could cause run-time crashes.
+.IP b. 4
+.IX Item "b."
+They deliver the correct results for the \f(CW\*(C`RADIXCHAR\*(C'\fR and \f(CW\*(C`THOUSEP\*(C'\fR items,
+without you having to write extra code. The reason for the extra code would be
+because these are from the \f(CW\*(C`LC_NUMERIC\*(C'\fR locale category, which is normally
+kept set by Perl so that the radix is a dot, and the separator is the empty
+string, no matter what the underlying locale is supposed to be, and so to get
+the expected results, you have to temporarily toggle into the underlying
+locale, and later toggle back. (You could use plain \f(CW\*(C`nl_langinfo\*(C'\fR and
+\&\f(CW"STORE_LC_NUMERIC_FORCE_TO_UNDERLYING"\fR for this but then you wouldn't get
+the other advantages of \f(CWPerl_langinfo()\fR; not keeping \f(CW\*(C`LC_NUMERIC\*(C'\fR in the C
+(or equivalent) locale would break a lot of CPAN, which is expecting the radix
+(decimal point) character to be a dot.)
+.IP c. 4
+.IX Item "c."
+The system function they replace can have its static return buffer trashed,
+not only by a subsequent call to that function, but by a \f(CW\*(C`freelocale\*(C'\fR,
+\&\f(CW\*(C`setlocale\*(C'\fR, or other locale change. The returned buffer of these functions
+is not changed until the next call to one or the other, so the buffer is never
+in a trashed state.
+.IP d. 4
+.IX Item "d."
+The return buffer is per-thread, so it also is never overwritten by a call to
+these functions from another thread; unlike the function it replaces.
+.IP e. 4
+.IX Item "e."
+But most importantly, they work on systems that don't have \f(CW\*(C`nl_langinfo\*(C'\fR, such
+as Windows, hence making your code more portable. Of the fifty-some possible
+items specified by the POSIX 2008 standard,
+<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html>,
+only one is completely unimplemented, though on non-Windows platforms, another
+significant one is not fully implemented). They use various techniques to
+recover the other items, including calling \f(CWlocaleconv(3)\fR, and
+\&\f(CWstrftime(3)\fR, both of which are specified in C89, so should be always be
+available. Later \f(CWstrftime()\fR versions have additional capabilities; What the
+C locale yields or \f(CW""\fR is returned for any item not available on your system.
+.Sp
+It is important to note that, when called with an item that is recovered by
+using \f(CW\*(C`localeconv\*(C'\fR, the buffer from any previous explicit call to
+\&\f(CWlocaleconv(3)\fR will be overwritten. But you shouldn't be using
+\&\f(CW\*(C`localeconv\*(C'\fR anyway because it is is very much not thread-safe, and suffers
+from the same problems outlined in item 'b.' above for the fields it returns that
+are controlled by the LC_NUMERIC locale category. Instead, avoid all of those
+problems by calling "Perl_localeconv", which is thread-safe; or by using the
+methods given in perlcall to call
+\&\f(CWPOSIX::localeconv()\fR, which is also thread-safe.
+.RE
+.RS 4
+.Sp
+The details for those items which may deviate from what this emulation returns
+and what a native \f(CWnl_langinfo()\fR would return are specified in
+I18N::Langinfo.
+.Sp
+When using \f(CW\*(C`Perl_langinfo8\*(C'\fR (or plain \f(CW\*(C`Perl_langinfo\*(C'\fR) on systems that don't
+have a native \f(CWnl_langinfo()\fR, you must
+.Sp
+.Vb 1
+\& #include "perl_langinfo.h"
+.Ve
+.Sp
+before the \f(CW\*(C`perl.h\*(C'\fR \f(CW\*(C`#include\*(C'\fR. You can replace your \fIlanginfo.h\fR
+\&\f(CW\*(C`#include\*(C'\fR with this one. (Doing it this way keeps out the symbols that plain
+\&\fIlanginfo.h\fR would try to import into the namespace for code that doesn't need
+it.)
+.Sp
+.Vb 2
+\& const char * Perl_langinfo (const int item)
+\& const char * Perl_langinfo8(const int item, utf8ness_t *utf8ness)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Perl_localeconv""" 4
+.el .IP \f(CWPerl_localeconv\fR 4
+.IX Xref "Perl_localeconv"
+.IX Item "Perl_localeconv"
+This is a thread-safe version of the libc \fBlocaleconv\fR\|(3). It is the same as
+POSIX::localeconv (returning a hash of the \f(CWlocaleconv()\fR
+fields), but directly callable from XS code.
+.RS 4
+.Sp
+.Vb 1
+\& HV * Perl_localeconv(pTHX)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Perl_setlocale""" 4
+.el .IP \f(CWPerl_setlocale\fR 4
+.IX Xref "Perl_setlocale"
+.IX Item "Perl_setlocale"
+This is an (almost) drop-in replacement for the system \f(CWsetlocale(3)\fR,
+taking the same parameters, and returning the same information, except that it
+returns the correct underlying \f(CW\*(C`LC_NUMERIC\*(C'\fR locale. Regular \f(CW\*(C`setlocale\*(C'\fR will
+instead return \f(CW\*(C`C\*(C'\fR if the underlying locale has a non-dot decimal point
+character, or a non-empty thousands separator for displaying floating point
+numbers. This is because perl keeps that locale category such that it has a
+dot and empty separator, changing the locale briefly during the operations
+where the underlying one is required. \f(CW\*(C`Perl_setlocale\*(C'\fR knows about this, and
+compensates; regular \f(CW\*(C`setlocale\*(C'\fR doesn't.
+.Sp
+Another reason it isn't completely a drop-in replacement is that it is
+declared to return \f(CW\*(C`const\ char\ *\*(C'\fR, whereas the system setlocale omits the
+\&\f(CW\*(C`const\*(C'\fR (presumably because its API was specified long ago, and can't be
+updated; it is illegal to change the information \f(CW\*(C`setlocale\*(C'\fR returns; doing
+so leads to segfaults.)
+.Sp
+Finally, \f(CW\*(C`Perl_setlocale\*(C'\fR works under all circumstances, whereas plain
+\&\f(CW\*(C`setlocale\*(C'\fR can be completely ineffective on some platforms under some
+configurations.
+.Sp
+Changing the locale is not a good idea when more than one thread is running,
+except on systems where the predefined variable \f(CW\*(C`${^SAFE_LOCALES}\*(C'\fR is 1.
+This is because on such systems the locale is global to the whole process and
+not local to just the thread calling the function. So changing it in one
+thread instantaneously changes it in all. On some such systems, the system
+\&\f(CWsetlocale()\fR is ineffective, returning the wrong information, and failing to
+actually change the locale. z/OS refuses to try to change the locale once a
+second thread is created. \f(CW\*(C`Perl_setlocale\*(C'\fR, should give you accurate results
+of what actually happened on these problematic platforms, returning NULL if the
+system forbade the locale change.
+.Sp
+The return points to a per-thread static buffer, which is overwritten the next
+time \f(CW\*(C`Perl_setlocale\*(C'\fR is called from the same thread.
+.RS 4
+.Sp
+.Vb 2
+\& const char * Perl_setlocale(const int category,
+\& const char *locale)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """RESTORE_LC_NUMERIC""" 4
+.el .IP \f(CWRESTORE_LC_NUMERIC\fR 4
+.IX Xref "RESTORE_LC_NUMERIC"
+.IX Item "RESTORE_LC_NUMERIC"
+This is used in conjunction with one of the macros
+"STORE_LC_NUMERIC_SET_TO_NEEDED"
+and "STORE_LC_NUMERIC_FORCE_TO_UNDERLYING" to properly restore the
+\&\f(CW\*(C`LC_NUMERIC\*(C'\fR state.
+.Sp
+A call to "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" must have been made to
+declare at compile time a private variable used by this macro and the two
+\&\f(CW\*(C`STORE\*(C'\fR ones. This macro should be called as a single statement, not an
+expression, but with an empty argument list, like this:
+.Sp
+.Vb 6
+\& {
+\& DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+\& ...
+\& RESTORE_LC_NUMERIC();
+\& ...
+\& }
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& void RESTORE_LC_NUMERIC()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SETLOCALE_ACCEPTS_ANY_LOCALE_NAME""" 4
+.el .IP \f(CWSETLOCALE_ACCEPTS_ANY_LOCALE_NAME\fR 4
+.IX Xref "SETLOCALE_ACCEPTS_ANY_LOCALE_NAME"
+.IX Item "SETLOCALE_ACCEPTS_ANY_LOCALE_NAME"
+This symbol, if defined, indicates that the setlocale routine is
+available and it accepts any input locale name as valid.
+.ie n .IP """STORE_LC_NUMERIC_FORCE_TO_UNDERLYING""" 4
+.el .IP \f(CWSTORE_LC_NUMERIC_FORCE_TO_UNDERLYING\fR 4
+.IX Xref "STORE_LC_NUMERIC_FORCE_TO_UNDERLYING"
+.IX Item "STORE_LC_NUMERIC_FORCE_TO_UNDERLYING"
+This is used by XS code that is \f(CW\*(C`LC_NUMERIC\*(C'\fR locale-aware to force the
+locale for category \f(CW\*(C`LC_NUMERIC\*(C'\fR to be what perl thinks is the current
+underlying locale. (The perl interpreter could be wrong about what the
+underlying locale actually is if some C or XS code has called the C library
+function \fBsetlocale\fR\|(3) behind its back; calling "sync_locale" before calling
+this macro will update perl's records.)
+.Sp
+A call to "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" must have been made to
+declare at compile time a private variable used by this macro. This macro
+should be called as a single statement, not an expression, but with an empty
+argument list, like this:
+.Sp
+.Vb 8
+\& {
+\& DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+\& ...
+\& STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
+\& ...
+\& RESTORE_LC_NUMERIC();
+\& ...
+\& }
+.Ve
+.Sp
+The private variable is used to save the current locale state, so
+that the requisite matching call to "RESTORE_LC_NUMERIC" can restore it.
+.Sp
+On threaded perls not operating with thread-safe functionality, this macro uses
+a mutex to force a critical section. Therefore the matching RESTORE should be
+close by, and guaranteed to be called.
+.RS 4
+.Sp
+.Vb 1
+\& void STORE_LC_NUMERIC_FORCE_TO_UNDERLYING()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """STORE_LC_NUMERIC_SET_TO_NEEDED""" 4
+.el .IP \f(CWSTORE_LC_NUMERIC_SET_TO_NEEDED\fR 4
+.IX Xref "STORE_LC_NUMERIC_SET_TO_NEEDED"
+.IX Item "STORE_LC_NUMERIC_SET_TO_NEEDED"
+This is used to help wrap XS or C code that is \f(CW\*(C`LC_NUMERIC\*(C'\fR locale-aware.
+This locale category is generally kept set to a locale where the decimal radix
+character is a dot, and the separator between groups of digits is empty. This
+is because most XS code that reads floating point numbers is expecting them to
+have this syntax.
+.Sp
+This macro makes sure the current \f(CW\*(C`LC_NUMERIC\*(C'\fR state is set properly, to be
+aware of locale if the call to the XS or C code from the Perl program is
+from within the scope of a \f(CW\*(C`use\ locale\*(C'\fR; or to ignore locale if the call is
+instead from outside such scope.
+.Sp
+This macro is the start of wrapping the C or XS code; the wrap ending is done
+by calling the "RESTORE_LC_NUMERIC" macro after the operation. Otherwise
+the state can be changed that will adversely affect other XS code.
+.Sp
+A call to "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" must have been made to
+declare at compile time a private variable used by this macro. This macro
+should be called as a single statement, not an expression, but with an empty
+argument list, like this:
+.Sp
+.Vb 8
+\& {
+\& DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+\& ...
+\& STORE_LC_NUMERIC_SET_TO_NEEDED();
+\& ...
+\& RESTORE_LC_NUMERIC();
+\& ...
+\& }
+.Ve
+.Sp
+On threaded perls not operating with thread-safe functionality, this macro uses
+a mutex to force a critical section. Therefore the matching RESTORE should be
+close by, and guaranteed to be called; see "WITH_LC_NUMERIC_SET_TO_NEEDED"
+for a more contained way to ensure that.
+.RS 4
+.Sp
+.Vb 1
+\& void STORE_LC_NUMERIC_SET_TO_NEEDED()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """STORE_LC_NUMERIC_SET_TO_NEEDED_IN""" 4
+.el .IP \f(CWSTORE_LC_NUMERIC_SET_TO_NEEDED_IN\fR 4
+.IX Xref "STORE_LC_NUMERIC_SET_TO_NEEDED_IN"
+.IX Item "STORE_LC_NUMERIC_SET_TO_NEEDED_IN"
+Same as "STORE_LC_NUMERIC_SET_TO_NEEDED" with in_lc_numeric provided
+as the precalculated value of \f(CWIN_LC(LC_NUMERIC)\fR. It is the caller's
+responsibility to ensure that the status of \f(CW\*(C`PL_compiling\*(C'\fR and \f(CW\*(C`PL_hints\*(C'\fR
+cannot have changed since the precalculation.
+.RS 4
+.Sp
+.Vb 1
+\& void STORE_LC_NUMERIC_SET_TO_NEEDED_IN(bool in_lc_numeric)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """WITH_LC_NUMERIC_SET_TO_NEEDED""" 4
+.el .IP \f(CWWITH_LC_NUMERIC_SET_TO_NEEDED\fR 4
+.IX Xref "WITH_LC_NUMERIC_SET_TO_NEEDED"
+.IX Item "WITH_LC_NUMERIC_SET_TO_NEEDED"
+This macro invokes the supplied statement or block within the context
+of a "STORE_LC_NUMERIC_SET_TO_NEEDED" .. "RESTORE_LC_NUMERIC" pair
+if required, so eg:
+.Sp
+.Vb 3
+\& WITH_LC_NUMERIC_SET_TO_NEEDED(
+\& SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis)
+\& );
+.Ve
+.Sp
+is equivalent to:
+.Sp
+.Vb 10
+\& {
+\&#ifdef USE_LOCALE_NUMERIC
+\& DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+\& STORE_LC_NUMERIC_SET_TO_NEEDED();
+\&#endif
+\& SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis);
+\&#ifdef USE_LOCALE_NUMERIC
+\& RESTORE_LC_NUMERIC();
+\&#endif
+\& }
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& void WITH_LC_NUMERIC_SET_TO_NEEDED(block)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """WITH_LC_NUMERIC_SET_TO_NEEDED_IN""" 4
+.el .IP \f(CWWITH_LC_NUMERIC_SET_TO_NEEDED_IN\fR 4
+.IX Xref "WITH_LC_NUMERIC_SET_TO_NEEDED_IN"
+.IX Item "WITH_LC_NUMERIC_SET_TO_NEEDED_IN"
+Same as "WITH_LC_NUMERIC_SET_TO_NEEDED" with in_lc_numeric provided
+as the precalculated value of \f(CWIN_LC(LC_NUMERIC)\fR. It is the caller's
+responsibility to ensure that the status of \f(CW\*(C`PL_compiling\*(C'\fR and \f(CW\*(C`PL_hints\*(C'\fR
+cannot have changed since the precalculation.
+.RS 4
+.Sp
+.Vb 1
+\& void WITH_LC_NUMERIC_SET_TO_NEEDED_IN(bool in_lc_numeric, block)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Magic
+.IX Xref "MAGIC"
+.IX Header "Magic"
+"Magic" is special data attached to SV structures in order to give them
+"magical" properties. When any Perl code tries to read from, or assign to,
+an SV marked as magical, it calls the 'get' or 'set' function associated
+with that SV's magic. A get is called prior to reading an SV, in order to
+give it a chance to update its internal value (get on $. writes the line
+number of the last read filehandle into the SV's IV slot), while
+set is called after an SV has been written to, in order to allow it to make
+use of its changed value (set on $/ copies the SV's new value to the
+PL_rs global variable).
+.PP
+Magic is implemented as a linked list of MAGIC structures attached to the
+SV. Each MAGIC struct holds the type of the magic, a pointer to an array
+of functions that implement the \fBget()\fR, \fBset()\fR, \fBlength()\fR etc functions,
+plus space for some flags and pointers. For example, a tied variable has
+a MAGIC structure that contains a pointer to the object associated with the
+tie.
+.ie n .IP """mg_clear""" 4
+.el .IP \f(CWmg_clear\fR 4
+.IX Xref "mg_clear"
+.IX Item "mg_clear"
+Clear something magical that the SV represents. See \f(CW"sv_magic"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int mg_clear(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mg_copy""" 4
+.el .IP \f(CWmg_copy\fR 4
+.IX Xref "mg_copy"
+.IX Item "mg_copy"
+Copies the magic from one SV to another. See \f(CW"sv_magic"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int mg_copy(SV *sv, SV *nsv, const char *key, I32 klen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MGf_COPY""" 4
+.el .IP \f(CWMGf_COPY\fR 4
+.IX Item "MGf_COPY"
+.PD 0
+.ie n .IP """MGf_DUP""" 4
+.el .IP \f(CWMGf_DUP\fR 4
+.IX Item "MGf_DUP"
+.ie n .IP """MGf_LOCAL""" 4
+.el .IP \f(CWMGf_LOCAL\fR 4
+.IX Item "MGf_LOCAL"
+.PD
+Described in perlguts.
+.ie n .IP """mg_find""" 4
+.el .IP \f(CWmg_find\fR 4
+.IX Xref "mg_find"
+.IX Item "mg_find"
+Finds the magic pointer for \f(CW\*(C`type\*(C'\fR matching the SV. See \f(CW"sv_magic"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& MAGIC * mg_find(const SV *sv, int type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mg_findext""" 4
+.el .IP \f(CWmg_findext\fR 4
+.IX Xref "mg_findext"
+.IX Item "mg_findext"
+Finds the magic pointer of \f(CW\*(C`type\*(C'\fR with the given \f(CW\*(C`vtbl\*(C'\fR for the \f(CW\*(C`SV\*(C'\fR. See
+\&\f(CW"sv_magicext"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& MAGIC * mg_findext(const SV *sv, int type, const MGVTBL *vtbl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mg_free""" 4
+.el .IP \f(CWmg_free\fR 4
+.IX Xref "mg_free"
+.IX Item "mg_free"
+Free any magic storage used by the SV. See \f(CW"sv_magic"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int mg_free(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mg_freeext""" 4
+.el .IP \f(CWmg_freeext\fR 4
+.IX Xref "mg_freeext"
+.IX Item "mg_freeext"
+Remove any magic of type \f(CW\*(C`how\*(C'\fR using virtual table \f(CW\*(C`vtbl\*(C'\fR from the
+SV \f(CW\*(C`sv\*(C'\fR. See "sv_magic".
+.Sp
+\&\f(CW\*(C`mg_freeext(sv, how, NULL)\*(C'\fR is equivalent to \f(CW\*(C`mg_free_type(sv, how)\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mg_freeext(SV *sv, int how, const MGVTBL *vtbl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mg_free_type""" 4
+.el .IP \f(CWmg_free_type\fR 4
+.IX Xref "mg_free_type"
+.IX Item "mg_free_type"
+Remove any magic of type \f(CW\*(C`how\*(C'\fR from the SV \f(CW\*(C`sv\*(C'\fR. See "sv_magic".
+.RS 4
+.Sp
+.Vb 1
+\& void mg_free_type(SV *sv, int how)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mg_get""" 4
+.el .IP \f(CWmg_get\fR 4
+.IX Xref "mg_get"
+.IX Item "mg_get"
+Do magic before a value is retrieved from the SV. The type of SV must
+be >= \f(CW\*(C`SVt_PVMG\*(C'\fR. See \f(CW"sv_magic"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int mg_get(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mg_magical""" 4
+.el .IP \f(CWmg_magical\fR 4
+.IX Xref "mg_magical"
+.IX Item "mg_magical"
+Turns on the magical status of an SV. See \f(CW"sv_magic"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mg_magical(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mg_set""" 4
+.el .IP \f(CWmg_set\fR 4
+.IX Xref "mg_set"
+.IX Item "mg_set"
+Do magic after a value is assigned to the SV. See \f(CW"sv_magic"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int mg_set(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MGVTBL""" 4
+.el .IP \f(CWMGVTBL\fR 4
+.IX Item "MGVTBL"
+Described in perlguts.
+.ie n .IP """PERL_MAGIC_arylen""" 4
+.el .IP \f(CWPERL_MAGIC_arylen\fR 4
+.IX Item "PERL_MAGIC_arylen"
+.PD 0
+.ie n .IP """PERL_MAGIC_arylen_p""" 4
+.el .IP \f(CWPERL_MAGIC_arylen_p\fR 4
+.IX Item "PERL_MAGIC_arylen_p"
+.ie n .IP """PERL_MAGIC_backref""" 4
+.el .IP \f(CWPERL_MAGIC_backref\fR 4
+.IX Item "PERL_MAGIC_backref"
+.ie n .IP """PERL_MAGIC_bm""" 4
+.el .IP \f(CWPERL_MAGIC_bm\fR 4
+.IX Item "PERL_MAGIC_bm"
+.ie n .IP """PERL_MAGIC_checkcall""" 4
+.el .IP \f(CWPERL_MAGIC_checkcall\fR 4
+.IX Item "PERL_MAGIC_checkcall"
+.ie n .IP """PERL_MAGIC_collxfrm""" 4
+.el .IP \f(CWPERL_MAGIC_collxfrm\fR 4
+.IX Item "PERL_MAGIC_collxfrm"
+.ie n .IP """PERL_MAGIC_dbfile""" 4
+.el .IP \f(CWPERL_MAGIC_dbfile\fR 4
+.IX Item "PERL_MAGIC_dbfile"
+.ie n .IP """PERL_MAGIC_dbline""" 4
+.el .IP \f(CWPERL_MAGIC_dbline\fR 4
+.IX Item "PERL_MAGIC_dbline"
+.ie n .IP """PERL_MAGIC_debugvar""" 4
+.el .IP \f(CWPERL_MAGIC_debugvar\fR 4
+.IX Item "PERL_MAGIC_debugvar"
+.ie n .IP """PERL_MAGIC_defelem""" 4
+.el .IP \f(CWPERL_MAGIC_defelem\fR 4
+.IX Item "PERL_MAGIC_defelem"
+.ie n .IP """PERL_MAGIC_destruct""" 4
+.el .IP \f(CWPERL_MAGIC_destruct\fR 4
+.IX Item "PERL_MAGIC_destruct"
+.ie n .IP """PERL_MAGIC_env""" 4
+.el .IP \f(CWPERL_MAGIC_env\fR 4
+.IX Item "PERL_MAGIC_env"
+.ie n .IP """PERL_MAGIC_envelem""" 4
+.el .IP \f(CWPERL_MAGIC_envelem\fR 4
+.IX Item "PERL_MAGIC_envelem"
+.ie n .IP """PERL_MAGIC_ext""" 4
+.el .IP \f(CWPERL_MAGIC_ext\fR 4
+.IX Item "PERL_MAGIC_ext"
+.ie n .IP """PERL_MAGIC_extvalue""" 4
+.el .IP \f(CWPERL_MAGIC_extvalue\fR 4
+.IX Item "PERL_MAGIC_extvalue"
+.ie n .IP """PERL_MAGIC_fm""" 4
+.el .IP \f(CWPERL_MAGIC_fm\fR 4
+.IX Item "PERL_MAGIC_fm"
+.ie n .IP """PERL_MAGIC_hints""" 4
+.el .IP \f(CWPERL_MAGIC_hints\fR 4
+.IX Item "PERL_MAGIC_hints"
+.ie n .IP """PERL_MAGIC_hintselem""" 4
+.el .IP \f(CWPERL_MAGIC_hintselem\fR 4
+.IX Item "PERL_MAGIC_hintselem"
+.ie n .IP """PERL_MAGIC_hook""" 4
+.el .IP \f(CWPERL_MAGIC_hook\fR 4
+.IX Item "PERL_MAGIC_hook"
+.ie n .IP """PERL_MAGIC_hookelem""" 4
+.el .IP \f(CWPERL_MAGIC_hookelem\fR 4
+.IX Item "PERL_MAGIC_hookelem"
+.ie n .IP """PERL_MAGIC_isa""" 4
+.el .IP \f(CWPERL_MAGIC_isa\fR 4
+.IX Item "PERL_MAGIC_isa"
+.ie n .IP """PERL_MAGIC_isaelem""" 4
+.el .IP \f(CWPERL_MAGIC_isaelem\fR 4
+.IX Item "PERL_MAGIC_isaelem"
+.ie n .IP """PERL_MAGIC_lvref""" 4
+.el .IP \f(CWPERL_MAGIC_lvref\fR 4
+.IX Item "PERL_MAGIC_lvref"
+.ie n .IP """PERL_MAGIC_nkeys""" 4
+.el .IP \f(CWPERL_MAGIC_nkeys\fR 4
+.IX Item "PERL_MAGIC_nkeys"
+.ie n .IP """PERL_MAGIC_nonelem""" 4
+.el .IP \f(CWPERL_MAGIC_nonelem\fR 4
+.IX Item "PERL_MAGIC_nonelem"
+.ie n .IP """PERL_MAGIC_overload_table""" 4
+.el .IP \f(CWPERL_MAGIC_overload_table\fR 4
+.IX Item "PERL_MAGIC_overload_table"
+.ie n .IP """PERL_MAGIC_pos""" 4
+.el .IP \f(CWPERL_MAGIC_pos\fR 4
+.IX Item "PERL_MAGIC_pos"
+.ie n .IP """PERL_MAGIC_qr""" 4
+.el .IP \f(CWPERL_MAGIC_qr\fR 4
+.IX Item "PERL_MAGIC_qr"
+.ie n .IP """PERL_MAGIC_regdata""" 4
+.el .IP \f(CWPERL_MAGIC_regdata\fR 4
+.IX Item "PERL_MAGIC_regdata"
+.ie n .IP """PERL_MAGIC_regdatum""" 4
+.el .IP \f(CWPERL_MAGIC_regdatum\fR 4
+.IX Item "PERL_MAGIC_regdatum"
+.ie n .IP """PERL_MAGIC_regex_global""" 4
+.el .IP \f(CWPERL_MAGIC_regex_global\fR 4
+.IX Item "PERL_MAGIC_regex_global"
+.ie n .IP """PERL_MAGIC_rhash""" 4
+.el .IP \f(CWPERL_MAGIC_rhash\fR 4
+.IX Item "PERL_MAGIC_rhash"
+.ie n .IP """PERL_MAGIC_shared""" 4
+.el .IP \f(CWPERL_MAGIC_shared\fR 4
+.IX Item "PERL_MAGIC_shared"
+.ie n .IP """PERL_MAGIC_shared_scalar""" 4
+.el .IP \f(CWPERL_MAGIC_shared_scalar\fR 4
+.IX Item "PERL_MAGIC_shared_scalar"
+.ie n .IP """PERL_MAGIC_sig""" 4
+.el .IP \f(CWPERL_MAGIC_sig\fR 4
+.IX Item "PERL_MAGIC_sig"
+.ie n .IP """PERL_MAGIC_sigelem""" 4
+.el .IP \f(CWPERL_MAGIC_sigelem\fR 4
+.IX Item "PERL_MAGIC_sigelem"
+.ie n .IP """PERL_MAGIC_substr""" 4
+.el .IP \f(CWPERL_MAGIC_substr\fR 4
+.IX Item "PERL_MAGIC_substr"
+.ie n .IP """PERL_MAGIC_sv""" 4
+.el .IP \f(CWPERL_MAGIC_sv\fR 4
+.IX Item "PERL_MAGIC_sv"
+.ie n .IP """PERL_MAGIC_symtab""" 4
+.el .IP \f(CWPERL_MAGIC_symtab\fR 4
+.IX Item "PERL_MAGIC_symtab"
+.ie n .IP """PERL_MAGIC_taint""" 4
+.el .IP \f(CWPERL_MAGIC_taint\fR 4
+.IX Item "PERL_MAGIC_taint"
+.ie n .IP """PERL_MAGIC_tied""" 4
+.el .IP \f(CWPERL_MAGIC_tied\fR 4
+.IX Item "PERL_MAGIC_tied"
+.ie n .IP """PERL_MAGIC_tiedelem""" 4
+.el .IP \f(CWPERL_MAGIC_tiedelem\fR 4
+.IX Item "PERL_MAGIC_tiedelem"
+.ie n .IP """PERL_MAGIC_tiedscalar""" 4
+.el .IP \f(CWPERL_MAGIC_tiedscalar\fR 4
+.IX Item "PERL_MAGIC_tiedscalar"
+.ie n .IP """PERL_MAGIC_utf8""" 4
+.el .IP \f(CWPERL_MAGIC_utf8\fR 4
+.IX Item "PERL_MAGIC_utf8"
+.ie n .IP """PERL_MAGIC_uvar""" 4
+.el .IP \f(CWPERL_MAGIC_uvar\fR 4
+.IX Item "PERL_MAGIC_uvar"
+.ie n .IP """PERL_MAGIC_uvar_elem""" 4
+.el .IP \f(CWPERL_MAGIC_uvar_elem\fR 4
+.IX Item "PERL_MAGIC_uvar_elem"
+.ie n .IP """PERL_MAGIC_vec""" 4
+.el .IP \f(CWPERL_MAGIC_vec\fR 4
+.IX Item "PERL_MAGIC_vec"
+.ie n .IP """PERL_MAGIC_vstring""" 4
+.el .IP \f(CWPERL_MAGIC_vstring\fR 4
+.IX Item "PERL_MAGIC_vstring"
+.PD
+Described in perlguts.
+.ie n .IP """SvTIED_obj""" 4
+.el .IP \f(CWSvTIED_obj\fR 4
+.IX Item "SvTIED_obj"
+Described in perlinterp.
+.RS 4
+.Sp
+.Vb 1
+\& SvTIED_obj(SV *sv, MAGIC *mg)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Memory Management"
+.IX Header "Memory Management"
+.ie n .IP """dump_mstats""" 4
+.el .IP \f(CWdump_mstats\fR 4
+.IX Xref "dump_mstats"
+.IX Item "dump_mstats"
+When enabled by compiling with \f(CW\*(C`\-DDEBUGGING_MSTATS\*(C'\fR, print out statistics
+about malloc as two lines of numbers, one showing the length of the free list
+for each size category, the second showing the number of mallocs\ \-\ frees for
+each size category.
+.Sp
+\&\f(CW\*(C`s\*(C'\fR, if not NULL, is used as a phrase to include in the output, such as
+"after\ compilation".
+.RS 4
+.Sp
+.Vb 1
+\& void dump_mstats(const char *s)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """HASATTRIBUTE_MALLOC""" 4
+.el .IP \f(CWHASATTRIBUTE_MALLOC\fR 4
+.IX Xref "HASATTRIBUTE_MALLOC"
+.IX Item "HASATTRIBUTE_MALLOC"
+Can we handle \f(CW\*(C`GCC\*(C'\fR attribute for malloc-style functions.
+.ie n .IP """HAS_MALLOC_GOOD_SIZE""" 4
+.el .IP \f(CWHAS_MALLOC_GOOD_SIZE\fR 4
+.IX Xref "HAS_MALLOC_GOOD_SIZE"
+.IX Item "HAS_MALLOC_GOOD_SIZE"
+This symbol, if defined, indicates that the \f(CW\*(C`malloc_good_size\*(C'\fR
+routine is available for use.
+.ie n .IP """HAS_MALLOC_SIZE""" 4
+.el .IP \f(CWHAS_MALLOC_SIZE\fR 4
+.IX Xref "HAS_MALLOC_SIZE"
+.IX Item "HAS_MALLOC_SIZE"
+This symbol, if defined, indicates that the \f(CW\*(C`malloc_size\*(C'\fR
+routine is available for use.
+.ie n .IP """I_MALLOCMALLOC""" 4
+.el .IP \f(CWI_MALLOCMALLOC\fR 4
+.IX Xref "I_MALLOCMALLOC"
+.IX Item "I_MALLOCMALLOC"
+This symbol, if defined, indicates to the C program that it should
+include \fImalloc/malloc.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_MALLOCMALLOC
+\& #include <mallocmalloc.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MYMALLOC""" 4
+.el .IP \f(CWMYMALLOC\fR 4
+.IX Xref "MYMALLOC"
+.IX Item "MYMALLOC"
+This symbol, if defined, indicates that we're using our own malloc.
+.ie n .IP """Newx""" 4
+.el .IP \f(CWNewx\fR 4
+.IX Item "Newx"
+.PD 0
+.ie n .IP """safemalloc""" 4
+.el .IP \f(CWsafemalloc\fR 4
+.IX Xref "Newx safemalloc"
+.IX Item "safemalloc"
+.PD
+The XSUB-writer's interface to the C \f(CW\*(C`malloc\*(C'\fR function.
+.Sp
+Memory obtained by this should \fBONLY\fR be freed with "Safefree".
+.Sp
+In 5.9.3, \fBNewx()\fR and friends replace the older \fBNew()\fR API, and drops
+the first parameter, \fIx\fR, a debug aid which allowed callers to identify
+themselves. This aid has been superseded by a new build option,
+PERL_MEM_LOG (see "PERL_MEM_LOG" in perlhacktips). The older API is still
+there for use in XS modules supporting older perls.
+.RS 4
+.Sp
+.Vb 2
+\& void Newx (void* ptr, int nitems, type)
+\& void* safemalloc(size_t size)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Newxc""" 4
+.el .IP \f(CWNewxc\fR 4
+.IX Xref "Newxc"
+.IX Item "Newxc"
+The XSUB-writer's interface to the C \f(CW\*(C`malloc\*(C'\fR function, with
+cast. See also \f(CW"Newx"\fR.
+.Sp
+Memory obtained by this should \fBONLY\fR be freed with "Safefree".
+.RS 4
+.Sp
+.Vb 1
+\& void Newxc(void* ptr, int nitems, type, cast)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Newxz""" 4
+.el .IP \f(CWNewxz\fR 4
+.IX Item "Newxz"
+.PD 0
+.ie n .IP """safecalloc""" 4
+.el .IP \f(CWsafecalloc\fR 4
+.IX Xref "Newxz safecalloc"
+.IX Item "safecalloc"
+.PD
+The XSUB-writer's interface to the C \f(CW\*(C`malloc\*(C'\fR function. The allocated
+memory is zeroed with \f(CW\*(C`memzero\*(C'\fR. See also \f(CW"Newx"\fR.
+.Sp
+Memory obtained by this should \fBONLY\fR be freed with "Safefree".
+.RS 4
+.Sp
+.Vb 2
+\& void Newxz (void* ptr, int nitems, type)
+\& void* safecalloc(size_t nitems, size_t item_size)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_MALLOC_WRAP""" 4
+.el .IP \f(CWPERL_MALLOC_WRAP\fR 4
+.IX Xref "PERL_MALLOC_WRAP"
+.IX Item "PERL_MALLOC_WRAP"
+This symbol, if defined, indicates that we'd like malloc wrap checks.
+.ie n .IP """Renew""" 4
+.el .IP \f(CWRenew\fR 4
+.IX Item "Renew"
+.PD 0
+.ie n .IP """saferealloc""" 4
+.el .IP \f(CWsaferealloc\fR 4
+.IX Xref "Renew saferealloc"
+.IX Item "saferealloc"
+.PD
+The XSUB-writer's interface to the C \f(CW\*(C`realloc\*(C'\fR function.
+.Sp
+Memory obtained by this should \fBONLY\fR be freed with "Safefree".
+.RS 4
+.Sp
+.Vb 2
+\& void Renew (void* ptr, int nitems, type)
+\& void* saferealloc(void *ptr, size_t size)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Renewc""" 4
+.el .IP \f(CWRenewc\fR 4
+.IX Xref "Renewc"
+.IX Item "Renewc"
+The XSUB-writer's interface to the C \f(CW\*(C`realloc\*(C'\fR function, with
+cast.
+.Sp
+Memory obtained by this should \fBONLY\fR be freed with "Safefree".
+.RS 4
+.Sp
+.Vb 1
+\& void Renewc(void* ptr, int nitems, type, cast)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Safefree""" 4
+.el .IP \f(CWSafefree\fR 4
+.IX Xref "Safefree"
+.IX Item "Safefree"
+The XSUB-writer's interface to the C \f(CW\*(C`free\*(C'\fR function.
+.Sp
+This should \fBONLY\fR be used on memory obtained using "Newx" and friends.
+.RS 4
+.Sp
+.Vb 1
+\& void Safefree(void* ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """safesyscalloc""" 4
+.el .IP \f(CWsafesyscalloc\fR 4
+.IX Xref "safesyscalloc"
+.IX Item "safesyscalloc"
+Safe version of system's \fBcalloc()\fR
+.RS 4
+.Sp
+.Vb 1
+\& Malloc_t safesyscalloc(MEM_SIZE elements, MEM_SIZE size)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """safesysfree""" 4
+.el .IP \f(CWsafesysfree\fR 4
+.IX Xref "safesysfree"
+.IX Item "safesysfree"
+Safe version of system's \fBfree()\fR
+.RS 4
+.Sp
+.Vb 1
+\& Free_t safesysfree(Malloc_t where)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """safesysmalloc""" 4
+.el .IP \f(CWsafesysmalloc\fR 4
+.IX Xref "safesysmalloc"
+.IX Item "safesysmalloc"
+Paranoid version of system's \fBmalloc()\fR
+.RS 4
+.Sp
+.Vb 1
+\& Malloc_t safesysmalloc(MEM_SIZE nbytes)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """safesysrealloc""" 4
+.el .IP \f(CWsafesysrealloc\fR 4
+.IX Xref "safesysrealloc"
+.IX Item "safesysrealloc"
+Paranoid version of system's \fBrealloc()\fR
+.RS 4
+.Sp
+.Vb 1
+\& Malloc_t safesysrealloc(Malloc_t where, MEM_SIZE nbytes)
+.Ve
+.RE
+.RS 4
+.RE
+.SH MRO
+.IX Header "MRO"
+These functions are related to the method resolution order of perl classes
+Also see perlmroapi.
+.ie n .IP """HvMROMETA""" 4
+.el .IP \f(CWHvMROMETA\fR 4
+.IX Item "HvMROMETA"
+Described in perlmroapi.
+.RS 4
+.Sp
+.Vb 1
+\& struct mro_meta * HvMROMETA(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mro_get_from_name""" 4
+.el .IP \f(CWmro_get_from_name\fR 4
+.IX Xref "mro_get_from_name"
+.IX Item "mro_get_from_name"
+Returns the previously registered mro with the given \f(CW\*(C`name\*(C'\fR, or NULL if not
+registered. See "\f(CW\*(C`mro_register\*(C'\fR".
+.Sp
+NOTE: \f(CW\*(C`mro_get_from_name\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_mro_get_from_name\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 1
+\& const struct mro_alg * Perl_mro_get_from_name(pTHX_ SV *name)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mro_get_linear_isa""" 4
+.el .IP \f(CWmro_get_linear_isa\fR 4
+.IX Xref "mro_get_linear_isa"
+.IX Item "mro_get_linear_isa"
+Returns the mro linearisation for the given stash. By default, this
+will be whatever \f(CW\*(C`mro_get_linear_isa_dfs\*(C'\fR returns unless some
+other MRO is in effect for the stash. The return value is a
+read-only AV* whose values are string SVs giving class names.
+.Sp
+You are responsible for \f(CWSvREFCNT_inc()\fR on the
+return value if you plan to store it anywhere
+semi-permanently (otherwise it might be deleted
+out from under you the next time the cache is
+invalidated).
+.RS 4
+.Sp
+.Vb 1
+\& AV * mro_get_linear_isa(HV *stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MRO_GET_PRIVATE_DATA""" 4
+.el .IP \f(CWMRO_GET_PRIVATE_DATA\fR 4
+.IX Item "MRO_GET_PRIVATE_DATA"
+Described in perlmroapi.
+.RS 4
+.Sp
+.Vb 2
+\& SV* MRO_GET_PRIVATE_DATA(struct mro_meta *const smeta,
+\& const struct mro_alg *const which)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mro_method_changed_in""" 4
+.el .IP \f(CWmro_method_changed_in\fR 4
+.IX Xref "mro_method_changed_in"
+.IX Item "mro_method_changed_in"
+Invalidates method caching on any child classes
+of the given stash, so that they might notice
+the changes in this one.
+.Sp
+Ideally, all instances of \f(CW\*(C`PL_sub_generation++\*(C'\fR in
+perl source outside of \fImro.c\fR should be
+replaced by calls to this.
+.Sp
+Perl automatically handles most of the common
+ways a method might be redefined. However, there
+are a few ways you could change a method in a stash
+without the cache code noticing, in which case you
+need to call this method afterwards:
+.Sp
+1) Directly manipulating the stash HV entries from
+XS code.
+.Sp
+2) Assigning a reference to a readonly scalar
+constant into a stash entry in order to create
+a constant subroutine (like \fIconstant.pm\fR
+does).
+.Sp
+This same method is available from pure perl
+via, \f(CWmro::method_changed_in(classname)\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mro_method_changed_in(HV *stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mro_register""" 4
+.el .IP \f(CWmro_register\fR 4
+.IX Xref "mro_register"
+.IX Item "mro_register"
+Registers a custom mro plugin. See perlmroapi for details on this and other
+mro functions.
+.Sp
+NOTE: \f(CW\*(C`mro_register\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_mro_register\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 1
+\& void Perl_mro_register(pTHX_ const struct mro_alg *mro)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mro_set_mro""" 4
+.el .IP \f(CWmro_set_mro\fR 4
+.IX Xref "mro_set_mro"
+.IX Item "mro_set_mro"
+Set \f(CW\*(C`meta\*(C'\fR to the value contained in the registered mro plugin whose name is
+\&\f(CW\*(C`name\*(C'\fR.
+.Sp
+Croaks if \f(CW\*(C`name\*(C'\fR hasn't been registered
+.Sp
+NOTE: \f(CW\*(C`mro_set_mro\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_mro_set_mro\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& void Perl_mro_set_mro(pTHX_ struct mro_meta * const meta,
+\& SV * const name)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mro_set_private_data""" 4
+.el .IP \f(CWmro_set_private_data\fR 4
+.IX Item "mro_set_private_data"
+Described in perlmroapi.
+.Sp
+NOTE: \f(CW\*(C`mro_set_private_data\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_mro_set_private_data\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 4
+\& SV * Perl_mro_set_private_data(pTHX_
+\& struct mro_meta * const smeta,
+\& const struct mro_alg * const which,
+\& SV * const data)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Multicall Functions"
+.IX Header "Multicall Functions"
+.ie n .IP """dMULTICALL""" 4
+.el .IP \f(CWdMULTICALL\fR 4
+.IX Xref "dMULTICALL"
+.IX Item "dMULTICALL"
+Declare local variables for a multicall. See "LIGHTWEIGHT CALLBACKS" in perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& dMULTICALL;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MULTICALL""" 4
+.el .IP \f(CWMULTICALL\fR 4
+.IX Xref "MULTICALL"
+.IX Item "MULTICALL"
+Make a lightweight callback. See "LIGHTWEIGHT CALLBACKS" in perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& MULTICALL;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POP_MULTICALL""" 4
+.el .IP \f(CWPOP_MULTICALL\fR 4
+.IX Xref "POP_MULTICALL"
+.IX Item "POP_MULTICALL"
+Closing bracket for a lightweight callback.
+See "LIGHTWEIGHT CALLBACKS" in perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& POP_MULTICALL;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSH_MULTICALL""" 4
+.el .IP \f(CWPUSH_MULTICALL\fR 4
+.IX Xref "PUSH_MULTICALL"
+.IX Item "PUSH_MULTICALL"
+Opening bracket for a lightweight callback.
+See "LIGHTWEIGHT CALLBACKS" in perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& PUSH_MULTICALL(CV* the_cv);
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Numeric Functions"
+.IX Xref "IS_NUMBER_GREATER_THAN_UV_MAX IS_NUMBER_INFINITY IS_NUMBER_IN_UV IS_NUMBER_NAN IS_NUMBER_NEG IS_NUMBER_NOT_INT PERL_SCAN_ALLOW_UNDERSCORES PERL_SCAN_DISALLOW_PREFIX PERL_SCAN_GREATER_THAN_UV_MAX PERL_SCAN_SILENT_ILLDIGIT PERL_SCAN_TRAILING"
+.IX Header "Numeric Functions"
+.ie n .IP """Atol""" 4
+.el .IP \f(CWAtol\fR 4
+.IX Item "Atol"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`Atol\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Described in perlhacktips.
+.RS 4
+.Sp
+.Vb 1
+\& Atol(const char * nptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Atoul""" 4
+.el .IP \f(CWAtoul\fR 4
+.IX Item "Atoul"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`Atoul\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Described in perlhacktips.
+.RS 4
+.Sp
+.Vb 1
+\& Atoul(const char * nptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Drand01""" 4
+.el .IP \f(CWDrand01\fR 4
+.IX Xref "Drand01"
+.IX Item "Drand01"
+This macro is to be used to generate uniformly distributed
+random numbers over the range [0., 1.[. You may have to supply
+an 'extern double \f(CWdrand48()\fR;' in your program since SunOS 4.1.3
+doesn't provide you with anything relevant in its headers.
+See \f(CW"HAS_DRAND48_PROTO"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& double Drand01()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Gconvert""" 4
+.el .IP \f(CWGconvert\fR 4
+.IX Xref "Gconvert"
+.IX Item "Gconvert"
+This preprocessor macro is defined to convert a floating point
+number to a string without a trailing decimal point. This
+emulates the behavior of \f(CWsprintf("%g")\fR, but is sometimes much more
+efficient. If \f(CWgconvert()\fR is not available, but \f(CWgcvt()\fR drops the
+trailing decimal point, then \f(CWgcvt()\fR is used. If all else fails,
+a macro using \f(CWsprintf("%g")\fR is used. Arguments for the Gconvert
+macro are: value, number of digits, whether trailing zeros should
+be retained, and the output buffer.
+The usual values are:
+.Sp
+.Vb 3
+\& d_Gconvert=\*(Aqgconvert((x),(n),(t),(b))\*(Aq
+\& d_Gconvert=\*(Aqgcvt((x),(n),(b))\*(Aq
+\& d_Gconvert=\*(Aqsprintf((b),"%.*g",(n),(x))\*(Aq
+.Ve
+.Sp
+The last two assume trailing zeros should not be kept.
+.RS 4
+.Sp
+.Vb 1
+\& char * Gconvert(double x, Size_t n, bool t, char * b)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """grok_atoUV""" 4
+.el .IP \f(CWgrok_atoUV\fR 4
+.IX Xref "grok_atoUV"
+.IX Item "grok_atoUV"
+parse a string, looking for a decimal unsigned integer.
+.Sp
+On entry, \f(CW\*(C`pv\*(C'\fR points to the beginning of the string;
+\&\f(CW\*(C`valptr\*(C'\fR points to a UV that will receive the converted value, if found;
+\&\f(CW\*(C`endptr\*(C'\fR is either NULL or points to a variable that points to one byte
+beyond the point in \f(CW\*(C`pv\*(C'\fR that this routine should examine.
+If \f(CW\*(C`endptr\*(C'\fR is NULL, \f(CW\*(C`pv\*(C'\fR is assumed to be NUL-terminated.
+.Sp
+Returns FALSE if \f(CW\*(C`pv\*(C'\fR doesn't represent a valid unsigned integer value (with
+no leading zeros). Otherwise it returns TRUE, and sets \f(CW*valptr\fR to that
+value.
+.Sp
+If you constrain the portion of \f(CW\*(C`pv\*(C'\fR that is looked at by this function (by
+passing a non-NULL \f(CW\*(C`endptr\*(C'\fR), and if the initial bytes of that portion form a
+valid value, it will return TRUE, setting \f(CW*endptr\fR to the byte following the
+final digit of the value. But if there is no constraint at what's looked at,
+all of \f(CW\*(C`pv\*(C'\fR must be valid in order for TRUE to be returned. \f(CW*endptr\fR is
+unchanged from its value on input if FALSE is returned;
+.Sp
+The only characters this accepts are the decimal digits '0'..'9'.
+.Sp
+As opposed to \fBatoi\fR\|(3) or \fBstrtol\fR\|(3), \f(CW\*(C`grok_atoUV\*(C'\fR does NOT allow optional
+leading whitespace, nor negative inputs. If such features are required, the
+calling code needs to explicitly implement those.
+.Sp
+Note that this function returns FALSE for inputs that would overflow a UV,
+or have leading zeros. Thus a single \f(CW0\fR is accepted, but not \f(CW00\fR nor
+\&\f(CW01\fR, \f(CW002\fR, \fIetc\fR.
+.Sp
+Background: \f(CW\*(C`atoi\*(C'\fR has severe problems with illegal inputs, it cannot be
+used for incremental parsing, and therefore should be avoided
+\&\f(CW\*(C`atoi\*(C'\fR and \f(CW\*(C`strtol\*(C'\fR are also affected by locale settings, which can also be
+seen as a bug (global state controlled by user environment).
+.RS 4
+.Sp
+.Vb 1
+\& bool grok_atoUV(const char *pv, UV *valptr, const char **endptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """grok_bin""" 4
+.el .IP \f(CWgrok_bin\fR 4
+.IX Xref "grok_bin"
+.IX Item "grok_bin"
+converts a string representing a binary number to numeric form.
+.Sp
+On entry \f(CW\*(C`start\*(C'\fR and \f(CW*len_p\fR give the string to scan, \f(CW*flags\fR gives
+conversion flags, and \f(CW\*(C`result\*(C'\fR should be \f(CW\*(C`NULL\*(C'\fR or a pointer to an NV. The
+scan stops at the end of the string, or at just before the first invalid
+character. Unless \f(CW\*(C`PERL_SCAN_SILENT_ILLDIGIT\*(C'\fR is set in \f(CW*flags\fR,
+encountering an invalid character (except NUL) will also trigger a warning. On
+return \f(CW*len_p\fR is set to the length of the scanned string, and \f(CW*flags\fR
+gives output flags.
+.Sp
+If the value is <= \f(CW\*(C`UV_MAX\*(C'\fR it is returned as a UV, the output flags are clear,
+and nothing is written to \f(CW*result\fR. If the value is > \f(CW\*(C`UV_MAX\*(C'\fR, \f(CW\*(C`grok_bin\*(C'\fR
+returns \f(CW\*(C`UV_MAX\*(C'\fR, sets \f(CW\*(C`PERL_SCAN_GREATER_THAN_UV_MAX\*(C'\fR in the output flags,
+and writes an approximation of the correct value into \f(CW*result\fR (which is an
+NV; or the approximation is discarded if \f(CW\*(C`result\*(C'\fR is NULL).
+.Sp
+The binary number may optionally be prefixed with \f(CW"0b"\fR or \f(CW"b"\fR unless
+\&\f(CW\*(C`PERL_SCAN_DISALLOW_PREFIX\*(C'\fR is set in \f(CW*flags\fR on entry.
+.Sp
+If \f(CW\*(C`PERL_SCAN_ALLOW_UNDERSCORES\*(C'\fR is set in \f(CW*flags\fR then any or all pairs of
+digits may be separated from each other by a single underscore; also a single
+leading underscore is accepted.
+.RS 4
+.Sp
+.Vb 2
+\& UV grok_bin(const char *start, STRLEN *len_p, I32 *flags,
+\& NV *result)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """grok_hex""" 4
+.el .IP \f(CWgrok_hex\fR 4
+.IX Xref "grok_hex"
+.IX Item "grok_hex"
+converts a string representing a hex number to numeric form.
+.Sp
+On entry \f(CW\*(C`start\*(C'\fR and \f(CW*len_p\fR give the string to scan, \f(CW*flags\fR gives
+conversion flags, and \f(CW\*(C`result\*(C'\fR should be \f(CW\*(C`NULL\*(C'\fR or a pointer to an NV. The
+scan stops at the end of the string, or at just before the first invalid
+character. Unless \f(CW\*(C`PERL_SCAN_SILENT_ILLDIGIT\*(C'\fR is set in \f(CW*flags\fR,
+encountering an invalid character (except NUL) will also trigger a warning. On
+return \f(CW*len_p\fR is set to the length of the scanned string, and \f(CW*flags\fR
+gives output flags.
+.Sp
+If the value is <= \f(CW\*(C`UV_MAX\*(C'\fR it is returned as a UV, the output flags are clear,
+and nothing is written to \f(CW*result\fR. If the value is > \f(CW\*(C`UV_MAX\*(C'\fR, \f(CW\*(C`grok_hex\*(C'\fR
+returns \f(CW\*(C`UV_MAX\*(C'\fR, sets \f(CW\*(C`PERL_SCAN_GREATER_THAN_UV_MAX\*(C'\fR in the output flags,
+and writes an approximation of the correct value into \f(CW*result\fR (which is an
+NV; or the approximation is discarded if \f(CW\*(C`result\*(C'\fR is NULL).
+.Sp
+The hex number may optionally be prefixed with \f(CW"0x"\fR or \f(CW"x"\fR unless
+\&\f(CW\*(C`PERL_SCAN_DISALLOW_PREFIX\*(C'\fR is set in \f(CW*flags\fR on entry.
+.Sp
+If \f(CW\*(C`PERL_SCAN_ALLOW_UNDERSCORES\*(C'\fR is set in \f(CW*flags\fR then any or all pairs of
+digits may be separated from each other by a single underscore; also a single
+leading underscore is accepted.
+.RS 4
+.Sp
+.Vb 2
+\& UV grok_hex(const char *start, STRLEN *len_p, I32 *flags,
+\& NV *result)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """grok_infnan""" 4
+.el .IP \f(CWgrok_infnan\fR 4
+.IX Xref "grok_infnan"
+.IX Item "grok_infnan"
+Helper for \f(CWgrok_number()\fR, accepts various ways of spelling "infinity"
+or "not a number", and returns one of the following flag combinations:
+.Sp
+.Vb 5
+\& IS_NUMBER_INFINITY
+\& IS_NUMBER_NAN
+\& IS_NUMBER_INFINITY | IS_NUMBER_NEG
+\& IS_NUMBER_NAN | IS_NUMBER_NEG
+\& 0
+.Ve
+.Sp
+possibly |\-ed with \f(CW\*(C`IS_NUMBER_TRAILING\*(C'\fR.
+.Sp
+If an infinity or a not-a-number is recognized, \f(CW*sp\fR will point to
+one byte past the end of the recognized string. If the recognition fails,
+zero is returned, and \f(CW*sp\fR will not move.
+.RS 4
+.Sp
+.Vb 1
+\& int grok_infnan(const char **sp, const char *send)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """grok_number""" 4
+.el .IP \f(CWgrok_number\fR 4
+.IX Xref "grok_number"
+.IX Item "grok_number"
+Identical to \f(CWgrok_number_flags()\fR with \f(CW\*(C`flags\*(C'\fR set to zero.
+.RS 4
+.Sp
+.Vb 1
+\& int grok_number(const char *pv, STRLEN len, UV *valuep)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """grok_number_flags""" 4
+.el .IP \f(CWgrok_number_flags\fR 4
+.IX Xref "grok_number_flags"
+.IX Item "grok_number_flags"
+Recognise (or not) a number. The type of the number is returned
+(0 if unrecognised), otherwise it is a bit-ORed combination of
+\&\f(CW\*(C`IS_NUMBER_IN_UV\*(C'\fR, \f(CW\*(C`IS_NUMBER_GREATER_THAN_UV_MAX\*(C'\fR, \f(CW\*(C`IS_NUMBER_NOT_INT\*(C'\fR,
+\&\f(CW\*(C`IS_NUMBER_NEG\*(C'\fR, \f(CW\*(C`IS_NUMBER_INFINITY\*(C'\fR, \f(CW\*(C`IS_NUMBER_NAN\*(C'\fR (defined in perl.h).
+.Sp
+If the value of the number can fit in a UV, it is returned in \f(CW*valuep\fR.
+\&\f(CW\*(C`IS_NUMBER_IN_UV\*(C'\fR will be set to indicate that \f(CW*valuep\fR is valid, \f(CW\*(C`IS_NUMBER_IN_UV\*(C'\fR
+will never be set unless \f(CW*valuep\fR is valid, but \f(CW*valuep\fR may have been assigned
+to during processing even though \f(CW\*(C`IS_NUMBER_IN_UV\*(C'\fR is not set on return.
+If \f(CW\*(C`valuep\*(C'\fR is \f(CW\*(C`NULL\*(C'\fR, \f(CW\*(C`IS_NUMBER_IN_UV\*(C'\fR will be set for the same cases as when
+\&\f(CW\*(C`valuep\*(C'\fR is non\-\f(CW\*(C`NULL\*(C'\fR, but no actual assignment (or SEGV) will occur.
+.Sp
+\&\f(CW\*(C`IS_NUMBER_NOT_INT\*(C'\fR will be set with \f(CW\*(C`IS_NUMBER_IN_UV\*(C'\fR if trailing decimals were
+seen (in which case \f(CW*valuep\fR gives the true value truncated to an integer), and
+\&\f(CW\*(C`IS_NUMBER_NEG\*(C'\fR if the number is negative (in which case \f(CW*valuep\fR holds the
+absolute value). \f(CW\*(C`IS_NUMBER_IN_UV\*(C'\fR is not set if \f(CW\*(C`e\*(C'\fR notation was used or the
+number is larger than a UV.
+.Sp
+\&\f(CW\*(C`flags\*(C'\fR allows only \f(CW\*(C`PERL_SCAN_TRAILING\*(C'\fR, which allows for trailing
+non-numeric text on an otherwise successful \fIgrok\fR, setting
+\&\f(CW\*(C`IS_NUMBER_TRAILING\*(C'\fR on the result.
+.RS 4
+.Sp
+.Vb 2
+\& int grok_number_flags(const char *pv, STRLEN len, UV *valuep,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """GROK_NUMERIC_RADIX""" 4
+.el .IP \f(CWGROK_NUMERIC_RADIX\fR 4
+.IX Xref "GROK_NUMERIC_RADIX"
+.IX Item "GROK_NUMERIC_RADIX"
+A synonym for "grok_numeric_radix"
+.RS 4
+.Sp
+.Vb 1
+\& bool GROK_NUMERIC_RADIX(NN const char **sp, NN const char *send)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """grok_numeric_radix""" 4
+.el .IP \f(CWgrok_numeric_radix\fR 4
+.IX Xref "grok_numeric_radix"
+.IX Item "grok_numeric_radix"
+Scan and skip for a numeric decimal separator (radix).
+.RS 4
+.Sp
+.Vb 1
+\& bool grok_numeric_radix(const char **sp, const char *send)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """grok_oct""" 4
+.el .IP \f(CWgrok_oct\fR 4
+.IX Xref "grok_oct"
+.IX Item "grok_oct"
+converts a string representing an octal number to numeric form.
+.Sp
+On entry \f(CW\*(C`start\*(C'\fR and \f(CW*len_p\fR give the string to scan, \f(CW*flags\fR gives
+conversion flags, and \f(CW\*(C`result\*(C'\fR should be \f(CW\*(C`NULL\*(C'\fR or a pointer to an NV. The
+scan stops at the end of the string, or at just before the first invalid
+character. Unless \f(CW\*(C`PERL_SCAN_SILENT_ILLDIGIT\*(C'\fR is set in \f(CW*flags\fR,
+encountering an invalid character (except NUL) will also trigger a warning. On
+return \f(CW*len_p\fR is set to the length of the scanned string, and \f(CW*flags\fR
+gives output flags.
+.Sp
+If the value is <= \f(CW\*(C`UV_MAX\*(C'\fR it is returned as a UV, the output flags are clear,
+and nothing is written to \f(CW*result\fR. If the value is > \f(CW\*(C`UV_MAX\*(C'\fR, \f(CW\*(C`grok_oct\*(C'\fR
+returns \f(CW\*(C`UV_MAX\*(C'\fR, sets \f(CW\*(C`PERL_SCAN_GREATER_THAN_UV_MAX\*(C'\fR in the output flags,
+and writes an approximation of the correct value into \f(CW*result\fR (which is an
+NV; or the approximation is discarded if \f(CW\*(C`result\*(C'\fR is NULL).
+.Sp
+If \f(CW\*(C`PERL_SCAN_ALLOW_UNDERSCORES\*(C'\fR is set in \f(CW*flags\fR then any or all pairs of
+digits may be separated from each other by a single underscore; also a single
+leading underscore is accepted.
+.Sp
+The \f(CW\*(C`PERL_SCAN_DISALLOW_PREFIX\*(C'\fR flag is always treated as being set for
+this function.
+.RS 4
+.Sp
+.Vb 2
+\& UV grok_oct(const char *start, STRLEN *len_p, I32 *flags,
+\& NV *result)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isinfnan""" 4
+.el .IP \f(CWisinfnan\fR 4
+.IX Xref "isinfnan"
+.IX Item "isinfnan"
+\&\f(CWPerl_isinfnan()\fR is a utility function that returns true if the NV
+argument is either an infinity or a \f(CW\*(C`NaN\*(C'\fR, false otherwise. To test
+in more detail, use \f(CWPerl_isinf()\fR and \f(CWPerl_isnan()\fR.
+.Sp
+This is also the logical inverse of \fBPerl_isfinite()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool isinfnan(NV nv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_atof""" 4
+.el .IP \f(CWmy_atof\fR 4
+.IX Xref "my_atof"
+.IX Item "my_atof"
+\&\f(CW\*(C`atof\*(C'\fR(3), but properly works with Perl locale handling, accepting a dot
+radix character always, but also the current locale's radix character if and
+only if called from within the lexical scope of a Perl \f(CW\*(C`use locale\*(C'\fR statement.
+.Sp
+N.B. \f(CW\*(C`s\*(C'\fR must be NUL terminated.
+.RS 4
+.Sp
+.Vb 1
+\& NV my_atof(const char *s)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_strtod""" 4
+.el .IP \f(CWmy_strtod\fR 4
+.IX Xref "my_strtod"
+.IX Item "my_strtod"
+This function is equivalent to the libc \fBstrtod()\fR function, and is available
+even on platforms that lack plain \fBstrtod()\fR. Its return value is the best
+available precision depending on platform capabilities and \fIConfigure\fR
+options.
+.Sp
+It properly handles the locale radix character, meaning it expects a dot except
+when called from within the scope of \f(CW\*(C`use\ locale\*(C'\fR, in which case the radix
+character should be that specified by the current locale.
+.Sp
+The synonym \fBStrtod()\fR may be used instead.
+.RS 4
+.Sp
+.Vb 1
+\& NV my_strtod(const char * const s, char **e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_ABS""" 4
+.el .IP \f(CWPERL_ABS\fR 4
+.IX Xref "PERL_ABS"
+.IX Item "PERL_ABS"
+Typeless \f(CW\*(C`abs\*(C'\fR or \f(CW\*(C`fabs\*(C'\fR, \fIetc\fR. (The usage below indicates it is for
+integers, but it works for any type.) Use instead of these, since the C
+library ones force their argument to be what it is expecting, potentially
+leading to disaster. But also beware that this evaluates its argument twice,
+so no \f(CW\*(C`x++\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int PERL_ABS(int x)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Perl_acos""" 4
+.el .IP \f(CWPerl_acos\fR 4
+.IX Item "Perl_acos"
+.PD 0
+.ie n .IP """Perl_asin""" 4
+.el .IP \f(CWPerl_asin\fR 4
+.IX Item "Perl_asin"
+.ie n .IP """Perl_atan""" 4
+.el .IP \f(CWPerl_atan\fR 4
+.IX Item "Perl_atan"
+.ie n .IP """Perl_atan2""" 4
+.el .IP \f(CWPerl_atan2\fR 4
+.IX Item "Perl_atan2"
+.ie n .IP """Perl_ceil""" 4
+.el .IP \f(CWPerl_ceil\fR 4
+.IX Item "Perl_ceil"
+.ie n .IP """Perl_cos""" 4
+.el .IP \f(CWPerl_cos\fR 4
+.IX Item "Perl_cos"
+.ie n .IP """Perl_cosh""" 4
+.el .IP \f(CWPerl_cosh\fR 4
+.IX Item "Perl_cosh"
+.ie n .IP """Perl_exp""" 4
+.el .IP \f(CWPerl_exp\fR 4
+.IX Item "Perl_exp"
+.ie n .IP """Perl_floor""" 4
+.el .IP \f(CWPerl_floor\fR 4
+.IX Item "Perl_floor"
+.ie n .IP """Perl_fmod""" 4
+.el .IP \f(CWPerl_fmod\fR 4
+.IX Item "Perl_fmod"
+.ie n .IP """Perl_frexp""" 4
+.el .IP \f(CWPerl_frexp\fR 4
+.IX Item "Perl_frexp"
+.ie n .IP """Perl_isfinite""" 4
+.el .IP \f(CWPerl_isfinite\fR 4
+.IX Item "Perl_isfinite"
+.ie n .IP """Perl_isinf""" 4
+.el .IP \f(CWPerl_isinf\fR 4
+.IX Item "Perl_isinf"
+.ie n .IP """Perl_isnan""" 4
+.el .IP \f(CWPerl_isnan\fR 4
+.IX Item "Perl_isnan"
+.ie n .IP """Perl_ldexp""" 4
+.el .IP \f(CWPerl_ldexp\fR 4
+.IX Item "Perl_ldexp"
+.ie n .IP """Perl_log""" 4
+.el .IP \f(CWPerl_log\fR 4
+.IX Item "Perl_log"
+.ie n .IP """Perl_log10""" 4
+.el .IP \f(CWPerl_log10\fR 4
+.IX Item "Perl_log10"
+.ie n .IP """Perl_modf""" 4
+.el .IP \f(CWPerl_modf\fR 4
+.IX Item "Perl_modf"
+.ie n .IP """Perl_pow""" 4
+.el .IP \f(CWPerl_pow\fR 4
+.IX Item "Perl_pow"
+.ie n .IP """Perl_sin""" 4
+.el .IP \f(CWPerl_sin\fR 4
+.IX Item "Perl_sin"
+.ie n .IP """Perl_sinh""" 4
+.el .IP \f(CWPerl_sinh\fR 4
+.IX Item "Perl_sinh"
+.ie n .IP """Perl_sqrt""" 4
+.el .IP \f(CWPerl_sqrt\fR 4
+.IX Item "Perl_sqrt"
+.ie n .IP """Perl_tan""" 4
+.el .IP \f(CWPerl_tan\fR 4
+.IX Item "Perl_tan"
+.ie n .IP """Perl_tanh""" 4
+.el .IP \f(CWPerl_tanh\fR 4
+.IX Xref "Perl_acos Perl_asin Perl_atan Perl_atan2 Perl_ceil Perl_cos Perl_cosh Perl_exp Perl_floor Perl_fmod Perl_frexp Perl_isfinite Perl_isinf Perl_isnan Perl_ldexp Perl_log Perl_log10 Perl_modf Perl_pow Perl_sin Perl_sinh Perl_sqrt Perl_tan Perl_tanh"
+.IX Item "Perl_tanh"
+.PD
+These perform the corresponding mathematical operation on the operand(s), using
+the libc function designed for the task that has just enough precision for an
+NV on this platform. If no such function with sufficient precision exists,
+the highest precision one available is used.
+.RS 4
+.Sp
+.Vb 10
+\& NV Perl_acos (NV x)
+\& NV Perl_asin (NV x)
+\& NV Perl_atan (NV x)
+\& NV Perl_atan2 (NV x, NV y)
+\& NV Perl_ceil (NV x)
+\& NV Perl_cos (NV x)
+\& NV Perl_cosh (NV x)
+\& NV Perl_exp (NV x)
+\& NV Perl_floor (NV x)
+\& NV Perl_fmod (NV x, NV y)
+\& NV Perl_frexp (NV x, int *exp)
+\& IV Perl_isfinite(NV x)
+\& IV Perl_isinf (NV x)
+\& IV Perl_isnan (NV x)
+\& NV Perl_ldexp (NV x, int exp)
+\& NV Perl_log (NV x)
+\& NV Perl_log10 (NV x)
+\& NV Perl_modf (NV x, NV *iptr)
+\& NV Perl_pow (NV x, NV y)
+\& NV Perl_sin (NV x)
+\& NV Perl_sinh (NV x)
+\& NV Perl_sqrt (NV x)
+\& NV Perl_tan (NV x)
+\& NV Perl_tanh (NV x)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Perl_signbit""" 4
+.el .IP \f(CWPerl_signbit\fR 4
+.IX Xref "Perl_signbit"
+.IX Item "Perl_signbit"
+NOTE: \f(CW\*(C`Perl_signbit\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Return a non-zero integer if the sign bit on an NV is set, and 0 if
+it is not.
+.Sp
+If \fIConfigure\fR detects this system has a \f(CWsignbit()\fR that will work with
+our NVs, then we just use it via the \f(CW\*(C`#define\*(C'\fR in \fIperl.h\fR. Otherwise,
+fall back on this implementation. The main use of this function
+is catching \f(CW\-0.0\fR.
+.Sp
+\&\f(CW\*(C`Configure\*(C'\fR notes: This function is called \f(CW\*(AqPerl_signbit\*(Aq\fR instead of a
+plain \f(CW\*(Aqsignbit\*(Aq\fR because it is easy to imagine a system having a \f(CWsignbit()\fR
+function or macro that doesn't happen to work with our particular choice
+of NVs. We shouldn't just re\-\f(CW\*(C`#define\*(C'\fR \f(CW\*(C`signbit\*(C'\fR as \f(CW\*(C`Perl_signbit\*(C'\fR and expect
+the standard system headers to be happy. Also, this is a no-context
+function (no \f(CW\*(C`pTHX_\*(C'\fR) because \f(CWPerl_signbit()\fR is usually re\-\f(CW\*(C`#defined\*(C'\fR in
+\&\fIperl.h\fR as a simple macro call to the system's \f(CWsignbit()\fR.
+Users should just always call \f(CWPerl_signbit()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int Perl_signbit(NV f)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_hexdigit""" 4
+.el .IP \f(CWPL_hexdigit\fR 4
+.IX Xref "PL_hexdigit"
+.IX Item "PL_hexdigit"
+This array, indexed by an integer, converts that value into the character that
+represents it. For example, if the input is 8, the return will be a string
+whose first character is '8'. What is actually returned is a pointer into a
+string. All you are interested in is the first character of that string. To
+get uppercase letters (for the values 10..15), add 16 to the index. Hence,
+\&\f(CW\*(C`PL_hexdigit[11]\*(C'\fR is \f(CW\*(Aqb\*(Aq\fR, and \f(CW\*(C`PL_hexdigit[11+16]\*(C'\fR is \f(CW\*(AqB\*(Aq\fR. Adding 16
+to an index whose representation is '0'..'9' yields the same as not adding 16.
+Indices outside the range 0..31 result in (bad) undedefined behavior.
+.ie n .IP """READ_XDIGIT""" 4
+.el .IP \f(CWREAD_XDIGIT\fR 4
+.IX Xref "READ_XDIGIT"
+.IX Item "READ_XDIGIT"
+Returns the value of an ASCII-range hex digit and advances the string pointer.
+Behaviour is only well defined when isXDIGIT(*str) is true.
+.RS 4
+.Sp
+.Vb 1
+\& U8 READ_XDIGIT(char str*)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """scan_bin""" 4
+.el .IP \f(CWscan_bin\fR 4
+.IX Xref "scan_bin"
+.IX Item "scan_bin"
+For backwards compatibility. Use \f(CW\*(C`grok_bin\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& NV scan_bin(const char *start, STRLEN len, STRLEN *retlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """scan_hex""" 4
+.el .IP \f(CWscan_hex\fR 4
+.IX Xref "scan_hex"
+.IX Item "scan_hex"
+For backwards compatibility. Use \f(CW\*(C`grok_hex\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& NV scan_hex(const char *start, STRLEN len, STRLEN *retlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """scan_oct""" 4
+.el .IP \f(CWscan_oct\fR 4
+.IX Xref "scan_oct"
+.IX Item "scan_oct"
+For backwards compatibility. Use \f(CW\*(C`grok_oct\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& NV scan_oct(const char *start, STRLEN len, STRLEN *retlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """seedDrand01""" 4
+.el .IP \f(CWseedDrand01\fR 4
+.IX Xref "seedDrand01"
+.IX Item "seedDrand01"
+This symbol defines the macro to be used in seeding the
+random number generator (see \f(CW"Drand01"\fR).
+.RS 4
+.Sp
+.Vb 1
+\& void seedDrand01(Rand_seed_t x)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Strtod""" 4
+.el .IP \f(CWStrtod\fR 4
+.IX Xref "Strtod"
+.IX Item "Strtod"
+This is a synonym for "my_strtod".
+.RS 4
+.Sp
+.Vb 1
+\& NV Strtod(NN const char * const s, NULLOK char ** e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Strtol""" 4
+.el .IP \f(CWStrtol\fR 4
+.IX Xref "Strtol"
+.IX Item "Strtol"
+Platform and configuration independent \f(CW\*(C`strtol\*(C'\fR. This expands to the
+appropriate \f(CW\*(C`strotol\*(C'\fR\-like function based on the platform and \fIConfigure\fR
+options>. For example it could expand to \f(CW\*(C`strtoll\*(C'\fR or \f(CW\*(C`strtoq\*(C'\fR instead of
+\&\f(CW\*(C`strtol\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& NV Strtol(NN const char * const s, NULLOK char ** e, int base)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Strtoul""" 4
+.el .IP \f(CWStrtoul\fR 4
+.IX Xref "Strtoul"
+.IX Item "Strtoul"
+Platform and configuration independent \f(CW\*(C`strtoul\*(C'\fR. This expands to the
+appropriate \f(CW\*(C`strotoul\*(C'\fR\-like function based on the platform and \fIConfigure\fR
+options>. For example it could expand to \f(CW\*(C`strtoull\*(C'\fR or \f(CW\*(C`strtouq\*(C'\fR instead of
+\&\f(CW\*(C`strtoul\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& NV Strtoul(NN const char * const s, NULLOK char ** e, int base)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Optrees
+.IX Xref "CALL_CHECKER_REQUIRE_GV OPf_KIDS OPpEARLY_CV OPpENTERSUB_AMPER RV2CVOPCV_MARK_EARLY RV2CVOPCV_RETURN_NAME_GV"
+.IX Header "Optrees"
+.ie n .IP """alloccopstash""" 4
+.el .IP \f(CWalloccopstash\fR 4
+.IX Xref "alloccopstash"
+.IX Item "alloccopstash"
+NOTE: \f(CW\*(C`alloccopstash\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Available only under threaded builds, this function allocates an entry in
+\&\f(CW\*(C`PL_stashpad\*(C'\fR for the stash passed to it.
+.RS 4
+.Sp
+.Vb 1
+\& PADOFFSET alloccopstash(HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """BINOP""" 4
+.el .IP \f(CWBINOP\fR 4
+.IX Item "BINOP"
+Described in perlguts.
+.ie n .IP """block_end""" 4
+.el .IP \f(CWblock_end\fR 4
+.IX Xref "block_end"
+.IX Item "block_end"
+Handles compile-time scope exit. \f(CW\*(C`floor\*(C'\fR
+is the savestack index returned by
+\&\f(CW\*(C`block_start\*(C'\fR, and \f(CW\*(C`seq\*(C'\fR is the body of the block. Returns the block,
+possibly modified.
+.RS 4
+.Sp
+.Vb 1
+\& OP * block_end(I32 floor, OP *seq)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """block_start""" 4
+.el .IP \f(CWblock_start\fR 4
+.IX Xref "block_start"
+.IX Item "block_start"
+Handles compile-time scope entry.
+Arranges for hints to be restored on block
+exit and also handles pad sequence numbers to make lexical variables scope
+right. Returns a savestack index for use with \f(CW\*(C`block_end\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int block_start(int full)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ck_entersub_args_list""" 4
+.el .IP \f(CWck_entersub_args_list\fR 4
+.IX Xref "ck_entersub_args_list"
+.IX Item "ck_entersub_args_list"
+Performs the default fixup of the arguments part of an \f(CW\*(C`entersub\*(C'\fR
+op tree. This consists of applying list context to each of the
+argument ops. This is the standard treatment used on a call marked
+with \f(CW\*(C`&\*(C'\fR, or a method call, or a call through a subroutine reference,
+or any other call where the callee can't be identified at compile time,
+or a call where the callee has no prototype.
+.RS 4
+.Sp
+.Vb 1
+\& OP * ck_entersub_args_list(OP *entersubop)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ck_entersub_args_proto""" 4
+.el .IP \f(CWck_entersub_args_proto\fR 4
+.IX Xref "ck_entersub_args_proto"
+.IX Item "ck_entersub_args_proto"
+Performs the fixup of the arguments part of an \f(CW\*(C`entersub\*(C'\fR op tree
+based on a subroutine prototype. This makes various modifications to
+the argument ops, from applying context up to inserting \f(CW\*(C`refgen\*(C'\fR ops,
+and checking the number and syntactic types of arguments, as directed by
+the prototype. This is the standard treatment used on a subroutine call,
+not marked with \f(CW\*(C`&\*(C'\fR, where the callee can be identified at compile time
+and has a prototype.
+.Sp
+\&\f(CW\*(C`protosv\*(C'\fR supplies the subroutine prototype to be applied to the call.
+It may be a normal defined scalar, of which the string value will be used.
+Alternatively, for convenience, it may be a subroutine object (a \f(CW\*(C`CV*\*(C'\fR
+that has been cast to \f(CW\*(C`SV*\*(C'\fR) which has a prototype. The prototype
+supplied, in whichever form, does not need to match the actual callee
+referenced by the op tree.
+.Sp
+If the argument ops disagree with the prototype, for example by having
+an unacceptable number of arguments, a valid op tree is returned anyway.
+The error is reflected in the parser state, normally resulting in a single
+exception at the top level of parsing which covers all the compilation
+errors that occurred. In the error message, the callee is referred to
+by the name defined by the \f(CW\*(C`namegv\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& OP * ck_entersub_args_proto(OP *entersubop, GV *namegv,
+\& SV *protosv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ck_entersub_args_proto_or_list""" 4
+.el .IP \f(CWck_entersub_args_proto_or_list\fR 4
+.IX Xref "ck_entersub_args_proto_or_list"
+.IX Item "ck_entersub_args_proto_or_list"
+Performs the fixup of the arguments part of an \f(CW\*(C`entersub\*(C'\fR op tree either
+based on a subroutine prototype or using default list-context processing.
+This is the standard treatment used on a subroutine call, not marked
+with \f(CW\*(C`&\*(C'\fR, where the callee can be identified at compile time.
+.Sp
+\&\f(CW\*(C`protosv\*(C'\fR supplies the subroutine prototype to be applied to the call,
+or indicates that there is no prototype. It may be a normal scalar,
+in which case if it is defined then the string value will be used
+as a prototype, and if it is undefined then there is no prototype.
+Alternatively, for convenience, it may be a subroutine object (a \f(CW\*(C`CV*\*(C'\fR
+that has been cast to \f(CW\*(C`SV*\*(C'\fR), of which the prototype will be used if it
+has one. The prototype (or lack thereof) supplied, in whichever form,
+does not need to match the actual callee referenced by the op tree.
+.Sp
+If the argument ops disagree with the prototype, for example by having
+an unacceptable number of arguments, a valid op tree is returned anyway.
+The error is reflected in the parser state, normally resulting in a single
+exception at the top level of parsing which covers all the compilation
+errors that occurred. In the error message, the callee is referred to
+by the name defined by the \f(CW\*(C`namegv\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& OP * ck_entersub_args_proto_or_list(OP *entersubop, GV *namegv,
+\& SV *protosv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cv_const_sv""" 4
+.el .IP \f(CWcv_const_sv\fR 4
+.IX Xref "cv_const_sv"
+.IX Item "cv_const_sv"
+If \f(CW\*(C`cv\*(C'\fR is a constant sub eligible for inlining, returns the constant
+value returned by the sub. Otherwise, returns \f(CW\*(C`NULL\*(C'\fR.
+.Sp
+Constant subs can be created with \f(CW\*(C`newCONSTSUB\*(C'\fR or as described in
+"Constant Functions" in perlsub.
+.RS 4
+.Sp
+.Vb 1
+\& SV * cv_const_sv(const CV * const cv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cv_get_call_checker""" 4
+.el .IP \f(CWcv_get_call_checker\fR 4
+.IX Xref "cv_get_call_checker"
+.IX Item "cv_get_call_checker"
+The original form of "cv_get_call_checker_flags", which does not return
+checker flags. When using a checker function returned by this function,
+it is only safe to call it with a genuine GV as its \f(CW\*(C`namegv\*(C'\fR argument.
+.RS 4
+.Sp
+.Vb 2
+\& void cv_get_call_checker(CV *cv, Perl_call_checker *ckfun_p,
+\& SV **ckobj_p)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cv_get_call_checker_flags""" 4
+.el .IP \f(CWcv_get_call_checker_flags\fR 4
+.IX Xref "cv_get_call_checker_flags"
+.IX Item "cv_get_call_checker_flags"
+Retrieves the function that will be used to fix up a call to \f(CW\*(C`cv\*(C'\fR.
+Specifically, the function is applied to an \f(CW\*(C`entersub\*(C'\fR op tree for a
+subroutine call, not marked with \f(CW\*(C`&\*(C'\fR, where the callee can be identified
+at compile time as \f(CW\*(C`cv\*(C'\fR.
+.Sp
+The C\-level function pointer is returned in \f(CW*ckfun_p\fR, an SV argument
+for it is returned in \f(CW*ckobj_p\fR, and control flags are returned in
+\&\f(CW*ckflags_p\fR. The function is intended to be called in this manner:
+.Sp
+.Vb 1
+\& entersubop = (*ckfun_p)(aTHX_ entersubop, namegv, (*ckobj_p));
+.Ve
+.Sp
+In this call, \f(CW\*(C`entersubop\*(C'\fR is a pointer to the \f(CW\*(C`entersub\*(C'\fR op,
+which may be replaced by the check function, and \f(CW\*(C`namegv\*(C'\fR supplies
+the name that should be used by the check function to refer
+to the callee of the \f(CW\*(C`entersub\*(C'\fR op if it needs to emit any diagnostics.
+It is permitted to apply the check function in non-standard situations,
+such as to a call to a different subroutine or to a method call.
+.Sp
+\&\f(CW\*(C`namegv\*(C'\fR may not actually be a GV. If the \f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR
+bit is clear in \f(CW*ckflags_p\fR, it is permitted to pass a CV or other SV
+instead, anything that can be used as the first argument to "cv_name".
+If the \f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR bit is set in \f(CW*ckflags_p\fR then the
+check function requires \f(CW\*(C`namegv\*(C'\fR to be a genuine GV.
+.Sp
+By default, the check function is
+Perl_ck_entersub_args_proto_or_list,
+the SV parameter is \f(CW\*(C`cv\*(C'\fR itself, and the \f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR
+flag is clear. This implements standard prototype processing. It can
+be changed, for a particular subroutine, by "cv_set_call_checker_flags".
+.Sp
+If the \f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR bit is set in \f(CW\*(C`gflags\*(C'\fR then it
+indicates that the caller only knows about the genuine GV version of
+\&\f(CW\*(C`namegv\*(C'\fR, and accordingly the corresponding bit will always be set in
+\&\f(CW*ckflags_p\fR, regardless of the check function's recorded requirements.
+If the \f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR bit is clear in \f(CW\*(C`gflags\*(C'\fR then it
+indicates the caller knows about the possibility of passing something
+other than a GV as \f(CW\*(C`namegv\*(C'\fR, and accordingly the corresponding bit may
+be either set or clear in \f(CW*ckflags_p\fR, indicating the check function's
+recorded requirements.
+.Sp
+\&\f(CW\*(C`gflags\*(C'\fR is a bitset passed into \f(CW\*(C`cv_get_call_checker_flags\*(C'\fR, in which
+only the \f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR bit currently has a defined meaning
+(for which see above). All other bits should be clear.
+.RS 4
+.Sp
+.Vb 3
+\& void cv_get_call_checker_flags(CV *cv, U32 gflags,
+\& Perl_call_checker *ckfun_p,
+\& SV **ckobj_p, U32 *ckflags_p)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cv_set_call_checker""" 4
+.el .IP \f(CWcv_set_call_checker\fR 4
+.IX Xref "cv_set_call_checker"
+.IX Item "cv_set_call_checker"
+The original form of "cv_set_call_checker_flags", which passes it the
+\&\f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR flag for backward-compatibility. The effect
+of that flag setting is that the check function is guaranteed to get a
+genuine GV as its \f(CW\*(C`namegv\*(C'\fR argument.
+.RS 4
+.Sp
+.Vb 2
+\& void cv_set_call_checker(CV *cv, Perl_call_checker ckfun,
+\& SV *ckobj)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """cv_set_call_checker_flags""" 4
+.el .IP \f(CWcv_set_call_checker_flags\fR 4
+.IX Xref "cv_set_call_checker_flags"
+.IX Item "cv_set_call_checker_flags"
+Sets the function that will be used to fix up a call to \f(CW\*(C`cv\*(C'\fR.
+Specifically, the function is applied to an \f(CW\*(C`entersub\*(C'\fR op tree for a
+subroutine call, not marked with \f(CW\*(C`&\*(C'\fR, where the callee can be identified
+at compile time as \f(CW\*(C`cv\*(C'\fR.
+.Sp
+The C\-level function pointer is supplied in \f(CW\*(C`ckfun\*(C'\fR, an SV argument for
+it is supplied in \f(CW\*(C`ckobj\*(C'\fR, and control flags are supplied in \f(CW\*(C`ckflags\*(C'\fR.
+The function should be defined like this:
+.Sp
+.Vb 1
+\& STATIC OP * ckfun(pTHX_ OP *op, GV *namegv, SV *ckobj)
+.Ve
+.Sp
+It is intended to be called in this manner:
+.Sp
+.Vb 1
+\& entersubop = ckfun(aTHX_ entersubop, namegv, ckobj);
+.Ve
+.Sp
+In this call, \f(CW\*(C`entersubop\*(C'\fR is a pointer to the \f(CW\*(C`entersub\*(C'\fR op,
+which may be replaced by the check function, and \f(CW\*(C`namegv\*(C'\fR supplies
+the name that should be used by the check function to refer
+to the callee of the \f(CW\*(C`entersub\*(C'\fR op if it needs to emit any diagnostics.
+It is permitted to apply the check function in non-standard situations,
+such as to a call to a different subroutine or to a method call.
+.Sp
+\&\f(CW\*(C`namegv\*(C'\fR may not actually be a GV. For efficiency, perl may pass a
+CV or other SV instead. Whatever is passed can be used as the first
+argument to "cv_name". You can force perl to pass a GV by including
+\&\f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR in the \f(CW\*(C`ckflags\*(C'\fR.
+.Sp
+\&\f(CW\*(C`ckflags\*(C'\fR is a bitset, in which only the \f(CW\*(C`CALL_CHECKER_REQUIRE_GV\*(C'\fR
+bit currently has a defined meaning (for which see above). All other
+bits should be clear.
+.Sp
+The current setting for a particular CV can be retrieved by
+"cv_get_call_checker_flags".
+.RS 4
+.Sp
+.Vb 2
+\& void cv_set_call_checker_flags(CV *cv, Perl_call_checker ckfun,
+\& SV *ckobj, U32 ckflags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """finalize_optree""" 4
+.el .IP \f(CWfinalize_optree\fR 4
+.IX Xref "finalize_optree"
+.IX Item "finalize_optree"
+This function finalizes the optree. Should be called directly after
+the complete optree is built. It does some additional
+checking which can't be done in the normal \f(CW\*(C`ck_\*(C'\fRxxx functions and makes
+the tree thread-safe.
+.RS 4
+.Sp
+.Vb 1
+\& void finalize_optree(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """forbid_outofblock_ops""" 4
+.el .IP \f(CWforbid_outofblock_ops\fR 4
+.IX Xref "forbid_outofblock_ops"
+.IX Item "forbid_outofblock_ops"
+NOTE: \f(CW\*(C`forbid_outofblock_ops\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Checks an optree that implements a block, to ensure there are no control-flow
+ops that attempt to leave the block. Any \f(CW\*(C`OP_RETURN\*(C'\fR is forbidden, as is any
+\&\f(CW\*(C`OP_GOTO\*(C'\fR. Loops are analysed, so any LOOPEX op (\f(CW\*(C`OP_NEXT\*(C'\fR, \f(CW\*(C`OP_LAST\*(C'\fR or
+\&\f(CW\*(C`OP_REDO\*(C'\fR) that affects a loop that contains it within the block are
+permitted, but those that do not are forbidden.
+.Sp
+If any of these forbidden constructions are detected, an exception is thrown
+by using the op name and the blockname argument to construct a suitable
+message.
+.Sp
+This function alone is not sufficient to ensure the optree does not perform
+any of these forbidden activities during runtime, as it might call a different
+function that performs a non-local LOOPEX, or a string\-\fBeval()\fR that performs a
+\&\f(CW\*(C`goto\*(C'\fR, or various other things. It is intended purely as a compile-time
+check for those that could be detected statically. Additional runtime checks
+may be required depending on the circumstance it is used for.
+.Sp
+Note currently that \fIall\fR \f(CW\*(C`OP_GOTO\*(C'\fR ops are forbidden, even in cases where
+they might otherwise be safe to execute. This may be permitted in a later
+version.
+.RS 4
+.Sp
+.Vb 1
+\& void forbid_outofblock_ops(OP *o, const char *blockname)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LINKLIST""" 4
+.el .IP \f(CWLINKLIST\fR 4
+.IX Xref "LINKLIST"
+.IX Item "LINKLIST"
+Given the root of an optree, link the tree in execution order using the
+\&\f(CW\*(C`op_next\*(C'\fR pointers and return the first op executed. If this has
+already been done, it will not be redone, and \f(CW\*(C`o\->op_next\*(C'\fR will be
+returned. If \f(CW\*(C`o\->op_next\*(C'\fR is not already set, \f(CW\*(C`o\*(C'\fR should be at
+least an \f(CW\*(C`UNOP\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& OP* LINKLIST(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LISTOP""" 4
+.el .IP \f(CWLISTOP\fR 4
+.IX Item "LISTOP"
+Described in perlguts.
+.ie n .IP """LOGOP""" 4
+.el .IP \f(CWLOGOP\fR 4
+.IX Item "LOGOP"
+Described in perlguts.
+.ie n .IP """LOOP""" 4
+.el .IP \f(CWLOOP\fR 4
+.IX Item "LOOP"
+Described in perlguts.
+.ie n .IP """newARGDEFELEMOP""" 4
+.el .IP \f(CWnewARGDEFELEMOP\fR 4
+.IX Xref "newARGDEFELEMOP"
+.IX Item "newARGDEFELEMOP"
+Constructs and returns a new \f(CW\*(C`OP_ARGDEFELEM\*(C'\fR op which provides a defaulting
+expression given by \f(CW\*(C`expr\*(C'\fR for the signature parameter at the index given
+by \f(CW\*(C`argindex\*(C'\fR. The expression optree is consumed by this function and
+becomes part of the returned optree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newARGDEFELEMOP(I32 flags, OP *expr, I32 argindex)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newASSIGNOP""" 4
+.el .IP \f(CWnewASSIGNOP\fR 4
+.IX Xref "newASSIGNOP"
+.IX Item "newASSIGNOP"
+Constructs, checks, and returns an assignment op. \f(CW\*(C`left\*(C'\fR and \f(CW\*(C`right\*(C'\fR
+supply the parameters of the assignment; they are consumed by this
+function and become part of the constructed op tree.
+.Sp
+If \f(CW\*(C`optype\*(C'\fR is \f(CW\*(C`OP_ANDASSIGN\*(C'\fR, \f(CW\*(C`OP_ORASSIGN\*(C'\fR, or \f(CW\*(C`OP_DORASSIGN\*(C'\fR, then
+a suitable conditional optree is constructed. If \f(CW\*(C`optype\*(C'\fR is the opcode
+of a binary operator, such as \f(CW\*(C`OP_BIT_OR\*(C'\fR, then an op is constructed that
+performs the binary operation and assigns the result to the left argument.
+Either way, if \f(CW\*(C`optype\*(C'\fR is non-zero then \f(CW\*(C`flags\*(C'\fR has no effect.
+.Sp
+If \f(CW\*(C`optype\*(C'\fR is zero, then a plain scalar or list assignment is
+constructed. Which type of assignment it is is automatically determined.
+\&\f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR, except that \f(CW\*(C`OPf_KIDS\*(C'\fR
+will be set automatically, and, shifted up eight bits, the eight bits
+of \f(CW\*(C`op_private\*(C'\fR, except that the bit with value 1 or 2 is automatically
+set as required.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newASSIGNOP(I32 flags, OP *left, I32 optype, OP *right)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newATTRSUB""" 4
+.el .IP \f(CWnewATTRSUB\fR 4
+.IX Xref "newATTRSUB"
+.IX Item "newATTRSUB"
+Construct a Perl subroutine, also performing some surrounding jobs.
+.Sp
+This is the same as "\f(CW\*(C`newATTRSUB_x\*(C'\fR" in perlintern with its \f(CW\*(C`o_is_gv\*(C'\fR parameter set to
+FALSE. This means that if \f(CW\*(C`o\*(C'\fR is null, the new sub will be anonymous; otherwise
+the name will be derived from \f(CW\*(C`o\*(C'\fR in the way described (as with all other
+details) in "\f(CW\*(C`newATTRSUB_x\*(C'\fR" in perlintern.
+.RS 4
+.Sp
+.Vb 2
+\& CV * newATTRSUB(I32 floor, OP *o, OP *proto, OP *attrs,
+\& OP *block)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newBINOP""" 4
+.el .IP \f(CWnewBINOP\fR 4
+.IX Xref "newBINOP"
+.IX Item "newBINOP"
+Constructs, checks, and returns an op of any binary type. \f(CW\*(C`type\*(C'\fR
+is the opcode. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR, except
+that \f(CW\*(C`OPf_KIDS\*(C'\fR will be set automatically, and, shifted up eight bits,
+the eight bits of \f(CW\*(C`op_private\*(C'\fR, except that the bit with value 1 or
+2 is automatically set as required. \f(CW\*(C`first\*(C'\fR and \f(CW\*(C`last\*(C'\fR supply up to
+two ops to be the direct children of the binary op; they are consumed
+by this function and become part of the constructed op tree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newBINOP(I32 type, I32 flags, OP *first, OP *last)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newCONDOP""" 4
+.el .IP \f(CWnewCONDOP\fR 4
+.IX Xref "newCONDOP"
+.IX Item "newCONDOP"
+Constructs, checks, and returns a conditional-expression (\f(CW\*(C`cond_expr\*(C'\fR)
+op. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR, except that \f(CW\*(C`OPf_KIDS\*(C'\fR
+will be set automatically, and, shifted up eight bits, the eight bits of
+\&\f(CW\*(C`op_private\*(C'\fR, except that the bit with value 1 is automatically set.
+\&\f(CW\*(C`first\*(C'\fR supplies the expression selecting between the two branches,
+and \f(CW\*(C`trueop\*(C'\fR and \f(CW\*(C`falseop\*(C'\fR supply the branches; they are consumed by
+this function and become part of the constructed op tree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newCONDOP(I32 flags, OP *first, OP *trueop, OP *falseop)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newCONSTSUB""" 4
+.el .IP \f(CWnewCONSTSUB\fR 4
+.IX Xref "newCONSTSUB"
+.IX Item "newCONSTSUB"
+Behaves like "newCONSTSUB_flags", except that \f(CW\*(C`name\*(C'\fR is nul-terminated
+rather than of counted length, and no flags are set. (This means that
+\&\f(CW\*(C`name\*(C'\fR is always interpreted as Latin\-1.)
+.RS 4
+.Sp
+.Vb 1
+\& CV * newCONSTSUB(HV *stash, const char *name, SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newCONSTSUB_flags""" 4
+.el .IP \f(CWnewCONSTSUB_flags\fR 4
+.IX Xref "newCONSTSUB_flags"
+.IX Item "newCONSTSUB_flags"
+Construct a constant subroutine, also performing some surrounding
+jobs. A scalar constant-valued subroutine is eligible for inlining
+at compile-time, and in Perl code can be created by \f(CW\*(C`sub\ FOO\ ()\ {\ 123\ }\*(C'\fR. Other kinds of constant subroutine have other treatment.
+.Sp
+The subroutine will have an empty prototype and will ignore any arguments
+when called. Its constant behaviour is determined by \f(CW\*(C`sv\*(C'\fR. If \f(CW\*(C`sv\*(C'\fR
+is null, the subroutine will yield an empty list. If \f(CW\*(C`sv\*(C'\fR points to a
+scalar, the subroutine will always yield that scalar. If \f(CW\*(C`sv\*(C'\fR points
+to an array, the subroutine will always yield a list of the elements of
+that array in list context, or the number of elements in the array in
+scalar context. This function takes ownership of one counted reference
+to the scalar or array, and will arrange for the object to live as long
+as the subroutine does. If \f(CW\*(C`sv\*(C'\fR points to a scalar then the inlining
+assumes that the value of the scalar will never change, so the caller
+must ensure that the scalar is not subsequently written to. If \f(CW\*(C`sv\*(C'\fR
+points to an array then no such assumption is made, so it is ostensibly
+safe to mutate the array or its elements, but whether this is really
+supported has not been determined.
+.Sp
+The subroutine will have \f(CW\*(C`CvFILE\*(C'\fR set according to \f(CW\*(C`PL_curcop\*(C'\fR.
+Other aspects of the subroutine will be left in their default state.
+The caller is free to mutate the subroutine beyond its initial state
+after this function has returned.
+.Sp
+If \f(CW\*(C`name\*(C'\fR is null then the subroutine will be anonymous, with its
+\&\f(CW\*(C`CvGV\*(C'\fR referring to an \f(CW\*(C`_\|_ANON_\|_\*(C'\fR glob. If \f(CW\*(C`name\*(C'\fR is non-null then the
+subroutine will be named accordingly, referenced by the appropriate glob.
+\&\f(CW\*(C`name\*(C'\fR is a string of length \f(CW\*(C`len\*(C'\fR bytes giving a sigilless symbol
+name, in UTF\-8 if \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`SVf_UTF8\*(C'\fR bit set and in Latin\-1
+otherwise. The name may be either qualified or unqualified. If the
+name is unqualified then it defaults to being in the stash specified by
+\&\f(CW\*(C`stash\*(C'\fR if that is non-null, or to \f(CW\*(C`PL_curstash\*(C'\fR if \f(CW\*(C`stash\*(C'\fR is null.
+The symbol is always added to the stash if necessary, with \f(CW\*(C`GV_ADDMULTI\*(C'\fR
+semantics.
+.Sp
+\&\f(CW\*(C`flags\*(C'\fR should not have bits set other than \f(CW\*(C`SVf_UTF8\*(C'\fR.
+.Sp
+If there is already a subroutine of the specified name, then the new sub
+will replace the existing one in the glob. A warning may be generated
+about the redefinition.
+.Sp
+If the subroutine has one of a few special names, such as \f(CW\*(C`BEGIN\*(C'\fR or
+\&\f(CW\*(C`END\*(C'\fR, then it will be claimed by the appropriate queue for automatic
+running of phase-related subroutines. In this case the relevant glob will
+be left not containing any subroutine, even if it did contain one before.
+Execution of the subroutine will likely be a no-op, unless \f(CW\*(C`sv\*(C'\fR was
+a tied array or the caller modified the subroutine in some interesting
+way before it was executed. In the case of \f(CW\*(C`BEGIN\*(C'\fR, the treatment is
+buggy: the sub will be executed when only half built, and may be deleted
+prematurely, possibly causing a crash.
+.Sp
+The function returns a pointer to the constructed subroutine. If the sub
+is anonymous then ownership of one counted reference to the subroutine
+is transferred to the caller. If the sub is named then the caller does
+not get ownership of a reference. In most such cases, where the sub
+has a non-phase name, the sub will be alive at the point it is returned
+by virtue of being contained in the glob that names it. A phase-named
+subroutine will usually be alive by virtue of the reference owned by
+the phase's automatic run queue. A \f(CW\*(C`BEGIN\*(C'\fR subroutine may have been
+destroyed already by the time this function returns, but currently bugs
+occur in that case before the caller gets control. It is the caller's
+responsibility to ensure that it knows which of these situations applies.
+.RS 4
+.Sp
+.Vb 2
+\& CV * newCONSTSUB_flags(HV *stash, const char *name, STRLEN len,
+\& U32 flags, SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newDEFEROP""" 4
+.el .IP \f(CWnewDEFEROP\fR 4
+.IX Xref "newDEFEROP"
+.IX Item "newDEFEROP"
+NOTE: \f(CW\*(C`newDEFEROP\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Constructs and returns a deferred-block statement that implements the
+\&\f(CW\*(C`defer\*(C'\fR semantics. The \f(CW\*(C`block\*(C'\fR optree is consumed by this function and
+becomes part of the returned optree.
+.Sp
+The \f(CW\*(C`flags\*(C'\fR argument carries additional flags to set on the returned op,
+including the \f(CW\*(C`op_private\*(C'\fR field.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newDEFEROP(I32 flags, OP *block)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newDEFSVOP""" 4
+.el .IP \f(CWnewDEFSVOP\fR 4
+.IX Xref "newDEFSVOP"
+.IX Item "newDEFSVOP"
+Constructs and returns an op to access \f(CW$_\fR.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newDEFSVOP()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newFOROP""" 4
+.el .IP \f(CWnewFOROP\fR 4
+.IX Xref "newFOROP"
+.IX Item "newFOROP"
+Constructs, checks, and returns an op tree expressing a \f(CW\*(C`foreach\*(C'\fR
+loop (iteration through a list of values). This is a heavyweight loop,
+with structure that allows exiting the loop by \f(CW\*(C`last\*(C'\fR and suchlike.
+.Sp
+\&\f(CW\*(C`sv\*(C'\fR optionally supplies the variable(s) that will be aliased to each
+item in turn; if null, it defaults to \f(CW$_\fR.
+\&\f(CW\*(C`expr\*(C'\fR supplies the list of values to iterate over. \f(CW\*(C`block\*(C'\fR supplies
+the main body of the loop, and \f(CW\*(C`cont\*(C'\fR optionally supplies a \f(CW\*(C`continue\*(C'\fR
+block that operates as a second half of the body. All of these optree
+inputs are consumed by this function and become part of the constructed
+op tree.
+.Sp
+\&\f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR for the \f(CW\*(C`leaveloop\*(C'\fR
+op and, shifted up eight bits, the eight bits of \f(CW\*(C`op_private\*(C'\fR for
+the \f(CW\*(C`leaveloop\*(C'\fR op, except that (in both cases) some bits will be set
+automatically.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newFOROP(I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newGIVENOP""" 4
+.el .IP \f(CWnewGIVENOP\fR 4
+.IX Xref "newGIVENOP"
+.IX Item "newGIVENOP"
+Constructs, checks, and returns an op tree expressing a \f(CW\*(C`given\*(C'\fR block.
+\&\f(CW\*(C`cond\*(C'\fR supplies the expression to whose value \f(CW$_\fR will be locally
+aliased, and \f(CW\*(C`block\*(C'\fR supplies the body of the \f(CW\*(C`given\*(C'\fR construct; they
+are consumed by this function and become part of the constructed op tree.
+\&\f(CW\*(C`defsv_off\*(C'\fR must be zero (it used to identity the pad slot of lexical \f(CW$_\fR).
+.RS 4
+.Sp
+.Vb 1
+\& OP * newGIVENOP(OP *cond, OP *block, PADOFFSET defsv_off)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newGVOP""" 4
+.el .IP \f(CWnewGVOP\fR 4
+.IX Xref "newGVOP"
+.IX Item "newGVOP"
+Constructs, checks, and returns an op of any type that involves an
+embedded reference to a GV. \f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`flags\*(C'\fR gives the
+eight bits of \f(CW\*(C`op_flags\*(C'\fR. \f(CW\*(C`gv\*(C'\fR identifies the GV that the op should
+reference; calling this function does not transfer ownership of any
+reference to it.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newGVOP(I32 type, I32 flags, GV *gv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newLISTOP""" 4
+.el .IP \f(CWnewLISTOP\fR 4
+.IX Xref "newLISTOP"
+.IX Item "newLISTOP"
+Constructs, checks, and returns an op of any list type. \f(CW\*(C`type\*(C'\fR is
+the opcode. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR, except that
+\&\f(CW\*(C`OPf_KIDS\*(C'\fR will be set automatically if required. \f(CW\*(C`first\*(C'\fR and \f(CW\*(C`last\*(C'\fR
+supply up to two ops to be direct children of the list op; they are
+consumed by this function and become part of the constructed op tree.
+.Sp
+For most list operators, the check function expects all the kid ops to be
+present already, so calling \f(CW\*(C`newLISTOP(OP_JOIN, ...)\*(C'\fR (e.g.) is not
+appropriate. What you want to do in that case is create an op of type
+\&\f(CW\*(C`OP_LIST\*(C'\fR, append more children to it, and then call "op_convert_list".
+See "op_convert_list" for more information.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newLISTOP(I32 type, I32 flags, OP *first, OP *last)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newLOGOP""" 4
+.el .IP \f(CWnewLOGOP\fR 4
+.IX Xref "newLOGOP"
+.IX Item "newLOGOP"
+Constructs, checks, and returns a logical (flow control) op. \f(CW\*(C`type\*(C'\fR
+is the opcode. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR, except
+that \f(CW\*(C`OPf_KIDS\*(C'\fR will be set automatically, and, shifted up eight bits,
+the eight bits of \f(CW\*(C`op_private\*(C'\fR, except that the bit with value 1 is
+automatically set. \f(CW\*(C`first\*(C'\fR supplies the expression controlling the
+flow, and \f(CW\*(C`other\*(C'\fR supplies the side (alternate) chain of ops; they are
+consumed by this function and become part of the constructed op tree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newLOGOP(I32 optype, I32 flags, OP *first, OP *other)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newLOOPEX""" 4
+.el .IP \f(CWnewLOOPEX\fR 4
+.IX Xref "newLOOPEX"
+.IX Item "newLOOPEX"
+Constructs, checks, and returns a loop-exiting op (such as \f(CW\*(C`goto\*(C'\fR
+or \f(CW\*(C`last\*(C'\fR). \f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`label\*(C'\fR supplies the parameter
+determining the target of the op; it is consumed by this function and
+becomes part of the constructed op tree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newLOOPEX(I32 type, OP *label)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newLOOPOP""" 4
+.el .IP \f(CWnewLOOPOP\fR 4
+.IX Xref "newLOOPOP"
+.IX Item "newLOOPOP"
+Constructs, checks, and returns an op tree expressing a loop. This is
+only a loop in the control flow through the op tree; it does not have
+the heavyweight loop structure that allows exiting the loop by \f(CW\*(C`last\*(C'\fR
+and suchlike. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR for the
+top-level op, except that some bits will be set automatically as required.
+\&\f(CW\*(C`expr\*(C'\fR supplies the expression controlling loop iteration, and \f(CW\*(C`block\*(C'\fR
+supplies the body of the loop; they are consumed by this function and
+become part of the constructed op tree. \f(CW\*(C`debuggable\*(C'\fR is currently
+unused and should always be 1.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newLOOPOP(I32 flags, I32 debuggable, OP *expr, OP *block)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newMETHOP""" 4
+.el .IP \f(CWnewMETHOP\fR 4
+.IX Xref "newMETHOP"
+.IX Item "newMETHOP"
+Constructs, checks, and returns an op of method type with a method name
+evaluated at runtime. \f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`flags\*(C'\fR gives the eight
+bits of \f(CW\*(C`op_flags\*(C'\fR, except that \f(CW\*(C`OPf_KIDS\*(C'\fR will be set automatically,
+and, shifted up eight bits, the eight bits of \f(CW\*(C`op_private\*(C'\fR, except that
+the bit with value 1 is automatically set. \f(CW\*(C`dynamic_meth\*(C'\fR supplies an
+op which evaluates method name; it is consumed by this function and
+become part of the constructed op tree.
+Supported optypes: \f(CW\*(C`OP_METHOD\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newMETHOP(I32 type, I32 flags, OP *dynamic_meth)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newMETHOP_named""" 4
+.el .IP \f(CWnewMETHOP_named\fR 4
+.IX Xref "newMETHOP_named"
+.IX Item "newMETHOP_named"
+Constructs, checks, and returns an op of method type with a constant
+method name. \f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`flags\*(C'\fR gives the eight bits of
+\&\f(CW\*(C`op_flags\*(C'\fR, and, shifted up eight bits, the eight bits of
+\&\f(CW\*(C`op_private\*(C'\fR. \f(CW\*(C`const_meth\*(C'\fR supplies a constant method name;
+it must be a shared COW string.
+Supported optypes: \f(CW\*(C`OP_METHOD_NAMED\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newMETHOP_named(I32 type, I32 flags, SV * const_meth)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newNULLLIST""" 4
+.el .IP \f(CWnewNULLLIST\fR 4
+.IX Xref "newNULLLIST"
+.IX Item "newNULLLIST"
+Constructs, checks, and returns a new \f(CW\*(C`stub\*(C'\fR op, which represents an
+empty list expression.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newNULLLIST()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newOP""" 4
+.el .IP \f(CWnewOP\fR 4
+.IX Xref "newOP"
+.IX Item "newOP"
+Constructs, checks, and returns an op of any base type (any type that
+has no extra fields). \f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`flags\*(C'\fR gives the
+eight bits of \f(CW\*(C`op_flags\*(C'\fR, and, shifted up eight bits, the eight bits
+of \f(CW\*(C`op_private\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newOP(I32 optype, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newPADOP""" 4
+.el .IP \f(CWnewPADOP\fR 4
+.IX Xref "newPADOP"
+.IX Item "newPADOP"
+Constructs, checks, and returns an op of any type that involves a
+reference to a pad element. \f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`flags\*(C'\fR gives the
+eight bits of \f(CW\*(C`op_flags\*(C'\fR. A pad slot is automatically allocated, and
+is populated with \f(CW\*(C`sv\*(C'\fR; this function takes ownership of one reference
+to it.
+.Sp
+This function only exists if Perl has been compiled to use ithreads.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newPADOP(I32 type, I32 flags, SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newPMOP""" 4
+.el .IP \f(CWnewPMOP\fR 4
+.IX Xref "newPMOP"
+.IX Item "newPMOP"
+Constructs, checks, and returns an op of any pattern matching type.
+\&\f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR
+and, shifted up eight bits, the eight bits of \f(CW\*(C`op_private\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newPMOP(I32 type, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newPVOP""" 4
+.el .IP \f(CWnewPVOP\fR 4
+.IX Xref "newPVOP"
+.IX Item "newPVOP"
+Constructs, checks, and returns an op of any type that involves an
+embedded C\-level pointer (PV). \f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`flags\*(C'\fR gives
+the eight bits of \f(CW\*(C`op_flags\*(C'\fR. \f(CW\*(C`pv\*(C'\fR supplies the C\-level pointer.
+Depending on the op type, the memory referenced by \f(CW\*(C`pv\*(C'\fR may be freed
+when the op is destroyed. If the op is of a freeing type, \f(CW\*(C`pv\*(C'\fR must
+have been allocated using \f(CW\*(C`PerlMemShared_malloc\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newPVOP(I32 type, I32 flags, char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newRANGE""" 4
+.el .IP \f(CWnewRANGE\fR 4
+.IX Xref "newRANGE"
+.IX Item "newRANGE"
+Constructs and returns a \f(CW\*(C`range\*(C'\fR op, with subordinate \f(CW\*(C`flip\*(C'\fR and
+\&\f(CW\*(C`flop\*(C'\fR ops. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR for the
+\&\f(CW\*(C`flip\*(C'\fR op and, shifted up eight bits, the eight bits of \f(CW\*(C`op_private\*(C'\fR
+for both the \f(CW\*(C`flip\*(C'\fR and \f(CW\*(C`range\*(C'\fR ops, except that the bit with value
+1 is automatically set. \f(CW\*(C`left\*(C'\fR and \f(CW\*(C`right\*(C'\fR supply the expressions
+controlling the endpoints of the range; they are consumed by this function
+and become part of the constructed op tree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newRANGE(I32 flags, OP *left, OP *right)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSLICEOP""" 4
+.el .IP \f(CWnewSLICEOP\fR 4
+.IX Xref "newSLICEOP"
+.IX Item "newSLICEOP"
+Constructs, checks, and returns an \f(CW\*(C`lslice\*(C'\fR (list slice) op. \f(CW\*(C`flags\*(C'\fR
+gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR, except that \f(CW\*(C`OPf_KIDS\*(C'\fR will
+be set automatically, and, shifted up eight bits, the eight bits of
+\&\f(CW\*(C`op_private\*(C'\fR, except that the bit with value 1 or 2 is automatically
+set as required. \f(CW\*(C`listval\*(C'\fR and \f(CW\*(C`subscript\*(C'\fR supply the parameters of
+the slice; they are consumed by this function and become part of the
+constructed op tree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newSLICEOP(I32 flags, OP *subscript, OP *listop)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSTATEOP""" 4
+.el .IP \f(CWnewSTATEOP\fR 4
+.IX Xref "newSTATEOP"
+.IX Item "newSTATEOP"
+Constructs a state op (COP). The state op is normally a \f(CW\*(C`nextstate\*(C'\fR op,
+but will be a \f(CW\*(C`dbstate\*(C'\fR op if debugging is enabled for currently-compiled
+code. The state op is populated from \f(CW\*(C`PL_curcop\*(C'\fR (or \f(CW\*(C`PL_compiling\*(C'\fR).
+If \f(CW\*(C`label\*(C'\fR is non-null, it supplies the name of a label to attach to
+the state op; this function takes ownership of the memory pointed at by
+\&\f(CW\*(C`label\*(C'\fR, and will free it. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR
+for the state op.
+.Sp
+If \f(CW\*(C`o\*(C'\fR is null, the state op is returned. Otherwise the state op is
+combined with \f(CW\*(C`o\*(C'\fR into a \f(CW\*(C`lineseq\*(C'\fR list op, which is returned. \f(CW\*(C`o\*(C'\fR
+is consumed by this function and becomes part of the returned op tree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newSTATEOP(I32 flags, char *label, OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSUB""" 4
+.el .IP \f(CWnewSUB\fR 4
+.IX Xref "newSUB"
+.IX Item "newSUB"
+Like \f(CW"newATTRSUB"\fR, but without attributes.
+.RS 4
+.Sp
+.Vb 1
+\& CV * newSUB(I32 floor, OP *o, OP *proto, OP *block)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVOP""" 4
+.el .IP \f(CWnewSVOP\fR 4
+.IX Xref "newSVOP"
+.IX Item "newSVOP"
+Constructs, checks, and returns an op of any type that involves an
+embedded SV. \f(CW\*(C`type\*(C'\fR is the opcode. \f(CW\*(C`flags\*(C'\fR gives the eight bits
+of \f(CW\*(C`op_flags\*(C'\fR. \f(CW\*(C`sv\*(C'\fR gives the SV to embed in the op; this function
+takes ownership of one reference to it.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newSVOP(I32 type, I32 flags, SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newTRYCATCHOP""" 4
+.el .IP \f(CWnewTRYCATCHOP\fR 4
+.IX Xref "newTRYCATCHOP"
+.IX Item "newTRYCATCHOP"
+NOTE: \f(CW\*(C`newTRYCATCHOP\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Constructs and returns a conditional execution statement that implements
+the \f(CW\*(C`try\*(C'\fR/\f(CW\*(C`catch\*(C'\fR semantics. First the op tree in \f(CW\*(C`tryblock\*(C'\fR is executed,
+inside a context that traps exceptions. If an exception occurs then the
+optree in \f(CW\*(C`catchblock\*(C'\fR is executed, with the trapped exception set into the
+lexical variable given by \f(CW\*(C`catchvar\*(C'\fR (which must be an op of type
+\&\f(CW\*(C`OP_PADSV\*(C'\fR). All the optrees are consumed by this function and become part
+of the returned op tree.
+.Sp
+The \f(CW\*(C`flags\*(C'\fR argument is currently ignored.
+.RS 4
+.Sp
+.Vb 2
+\& OP * newTRYCATCHOP(I32 flags, OP *tryblock, OP *catchvar,
+\& OP *catchblock)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newUNOP""" 4
+.el .IP \f(CWnewUNOP\fR 4
+.IX Xref "newUNOP"
+.IX Item "newUNOP"
+Constructs, checks, and returns an op of any unary type. \f(CW\*(C`type\*(C'\fR is
+the opcode. \f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR, except that
+\&\f(CW\*(C`OPf_KIDS\*(C'\fR will be set automatically if required, and, shifted up eight
+bits, the eight bits of \f(CW\*(C`op_private\*(C'\fR, except that the bit with value 1
+is automatically set. \f(CW\*(C`first\*(C'\fR supplies an optional op to be the direct
+child of the unary op; it is consumed by this function and become part
+of the constructed op tree.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newUNOP(I32 type, I32 flags, OP *first)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newUNOP_AUX""" 4
+.el .IP \f(CWnewUNOP_AUX\fR 4
+.IX Xref "newUNOP_AUX"
+.IX Item "newUNOP_AUX"
+Similar to \f(CW\*(C`newUNOP\*(C'\fR, but creates an \f(CW\*(C`UNOP_AUX\*(C'\fR struct instead, with \f(CW\*(C`op_aux\*(C'\fR
+initialised to \f(CW\*(C`aux\*(C'\fR
+.RS 4
+.Sp
+.Vb 2
+\& OP * newUNOP_AUX(I32 type, I32 flags, OP *first,
+\& UNOP_AUX_item *aux)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newWHENOP""" 4
+.el .IP \f(CWnewWHENOP\fR 4
+.IX Xref "newWHENOP"
+.IX Item "newWHENOP"
+Constructs, checks, and returns an op tree expressing a \f(CW\*(C`when\*(C'\fR block.
+\&\f(CW\*(C`cond\*(C'\fR supplies the test expression, and \f(CW\*(C`block\*(C'\fR supplies the block
+that will be executed if the test evaluates to true; they are consumed
+by this function and become part of the constructed op tree. \f(CW\*(C`cond\*(C'\fR
+will be interpreted DWIMically, often as a comparison against \f(CW$_\fR,
+and may be null to generate a \f(CW\*(C`default\*(C'\fR block.
+.RS 4
+.Sp
+.Vb 1
+\& OP * newWHENOP(OP *cond, OP *block)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newWHILEOP""" 4
+.el .IP \f(CWnewWHILEOP\fR 4
+.IX Xref "newWHILEOP"
+.IX Item "newWHILEOP"
+Constructs, checks, and returns an op tree expressing a \f(CW\*(C`while\*(C'\fR loop.
+This is a heavyweight loop, with structure that allows exiting the loop
+by \f(CW\*(C`last\*(C'\fR and suchlike.
+.Sp
+\&\f(CW\*(C`loop\*(C'\fR is an optional preconstructed \f(CW\*(C`enterloop\*(C'\fR op to use in the
+loop; if it is null then a suitable op will be constructed automatically.
+\&\f(CW\*(C`expr\*(C'\fR supplies the loop's controlling expression. \f(CW\*(C`block\*(C'\fR supplies the
+main body of the loop, and \f(CW\*(C`cont\*(C'\fR optionally supplies a \f(CW\*(C`continue\*(C'\fR block
+that operates as a second half of the body. All of these optree inputs
+are consumed by this function and become part of the constructed op tree.
+.Sp
+\&\f(CW\*(C`flags\*(C'\fR gives the eight bits of \f(CW\*(C`op_flags\*(C'\fR for the \f(CW\*(C`leaveloop\*(C'\fR
+op and, shifted up eight bits, the eight bits of \f(CW\*(C`op_private\*(C'\fR for
+the \f(CW\*(C`leaveloop\*(C'\fR op, except that (in both cases) some bits will be set
+automatically. \f(CW\*(C`debuggable\*(C'\fR is currently unused and should always be 1.
+\&\f(CW\*(C`has_my\*(C'\fR can be supplied as true to force the
+loop body to be enclosed in its own scope.
+.RS 4
+.Sp
+.Vb 2
+\& OP * newWHILEOP(I32 flags, I32 debuggable, LOOP *loop, OP *expr,
+\& OP *block, OP *cont, I32 has_my)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newXS""" 4
+.el .IP \f(CWnewXS\fR 4
+.IX Xref "newXS"
+.IX Item "newXS"
+Used by \f(CW\*(C`xsubpp\*(C'\fR to hook up XSUBs as Perl subs. \f(CW\*(C`filename\*(C'\fR needs to be
+static storage, as it is used directly as \fBCvFILE()\fR, without a copy being made.
+.ie n .IP """OA_BASEOP""" 4
+.el .IP \f(CWOA_BASEOP\fR 4
+.IX Item "OA_BASEOP"
+.PD 0
+.ie n .IP """OA_BINOP""" 4
+.el .IP \f(CWOA_BINOP\fR 4
+.IX Item "OA_BINOP"
+.ie n .IP """OA_COP""" 4
+.el .IP \f(CWOA_COP\fR 4
+.IX Item "OA_COP"
+.ie n .IP """OA_LISTOP""" 4
+.el .IP \f(CWOA_LISTOP\fR 4
+.IX Item "OA_LISTOP"
+.ie n .IP """OA_LOGOP""" 4
+.el .IP \f(CWOA_LOGOP\fR 4
+.IX Item "OA_LOGOP"
+.ie n .IP """OA_LOOP""" 4
+.el .IP \f(CWOA_LOOP\fR 4
+.IX Item "OA_LOOP"
+.ie n .IP """OA_PADOP""" 4
+.el .IP \f(CWOA_PADOP\fR 4
+.IX Item "OA_PADOP"
+.ie n .IP """OA_PMOP""" 4
+.el .IP \f(CWOA_PMOP\fR 4
+.IX Item "OA_PMOP"
+.ie n .IP """OA_PVOP_OR_SVOP""" 4
+.el .IP \f(CWOA_PVOP_OR_SVOP\fR 4
+.IX Item "OA_PVOP_OR_SVOP"
+.ie n .IP """OA_SVOP""" 4
+.el .IP \f(CWOA_SVOP\fR 4
+.IX Item "OA_SVOP"
+.ie n .IP """OA_UNOP""" 4
+.el .IP \f(CWOA_UNOP\fR 4
+.IX Item "OA_UNOP"
+.PD
+Described in perlguts.
+.ie n .IP """OP""" 4
+.el .IP \f(CWOP\fR 4
+.IX Item "OP"
+Described in perlguts.
+.ie n .IP """op_append_elem""" 4
+.el .IP \f(CWop_append_elem\fR 4
+.IX Xref "op_append_elem"
+.IX Item "op_append_elem"
+Append an item to the list of ops contained directly within a list-type
+op, returning the lengthened list. \f(CW\*(C`first\*(C'\fR is the list-type op,
+and \f(CW\*(C`last\*(C'\fR is the op to append to the list. \f(CW\*(C`optype\*(C'\fR specifies the
+intended opcode for the list. If \f(CW\*(C`first\*(C'\fR is not already a list of the
+right type, it will be upgraded into one. If either \f(CW\*(C`first\*(C'\fR or \f(CW\*(C`last\*(C'\fR
+is null, the other is returned unchanged.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_append_elem(I32 optype, OP *first, OP *last)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_append_list""" 4
+.el .IP \f(CWop_append_list\fR 4
+.IX Xref "op_append_list"
+.IX Item "op_append_list"
+Concatenate the lists of ops contained directly within two list-type ops,
+returning the combined list. \f(CW\*(C`first\*(C'\fR and \f(CW\*(C`last\*(C'\fR are the list-type ops
+to concatenate. \f(CW\*(C`optype\*(C'\fR specifies the intended opcode for the list.
+If either \f(CW\*(C`first\*(C'\fR or \f(CW\*(C`last\*(C'\fR is not already a list of the right type,
+it will be upgraded into one. If either \f(CW\*(C`first\*(C'\fR or \f(CW\*(C`last\*(C'\fR is null,
+the other is returned unchanged.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_append_list(I32 optype, OP *first, OP *last)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OP_CLASS""" 4
+.el .IP \f(CWOP_CLASS\fR 4
+.IX Xref "OP_CLASS"
+.IX Item "OP_CLASS"
+Return the class of the provided OP: that is, which of the *OP
+structures it uses. For core ops this currently gets the information out
+of \f(CW\*(C`PL_opargs\*(C'\fR, which does not always accurately reflect the type used;
+in v5.26 onwards, see also the function \f(CW"op_class"\fR which can do a better
+job of determining the used type.
+.Sp
+For custom ops the type is returned from the registration, and it is up
+to the registree to ensure it is accurate. The value returned will be
+one of the \f(CW\*(C`OA_\*(C'\fR* constants from \fIop.h\fR.
+.RS 4
+.Sp
+.Vb 1
+\& U32 OP_CLASS(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_contextualize""" 4
+.el .IP \f(CWop_contextualize\fR 4
+.IX Xref "op_contextualize"
+.IX Item "op_contextualize"
+Applies a syntactic context to an op tree representing an expression.
+\&\f(CW\*(C`o\*(C'\fR is the op tree, and \f(CW\*(C`context\*(C'\fR must be \f(CW\*(C`G_SCALAR\*(C'\fR, \f(CW\*(C`G_LIST\*(C'\fR,
+or \f(CW\*(C`G_VOID\*(C'\fR to specify the context to apply. The modified op tree
+is returned.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_contextualize(OP *o, I32 context)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_convert_list""" 4
+.el .IP \f(CWop_convert_list\fR 4
+.IX Xref "op_convert_list"
+.IX Item "op_convert_list"
+Converts \f(CW\*(C`o\*(C'\fR into a list op if it is not one already, and then converts it
+into the specified \f(CW\*(C`type\*(C'\fR, calling its check function, allocating a target if
+it needs one, and folding constants.
+.Sp
+A list-type op is usually constructed one kid at a time via \f(CW\*(C`newLISTOP\*(C'\fR,
+\&\f(CW\*(C`op_prepend_elem\*(C'\fR and \f(CW\*(C`op_append_elem\*(C'\fR. Then finally it is passed to
+\&\f(CW\*(C`op_convert_list\*(C'\fR to make it the right type.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_convert_list(I32 optype, I32 flags, OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OP_DESC""" 4
+.el .IP \f(CWOP_DESC\fR 4
+.IX Xref "OP_DESC"
+.IX Item "OP_DESC"
+Return a short description of the provided OP.
+.RS 4
+.Sp
+.Vb 1
+\& const char * OP_DESC(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_force_list""" 4
+.el .IP \f(CWop_force_list\fR 4
+.IX Xref "op_force_list"
+.IX Item "op_force_list"
+Promotes o and any siblings to be an \f(CW\*(C`OP_LIST\*(C'\fR if it is not already. If
+a new \f(CW\*(C`OP_LIST\*(C'\fR op was created, its first child will be \f(CW\*(C`OP_PUSHMARK\*(C'\fR.
+The returned node itself will be nulled, leaving only its children.
+.Sp
+This is often what you want to do before putting the optree into list
+context; as
+.Sp
+.Vb 1
+\& o = op_contextualize(op_force_list(o), G_LIST);
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_force_list(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_free""" 4
+.el .IP \f(CWop_free\fR 4
+.IX Xref "op_free"
+.IX Item "op_free"
+Free an op and its children. Only use this when an op is no longer linked
+to from any optree.
+.Sp
+Remember that any op with \f(CW\*(C`OPf_KIDS\*(C'\fR set is expected to have a valid
+\&\f(CW\*(C`op_first\*(C'\fR pointer. If you are attempting to free an op but preserve its
+child op, make sure to clear that flag before calling \f(CWop_free()\fR. For
+example:
+.Sp
+.Vb 3
+\& OP *kid = o\->op_first; o\->op_first = NULL;
+\& o\->op_flags &= ~OPf_KIDS;
+\& op_free(o);
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& void op_free(OP *arg)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OpHAS_SIBLING""" 4
+.el .IP \f(CWOpHAS_SIBLING\fR 4
+.IX Xref "OpHAS_SIBLING"
+.IX Item "OpHAS_SIBLING"
+Returns true if \f(CW\*(C`o\*(C'\fR has a sibling
+.RS 4
+.Sp
+.Vb 1
+\& bool OpHAS_SIBLING(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OpLASTSIB_set""" 4
+.el .IP \f(CWOpLASTSIB_set\fR 4
+.IX Xref "OpLASTSIB_set"
+.IX Item "OpLASTSIB_set"
+Marks \f(CW\*(C`o\*(C'\fR as having no further siblings and marks
+o as having the specified parent. See also \f(CW"OpMORESIB_set"\fR and
+\&\f(CW\*(C`OpMAYBESIB_set\*(C'\fR. For a higher-level interface, see
+\&\f(CW"op_sibling_splice"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void OpLASTSIB_set(OP *o, OP *parent)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_linklist""" 4
+.el .IP \f(CWop_linklist\fR 4
+.IX Xref "op_linklist"
+.IX Item "op_linklist"
+This function is the implementation of the "LINKLIST" macro. It should
+not be called directly.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_linklist(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_lvalue""" 4
+.el .IP \f(CWop_lvalue\fR 4
+.IX Xref "op_lvalue"
+.IX Item "op_lvalue"
+NOTE: \f(CW\*(C`op_lvalue\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Propagate lvalue ("modifiable") context to an op and its children.
+\&\f(CW\*(C`type\*(C'\fR represents the context type, roughly based on the type of op that
+would do the modifying, although \f(CWlocal()\fR is represented by \f(CW\*(C`OP_NULL\*(C'\fR,
+because it has no op type of its own (it is signalled by a flag on
+the lvalue op).
+.Sp
+This function detects things that can't be modified, such as \f(CW\*(C`$x+1\*(C'\fR, and
+generates errors for them. For example, \f(CW\*(C`$x+1 = 2\*(C'\fR would cause it to be
+called with an op of type \f(CW\*(C`OP_ADD\*(C'\fR and a \f(CW\*(C`type\*(C'\fR argument of \f(CW\*(C`OP_SASSIGN\*(C'\fR.
+.Sp
+It also flags things that need to behave specially in an lvalue context,
+such as \f(CW\*(C`$$x = 5\*(C'\fR which might have to vivify a reference in \f(CW$x\fR.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_lvalue(OP *o, I32 type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OpMAYBESIB_set""" 4
+.el .IP \f(CWOpMAYBESIB_set\fR 4
+.IX Xref "OpMAYBESIB_set"
+.IX Item "OpMAYBESIB_set"
+Conditionally does \f(CW\*(C`OpMORESIB_set\*(C'\fR or \f(CW\*(C`OpLASTSIB_set\*(C'\fR depending on whether
+\&\f(CW\*(C`sib\*(C'\fR is non-null. For a higher-level interface, see \f(CW"op_sibling_splice"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void OpMAYBESIB_set(OP *o, OP *sib, OP *parent)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OpMORESIB_set""" 4
+.el .IP \f(CWOpMORESIB_set\fR 4
+.IX Xref "OpMORESIB_set"
+.IX Item "OpMORESIB_set"
+Sets the sibling of \f(CW\*(C`o\*(C'\fR to the non-zero value \f(CW\*(C`sib\*(C'\fR. See also \f(CW"OpLASTSIB_set"\fR
+and \f(CW"OpMAYBESIB_set"\fR. For a higher-level interface, see
+\&\f(CW"op_sibling_splice"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void OpMORESIB_set(OP *o, OP *sib)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OP_NAME""" 4
+.el .IP \f(CWOP_NAME\fR 4
+.IX Xref "OP_NAME"
+.IX Item "OP_NAME"
+Return the name of the provided OP. For core ops this looks up the name
+from the op_type; for custom ops from the op_ppaddr.
+.RS 4
+.Sp
+.Vb 1
+\& const char * OP_NAME(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_null""" 4
+.el .IP \f(CWop_null\fR 4
+.IX Xref "op_null"
+.IX Item "op_null"
+Neutralizes an op when it is no longer needed, but is still linked to from
+other ops.
+.RS 4
+.Sp
+.Vb 1
+\& void op_null(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_parent""" 4
+.el .IP \f(CWop_parent\fR 4
+.IX Xref "op_parent"
+.IX Item "op_parent"
+Returns the parent OP of \f(CW\*(C`o\*(C'\fR, if it has a parent. Returns \f(CW\*(C`NULL\*(C'\fR otherwise.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_parent(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_prepend_elem""" 4
+.el .IP \f(CWop_prepend_elem\fR 4
+.IX Xref "op_prepend_elem"
+.IX Item "op_prepend_elem"
+Prepend an item to the list of ops contained directly within a list-type
+op, returning the lengthened list. \f(CW\*(C`first\*(C'\fR is the op to prepend to the
+list, and \f(CW\*(C`last\*(C'\fR is the list-type op. \f(CW\*(C`optype\*(C'\fR specifies the intended
+opcode for the list. If \f(CW\*(C`last\*(C'\fR is not already a list of the right type,
+it will be upgraded into one. If either \f(CW\*(C`first\*(C'\fR or \f(CW\*(C`last\*(C'\fR is null,
+the other is returned unchanged.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_prepend_elem(I32 optype, OP *first, OP *last)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_scope""" 4
+.el .IP \f(CWop_scope\fR 4
+.IX Xref "op_scope"
+.IX Item "op_scope"
+NOTE: \f(CW\*(C`op_scope\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Wraps up an op tree with some additional ops so that at runtime a dynamic
+scope will be created. The original ops run in the new dynamic scope,
+and then, provided that they exit normally, the scope will be unwound.
+The additional ops used to create and unwind the dynamic scope will
+normally be an \f(CW\*(C`enter\*(C'\fR/\f(CW\*(C`leave\*(C'\fR pair, but a \f(CW\*(C`scope\*(C'\fR op may be used
+instead if the ops are simple enough to not need the full dynamic scope
+structure.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_scope(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OpSIBLING""" 4
+.el .IP \f(CWOpSIBLING\fR 4
+.IX Xref "OpSIBLING"
+.IX Item "OpSIBLING"
+Returns the sibling of \f(CW\*(C`o\*(C'\fR, or \f(CW\*(C`NULL\*(C'\fR if there is no sibling
+.RS 4
+.Sp
+.Vb 1
+\& OP* OpSIBLING(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_sibling_splice""" 4
+.el .IP \f(CWop_sibling_splice\fR 4
+.IX Xref "op_sibling_splice"
+.IX Item "op_sibling_splice"
+A general function for editing the structure of an existing chain of
+op_sibling nodes. By analogy with the perl-level \f(CWsplice()\fR function, allows
+you to delete zero or more sequential nodes, replacing them with zero or
+more different nodes. Performs the necessary op_first/op_last
+housekeeping on the parent node and op_sibling manipulation on the
+children. The last deleted node will be marked as the last node by
+updating the op_sibling/op_sibparent or op_moresib field as appropriate.
+.Sp
+Note that op_next is not manipulated, and nodes are not freed; that is the
+responsibility of the caller. It also won't create a new list op for an
+empty list etc; use higher-level functions like \fBop_append_elem()\fR for that.
+.Sp
+\&\f(CW\*(C`parent\*(C'\fR is the parent node of the sibling chain. It may passed as \f(CW\*(C`NULL\*(C'\fR if
+the splicing doesn't affect the first or last op in the chain.
+.Sp
+\&\f(CW\*(C`start\*(C'\fR is the node preceding the first node to be spliced. Node(s)
+following it will be deleted, and ops will be inserted after it. If it is
+\&\f(CW\*(C`NULL\*(C'\fR, the first node onwards is deleted, and nodes are inserted at the
+beginning.
+.Sp
+\&\f(CW\*(C`del_count\*(C'\fR is the number of nodes to delete. If zero, no nodes are deleted.
+If \-1 or greater than or equal to the number of remaining kids, all
+remaining kids are deleted.
+.Sp
+\&\f(CW\*(C`insert\*(C'\fR is the first of a chain of nodes to be inserted in place of the nodes.
+If \f(CW\*(C`NULL\*(C'\fR, no nodes are inserted.
+.Sp
+The head of the chain of deleted ops is returned, or \f(CW\*(C`NULL\*(C'\fR if no ops were
+deleted.
+.Sp
+For example:
+.Sp
+.Vb 2
+\& action before after returns
+\& \-\-\-\-\-\- \-\-\-\-\- \-\-\-\-\- \-\-\-\-\-\-\-
+\&
+\& P P
+\& splice(P, A, 2, X\-Y\-Z) | | B\-C
+\& A\-B\-C\-D A\-X\-Y\-Z\-D
+\&
+\& P P
+\& splice(P, NULL, 1, X\-Y) | | A
+\& A\-B\-C\-D X\-Y\-B\-C\-D
+\&
+\& P P
+\& splice(P, NULL, 3, NULL) | | A\-B\-C
+\& A\-B\-C\-D D
+\&
+\& P P
+\& splice(P, B, 0, X\-Y) | | NULL
+\& A\-B\-C\-D A\-B\-X\-Y\-C\-D
+.Ve
+.Sp
+For lower-level direct manipulation of \f(CW\*(C`op_sibparent\*(C'\fR and \f(CW\*(C`op_moresib\*(C'\fR,
+see \f(CW"OpMORESIB_set"\fR, \f(CW"OpLASTSIB_set"\fR, \f(CW"OpMAYBESIB_set"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& OP * op_sibling_splice(OP *parent, OP *start, int del_count,
+\& OP *insert)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """optimize_optree""" 4
+.el .IP \f(CWoptimize_optree\fR 4
+.IX Xref "optimize_optree"
+.IX Item "optimize_optree"
+This function applies some optimisations to the optree in top-down order.
+It is called before the peephole optimizer, which processes ops in
+execution order. Note that \fBfinalize_optree()\fR also does a top-down scan,
+but is called *after* the peephole optimizer.
+.RS 4
+.Sp
+.Vb 1
+\& void optimize_optree(OP *o)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OP_TYPE_IS""" 4
+.el .IP \f(CWOP_TYPE_IS\fR 4
+.IX Xref "OP_TYPE_IS"
+.IX Item "OP_TYPE_IS"
+Returns true if the given OP is not a \f(CW\*(C`NULL\*(C'\fR pointer
+and if it is of the given type.
+.Sp
+The negation of this macro, \f(CW\*(C`OP_TYPE_ISNT\*(C'\fR is also available
+as well as \f(CW\*(C`OP_TYPE_IS_NN\*(C'\fR and \f(CW\*(C`OP_TYPE_ISNT_NN\*(C'\fR which elide
+the NULL pointer check.
+.RS 4
+.Sp
+.Vb 1
+\& bool OP_TYPE_IS(OP *o, Optype type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """OP_TYPE_IS_OR_WAS""" 4
+.el .IP \f(CWOP_TYPE_IS_OR_WAS\fR 4
+.IX Xref "OP_TYPE_IS_OR_WAS"
+.IX Item "OP_TYPE_IS_OR_WAS"
+Returns true if the given OP is not a NULL pointer and
+if it is of the given type or used to be before being
+replaced by an OP of type OP_NULL.
+.Sp
+The negation of this macro, \f(CW\*(C`OP_TYPE_ISNT_AND_WASNT\*(C'\fR
+is also available as well as \f(CW\*(C`OP_TYPE_IS_OR_WAS_NN\*(C'\fR
+and \f(CW\*(C`OP_TYPE_ISNT_AND_WASNT_NN\*(C'\fR which elide
+the \f(CW\*(C`NULL\*(C'\fR pointer check.
+.RS 4
+.Sp
+.Vb 1
+\& bool OP_TYPE_IS_OR_WAS(OP *o, Optype type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """op_wrap_finally""" 4
+.el .IP \f(CWop_wrap_finally\fR 4
+.IX Xref "op_wrap_finally"
+.IX Item "op_wrap_finally"
+NOTE: \f(CW\*(C`op_wrap_finally\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Wraps the given \f(CW\*(C`block\*(C'\fR optree fragment in its own scoped block, arranging
+for the \f(CW\*(C`finally\*(C'\fR optree fragment to be invoked when leaving that block for
+any reason. Both optree fragments are consumed and the combined result is
+returned.
+.RS 4
+.Sp
+.Vb 1
+\& OP * op_wrap_finally(OP *block, OP *finally)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """peep_t""" 4
+.el .IP \f(CWpeep_t\fR 4
+.IX Item "peep_t"
+Described in perlguts.
+.ie n .IP """Perl_cpeep_t""" 4
+.el .IP \f(CWPerl_cpeep_t\fR 4
+.IX Item "Perl_cpeep_t"
+Described in perlguts.
+.ie n .IP """PL_opfreehook""" 4
+.el .IP \f(CWPL_opfreehook\fR 4
+.IX Xref "PL_opfreehook"
+.IX Item "PL_opfreehook"
+When non\-\f(CW\*(C`NULL\*(C'\fR, the function pointed by this variable will be called each time an OP is freed with the corresponding OP as the argument.
+This allows extensions to free any extra attribute they have locally attached to an OP.
+It is also assured to first fire for the parent OP and then for its kids.
+.Sp
+When you replace this variable, it is considered a good practice to store the possibly previously installed hook and that you recall it inside your own.
+.Sp
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+.RS 4
+.Sp
+.Vb 1
+\& Perl_ophook_t PL_opfreehook
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_peepp""" 4
+.el .IP \f(CWPL_peepp\fR 4
+.IX Xref "PL_peepp"
+.IX Item "PL_peepp"
+Pointer to the per-subroutine peephole optimiser. This is a function
+that gets called at the end of compilation of a Perl subroutine (or
+equivalently independent piece of Perl code) to perform fixups of
+some ops and to perform small-scale optimisations. The function is
+called once for each subroutine that is compiled, and is passed, as sole
+parameter, a pointer to the op that is the entry point to the subroutine.
+It modifies the op tree in place.
+.Sp
+The peephole optimiser should never be completely replaced. Rather,
+add code to it by wrapping the existing optimiser. The basic way to do
+this can be seen in "Compile pass 3: peephole optimization" in perlguts.
+If the new code wishes to operate on ops throughout the subroutine's
+structure, rather than just at the top level, it is likely to be more
+convenient to wrap the "PL_rpeepp" hook.
+.Sp
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+.RS 4
+.Sp
+.Vb 1
+\& peep_t PL_peepp
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_rpeepp""" 4
+.el .IP \f(CWPL_rpeepp\fR 4
+.IX Xref "PL_rpeepp"
+.IX Item "PL_rpeepp"
+Pointer to the recursive peephole optimiser. This is a function
+that gets called at the end of compilation of a Perl subroutine (or
+equivalently independent piece of Perl code) to perform fixups of some
+ops and to perform small-scale optimisations. The function is called
+once for each chain of ops linked through their \f(CW\*(C`op_next\*(C'\fR fields;
+it is recursively called to handle each side chain. It is passed, as
+sole parameter, a pointer to the op that is at the head of the chain.
+It modifies the op tree in place.
+.Sp
+The peephole optimiser should never be completely replaced. Rather,
+add code to it by wrapping the existing optimiser. The basic way to do
+this can be seen in "Compile pass 3: peephole optimization" in perlguts.
+If the new code wishes to operate only on ops at a subroutine's top level,
+rather than throughout the structure, it is likely to be more convenient
+to wrap the "PL_peepp" hook.
+.Sp
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+.RS 4
+.Sp
+.Vb 1
+\& peep_t PL_rpeepp
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PMOP""" 4
+.el .IP \f(CWPMOP\fR 4
+.IX Item "PMOP"
+Described in perlguts.
+.ie n .IP """rv2cv_op_cv""" 4
+.el .IP \f(CWrv2cv_op_cv\fR 4
+.IX Xref "rv2cv_op_cv"
+.IX Item "rv2cv_op_cv"
+Examines an op, which is expected to identify a subroutine at runtime,
+and attempts to determine at compile time which subroutine it identifies.
+This is normally used during Perl compilation to determine whether
+a prototype can be applied to a function call. \f(CW\*(C`cvop\*(C'\fR is the op
+being considered, normally an \f(CW\*(C`rv2cv\*(C'\fR op. A pointer to the identified
+subroutine is returned, if it could be determined statically, and a null
+pointer is returned if it was not possible to determine statically.
+.Sp
+Currently, the subroutine can be identified statically if the RV that the
+\&\f(CW\*(C`rv2cv\*(C'\fR is to operate on is provided by a suitable \f(CW\*(C`gv\*(C'\fR or \f(CW\*(C`const\*(C'\fR op.
+A \f(CW\*(C`gv\*(C'\fR op is suitable if the GV's CV slot is populated. A \f(CW\*(C`const\*(C'\fR op is
+suitable if the constant value must be an RV pointing to a CV. Details of
+this process may change in future versions of Perl. If the \f(CW\*(C`rv2cv\*(C'\fR op
+has the \f(CW\*(C`OPpENTERSUB_AMPER\*(C'\fR flag set then no attempt is made to identify
+the subroutine statically: this flag is used to suppress compile-time
+magic on a subroutine call, forcing it to use default runtime behaviour.
+.Sp
+If \f(CW\*(C`flags\*(C'\fR has the bit \f(CW\*(C`RV2CVOPCV_MARK_EARLY\*(C'\fR set, then the handling
+of a GV reference is modified. If a GV was examined and its CV slot was
+found to be empty, then the \f(CW\*(C`gv\*(C'\fR op has the \f(CW\*(C`OPpEARLY_CV\*(C'\fR flag set.
+If the op is not optimised away, and the CV slot is later populated with
+a subroutine having a prototype, that flag eventually triggers the warning
+"called too early to check prototype".
+.Sp
+If \f(CW\*(C`flags\*(C'\fR has the bit \f(CW\*(C`RV2CVOPCV_RETURN_NAME_GV\*(C'\fR set, then instead
+of returning a pointer to the subroutine it returns a pointer to the
+GV giving the most appropriate name for the subroutine in this context.
+Normally this is just the \f(CW\*(C`CvGV\*(C'\fR of the subroutine, but for an anonymous
+(\f(CW\*(C`CvANON\*(C'\fR) subroutine that is referenced through a GV it will be the
+referencing GV. The resulting \f(CW\*(C`GV*\*(C'\fR is cast to \f(CW\*(C`CV*\*(C'\fR to be returned.
+A null pointer is returned as usual if there is no statically-determinable
+subroutine.
+.RS 4
+.Sp
+.Vb 1
+\& CV * rv2cv_op_cv(OP *cvop, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UNOP""" 4
+.el .IP \f(CWUNOP\fR 4
+.IX Item "UNOP"
+Described in perlguts.
+.ie n .IP """XOP""" 4
+.el .IP \f(CWXOP\fR 4
+.IX Item "XOP"
+Described in perlguts.
+.SH "Pack and Unpack"
+.IX Header "Pack and Unpack"
+.ie n .IP """packlist""" 4
+.el .IP \f(CWpacklist\fR 4
+.IX Xref "packlist"
+.IX Item "packlist"
+The engine implementing \f(CWpack()\fR Perl function.
+.RS 4
+.Sp
+.Vb 2
+\& void packlist(SV *cat, const char *pat, const char *patend,
+\& SV **beglist, SV **endlist)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """unpackstring""" 4
+.el .IP \f(CWunpackstring\fR 4
+.IX Xref "unpackstring"
+.IX Item "unpackstring"
+The engine implementing the \f(CWunpack()\fR Perl function.
+.Sp
+Using the template \f(CW\*(C`pat..patend\*(C'\fR, this function unpacks the string
+\&\f(CW\*(C`s..strend\*(C'\fR into a number of mortal SVs, which it pushes onto the perl
+argument (\f(CW@_\fR) stack (so you will need to issue a \f(CW\*(C`PUTBACK\*(C'\fR before and
+\&\f(CW\*(C`SPAGAIN\*(C'\fR after the call to this function). It returns the number of
+pushed elements.
+.Sp
+The \f(CW\*(C`strend\*(C'\fR and \f(CW\*(C`patend\*(C'\fR pointers should point to the byte following the
+last character of each string.
+.Sp
+Although this function returns its values on the perl argument stack, it
+doesn't take any parameters from that stack (and thus in particular
+there's no need to do a \f(CW\*(C`PUSHMARK\*(C'\fR before calling it, unlike "call_pv" for
+example).
+.RS 4
+.Sp
+.Vb 3
+\& SSize_t unpackstring(const char *pat, const char *patend,
+\& const char *s, const char *strend,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Pad Data Structures"
+.IX Xref "SVs_PADSTALE"
+.IX Header "Pad Data Structures"
+.ie n .IP """CvPADLIST""" 4
+.el .IP \f(CWCvPADLIST\fR 4
+.IX Xref "CvPADLIST"
+.IX Item "CvPADLIST"
+NOTE: \f(CW\*(C`CvPADLIST\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+CV's can have CvPADLIST(cv) set to point to a PADLIST. This is the CV's
+scratchpad, which stores lexical variables and opcode temporary and
+per-thread values.
+.Sp
+For these purposes "formats" are a kind-of CV; eval""s are too (except they're
+not callable at will and are always thrown away after the eval"" is done
+executing). Require'd files are simply evals without any outer lexical
+scope.
+.Sp
+XSUBs do not have a \f(CW\*(C`CvPADLIST\*(C'\fR. \f(CW\*(C`dXSTARG\*(C'\fR fetches values from \f(CW\*(C`PL_curpad\*(C'\fR,
+but that is really the callers pad (a slot of which is allocated by
+every entersub). Do not get or set \f(CW\*(C`CvPADLIST\*(C'\fR if a CV is an XSUB (as
+determined by \f(CWCvISXSUB()\fR), \f(CW\*(C`CvPADLIST\*(C'\fR slot is reused for a different
+internal purpose in XSUBs.
+.Sp
+The PADLIST has a C array where pads are stored.
+.Sp
+The 0th entry of the PADLIST is a PADNAMELIST
+which represents the "names" or rather
+the "static type information" for lexicals. The individual elements of a
+PADNAMELIST are PADNAMEs. Future
+refactorings might stop the PADNAMELIST from being stored in the PADLIST's
+array, so don't rely on it. See "PadlistNAMES".
+.Sp
+The CvDEPTH'th entry of a PADLIST is a PAD (an AV) which is the stack frame
+at that depth of recursion into the CV. The 0th slot of a frame AV is an
+AV which is \f(CW@_\fR. Other entries are storage for variables and op targets.
+.Sp
+Iterating over the PADNAMELIST iterates over all possible pad
+items. Pad slots for targets (\f(CW\*(C`SVs_PADTMP\*(C'\fR)
+and GVs end up having &PL_padname_undef "names", while slots for constants
+have \f(CW&PL_padname_const\fR "names" (see \f(CW"pad_alloc"\fR). That
+\&\f(CW&PL_padname_undef\fR
+and \f(CW&PL_padname_const\fR are used is an implementation detail subject to
+change. To test for them, use \f(CW\*(C`!PadnamePV(name)\*(C'\fR and
+\&\f(CW\*(C`PadnamePV(name)\ &&\ !PadnameLEN(name)\*(C'\fR, respectively.
+.Sp
+Only \f(CW\*(C`my\*(C'\fR/\f(CW\*(C`our\*(C'\fR variable slots get valid names.
+The rest are op targets/GVs/constants which are statically allocated
+or resolved at compile time. These don't have names by which they
+can be looked up from Perl code at run time through eval"" the way
+\&\f(CW\*(C`my\*(C'\fR/\f(CW\*(C`our\*(C'\fR variables can be. Since they can't be looked up by "name"
+but only by their index allocated at compile time (which is usually
+in \f(CW\*(C`PL_op\->op_targ\*(C'\fR), wasting a name SV for them doesn't make sense.
+.Sp
+The pad names in the PADNAMELIST have their PV holding the name of
+the variable. The \f(CW\*(C`COP_SEQ_RANGE_LOW\*(C'\fR and \f(CW\*(C`_HIGH\*(C'\fR fields form a range
+(low+1..high inclusive) of cop_seq numbers for which the name is
+valid. During compilation, these fields may hold the special value
+PERL_PADSEQ_INTRO to indicate various stages:
+.Sp
+.Vb 8
+\& COP_SEQ_RANGE_LOW _HIGH
+\& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-
+\& PERL_PADSEQ_INTRO 0 variable not yet introduced:
+\& { my ($x
+\& valid\-seq# PERL_PADSEQ_INTRO variable in scope:
+\& { my ($x);
+\& valid\-seq# valid\-seq# compilation of scope complete:
+\& { my ($x); .... }
+.Ve
+.Sp
+When a lexical var hasn't yet been introduced, it already exists from the
+perspective of duplicate declarations, but not for variable lookups, e.g.
+.Sp
+.Vb 2
+\& my ($x, $x); # \*(Aq"my" variable $x masks earlier declaration\*(Aq
+\& my $x = $x; # equal to my $x = $::x;
+.Ve
+.Sp
+For typed lexicals \f(CW\*(C`PadnameTYPE\*(C'\fR points at the type stash. For \f(CW\*(C`our\*(C'\fR
+lexicals, \f(CW\*(C`PadnameOURSTASH\*(C'\fR points at the stash of the associated global (so
+that duplicate \f(CW\*(C`our\*(C'\fR declarations in the same package can be detected).
+\&\f(CW\*(C`PadnameGEN\*(C'\fR is sometimes used to store the generation number during
+compilation.
+.Sp
+If \f(CW\*(C`PadnameOUTER\*(C'\fR is set on the pad name, then that slot in the frame AV
+is a REFCNT'ed reference to a lexical from "outside". Such entries
+are sometimes referred to as 'fake'. In this case, the name does not
+use 'low' and 'high' to store a cop_seq range, since it is in scope
+throughout. Instead 'high' stores some flags containing info about
+the real lexical (is it declared in an anon, and is it capable of being
+instantiated multiple times?), and for fake ANONs, 'low' contains the index
+within the parent's pad where the lexical's value is stored, to make
+cloning quicker.
+.Sp
+If the 'name' is \f(CW\*(C`&\*(C'\fR the corresponding entry in the PAD
+is a CV representing a possible closure.
+.Sp
+Note that formats are treated as anon subs, and are cloned each time
+write is called (if necessary).
+.Sp
+The flag \f(CW\*(C`SVs_PADSTALE\*(C'\fR is cleared on lexicals each time the \f(CWmy()\fR is executed,
+and set on scope exit. This allows the
+\&\f(CW"Variable $x is not available"\fR warning
+to be generated in evals, such as
+.Sp
+.Vb 1
+\& { my $x = 1; sub f { eval \*(Aq$x\*(Aq} } f();
+.Ve
+.Sp
+For state vars, \f(CW\*(C`SVs_PADSTALE\*(C'\fR is overloaded to mean 'not yet initialised',
+but this internal state is stored in a separate pad entry.
+.RS 4
+.Sp
+.Vb 1
+\& PADLIST * CvPADLIST(CV *cv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_add_name_pvs""" 4
+.el .IP \f(CWpad_add_name_pvs\fR 4
+.IX Xref "pad_add_name_pvs"
+.IX Item "pad_add_name_pvs"
+Exactly like "pad_add_name_pvn", but takes a literal string
+instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 2
+\& PADOFFSET pad_add_name_pvs("name", U32 flags, HV *typestash,
+\& HV *ourstash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadARRAY""" 4
+.el .IP \f(CWPadARRAY\fR 4
+.IX Xref "PadARRAY"
+.IX Item "PadARRAY"
+NOTE: \f(CW\*(C`PadARRAY\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The C array of pad entries.
+.RS 4
+.Sp
+.Vb 1
+\& SV ** PadARRAY(PAD * pad)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_findmy_pvs""" 4
+.el .IP \f(CWpad_findmy_pvs\fR 4
+.IX Xref "pad_findmy_pvs"
+.IX Item "pad_findmy_pvs"
+Exactly like "pad_findmy_pvn", but takes a literal string
+instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& PADOFFSET pad_findmy_pvs("name", U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadlistARRAY""" 4
+.el .IP \f(CWPadlistARRAY\fR 4
+.IX Xref "PadlistARRAY"
+.IX Item "PadlistARRAY"
+NOTE: \f(CW\*(C`PadlistARRAY\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The C array of a padlist, containing the pads. Only subscript it with
+numbers >= 1, as the 0th entry is not guaranteed to remain usable.
+.RS 4
+.Sp
+.Vb 1
+\& PAD ** PadlistARRAY(PADLIST * padlist)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadlistMAX""" 4
+.el .IP \f(CWPadlistMAX\fR 4
+.IX Xref "PadlistMAX"
+.IX Item "PadlistMAX"
+NOTE: \f(CW\*(C`PadlistMAX\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The index of the last allocated space in the padlist. Note that the last
+pad may be in an earlier slot. Any entries following it will be \f(CW\*(C`NULL\*(C'\fR in
+that case.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t PadlistMAX(PADLIST * padlist)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadlistNAMES""" 4
+.el .IP \f(CWPadlistNAMES\fR 4
+.IX Xref "PadlistNAMES"
+.IX Item "PadlistNAMES"
+NOTE: \f(CW\*(C`PadlistNAMES\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The names associated with pad entries.
+.RS 4
+.Sp
+.Vb 1
+\& PADNAMELIST * PadlistNAMES(PADLIST * padlist)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadlistNAMESARRAY""" 4
+.el .IP \f(CWPadlistNAMESARRAY\fR 4
+.IX Xref "PadlistNAMESARRAY"
+.IX Item "PadlistNAMESARRAY"
+NOTE: \f(CW\*(C`PadlistNAMESARRAY\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The C array of pad names.
+.RS 4
+.Sp
+.Vb 1
+\& PADNAME ** PadlistNAMESARRAY(PADLIST * padlist)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadlistNAMESMAX""" 4
+.el .IP \f(CWPadlistNAMESMAX\fR 4
+.IX Xref "PadlistNAMESMAX"
+.IX Item "PadlistNAMESMAX"
+NOTE: \f(CW\*(C`PadlistNAMESMAX\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The index of the last pad name.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t PadlistNAMESMAX(PADLIST * padlist)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadlistREFCNT""" 4
+.el .IP \f(CWPadlistREFCNT\fR 4
+.IX Xref "PadlistREFCNT"
+.IX Item "PadlistREFCNT"
+NOTE: \f(CW\*(C`PadlistREFCNT\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The reference count of the padlist. Currently this is always 1.
+.RS 4
+.Sp
+.Vb 1
+\& U32 PadlistREFCNT(PADLIST * padlist)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadMAX""" 4
+.el .IP \f(CWPadMAX\fR 4
+.IX Xref "PadMAX"
+.IX Item "PadMAX"
+NOTE: \f(CW\*(C`PadMAX\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The index of the last pad entry.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t PadMAX(PAD * pad)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnameLEN""" 4
+.el .IP \f(CWPadnameLEN\fR 4
+.IX Xref "PadnameLEN"
+.IX Item "PadnameLEN"
+NOTE: \f(CW\*(C`PadnameLEN\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The length of the name.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN PadnameLEN(PADNAME * pn)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnamelistARRAY""" 4
+.el .IP \f(CWPadnamelistARRAY\fR 4
+.IX Xref "PadnamelistARRAY"
+.IX Item "PadnamelistARRAY"
+NOTE: \f(CW\*(C`PadnamelistARRAY\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The C array of pad names.
+.RS 4
+.Sp
+.Vb 1
+\& PADNAME ** PadnamelistARRAY(PADNAMELIST * pnl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnamelistMAX""" 4
+.el .IP \f(CWPadnamelistMAX\fR 4
+.IX Xref "PadnamelistMAX"
+.IX Item "PadnamelistMAX"
+NOTE: \f(CW\*(C`PadnamelistMAX\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The index of the last pad name.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t PadnamelistMAX(PADNAMELIST * pnl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnamelistREFCNT""" 4
+.el .IP \f(CWPadnamelistREFCNT\fR 4
+.IX Xref "PadnamelistREFCNT"
+.IX Item "PadnamelistREFCNT"
+NOTE: \f(CW\*(C`PadnamelistREFCNT\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The reference count of the pad name list.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t PadnamelistREFCNT(PADNAMELIST * pnl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnamelistREFCNT_dec""" 4
+.el .IP \f(CWPadnamelistREFCNT_dec\fR 4
+.IX Xref "PadnamelistREFCNT_dec"
+.IX Item "PadnamelistREFCNT_dec"
+NOTE: \f(CW\*(C`PadnamelistREFCNT_dec\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Lowers the reference count of the pad name list.
+.RS 4
+.Sp
+.Vb 1
+\& void PadnamelistREFCNT_dec(PADNAMELIST * pnl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnamePV""" 4
+.el .IP \f(CWPadnamePV\fR 4
+.IX Xref "PadnamePV"
+.IX Item "PadnamePV"
+NOTE: \f(CW\*(C`PadnamePV\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The name stored in the pad name struct. This returns \f(CW\*(C`NULL\*(C'\fR for a target
+slot.
+.RS 4
+.Sp
+.Vb 1
+\& char * PadnamePV(PADNAME * pn)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnameREFCNT""" 4
+.el .IP \f(CWPadnameREFCNT\fR 4
+.IX Xref "PadnameREFCNT"
+.IX Item "PadnameREFCNT"
+NOTE: \f(CW\*(C`PadnameREFCNT\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+The reference count of the pad name.
+.RS 4
+.Sp
+.Vb 1
+\& SSize_t PadnameREFCNT(PADNAME * pn)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnameREFCNT_dec""" 4
+.el .IP \f(CWPadnameREFCNT_dec\fR 4
+.IX Xref "PadnameREFCNT_dec"
+.IX Item "PadnameREFCNT_dec"
+NOTE: \f(CW\*(C`PadnameREFCNT_dec\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Lowers the reference count of the pad name.
+.RS 4
+.Sp
+.Vb 1
+\& void PadnameREFCNT_dec(PADNAME * pn)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnameREFCNT_inc""" 4
+.el .IP \f(CWPadnameREFCNT_inc\fR 4
+.IX Xref "PadnameREFCNT_inc"
+.IX Item "PadnameREFCNT_inc"
+NOTE: \f(CW\*(C`PadnameREFCNT_inc\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Increases the reference count of the pad name. Returns the pad name itself.
+.RS 4
+.Sp
+.Vb 1
+\& PADNAME * PadnameREFCNT_inc(PADNAME * pn)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnameSV""" 4
+.el .IP \f(CWPadnameSV\fR 4
+.IX Xref "PadnameSV"
+.IX Item "PadnameSV"
+NOTE: \f(CW\*(C`PadnameSV\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Returns the pad name as a mortal SV.
+.RS 4
+.Sp
+.Vb 1
+\& SV * PadnameSV(PADNAME * pn)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PadnameUTF8""" 4
+.el .IP \f(CWPadnameUTF8\fR 4
+.IX Xref "PadnameUTF8"
+.IX Item "PadnameUTF8"
+NOTE: \f(CW\*(C`PadnameUTF8\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Whether PadnamePV is in UTF\-8. Currently, this is always true.
+.RS 4
+.Sp
+.Vb 1
+\& bool PadnameUTF8(PADNAME * pn)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pad_new""" 4
+.el .IP \f(CWpad_new\fR 4
+.IX Xref "pad_new"
+.IX Item "pad_new"
+Create a new padlist, updating the global variables for the
+currently-compiling padlist to point to the new padlist. The following
+flags can be OR'ed together:
+.Sp
+.Vb 3
+\& padnew_CLONE this pad is for a cloned CV
+\& padnew_SAVE save old globals on the save stack
+\& padnew_SAVESUB also save extra stuff for start of sub
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& PADLIST * pad_new(int flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_comppad""" 4
+.el .IP \f(CWPL_comppad\fR 4
+.IX Xref "PL_comppad"
+.IX Item "PL_comppad"
+NOTE: \f(CW\*(C`PL_comppad\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+During compilation, this points to the array containing the values
+part of the pad for the currently-compiling code. (At runtime a CV may
+have many such value arrays; at compile time just one is constructed.)
+At runtime, this points to the array containing the currently-relevant
+values for the pad for the currently-executing code.
+.ie n .IP """PL_comppad_name""" 4
+.el .IP \f(CWPL_comppad_name\fR 4
+.IX Xref "PL_comppad_name"
+.IX Item "PL_comppad_name"
+NOTE: \f(CW\*(C`PL_comppad_name\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+During compilation, this points to the array containing the names part
+of the pad for the currently-compiling code.
+.ie n .IP """PL_curpad""" 4
+.el .IP \f(CWPL_curpad\fR 4
+.IX Xref "PL_curpad"
+.IX Item "PL_curpad"
+NOTE: \f(CW\*(C`PL_curpad\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Points directly to the body of the "PL_comppad" array.
+(I.e., this is \f(CWPadARRAY(PL_comppad)\fR.)
+.ie n .IP """SVs_PADMY""" 4
+.el .IP \f(CWSVs_PADMY\fR 4
+.IX Item "SVs_PADMY"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`SVs_PADMY\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Described in perlguts.
+.ie n .IP """SVs_PADTMP""" 4
+.el .IP \f(CWSVs_PADTMP\fR 4
+.IX Item "SVs_PADTMP"
+Described in perlguts.
+.SH "Password and Group access"
+.IX Header "Password and Group access"
+.ie n .IP """GRPASSWD""" 4
+.el .IP \f(CWGRPASSWD\fR 4
+.IX Xref "GRPASSWD"
+.IX Item "GRPASSWD"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct group\*(C'\fR
+in \fIgrp.h\fR contains \f(CW\*(C`gr_passwd\*(C'\fR.
+.ie n .IP """HAS_ENDGRENT""" 4
+.el .IP \f(CWHAS_ENDGRENT\fR 4
+.IX Xref "HAS_ENDGRENT"
+.IX Item "HAS_ENDGRENT"
+This symbol, if defined, indicates that the getgrent routine is
+available for finalizing sequential access of the group database.
+.ie n .IP """HAS_ENDGRENT_R""" 4
+.el .IP \f(CWHAS_ENDGRENT_R\fR 4
+.IX Xref "HAS_ENDGRENT_R"
+.IX Item "HAS_ENDGRENT_R"
+This symbol, if defined, indicates that the \f(CW\*(C`endgrent_r\*(C'\fR routine
+is available to endgrent re-entrantly.
+.ie n .IP """HAS_ENDPWENT""" 4
+.el .IP \f(CWHAS_ENDPWENT\fR 4
+.IX Xref "HAS_ENDPWENT"
+.IX Item "HAS_ENDPWENT"
+This symbol, if defined, indicates that the \f(CW\*(C`endpwent\*(C'\fR routine is
+available for finalizing sequential access of the passwd database.
+.ie n .IP """HAS_ENDPWENT_R""" 4
+.el .IP \f(CWHAS_ENDPWENT_R\fR 4
+.IX Xref "HAS_ENDPWENT_R"
+.IX Item "HAS_ENDPWENT_R"
+This symbol, if defined, indicates that the \f(CW\*(C`endpwent_r\*(C'\fR routine
+is available to endpwent re-entrantly.
+.ie n .IP """HAS_GETGRENT""" 4
+.el .IP \f(CWHAS_GETGRENT\fR 4
+.IX Xref "HAS_GETGRENT"
+.IX Item "HAS_GETGRENT"
+This symbol, if defined, indicates that the \f(CW\*(C`getgrent\*(C'\fR routine is
+available for sequential access of the group database.
+.ie n .IP """HAS_GETGRENT_R""" 4
+.el .IP \f(CWHAS_GETGRENT_R\fR 4
+.IX Xref "HAS_GETGRENT_R"
+.IX Item "HAS_GETGRENT_R"
+This symbol, if defined, indicates that the \f(CW\*(C`getgrent_r\*(C'\fR routine
+is available to getgrent re-entrantly.
+.ie n .IP """HAS_GETPWENT""" 4
+.el .IP \f(CWHAS_GETPWENT\fR 4
+.IX Xref "HAS_GETPWENT"
+.IX Item "HAS_GETPWENT"
+This symbol, if defined, indicates that the \f(CW\*(C`getpwent\*(C'\fR routine is
+available for sequential access of the passwd database.
+If this is not available, the older \f(CWgetpw()\fR function may be available.
+.ie n .IP """HAS_GETPWENT_R""" 4
+.el .IP \f(CWHAS_GETPWENT_R\fR 4
+.IX Xref "HAS_GETPWENT_R"
+.IX Item "HAS_GETPWENT_R"
+This symbol, if defined, indicates that the \f(CW\*(C`getpwent_r\*(C'\fR routine
+is available to getpwent re-entrantly.
+.ie n .IP """HAS_SETGRENT""" 4
+.el .IP \f(CWHAS_SETGRENT\fR 4
+.IX Xref "HAS_SETGRENT"
+.IX Item "HAS_SETGRENT"
+This symbol, if defined, indicates that the \f(CW\*(C`setgrent\*(C'\fR routine is
+available for initializing sequential access of the group database.
+.ie n .IP """HAS_SETGRENT_R""" 4
+.el .IP \f(CWHAS_SETGRENT_R\fR 4
+.IX Xref "HAS_SETGRENT_R"
+.IX Item "HAS_SETGRENT_R"
+This symbol, if defined, indicates that the \f(CW\*(C`setgrent_r\*(C'\fR routine
+is available to setgrent re-entrantly.
+.ie n .IP """HAS_SETPWENT""" 4
+.el .IP \f(CWHAS_SETPWENT\fR 4
+.IX Xref "HAS_SETPWENT"
+.IX Item "HAS_SETPWENT"
+This symbol, if defined, indicates that the \f(CW\*(C`setpwent\*(C'\fR routine is
+available for initializing sequential access of the passwd database.
+.ie n .IP """HAS_SETPWENT_R""" 4
+.el .IP \f(CWHAS_SETPWENT_R\fR 4
+.IX Xref "HAS_SETPWENT_R"
+.IX Item "HAS_SETPWENT_R"
+This symbol, if defined, indicates that the \f(CW\*(C`setpwent_r\*(C'\fR routine
+is available to setpwent re-entrantly.
+.ie n .IP """PWAGE""" 4
+.el .IP \f(CWPWAGE\fR 4
+.IX Xref "PWAGE"
+.IX Item "PWAGE"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct passwd\*(C'\fR
+contains \f(CW\*(C`pw_age\*(C'\fR.
+.ie n .IP """PWCHANGE""" 4
+.el .IP \f(CWPWCHANGE\fR 4
+.IX Xref "PWCHANGE"
+.IX Item "PWCHANGE"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct passwd\*(C'\fR
+contains \f(CW\*(C`pw_change\*(C'\fR.
+.ie n .IP """PWCLASS""" 4
+.el .IP \f(CWPWCLASS\fR 4
+.IX Xref "PWCLASS"
+.IX Item "PWCLASS"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct passwd\*(C'\fR
+contains \f(CW\*(C`pw_class\*(C'\fR.
+.ie n .IP """PWCOMMENT""" 4
+.el .IP \f(CWPWCOMMENT\fR 4
+.IX Xref "PWCOMMENT"
+.IX Item "PWCOMMENT"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct passwd\*(C'\fR
+contains \f(CW\*(C`pw_comment\*(C'\fR.
+.ie n .IP """PWEXPIRE""" 4
+.el .IP \f(CWPWEXPIRE\fR 4
+.IX Xref "PWEXPIRE"
+.IX Item "PWEXPIRE"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct passwd\*(C'\fR
+contains \f(CW\*(C`pw_expire\*(C'\fR.
+.ie n .IP """PWGECOS""" 4
+.el .IP \f(CWPWGECOS\fR 4
+.IX Xref "PWGECOS"
+.IX Item "PWGECOS"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct passwd\*(C'\fR
+contains \f(CW\*(C`pw_gecos\*(C'\fR.
+.ie n .IP """PWPASSWD""" 4
+.el .IP \f(CWPWPASSWD\fR 4
+.IX Xref "PWPASSWD"
+.IX Item "PWPASSWD"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct passwd\*(C'\fR
+contains \f(CW\*(C`pw_passwd\*(C'\fR.
+.ie n .IP """PWQUOTA""" 4
+.el .IP \f(CWPWQUOTA\fR 4
+.IX Xref "PWQUOTA"
+.IX Item "PWQUOTA"
+This symbol, if defined, indicates to the C program that \f(CW\*(C`struct passwd\*(C'\fR
+contains \f(CW\*(C`pw_quota\*(C'\fR.
+.SH "Paths to system commands"
+.IX Header "Paths to system commands"
+.ie n .IP """CSH""" 4
+.el .IP \f(CWCSH\fR 4
+.IX Xref "CSH"
+.IX Item "CSH"
+This symbol, if defined, contains the full pathname of csh.
+.ie n .IP """LOC_SED""" 4
+.el .IP \f(CWLOC_SED\fR 4
+.IX Xref "LOC_SED"
+.IX Item "LOC_SED"
+This symbol holds the complete pathname to the sed program.
+.ie n .IP """SH_PATH""" 4
+.el .IP \f(CWSH_PATH\fR 4
+.IX Xref "SH_PATH"
+.IX Item "SH_PATH"
+This symbol contains the full pathname to the shell used on this
+on this system to execute Bourne shell scripts. Usually, this will be
+\&\fI/bin/sh\fR, though it's possible that some systems will have \fI/bin/ksh\fR,
+\&\fI/bin/pdksh\fR, \fI/bin/ash\fR, \fI/bin/bash\fR, or even something such as
+D:\fI/bin/sh.exe\fR.
+.SH "Prototype information"
+.IX Header "Prototype information"
+.ie n .IP """CRYPT_R_PROTO""" 4
+.el .IP \f(CWCRYPT_R_PROTO\fR 4
+.IX Xref "CRYPT_R_PROTO"
+.IX Item "CRYPT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`crypt_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_crypt_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_crypt_r\*(C'\fR
+is defined.
+.ie n .IP """CTERMID_R_PROTO""" 4
+.el .IP \f(CWCTERMID_R_PROTO\fR 4
+.IX Xref "CTERMID_R_PROTO"
+.IX Item "CTERMID_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`ctermid_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_ctermid_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_ctermid_r\*(C'\fR
+is defined.
+.ie n .IP """DRAND48_R_PROTO""" 4
+.el .IP \f(CWDRAND48_R_PROTO\fR 4
+.IX Xref "DRAND48_R_PROTO"
+.IX Item "DRAND48_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`drand48_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_drand48_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_drand48_r\*(C'\fR
+is defined.
+.ie n .IP """ENDGRENT_R_PROTO""" 4
+.el .IP \f(CWENDGRENT_R_PROTO\fR 4
+.IX Xref "ENDGRENT_R_PROTO"
+.IX Item "ENDGRENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`endgrent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_endgrent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_endgrent_r\*(C'\fR
+is defined.
+.ie n .IP """ENDHOSTENT_R_PROTO""" 4
+.el .IP \f(CWENDHOSTENT_R_PROTO\fR 4
+.IX Xref "ENDHOSTENT_R_PROTO"
+.IX Item "ENDHOSTENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`endhostent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_endhostent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_endhostent_r\*(C'\fR
+is defined.
+.ie n .IP """ENDNETENT_R_PROTO""" 4
+.el .IP \f(CWENDNETENT_R_PROTO\fR 4
+.IX Xref "ENDNETENT_R_PROTO"
+.IX Item "ENDNETENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`endnetent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_endnetent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_endnetent_r\*(C'\fR
+is defined.
+.ie n .IP """ENDPROTOENT_R_PROTO""" 4
+.el .IP \f(CWENDPROTOENT_R_PROTO\fR 4
+.IX Xref "ENDPROTOENT_R_PROTO"
+.IX Item "ENDPROTOENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`endprotoent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_endprotoent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_endprotoent_r\*(C'\fR
+is defined.
+.ie n .IP """ENDPWENT_R_PROTO""" 4
+.el .IP \f(CWENDPWENT_R_PROTO\fR 4
+.IX Xref "ENDPWENT_R_PROTO"
+.IX Item "ENDPWENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`endpwent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_endpwent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_endpwent_r\*(C'\fR
+is defined.
+.ie n .IP """ENDSERVENT_R_PROTO""" 4
+.el .IP \f(CWENDSERVENT_R_PROTO\fR 4
+.IX Xref "ENDSERVENT_R_PROTO"
+.IX Item "ENDSERVENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`endservent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_endservent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_endservent_r\*(C'\fR
+is defined.
+.ie n .IP """GDBMNDBM_H_USES_PROTOTYPES""" 4
+.el .IP \f(CWGDBMNDBM_H_USES_PROTOTYPES\fR 4
+.IX Xref "GDBMNDBM_H_USES_PROTOTYPES"
+.IX Item "GDBMNDBM_H_USES_PROTOTYPES"
+This symbol, if defined, indicates that \fIgdbm/ndbm.h\fR uses real \f(CW\*(C`ANSI\*(C'\fR C
+prototypes instead of K&R style function declarations without any
+parameter information. While \f(CW\*(C`ANSI\*(C'\fR C prototypes are supported in C++,
+K&R style function declarations will yield errors.
+.ie n .IP """GDBM_NDBM_H_USES_PROTOTYPES""" 4
+.el .IP \f(CWGDBM_NDBM_H_USES_PROTOTYPES\fR 4
+.IX Xref "GDBM_NDBM_H_USES_PROTOTYPES"
+.IX Item "GDBM_NDBM_H_USES_PROTOTYPES"
+This symbol, if defined, indicates that <gdbm\-\fIndbm.h\fR> uses real \f(CW\*(C`ANSI\*(C'\fR C
+prototypes instead of K&R style function declarations without any
+parameter information. While \f(CW\*(C`ANSI\*(C'\fR C prototypes are supported in C++,
+K&R style function declarations will yield errors.
+.ie n .IP """GETGRENT_R_PROTO""" 4
+.el .IP \f(CWGETGRENT_R_PROTO\fR 4
+.IX Xref "GETGRENT_R_PROTO"
+.IX Item "GETGRENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getgrent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getgrent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getgrent_r\*(C'\fR
+is defined.
+.ie n .IP """GETGRGID_R_PROTO""" 4
+.el .IP \f(CWGETGRGID_R_PROTO\fR 4
+.IX Xref "GETGRGID_R_PROTO"
+.IX Item "GETGRGID_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getgrgid_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getgrgid_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getgrgid_r\*(C'\fR
+is defined.
+.ie n .IP """GETGRNAM_R_PROTO""" 4
+.el .IP \f(CWGETGRNAM_R_PROTO\fR 4
+.IX Xref "GETGRNAM_R_PROTO"
+.IX Item "GETGRNAM_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getgrnam_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getgrnam_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getgrnam_r\*(C'\fR
+is defined.
+.ie n .IP """GETHOSTBYADDR_R_PROTO""" 4
+.el .IP \f(CWGETHOSTBYADDR_R_PROTO\fR 4
+.IX Xref "GETHOSTBYADDR_R_PROTO"
+.IX Item "GETHOSTBYADDR_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`gethostbyaddr_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_gethostbyaddr_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_gethostbyaddr_r\*(C'\fR
+is defined.
+.ie n .IP """GETHOSTBYNAME_R_PROTO""" 4
+.el .IP \f(CWGETHOSTBYNAME_R_PROTO\fR 4
+.IX Xref "GETHOSTBYNAME_R_PROTO"
+.IX Item "GETHOSTBYNAME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`gethostbyname_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_gethostbyname_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_gethostbyname_r\*(C'\fR
+is defined.
+.ie n .IP """GETHOSTENT_R_PROTO""" 4
+.el .IP \f(CWGETHOSTENT_R_PROTO\fR 4
+.IX Xref "GETHOSTENT_R_PROTO"
+.IX Item "GETHOSTENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`gethostent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_gethostent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_gethostent_r\*(C'\fR
+is defined.
+.ie n .IP """GETLOGIN_R_PROTO""" 4
+.el .IP \f(CWGETLOGIN_R_PROTO\fR 4
+.IX Xref "GETLOGIN_R_PROTO"
+.IX Item "GETLOGIN_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getlogin_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getlogin_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getlogin_r\*(C'\fR
+is defined.
+.ie n .IP """GETNETBYADDR_R_PROTO""" 4
+.el .IP \f(CWGETNETBYADDR_R_PROTO\fR 4
+.IX Xref "GETNETBYADDR_R_PROTO"
+.IX Item "GETNETBYADDR_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getnetbyaddr_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getnetbyaddr_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getnetbyaddr_r\*(C'\fR
+is defined.
+.ie n .IP """GETNETBYNAME_R_PROTO""" 4
+.el .IP \f(CWGETNETBYNAME_R_PROTO\fR 4
+.IX Xref "GETNETBYNAME_R_PROTO"
+.IX Item "GETNETBYNAME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getnetbyname_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getnetbyname_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getnetbyname_r\*(C'\fR
+is defined.
+.ie n .IP """GETNETENT_R_PROTO""" 4
+.el .IP \f(CWGETNETENT_R_PROTO\fR 4
+.IX Xref "GETNETENT_R_PROTO"
+.IX Item "GETNETENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getnetent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getnetent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getnetent_r\*(C'\fR
+is defined.
+.ie n .IP """GETPROTOBYNAME_R_PROTO""" 4
+.el .IP \f(CWGETPROTOBYNAME_R_PROTO\fR 4
+.IX Xref "GETPROTOBYNAME_R_PROTO"
+.IX Item "GETPROTOBYNAME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getprotobyname_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getprotobyname_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getprotobyname_r\*(C'\fR
+is defined.
+.ie n .IP """GETPROTOBYNUMBER_R_PROTO""" 4
+.el .IP \f(CWGETPROTOBYNUMBER_R_PROTO\fR 4
+.IX Xref "GETPROTOBYNUMBER_R_PROTO"
+.IX Item "GETPROTOBYNUMBER_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getprotobynumber_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getprotobynumber_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getprotobynumber_r\*(C'\fR
+is defined.
+.ie n .IP """GETPROTOENT_R_PROTO""" 4
+.el .IP \f(CWGETPROTOENT_R_PROTO\fR 4
+.IX Xref "GETPROTOENT_R_PROTO"
+.IX Item "GETPROTOENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getprotoent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getprotoent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getprotoent_r\*(C'\fR
+is defined.
+.ie n .IP """GETPWENT_R_PROTO""" 4
+.el .IP \f(CWGETPWENT_R_PROTO\fR 4
+.IX Xref "GETPWENT_R_PROTO"
+.IX Item "GETPWENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getpwent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getpwent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getpwent_r\*(C'\fR
+is defined.
+.ie n .IP """GETPWNAM_R_PROTO""" 4
+.el .IP \f(CWGETPWNAM_R_PROTO\fR 4
+.IX Xref "GETPWNAM_R_PROTO"
+.IX Item "GETPWNAM_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getpwnam_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getpwnam_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getpwnam_r\*(C'\fR
+is defined.
+.ie n .IP """GETPWUID_R_PROTO""" 4
+.el .IP \f(CWGETPWUID_R_PROTO\fR 4
+.IX Xref "GETPWUID_R_PROTO"
+.IX Item "GETPWUID_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getpwuid_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getpwuid_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getpwuid_r\*(C'\fR
+is defined.
+.ie n .IP """GETSERVBYNAME_R_PROTO""" 4
+.el .IP \f(CWGETSERVBYNAME_R_PROTO\fR 4
+.IX Xref "GETSERVBYNAME_R_PROTO"
+.IX Item "GETSERVBYNAME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getservbyname_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getservbyname_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getservbyname_r\*(C'\fR
+is defined.
+.ie n .IP """GETSERVBYPORT_R_PROTO""" 4
+.el .IP \f(CWGETSERVBYPORT_R_PROTO\fR 4
+.IX Xref "GETSERVBYPORT_R_PROTO"
+.IX Item "GETSERVBYPORT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getservbyport_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getservbyport_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getservbyport_r\*(C'\fR
+is defined.
+.ie n .IP """GETSERVENT_R_PROTO""" 4
+.el .IP \f(CWGETSERVENT_R_PROTO\fR 4
+.IX Xref "GETSERVENT_R_PROTO"
+.IX Item "GETSERVENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getservent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getservent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getservent_r\*(C'\fR
+is defined.
+.ie n .IP """GETSPNAM_R_PROTO""" 4
+.el .IP \f(CWGETSPNAM_R_PROTO\fR 4
+.IX Xref "GETSPNAM_R_PROTO"
+.IX Item "GETSPNAM_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`getspnam_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_getspnam_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_getspnam_r\*(C'\fR
+is defined.
+.ie n .IP """HAS_DBMINIT_PROTO""" 4
+.el .IP \f(CWHAS_DBMINIT_PROTO\fR 4
+.IX Xref "HAS_DBMINIT_PROTO"
+.IX Item "HAS_DBMINIT_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWdbminit()\fR function. Otherwise, it is up
+to the program to supply one. A good guess is
+.Sp
+.Vb 1
+\& extern int dbminit(char *);
+.Ve
+.ie n .IP """HAS_DRAND48_PROTO""" 4
+.el .IP \f(CWHAS_DRAND48_PROTO\fR 4
+.IX Xref "HAS_DRAND48_PROTO"
+.IX Item "HAS_DRAND48_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWdrand48()\fR function. Otherwise, it is up
+to the program to supply one. A good guess is
+.Sp
+.Vb 1
+\& extern double drand48(void);
+.Ve
+.ie n .IP """HAS_FLOCK_PROTO""" 4
+.el .IP \f(CWHAS_FLOCK_PROTO\fR 4
+.IX Xref "HAS_FLOCK_PROTO"
+.IX Item "HAS_FLOCK_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWflock()\fR function. Otherwise, it is up
+to the program to supply one. A good guess is
+.Sp
+.Vb 1
+\& extern int flock(int, int);
+.Ve
+.ie n .IP """HAS_GETHOST_PROTOS""" 4
+.el .IP \f(CWHAS_GETHOST_PROTOS\fR 4
+.IX Xref "HAS_GETHOST_PROTOS"
+.IX Item "HAS_GETHOST_PROTOS"
+This symbol, if defined, indicates that \fInetdb.h\fR includes
+prototypes for \f(CWgethostent()\fR, \f(CWgethostbyname()\fR, and
+\&\f(CWgethostbyaddr()\fR. Otherwise, it is up to the program to guess
+them. See netdbtype.U (part of metaconfig) for probing for various \f(CW\*(C`Netdb_xxx_t\*(C'\fR types.
+.ie n .IP """HAS_GETNET_PROTOS""" 4
+.el .IP \f(CWHAS_GETNET_PROTOS\fR 4
+.IX Xref "HAS_GETNET_PROTOS"
+.IX Item "HAS_GETNET_PROTOS"
+This symbol, if defined, indicates that \fInetdb.h\fR includes
+prototypes for \f(CWgetnetent()\fR, \f(CWgetnetbyname()\fR, and
+\&\f(CWgetnetbyaddr()\fR. Otherwise, it is up to the program to guess
+them. See netdbtype.U (part of metaconfig) for probing for various \f(CW\*(C`Netdb_xxx_t\*(C'\fR types.
+.ie n .IP """HAS_GETPROTO_PROTOS""" 4
+.el .IP \f(CWHAS_GETPROTO_PROTOS\fR 4
+.IX Xref "HAS_GETPROTO_PROTOS"
+.IX Item "HAS_GETPROTO_PROTOS"
+This symbol, if defined, indicates that \fInetdb.h\fR includes
+prototypes for \f(CWgetprotoent()\fR, \f(CWgetprotobyname()\fR, and
+\&\f(CWgetprotobyaddr()\fR. Otherwise, it is up to the program to guess
+them. See netdbtype.U (part of metaconfig) for probing for various \f(CW\*(C`Netdb_xxx_t\*(C'\fR types.
+.ie n .IP """HAS_GETSERV_PROTOS""" 4
+.el .IP \f(CWHAS_GETSERV_PROTOS\fR 4
+.IX Xref "HAS_GETSERV_PROTOS"
+.IX Item "HAS_GETSERV_PROTOS"
+This symbol, if defined, indicates that \fInetdb.h\fR includes
+prototypes for \f(CWgetservent()\fR, \f(CWgetservbyname()\fR, and
+\&\f(CWgetservbyaddr()\fR. Otherwise, it is up to the program to guess
+them. See netdbtype.U (part of metaconfig) for probing for various \f(CW\*(C`Netdb_xxx_t\*(C'\fR types.
+.ie n .IP """HAS_MODFL_PROTO""" 4
+.el .IP \f(CWHAS_MODFL_PROTO\fR 4
+.IX Xref "HAS_MODFL_PROTO"
+.IX Item "HAS_MODFL_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWmodfl()\fR function. Otherwise, it is up
+to the program to supply one.
+.ie n .IP """HAS_SBRK_PROTO""" 4
+.el .IP \f(CWHAS_SBRK_PROTO\fR 4
+.IX Xref "HAS_SBRK_PROTO"
+.IX Item "HAS_SBRK_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWsbrk()\fR function. Otherwise, it is up
+to the program to supply one. Good guesses are
+.Sp
+.Vb 2
+\& extern void* sbrk(int);
+\& extern void* sbrk(size_t);
+.Ve
+.ie n .IP """HAS_SETRESGID_PROTO""" 4
+.el .IP \f(CWHAS_SETRESGID_PROTO\fR 4
+.IX Xref "HAS_SETRESGID_PROTO"
+.IX Item "HAS_SETRESGID_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWsetresgid()\fR function. Otherwise, it is up
+to the program to supply one. Good guesses are
+.Sp
+.Vb 1
+\& extern int setresgid(uid_t ruid, uid_t euid, uid_t suid);
+.Ve
+.ie n .IP """HAS_SETRESUID_PROTO""" 4
+.el .IP \f(CWHAS_SETRESUID_PROTO\fR 4
+.IX Xref "HAS_SETRESUID_PROTO"
+.IX Item "HAS_SETRESUID_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWsetresuid()\fR function. Otherwise, it is up
+to the program to supply one. Good guesses are
+.Sp
+.Vb 1
+\& extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);
+.Ve
+.ie n .IP """HAS_SHMAT_PROTOTYPE""" 4
+.el .IP \f(CWHAS_SHMAT_PROTOTYPE\fR 4
+.IX Xref "HAS_SHMAT_PROTOTYPE"
+.IX Item "HAS_SHMAT_PROTOTYPE"
+This symbol, if defined, indicates that the \fIsys/shm.h\fR includes
+a prototype for \f(CWshmat()\fR. Otherwise, it is up to the program to
+guess one. \f(CW\*(C`Shmat_t\*(C'\fR \f(CW\*(C`shmat(int, Shmat_t, int)\*(C'\fR is a good guess,
+but not always right so it should be emitted by the program only
+when \f(CW\*(C`HAS_SHMAT_PROTOTYPE\*(C'\fR is not defined to avoid conflicting defs.
+.ie n .IP """HAS_SOCKATMARK_PROTO""" 4
+.el .IP \f(CWHAS_SOCKATMARK_PROTO\fR 4
+.IX Xref "HAS_SOCKATMARK_PROTO"
+.IX Item "HAS_SOCKATMARK_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWsockatmark()\fR function. Otherwise, it is up
+to the program to supply one. A good guess is
+.Sp
+.Vb 1
+\& extern int sockatmark(int);
+.Ve
+.ie n .IP """HAS_SYSCALL_PROTO""" 4
+.el .IP \f(CWHAS_SYSCALL_PROTO\fR 4
+.IX Xref "HAS_SYSCALL_PROTO"
+.IX Item "HAS_SYSCALL_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWsyscall()\fR function. Otherwise, it is up
+to the program to supply one. Good guesses are
+.Sp
+.Vb 2
+\& extern int syscall(int, ...);
+\& extern int syscall(long, ...);
+.Ve
+.ie n .IP """HAS_TELLDIR_PROTO""" 4
+.el .IP \f(CWHAS_TELLDIR_PROTO\fR 4
+.IX Xref "HAS_TELLDIR_PROTO"
+.IX Item "HAS_TELLDIR_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWtelldir()\fR function. Otherwise, it is up
+to the program to supply one. A good guess is
+.Sp
+.Vb 1
+\& extern long telldir(DIR*);
+.Ve
+.ie n .IP """NDBM_H_USES_PROTOTYPES""" 4
+.el .IP \f(CWNDBM_H_USES_PROTOTYPES\fR 4
+.IX Xref "NDBM_H_USES_PROTOTYPES"
+.IX Item "NDBM_H_USES_PROTOTYPES"
+This symbol, if defined, indicates that \fIndbm.h\fR uses real \f(CW\*(C`ANSI\*(C'\fR C
+prototypes instead of K&R style function declarations without any
+parameter information. While \f(CW\*(C`ANSI\*(C'\fR C prototypes are supported in C++,
+K&R style function declarations will yield errors.
+.ie n .IP """RANDOM_R_PROTO""" 4
+.el .IP \f(CWRANDOM_R_PROTO\fR 4
+.IX Xref "RANDOM_R_PROTO"
+.IX Item "RANDOM_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`random_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_random_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_random_r\*(C'\fR
+is defined.
+.ie n .IP """READDIR_R_PROTO""" 4
+.el .IP \f(CWREADDIR_R_PROTO\fR 4
+.IX Xref "READDIR_R_PROTO"
+.IX Item "READDIR_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`readdir_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_readdir_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_readdir_r\*(C'\fR
+is defined.
+.ie n .IP """SETGRENT_R_PROTO""" 4
+.el .IP \f(CWSETGRENT_R_PROTO\fR 4
+.IX Xref "SETGRENT_R_PROTO"
+.IX Item "SETGRENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`setgrent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_setgrent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_setgrent_r\*(C'\fR
+is defined.
+.ie n .IP """SETHOSTENT_R_PROTO""" 4
+.el .IP \f(CWSETHOSTENT_R_PROTO\fR 4
+.IX Xref "SETHOSTENT_R_PROTO"
+.IX Item "SETHOSTENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`sethostent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_sethostent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_sethostent_r\*(C'\fR
+is defined.
+.ie n .IP """SETLOCALE_R_PROTO""" 4
+.el .IP \f(CWSETLOCALE_R_PROTO\fR 4
+.IX Xref "SETLOCALE_R_PROTO"
+.IX Item "SETLOCALE_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`setlocale_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_setlocale_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_setlocale_r\*(C'\fR
+is defined.
+.ie n .IP """SETNETENT_R_PROTO""" 4
+.el .IP \f(CWSETNETENT_R_PROTO\fR 4
+.IX Xref "SETNETENT_R_PROTO"
+.IX Item "SETNETENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`setnetent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_setnetent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_setnetent_r\*(C'\fR
+is defined.
+.ie n .IP """SETPROTOENT_R_PROTO""" 4
+.el .IP \f(CWSETPROTOENT_R_PROTO\fR 4
+.IX Xref "SETPROTOENT_R_PROTO"
+.IX Item "SETPROTOENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`setprotoent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_setprotoent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_setprotoent_r\*(C'\fR
+is defined.
+.ie n .IP """SETPWENT_R_PROTO""" 4
+.el .IP \f(CWSETPWENT_R_PROTO\fR 4
+.IX Xref "SETPWENT_R_PROTO"
+.IX Item "SETPWENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`setpwent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_setpwent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_setpwent_r\*(C'\fR
+is defined.
+.ie n .IP """SETSERVENT_R_PROTO""" 4
+.el .IP \f(CWSETSERVENT_R_PROTO\fR 4
+.IX Xref "SETSERVENT_R_PROTO"
+.IX Item "SETSERVENT_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`setservent_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_setservent_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_setservent_r\*(C'\fR
+is defined.
+.ie n .IP """SRANDOM_R_PROTO""" 4
+.el .IP \f(CWSRANDOM_R_PROTO\fR 4
+.IX Xref "SRANDOM_R_PROTO"
+.IX Item "SRANDOM_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`srandom_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_srandom_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_srandom_r\*(C'\fR
+is defined.
+.ie n .IP """SRAND48_R_PROTO""" 4
+.el .IP \f(CWSRAND48_R_PROTO\fR 4
+.IX Xref "SRAND48_R_PROTO"
+.IX Item "SRAND48_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`srand48_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_srand48_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_srand48_r\*(C'\fR
+is defined.
+.ie n .IP """STRERROR_R_PROTO""" 4
+.el .IP \f(CWSTRERROR_R_PROTO\fR 4
+.IX Xref "STRERROR_R_PROTO"
+.IX Item "STRERROR_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`strerror_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_strerror_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_strerror_r\*(C'\fR
+is defined.
+.ie n .IP """TMPNAM_R_PROTO""" 4
+.el .IP \f(CWTMPNAM_R_PROTO\fR 4
+.IX Xref "TMPNAM_R_PROTO"
+.IX Item "TMPNAM_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`tmpnam_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_tmpnam_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_tmpnam_r\*(C'\fR
+is defined.
+.ie n .IP """TTYNAME_R_PROTO""" 4
+.el .IP \f(CWTTYNAME_R_PROTO\fR 4
+.IX Xref "TTYNAME_R_PROTO"
+.IX Item "TTYNAME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`ttyname_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_ttyname_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_ttyname_r\*(C'\fR
+is defined.
+.SH "REGEXP Functions"
+.IX Header "REGEXP Functions"
+.ie n .IP """pregcomp""" 4
+.el .IP \f(CWpregcomp\fR 4
+.IX Item "pregcomp"
+Described in perlreguts.
+.RS 4
+.Sp
+.Vb 1
+\& REGEXP * pregcomp(SV * const pattern, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pregexec""" 4
+.el .IP \f(CWpregexec\fR 4
+.IX Item "pregexec"
+Described in perlreguts.
+.RS 4
+.Sp
+.Vb 3
+\& I32 pregexec(REGEXP * const prog, char *stringarg, char *strend,
+\& char *strbeg, SSize_t minend, SV *screamer,
+\& U32 nosave)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """re_compile""" 4
+.el .IP \f(CWre_compile\fR 4
+.IX Xref "re_compile"
+.IX Item "re_compile"
+Compile the regular expression pattern \f(CW\*(C`pattern\*(C'\fR, returning a pointer to the
+compiled object for later matching with the internal regex engine.
+.Sp
+This function is typically used by a custom regexp engine \f(CW\*(C`.comp()\*(C'\fR function
+to hand off to the core regexp engine those patterns it doesn't want to handle
+itself (typically passing through the same flags it was called with). In
+almost all other cases, a regexp should be compiled by calling "\f(CW\*(C`pregcomp\*(C'\fR"
+to compile using the currently active regexp engine.
+.Sp
+If \f(CW\*(C`pattern\*(C'\fR is already a \f(CW\*(C`REGEXP\*(C'\fR, this function does nothing but return a
+pointer to the input. Otherwise the PV is extracted and treated like a string
+representing a pattern. See perlre.
+.Sp
+The possible flags for \f(CW\*(C`rx_flags\*(C'\fR are documented in perlreapi. Their names
+all begin with \f(CW\*(C`RXf_\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& REGEXP * re_compile(SV * const pattern, U32 orig_rx_flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """re_dup_guts""" 4
+.el .IP \f(CWre_dup_guts\fR 4
+.IX Xref "re_dup_guts"
+.IX Item "re_dup_guts"
+Duplicate a regexp.
+.Sp
+This routine is expected to clone a given regexp structure. It is only
+compiled under USE_ITHREADS.
+.Sp
+After all of the core data stored in struct regexp is duplicated
+the \f(CW\*(C`regexp_engine.dupe\*(C'\fR method is used to copy any private data
+stored in the *pprivate pointer. This allows extensions to handle
+any duplication they need to do.
+.RS 4
+.Sp
+.Vb 2
+\& void re_dup_guts(const REGEXP *sstr, REGEXP *dstr,
+\& CLONE_PARAMS *param)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """REGEX_LOCALE_CHARSET""" 4
+.el .IP \f(CWREGEX_LOCALE_CHARSET\fR 4
+.IX Item "REGEX_LOCALE_CHARSET"
+Described in perlreapi.
+.ie n .IP """REGEXP""" 4
+.el .IP \f(CWREGEXP\fR 4
+.IX Item "REGEXP"
+Described in perlreapi.
+.ie n .IP """regexp_engine""" 4
+.el .IP \f(CWregexp_engine\fR 4
+.IX Xref "regexp_engine"
+.IX Item "regexp_engine"
+When a regexp is compiled, its \f(CW\*(C`engine\*(C'\fR field is then set to point at
+the appropriate structure, so that when it needs to be used Perl can find
+the right routines to do so.
+.Sp
+In order to install a new regexp handler, \f(CW$^H{regcomp}\fR is set
+to an integer which (when casted appropriately) resolves to one of these
+structures. When compiling, the \f(CW\*(C`comp\*(C'\fR method is executed, and the
+resulting \f(CW\*(C`regexp\*(C'\fR structure's engine field is expected to point back at
+the same structure.
+.Sp
+The pTHX_ symbol in the definition is a macro used by Perl under threading
+to provide an extra argument to the routine holding a pointer back to
+the interpreter that is executing the regexp. So under threading all
+routines get an extra argument.
+.ie n .IP """regexp_paren_pair""" 4
+.el .IP \f(CWregexp_paren_pair\fR 4
+.IX Item "regexp_paren_pair"
+Described in perlreapi.
+.ie n .IP """regmatch_info""" 4
+.el .IP \f(CWregmatch_info\fR 4
+.IX Xref "regmatch_info"
+.IX Item "regmatch_info"
+Some basic information about the current match that is created by
+Perl_regexec_flags and then passed to \fBregtry()\fR, \fBregmatch()\fR etc.
+It is allocated as a local var on the stack, so nothing should be
+stored in it that needs preserving or clearing up on \fBcroak()\fR.
+For that, see the aux_info and aux_info_eval members of the
+regmatch_state union.
+.ie n .IP """REXEC_COPY_SKIP_POST""" 4
+.el .IP \f(CWREXEC_COPY_SKIP_POST\fR 4
+.IX Item "REXEC_COPY_SKIP_POST"
+.PD 0
+.ie n .IP """REXEC_COPY_SKIP_PRE""" 4
+.el .IP \f(CWREXEC_COPY_SKIP_PRE\fR 4
+.IX Item "REXEC_COPY_SKIP_PRE"
+.ie n .IP """REXEC_COPY_STR""" 4
+.el .IP \f(CWREXEC_COPY_STR\fR 4
+.IX Item "REXEC_COPY_STR"
+.PD
+Described in perlreapi.
+.ie n .IP """RXapif_ALL""" 4
+.el .IP \f(CWRXapif_ALL\fR 4
+.IX Item "RXapif_ALL"
+.PD 0
+.ie n .IP """RXapif_CLEAR""" 4
+.el .IP \f(CWRXapif_CLEAR\fR 4
+.IX Item "RXapif_CLEAR"
+.ie n .IP """RXapif_DELETE""" 4
+.el .IP \f(CWRXapif_DELETE\fR 4
+.IX Item "RXapif_DELETE"
+.ie n .IP """RXapif_EXISTS""" 4
+.el .IP \f(CWRXapif_EXISTS\fR 4
+.IX Item "RXapif_EXISTS"
+.ie n .IP """RXapif_FETCH""" 4
+.el .IP \f(CWRXapif_FETCH\fR 4
+.IX Item "RXapif_FETCH"
+.ie n .IP """RXapif_FIRSTKEY""" 4
+.el .IP \f(CWRXapif_FIRSTKEY\fR 4
+.IX Item "RXapif_FIRSTKEY"
+.ie n .IP """RXapif_NEXTKEY""" 4
+.el .IP \f(CWRXapif_NEXTKEY\fR 4
+.IX Item "RXapif_NEXTKEY"
+.ie n .IP """RXapif_ONE""" 4
+.el .IP \f(CWRXapif_ONE\fR 4
+.IX Item "RXapif_ONE"
+.ie n .IP """RXapif_REGNAME""" 4
+.el .IP \f(CWRXapif_REGNAME\fR 4
+.IX Item "RXapif_REGNAME"
+.ie n .IP """RXapif_REGNAMES""" 4
+.el .IP \f(CWRXapif_REGNAMES\fR 4
+.IX Item "RXapif_REGNAMES"
+.ie n .IP """RXapif_REGNAMES_COUNT""" 4
+.el .IP \f(CWRXapif_REGNAMES_COUNT\fR 4
+.IX Item "RXapif_REGNAMES_COUNT"
+.ie n .IP """RXapif_SCALAR""" 4
+.el .IP \f(CWRXapif_SCALAR\fR 4
+.IX Item "RXapif_SCALAR"
+.ie n .IP """RXapif_STORE""" 4
+.el .IP \f(CWRXapif_STORE\fR 4
+.IX Item "RXapif_STORE"
+.PD
+Described in perlreapi.
+.ie n .IP """RX_BUFF_IDX_CARET_FULLMATCH""" 4
+.el .IP \f(CWRX_BUFF_IDX_CARET_FULLMATCH\fR 4
+.IX Item "RX_BUFF_IDX_CARET_FULLMATCH"
+.PD 0
+.ie n .IP """RX_BUFF_IDX_CARET_POSTMATCH""" 4
+.el .IP \f(CWRX_BUFF_IDX_CARET_POSTMATCH\fR 4
+.IX Item "RX_BUFF_IDX_CARET_POSTMATCH"
+.ie n .IP """RX_BUFF_IDX_CARET_PREMATCH""" 4
+.el .IP \f(CWRX_BUFF_IDX_CARET_PREMATCH\fR 4
+.IX Item "RX_BUFF_IDX_CARET_PREMATCH"
+.ie n .IP """RX_BUFF_IDX_FULLMATCH""" 4
+.el .IP \f(CWRX_BUFF_IDX_FULLMATCH\fR 4
+.IX Item "RX_BUFF_IDX_FULLMATCH"
+.ie n .IP """RX_BUFF_IDX_POSTMATCH""" 4
+.el .IP \f(CWRX_BUFF_IDX_POSTMATCH\fR 4
+.IX Item "RX_BUFF_IDX_POSTMATCH"
+.ie n .IP """RX_BUFF_IDX_PREMATCH""" 4
+.el .IP \f(CWRX_BUFF_IDX_PREMATCH\fR 4
+.IX Item "RX_BUFF_IDX_PREMATCH"
+.PD
+Described in perlreapi.
+.ie n .IP """RXf_NO_INPLACE_SUBST""" 4
+.el .IP \f(CWRXf_NO_INPLACE_SUBST\fR 4
+.IX Item "RXf_NO_INPLACE_SUBST"
+.PD 0
+.ie n .IP """RXf_NULL""" 4
+.el .IP \f(CWRXf_NULL\fR 4
+.IX Item "RXf_NULL"
+.ie n .IP """RXf_SKIPWHITE""" 4
+.el .IP \f(CWRXf_SKIPWHITE\fR 4
+.IX Item "RXf_SKIPWHITE"
+.ie n .IP """RXf_SPLIT""" 4
+.el .IP \f(CWRXf_SPLIT\fR 4
+.IX Item "RXf_SPLIT"
+.ie n .IP """RXf_START_ONLY""" 4
+.el .IP \f(CWRXf_START_ONLY\fR 4
+.IX Item "RXf_START_ONLY"
+.ie n .IP """RXf_WHITE""" 4
+.el .IP \f(CWRXf_WHITE\fR 4
+.IX Item "RXf_WHITE"
+.PD
+Described in perlreapi.
+.ie n .IP """RXf_PMf_EXTENDED""" 4
+.el .IP \f(CWRXf_PMf_EXTENDED\fR 4
+.IX Item "RXf_PMf_EXTENDED"
+.PD 0
+.ie n .IP """RXf_PMf_FOLD""" 4
+.el .IP \f(CWRXf_PMf_FOLD\fR 4
+.IX Item "RXf_PMf_FOLD"
+.ie n .IP """RXf_PMf_KEEPCOPY""" 4
+.el .IP \f(CWRXf_PMf_KEEPCOPY\fR 4
+.IX Item "RXf_PMf_KEEPCOPY"
+.ie n .IP """RXf_PMf_MULTILINE""" 4
+.el .IP \f(CWRXf_PMf_MULTILINE\fR 4
+.IX Item "RXf_PMf_MULTILINE"
+.ie n .IP """RXf_PMf_SINGLELINE""" 4
+.el .IP \f(CWRXf_PMf_SINGLELINE\fR 4
+.IX Item "RXf_PMf_SINGLELINE"
+.PD
+Described in perlreapi.
+.ie n .IP """RX_MATCH_COPIED""" 4
+.el .IP \f(CWRX_MATCH_COPIED\fR 4
+.IX Item "RX_MATCH_COPIED"
+Described in perlreapi.
+.RS 4
+.Sp
+.Vb 1
+\& RX_MATCH_COPIED(const REGEXP * rx)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """RX_OFFS""" 4
+.el .IP \f(CWRX_OFFS\fR 4
+.IX Item "RX_OFFS"
+Described in perlreapi.
+.RS 4
+.Sp
+.Vb 1
+\& RX_OFFS(const REGEXP * rx_sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvRX""" 4
+.el .IP \f(CWSvRX\fR 4
+.IX Xref "SvRX"
+.IX Item "SvRX"
+Convenience macro to get the REGEXP from a SV. This is approximately
+equivalent to the following snippet:
+.Sp
+.Vb 6
+\& if (SvMAGICAL(sv))
+\& mg_get(sv);
+\& if (SvROK(sv))
+\& sv = MUTABLE_SV(SvRV(sv));
+\& if (SvTYPE(sv) == SVt_REGEXP)
+\& return (REGEXP*) sv;
+.Ve
+.Sp
+\&\f(CW\*(C`NULL\*(C'\fR will be returned if a REGEXP* is not found.
+.RS 4
+.Sp
+.Vb 1
+\& REGEXP * SvRX(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvRXOK""" 4
+.el .IP \f(CWSvRXOK\fR 4
+.IX Xref "SvRXOK"
+.IX Item "SvRXOK"
+Returns a boolean indicating whether the SV (or the one it references)
+is a REGEXP.
+.Sp
+If you want to do something with the REGEXP* later use SvRX instead
+and check for NULL.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvRXOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SV_SAVED_COPY""" 4
+.el .IP \f(CWSV_SAVED_COPY\fR 4
+.IX Item "SV_SAVED_COPY"
+Described in perlreapi.
+.SH "Reports and Formats"
+.IX Header "Reports and Formats"
+These are used in the simple report generation feature of Perl.
+See perlform.
+.ie n .IP """IoBOTTOM_GV""" 4
+.el .IP \f(CWIoBOTTOM_GV\fR 4
+.IX Item "IoBOTTOM_GV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& GV * IoBOTTOM_GV(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoBOTTOM_NAME""" 4
+.el .IP \f(CWIoBOTTOM_NAME\fR 4
+.IX Item "IoBOTTOM_NAME"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& char * IoBOTTOM_NAME(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoFMT_GV""" 4
+.el .IP \f(CWIoFMT_GV\fR 4
+.IX Item "IoFMT_GV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& GV * IoFMT_GV(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoFMT_NAME""" 4
+.el .IP \f(CWIoFMT_NAME\fR 4
+.IX Item "IoFMT_NAME"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& char * IoFMT_NAME(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoLINES""" 4
+.el .IP \f(CWIoLINES\fR 4
+.IX Item "IoLINES"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& IV IoLINES(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoLINES_LEFT""" 4
+.el .IP \f(CWIoLINES_LEFT\fR 4
+.IX Item "IoLINES_LEFT"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& IV IoLINES_LEFT(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoPAGE""" 4
+.el .IP \f(CWIoPAGE\fR 4
+.IX Item "IoPAGE"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& IV IoPAGE(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoPAGE_LEN""" 4
+.el .IP \f(CWIoPAGE_LEN\fR 4
+.IX Item "IoPAGE_LEN"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& IV IoPAGE_LEN(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoTOP_GV""" 4
+.el .IP \f(CWIoTOP_GV\fR 4
+.IX Item "IoTOP_GV"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& GV * IoTOP_GV(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IoTOP_NAME""" 4
+.el .IP \f(CWIoTOP_NAME\fR 4
+.IX Item "IoTOP_NAME"
+Described in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& char * IoTOP_NAME(IO *io)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Signals
+.IX Header "Signals"
+.ie n .IP """HAS_SIGINFO_SI_ADDR""" 4
+.el .IP \f(CWHAS_SIGINFO_SI_ADDR\fR 4
+.IX Xref "HAS_SIGINFO_SI_ADDR"
+.IX Item "HAS_SIGINFO_SI_ADDR"
+This symbol, if defined, indicates that \f(CW\*(C`siginfo_t\*(C'\fR has the
+\&\f(CW\*(C`si_addr\*(C'\fR member
+.ie n .IP """HAS_SIGINFO_SI_BAND""" 4
+.el .IP \f(CWHAS_SIGINFO_SI_BAND\fR 4
+.IX Xref "HAS_SIGINFO_SI_BAND"
+.IX Item "HAS_SIGINFO_SI_BAND"
+This symbol, if defined, indicates that \f(CW\*(C`siginfo_t\*(C'\fR has the
+\&\f(CW\*(C`si_band\*(C'\fR member
+.ie n .IP """HAS_SIGINFO_SI_ERRNO""" 4
+.el .IP \f(CWHAS_SIGINFO_SI_ERRNO\fR 4
+.IX Xref "HAS_SIGINFO_SI_ERRNO"
+.IX Item "HAS_SIGINFO_SI_ERRNO"
+This symbol, if defined, indicates that \f(CW\*(C`siginfo_t\*(C'\fR has the
+\&\f(CW\*(C`si_errno\*(C'\fR member
+.ie n .IP """HAS_SIGINFO_SI_PID""" 4
+.el .IP \f(CWHAS_SIGINFO_SI_PID\fR 4
+.IX Xref "HAS_SIGINFO_SI_PID"
+.IX Item "HAS_SIGINFO_SI_PID"
+This symbol, if defined, indicates that \f(CW\*(C`siginfo_t\*(C'\fR has the
+\&\f(CW\*(C`si_pid\*(C'\fR member
+.ie n .IP """HAS_SIGINFO_SI_STATUS""" 4
+.el .IP \f(CWHAS_SIGINFO_SI_STATUS\fR 4
+.IX Xref "HAS_SIGINFO_SI_STATUS"
+.IX Item "HAS_SIGINFO_SI_STATUS"
+This symbol, if defined, indicates that \f(CW\*(C`siginfo_t\*(C'\fR has the
+\&\f(CW\*(C`si_status\*(C'\fR member
+.ie n .IP """HAS_SIGINFO_SI_UID""" 4
+.el .IP \f(CWHAS_SIGINFO_SI_UID\fR 4
+.IX Xref "HAS_SIGINFO_SI_UID"
+.IX Item "HAS_SIGINFO_SI_UID"
+This symbol, if defined, indicates that \f(CW\*(C`siginfo_t\*(C'\fR has the
+\&\f(CW\*(C`si_uid\*(C'\fR member
+.ie n .IP """HAS_SIGINFO_SI_VALUE""" 4
+.el .IP \f(CWHAS_SIGINFO_SI_VALUE\fR 4
+.IX Xref "HAS_SIGINFO_SI_VALUE"
+.IX Item "HAS_SIGINFO_SI_VALUE"
+This symbol, if defined, indicates that \f(CW\*(C`siginfo_t\*(C'\fR has the
+\&\f(CW\*(C`si_value\*(C'\fR member
+.ie n .IP """PERL_SIGNALS_UNSAFE_FLAG""" 4
+.el .IP \f(CWPERL_SIGNALS_UNSAFE_FLAG\fR 4
+.IX Xref "PERL_SIGNALS_UNSAFE_FLAG"
+.IX Item "PERL_SIGNALS_UNSAFE_FLAG"
+If this bit in \f(CW\*(C`PL_signals\*(C'\fR is set, the system is uing the pre-Perl 5.8
+unsafe signals. See "PERL_SIGNALS" in perlrun and "Deferred Signals
+(Safe Signals)" in perlipc.
+.RS 4
+.Sp
+.Vb 1
+\& U32 PERL_SIGNALS_UNSAFE_FLAG
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """rsignal""" 4
+.el .IP \f(CWrsignal\fR 4
+.IX Xref "rsignal"
+.IX Item "rsignal"
+A wrapper for the C library functions \fBsigaction\fR\|(2) or \fBsignal\fR\|(2).
+Use this instead of those libc functions, as the Perl version gives the
+safest available implementation, and knows things that interact with the
+rest of the perl interpreter.
+.RS 4
+.Sp
+.Vb 1
+\& Sighandler_t rsignal(int i, Sighandler_t t)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """rsignal_state""" 4
+.el .IP \f(CWrsignal_state\fR 4
+.IX Xref "rsignal_state"
+.IX Item "rsignal_state"
+Returns a the current signal handler for signal \f(CW\*(C`signo\*(C'\fR.
+See "\f(CW\*(C`rsignal\*(C'\fR".
+.RS 4
+.Sp
+.Vb 1
+\& Sighandler_t rsignal_state(int i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Sigjmp_buf""" 4
+.el .IP \f(CWSigjmp_buf\fR 4
+.IX Xref "Sigjmp_buf"
+.IX Item "Sigjmp_buf"
+This is the buffer type to be used with Sigsetjmp and Siglongjmp.
+.ie n .IP """Siglongjmp""" 4
+.el .IP \f(CWSiglongjmp\fR 4
+.IX Xref "Siglongjmp"
+.IX Item "Siglongjmp"
+This macro is used in the same way as \f(CWsiglongjmp()\fR, but will invoke
+traditional \f(CWlongjmp()\fR if siglongjmp isn't available.
+See \f(CW"HAS_SIGSETJMP"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void Siglongjmp(jmp_buf env, int val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SIG_NAME""" 4
+.el .IP \f(CWSIG_NAME\fR 4
+.IX Xref "SIG_NAME"
+.IX Item "SIG_NAME"
+This symbol contains a list of signal names in order of
+signal number. This is intended
+to be used as a static array initialization, like this:
+.Sp
+.Vb 1
+\& char *sig_name[] = { SIG_NAME };
+.Ve
+.Sp
+The signals in the list are separated with commas, and each signal
+is surrounded by double quotes. There is no leading \f(CW\*(C`SIG\*(C'\fR in the signal
+name, i.e. \f(CW\*(C`SIGQUIT\*(C'\fR is known as "\f(CW\*(C`QUIT\*(C'\fR".
+Gaps in the signal numbers (up to \f(CW\*(C`NSIG\*(C'\fR) are filled in with \f(CW\*(C`NUMnn\*(C'\fR,
+etc., where nn is the actual signal number (e.g. \f(CW\*(C`NUM37\*(C'\fR).
+The signal number for \f(CW\*(C`sig_name[i]\*(C'\fR is stored in \f(CW\*(C`sig_num[i]\*(C'\fR.
+The last element is 0 to terminate the list with a \f(CW\*(C`NULL\*(C'\fR. This
+corresponds to the 0 at the end of the \f(CW\*(C`sig_name_init\*(C'\fR list.
+Note that this variable is initialized from the \f(CW\*(C`sig_name_init\*(C'\fR,
+not from \f(CW\*(C`sig_name\*(C'\fR (which is unused).
+.ie n .IP """SIG_NUM""" 4
+.el .IP \f(CWSIG_NUM\fR 4
+.IX Xref "SIG_NUM"
+.IX Item "SIG_NUM"
+This symbol contains a list of signal numbers, in the same order as the
+\&\f(CW\*(C`SIG_NAME\*(C'\fR list. It is suitable for static array initialization, as in:
+.Sp
+.Vb 1
+\& int sig_num[] = { SIG_NUM };
+.Ve
+.Sp
+The signals in the list are separated with commas, and the indices
+within that list and the \f(CW\*(C`SIG_NAME\*(C'\fR list match, so it's easy to compute
+the signal name from a number or vice versa at the price of a small
+dynamic linear lookup.
+Duplicates are allowed, but are moved to the end of the list.
+The signal number corresponding to \f(CW\*(C`sig_name[i]\*(C'\fR is \f(CW\*(C`sig_number[i]\*(C'\fR.
+if (i < \f(CW\*(C`NSIG\*(C'\fR) then \f(CW\*(C`sig_number[i]\*(C'\fR == i.
+The last element is 0, corresponding to the 0 at the end of
+the \f(CW\*(C`sig_name_init\*(C'\fR list.
+Note that this variable is initialized from the \f(CW\*(C`sig_num_init\*(C'\fR,
+not from \f(CW\*(C`sig_num\*(C'\fR (which is unused).
+.ie n .IP """Sigsetjmp""" 4
+.el .IP \f(CWSigsetjmp\fR 4
+.IX Xref "Sigsetjmp"
+.IX Item "Sigsetjmp"
+This macro is used in the same way as \f(CWsigsetjmp()\fR, but will invoke
+traditional \f(CWsetjmp()\fR if sigsetjmp isn't available.
+See \f(CW"HAS_SIGSETJMP"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& int Sigsetjmp(jmp_buf env, int savesigs)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SIG_SIZE""" 4
+.el .IP \f(CWSIG_SIZE\fR 4
+.IX Xref "SIG_SIZE"
+.IX Item "SIG_SIZE"
+This variable contains the number of elements of the \f(CW\*(C`SIG_NAME\*(C'\fR
+and \f(CW\*(C`SIG_NUM\*(C'\fR arrays, excluding the final \f(CW\*(C`NULL\*(C'\fR entry.
+.ie n .IP """whichsig""" 4
+.el .IP \f(CWwhichsig\fR 4
+.IX Item "whichsig"
+.PD 0
+.ie n .IP """whichsig_pv""" 4
+.el .IP \f(CWwhichsig_pv\fR 4
+.IX Item "whichsig_pv"
+.ie n .IP """whichsig_pvn""" 4
+.el .IP \f(CWwhichsig_pvn\fR 4
+.IX Item "whichsig_pvn"
+.ie n .IP """whichsig_sv""" 4
+.el .IP \f(CWwhichsig_sv\fR 4
+.IX Xref "whichsig whichsig_pv whichsig_pvn whichsig_sv"
+.IX Item "whichsig_sv"
+.PD
+These all convert a signal name into its corresponding signal number;
+returning \-1 if no corresponding number was found.
+.Sp
+They differ only in the source of the signal name:
+.Sp
+\&\f(CW\*(C`whichsig_pv\*(C'\fR takes the name from the \f(CW\*(C`NUL\*(C'\fR\-terminated string starting at
+\&\f(CW\*(C`sig\*(C'\fR.
+.Sp
+\&\f(CW\*(C`whichsig\*(C'\fR is merely a different spelling, a synonym, of \f(CW\*(C`whichsig_pv\*(C'\fR.
+.Sp
+\&\f(CW\*(C`whichsig_pvn\*(C'\fR takes the name from the string starting at \f(CW\*(C`sig\*(C'\fR, with length
+\&\f(CW\*(C`len\*(C'\fR bytes.
+.Sp
+\&\f(CW\*(C`whichsig_sv\*(C'\fR takes the name from the PV stored in the SV \f(CW\*(C`sigsv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 4
+\& I32 whichsig (const char *sig)
+\& I32 whichsig_pv (const char *sig)
+\& I32 whichsig_pvn(const char *sig, STRLEN len)
+\& I32 whichsig_sv (SV *sigsv)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Site configuration"
+.IX Header "Site configuration"
+These variables give details as to where various libraries,
+installation destinations, \fIetc.\fR, go, as well as what various
+installation options were selected
+.ie n .IP """ARCHLIB""" 4
+.el .IP \f(CWARCHLIB\fR 4
+.IX Xref "ARCHLIB"
+.IX Item "ARCHLIB"
+This variable, if defined, holds the name of the directory in
+which the user wants to put architecture-dependent public
+library files for perl5. It is most often a local directory
+such as \fI/usr/local/lib\fR. Programs using this variable must be
+prepared to deal with filename expansion. If \f(CW\*(C`ARCHLIB\*(C'\fR is the
+same as \f(CW\*(C`PRIVLIB\*(C'\fR, it is not defined, since presumably the
+program already searches \f(CW\*(C`PRIVLIB\*(C'\fR.
+.ie n .IP """ARCHLIB_EXP""" 4
+.el .IP \f(CWARCHLIB_EXP\fR 4
+.IX Xref "ARCHLIB_EXP"
+.IX Item "ARCHLIB_EXP"
+This symbol contains the ~name expanded version of \f(CW\*(C`ARCHLIB\*(C'\fR, to be used
+in programs that are not prepared to deal with ~ expansion at run-time.
+.ie n .IP """ARCHNAME""" 4
+.el .IP \f(CWARCHNAME\fR 4
+.IX Xref "ARCHNAME"
+.IX Item "ARCHNAME"
+This symbol holds a string representing the architecture name.
+It may be used to construct an architecture-dependant pathname
+where library files may be held under a private library, for
+instance.
+.ie n .IP """BIN""" 4
+.el .IP \f(CWBIN\fR 4
+.IX Xref "BIN"
+.IX Item "BIN"
+This symbol holds the path of the bin directory where the package will
+be installed. Program must be prepared to deal with ~name substitution.
+.ie n .IP """BIN_EXP""" 4
+.el .IP \f(CWBIN_EXP\fR 4
+.IX Xref "BIN_EXP"
+.IX Item "BIN_EXP"
+This symbol is the filename expanded version of the \f(CW\*(C`BIN\*(C'\fR symbol, for
+programs that do not want to deal with that at run-time.
+.ie n .IP """INSTALL_USR_BIN_PERL""" 4
+.el .IP \f(CWINSTALL_USR_BIN_PERL\fR 4
+.IX Xref "INSTALL_USR_BIN_PERL"
+.IX Item "INSTALL_USR_BIN_PERL"
+This symbol, if defined, indicates that Perl is to be installed
+also as \fI/usr/bin/perl\fR.
+.ie n .IP """MULTIARCH""" 4
+.el .IP \f(CWMULTIARCH\fR 4
+.IX Xref "MULTIARCH"
+.IX Item "MULTIARCH"
+This symbol, if defined, signifies that the build
+process will produce some binary files that are going to be
+used in a cross-platform environment. This is the case for
+example with the NeXT "fat" binaries that contain executables
+for several \f(CW\*(C`CPUs\*(C'\fR.
+.ie n .IP """PERL_INC_VERSION_LIST""" 4
+.el .IP \f(CWPERL_INC_VERSION_LIST\fR 4
+.IX Xref "PERL_INC_VERSION_LIST"
+.IX Item "PERL_INC_VERSION_LIST"
+This variable specifies the list of subdirectories in over
+which \fIperl.c\fR:\f(CWincpush()\fR and \fIlib/lib.pm\fR will automatically
+search when adding directories to @\f(CW\*(C`INC\*(C'\fR, in a format suitable
+for a C initialization string. See the \f(CW\*(C`inc_version_list\*(C'\fR entry
+in Porting/Glossary for more details.
+.ie n .IP """PERL_OTHERLIBDIRS""" 4
+.el .IP \f(CWPERL_OTHERLIBDIRS\fR 4
+.IX Xref "PERL_OTHERLIBDIRS"
+.IX Item "PERL_OTHERLIBDIRS"
+This variable contains a colon-separated set of paths for the perl
+binary to search for additional library files or modules.
+These directories will be tacked to the end of @\f(CW\*(C`INC\*(C'\fR.
+Perl will automatically search below each path for version\-
+and architecture-specific directories. See \f(CW"PERL_INC_VERSION_LIST"\fR
+for more details.
+.ie n .IP """PERL_RELOCATABLE_INC""" 4
+.el .IP \f(CWPERL_RELOCATABLE_INC\fR 4
+.IX Xref "PERL_RELOCATABLE_INC"
+.IX Item "PERL_RELOCATABLE_INC"
+This symbol, if defined, indicates that we'd like to relocate entries
+in @\f(CW\*(C`INC\*(C'\fR at run time based on the location of the perl binary.
+.ie n .IP """PERL_TARGETARCH""" 4
+.el .IP \f(CWPERL_TARGETARCH\fR 4
+.IX Xref "PERL_TARGETARCH"
+.IX Item "PERL_TARGETARCH"
+This symbol, if defined, indicates the target architecture
+Perl has been cross-compiled to. Undefined if not a cross-compile.
+.ie n .IP """PERL_USE_DEVEL""" 4
+.el .IP \f(CWPERL_USE_DEVEL\fR 4
+.IX Xref "PERL_USE_DEVEL"
+.IX Item "PERL_USE_DEVEL"
+This symbol, if defined, indicates that Perl was configured with
+\&\f(CW\*(C`\-Dusedevel\*(C'\fR, to enable development features. This should not be
+done for production builds.
+.ie n .IP """PERL_VENDORARCH""" 4
+.el .IP \f(CWPERL_VENDORARCH\fR 4
+.IX Xref "PERL_VENDORARCH"
+.IX Item "PERL_VENDORARCH"
+If defined, this symbol contains the name of a private library.
+The library is private in the sense that it needn't be in anyone's
+execution path, but it should be accessible by the world.
+It may have a ~ on the front.
+The standard distribution will put nothing in this directory.
+Vendors who distribute perl may wish to place their own
+architecture-dependent modules and extensions in this directory with
+.Sp
+.Vb 1
+\& MakeMaker Makefile.PL INSTALLDIRS=vendor
+.Ve
+.Sp
+or equivalent. See \f(CW\*(C`INSTALL\*(C'\fR for details.
+.ie n .IP """PERL_VENDORARCH_EXP""" 4
+.el .IP \f(CWPERL_VENDORARCH_EXP\fR 4
+.IX Xref "PERL_VENDORARCH_EXP"
+.IX Item "PERL_VENDORARCH_EXP"
+This symbol contains the ~name expanded version of \f(CW\*(C`PERL_VENDORARCH\*(C'\fR, to be used
+in programs that are not prepared to deal with ~ expansion at run-time.
+.ie n .IP """PERL_VENDORLIB_EXP""" 4
+.el .IP \f(CWPERL_VENDORLIB_EXP\fR 4
+.IX Xref "PERL_VENDORLIB_EXP"
+.IX Item "PERL_VENDORLIB_EXP"
+This symbol contains the ~name expanded version of \f(CW\*(C`VENDORLIB\*(C'\fR, to be used
+in programs that are not prepared to deal with ~ expansion at run-time.
+.ie n .IP """PERL_VENDORLIB_STEM""" 4
+.el .IP \f(CWPERL_VENDORLIB_STEM\fR 4
+.IX Xref "PERL_VENDORLIB_STEM"
+.IX Item "PERL_VENDORLIB_STEM"
+This define is \f(CW\*(C`PERL_VENDORLIB_EXP\*(C'\fR with any trailing version-specific component
+removed. The elements in \f(CW\*(C`inc_version_list\*(C'\fR (\f(CW\*(C`inc_version_list\*(C'\fR.U (part of metaconfig)) can
+be tacked onto this variable to generate a list of directories to search.
+.ie n .IP """PRIVLIB""" 4
+.el .IP \f(CWPRIVLIB\fR 4
+.IX Xref "PRIVLIB"
+.IX Item "PRIVLIB"
+This symbol contains the name of the private library for this package.
+The library is private in the sense that it needn't be in anyone's
+execution path, but it should be accessible by the world. The program
+should be prepared to do ~ expansion.
+.ie n .IP """PRIVLIB_EXP""" 4
+.el .IP \f(CWPRIVLIB_EXP\fR 4
+.IX Xref "PRIVLIB_EXP"
+.IX Item "PRIVLIB_EXP"
+This symbol contains the ~name expanded version of \f(CW\*(C`PRIVLIB\*(C'\fR, to be used
+in programs that are not prepared to deal with ~ expansion at run-time.
+.ie n .IP """SITEARCH""" 4
+.el .IP \f(CWSITEARCH\fR 4
+.IX Xref "SITEARCH"
+.IX Item "SITEARCH"
+This symbol contains the name of the private library for this package.
+The library is private in the sense that it needn't be in anyone's
+execution path, but it should be accessible by the world. The program
+should be prepared to do ~ expansion.
+The standard distribution will put nothing in this directory.
+After perl has been installed, users may install their own local
+architecture-dependent modules in this directory with
+.Sp
+.Vb 1
+\& MakeMaker Makefile.PL
+.Ve
+.Sp
+or equivalent. See \f(CW\*(C`INSTALL\*(C'\fR for details.
+.ie n .IP """SITEARCH_EXP""" 4
+.el .IP \f(CWSITEARCH_EXP\fR 4
+.IX Xref "SITEARCH_EXP"
+.IX Item "SITEARCH_EXP"
+This symbol contains the ~name expanded version of \f(CW\*(C`SITEARCH\*(C'\fR, to be used
+in programs that are not prepared to deal with ~ expansion at run-time.
+.ie n .IP """SITELIB""" 4
+.el .IP \f(CWSITELIB\fR 4
+.IX Xref "SITELIB"
+.IX Item "SITELIB"
+This symbol contains the name of the private library for this package.
+The library is private in the sense that it needn't be in anyone's
+execution path, but it should be accessible by the world. The program
+should be prepared to do ~ expansion.
+The standard distribution will put nothing in this directory.
+After perl has been installed, users may install their own local
+architecture-independent modules in this directory with
+.Sp
+.Vb 1
+\& MakeMaker Makefile.PL
+.Ve
+.Sp
+or equivalent. See \f(CW\*(C`INSTALL\*(C'\fR for details.
+.ie n .IP """SITELIB_EXP""" 4
+.el .IP \f(CWSITELIB_EXP\fR 4
+.IX Xref "SITELIB_EXP"
+.IX Item "SITELIB_EXP"
+This symbol contains the ~name expanded version of \f(CW\*(C`SITELIB\*(C'\fR, to be used
+in programs that are not prepared to deal with ~ expansion at run-time.
+.ie n .IP """SITELIB_STEM""" 4
+.el .IP \f(CWSITELIB_STEM\fR 4
+.IX Xref "SITELIB_STEM"
+.IX Item "SITELIB_STEM"
+This define is \f(CW\*(C`SITELIB_EXP\*(C'\fR with any trailing version-specific component
+removed. The elements in \f(CW\*(C`inc_version_list\*(C'\fR (\f(CW\*(C`inc_version_list\*(C'\fR.U (part of metaconfig)) can
+be tacked onto this variable to generate a list of directories to search.
+.ie n .IP """STARTPERL""" 4
+.el .IP \f(CWSTARTPERL\fR 4
+.IX Xref "STARTPERL"
+.IX Item "STARTPERL"
+This variable contains the string to put in front of a perl
+script to make sure (one hopes) that it runs with perl and not
+some shell.
+.ie n .IP """USE_64_BIT_ALL""" 4
+.el .IP \f(CWUSE_64_BIT_ALL\fR 4
+.IX Xref "USE_64_BIT_ALL"
+.IX Item "USE_64_BIT_ALL"
+This symbol, if defined, indicates that 64\-bit integers should
+be used when available. If not defined, the native integers
+will be used (be they 32 or 64 bits). The maximal possible
+64\-bitness is employed: LP64 or \f(CW\*(C`ILP64\*(C'\fR, meaning that you will
+be able to use more than 2 gigabytes of memory. This mode is
+even more binary incompatible than \f(CW\*(C`USE_64_BIT_INT\*(C'\fR. You may not
+be able to run the resulting executable in a 32\-bit \f(CW\*(C`CPU\*(C'\fR at all or
+you may need at least to reboot your OS to 64\-bit mode.
+.ie n .IP """USE_64_BIT_INT""" 4
+.el .IP \f(CWUSE_64_BIT_INT\fR 4
+.IX Xref "USE_64_BIT_INT"
+.IX Item "USE_64_BIT_INT"
+This symbol, if defined, indicates that 64\-bit integers should
+be used when available. If not defined, the native integers
+will be employed (be they 32 or 64 bits). The minimal possible
+64\-bitness is used, just enough to get 64\-bit integers into Perl.
+This may mean using for example "long longs", while your memory
+may still be limited to 2 gigabytes.
+.ie n .IP """USE_BSD_GETPGRP""" 4
+.el .IP \f(CWUSE_BSD_GETPGRP\fR 4
+.IX Xref "USE_BSD_GETPGRP"
+.IX Item "USE_BSD_GETPGRP"
+This symbol, if defined, indicates that getpgrp needs one
+arguments whereas \f(CW\*(C`USG\*(C'\fR one needs none.
+.ie n .IP """USE_BSD_SETPGRP""" 4
+.el .IP \f(CWUSE_BSD_SETPGRP\fR 4
+.IX Xref "USE_BSD_SETPGRP"
+.IX Item "USE_BSD_SETPGRP"
+This symbol, if defined, indicates that setpgrp needs two
+arguments whereas \f(CW\*(C`USG\*(C'\fR one needs none. See also \f(CW"HAS_SETPGID"\fR
+for a \f(CW\*(C`POSIX\*(C'\fR interface.
+.ie n .IP """USE_C_BACKTRACE""" 4
+.el .IP \f(CWUSE_C_BACKTRACE\fR 4
+.IX Xref "USE_C_BACKTRACE"
+.IX Item "USE_C_BACKTRACE"
+This symbol, if defined, indicates that Perl should
+be built with support for backtrace.
+.ie n .IP """USE_CPLUSPLUS""" 4
+.el .IP \f(CWUSE_CPLUSPLUS\fR 4
+.IX Xref "USE_CPLUSPLUS"
+.IX Item "USE_CPLUSPLUS"
+This symbol, if defined, indicates that a C++ compiler was
+used to compiled Perl and will be used to compile extensions.
+.ie n .IP """USE_CROSS_COMPILE""" 4
+.el .IP \f(CWUSE_CROSS_COMPILE\fR 4
+.IX Xref "USE_CROSS_COMPILE"
+.IX Item "USE_CROSS_COMPILE"
+This symbol, if defined, indicates that Perl is being cross-compiled.
+.ie n .IP """USE_DTRACE""" 4
+.el .IP \f(CWUSE_DTRACE\fR 4
+.IX Xref "USE_DTRACE"
+.IX Item "USE_DTRACE"
+This symbol, if defined, indicates that Perl should
+be built with support for DTrace.
+.ie n .IP """USE_DYNAMIC_LOADING""" 4
+.el .IP \f(CWUSE_DYNAMIC_LOADING\fR 4
+.IX Xref "USE_DYNAMIC_LOADING"
+.IX Item "USE_DYNAMIC_LOADING"
+This symbol, if defined, indicates that dynamic loading of
+some sort is available.
+.ie n .IP """USE_FAST_STDIO""" 4
+.el .IP \f(CWUSE_FAST_STDIO\fR 4
+.IX Xref "USE_FAST_STDIO"
+.IX Item "USE_FAST_STDIO"
+This symbol, if defined, indicates that Perl should
+be built to use 'fast stdio'.
+Defaults to define in Perls 5.8 and earlier, to undef later.
+.ie n .IP """USE_ITHREADS""" 4
+.el .IP \f(CWUSE_ITHREADS\fR 4
+.IX Xref "USE_ITHREADS"
+.IX Item "USE_ITHREADS"
+This symbol, if defined, indicates that Perl should be built to
+use the interpreter-based threading implementation.
+.ie n .IP """USE_KERN_PROC_PATHNAME""" 4
+.el .IP \f(CWUSE_KERN_PROC_PATHNAME\fR 4
+.IX Xref "USE_KERN_PROC_PATHNAME"
+.IX Item "USE_KERN_PROC_PATHNAME"
+This symbol, if defined, indicates that we can use sysctl with
+\&\f(CW\*(C`KERN_PROC_PATHNAME\*(C'\fR to get a full path for the executable, and hence
+convert $^X to an absolute path.
+.ie n .IP """USE_LARGE_FILES""" 4
+.el .IP \f(CWUSE_LARGE_FILES\fR 4
+.IX Xref "USE_LARGE_FILES"
+.IX Item "USE_LARGE_FILES"
+This symbol, if defined, indicates that large file support
+should be used when available.
+.ie n .IP """USE_LONG_DOUBLE""" 4
+.el .IP \f(CWUSE_LONG_DOUBLE\fR 4
+.IX Xref "USE_LONG_DOUBLE"
+.IX Item "USE_LONG_DOUBLE"
+This symbol, if defined, indicates that long doubles should
+be used when available.
+.ie n .IP """USE_MORE_BITS""" 4
+.el .IP \f(CWUSE_MORE_BITS\fR 4
+.IX Xref "USE_MORE_BITS"
+.IX Item "USE_MORE_BITS"
+This symbol, if defined, indicates that 64\-bit interfaces and
+long doubles should be used when available.
+.ie n .IP """USE_NSGETEXECUTABLEPATH""" 4
+.el .IP \f(CWUSE_NSGETEXECUTABLEPATH\fR 4
+.IX Xref "USE_NSGETEXECUTABLEPATH"
+.IX Item "USE_NSGETEXECUTABLEPATH"
+This symbol, if defined, indicates that we can use \f(CW\*(C`_NSGetExecutablePath\*(C'\fR
+and realpath to get a full path for the executable, and hence convert
+$^X to an absolute path.
+.ie n .IP """USE_PERLIO""" 4
+.el .IP \f(CWUSE_PERLIO\fR 4
+.IX Xref "USE_PERLIO"
+.IX Item "USE_PERLIO"
+This symbol, if defined, indicates that the PerlIO abstraction should
+be used throughout. If not defined, stdio should be
+used in a fully backward compatible manner.
+.ie n .IP """USE_QUADMATH""" 4
+.el .IP \f(CWUSE_QUADMATH\fR 4
+.IX Xref "USE_QUADMATH"
+.IX Item "USE_QUADMATH"
+This symbol, if defined, indicates that the quadmath library should
+be used when available.
+.ie n .IP """USE_REENTRANT_API""" 4
+.el .IP \f(CWUSE_REENTRANT_API\fR 4
+.IX Xref "USE_REENTRANT_API"
+.IX Item "USE_REENTRANT_API"
+This symbol, if defined, indicates that Perl should
+try to use the various \f(CW\*(C`_r\*(C'\fR versions of library functions.
+This is extremely experimental.
+.ie n .IP """USE_SEMCTL_SEMID_DS""" 4
+.el .IP \f(CWUSE_SEMCTL_SEMID_DS\fR 4
+.IX Xref "USE_SEMCTL_SEMID_DS"
+.IX Item "USE_SEMCTL_SEMID_DS"
+This symbol, if defined, indicates that \f(CW\*(C`struct semid_ds\*(C'\fR * is
+used for semctl \f(CW\*(C`IPC_STAT\*(C'\fR.
+.ie n .IP """USE_SEMCTL_SEMUN""" 4
+.el .IP \f(CWUSE_SEMCTL_SEMUN\fR 4
+.IX Xref "USE_SEMCTL_SEMUN"
+.IX Item "USE_SEMCTL_SEMUN"
+This symbol, if defined, indicates that \f(CW\*(C`union semun\*(C'\fR is
+used for semctl \f(CW\*(C`IPC_STAT\*(C'\fR.
+.ie n .IP """USE_SITECUSTOMIZE""" 4
+.el .IP \f(CWUSE_SITECUSTOMIZE\fR 4
+.IX Xref "USE_SITECUSTOMIZE"
+.IX Item "USE_SITECUSTOMIZE"
+This symbol, if defined, indicates that sitecustomize should
+be used.
+.ie n .IP """USE_SOCKS""" 4
+.el .IP \f(CWUSE_SOCKS\fR 4
+.IX Xref "USE_SOCKS"
+.IX Item "USE_SOCKS"
+This symbol, if defined, indicates that Perl should
+be built to use socks.
+.ie n .IP """USE_STAT_BLOCKS""" 4
+.el .IP \f(CWUSE_STAT_BLOCKS\fR 4
+.IX Xref "USE_STAT_BLOCKS"
+.IX Item "USE_STAT_BLOCKS"
+This symbol is defined if this system has a stat structure declaring
+\&\f(CW\*(C`st_blksize\*(C'\fR and \f(CW\*(C`st_blocks\*(C'\fR.
+.ie n .IP """USE_STDIO_BASE""" 4
+.el .IP \f(CWUSE_STDIO_BASE\fR 4
+.IX Xref "USE_STDIO_BASE"
+.IX Item "USE_STDIO_BASE"
+This symbol is defined if the \f(CW\*(C`_base\*(C'\fR field (or similar) of the
+stdio \f(CW\*(C`FILE\*(C'\fR structure can be used to access the stdio buffer for
+a file handle. If this is defined, then the \f(CWFILE_base(fp)\fR macro
+will also be defined and should be used to access this field.
+Also, the \f(CWFILE_bufsiz(fp)\fR macro will be defined and should be used
+to determine the number of bytes in the buffer. \f(CW\*(C`USE_STDIO_BASE\*(C'\fR
+will never be defined unless \f(CW\*(C`USE_STDIO_PTR\*(C'\fR is.
+.ie n .IP """USE_STDIO_PTR""" 4
+.el .IP \f(CWUSE_STDIO_PTR\fR 4
+.IX Xref "USE_STDIO_PTR"
+.IX Item "USE_STDIO_PTR"
+This symbol is defined if the \f(CW\*(C`_ptr\*(C'\fR and \f(CW\*(C`_cnt\*(C'\fR fields (or similar)
+of the stdio \f(CW\*(C`FILE\*(C'\fR structure can be used to access the stdio buffer
+for a file handle. If this is defined, then the \f(CWFILE_ptr(fp)\fR
+and \f(CWFILE_cnt(fp)\fR macros will also be defined and should be used
+to access these fields.
+.ie n .IP """USE_STRICT_BY_DEFAULT""" 4
+.el .IP \f(CWUSE_STRICT_BY_DEFAULT\fR 4
+.IX Xref "USE_STRICT_BY_DEFAULT"
+.IX Item "USE_STRICT_BY_DEFAULT"
+This symbol, if defined, enables additional defaults.
+At this time it only enables implicit strict by default.
+.ie n .IP """USE_THREADS""" 4
+.el .IP \f(CWUSE_THREADS\fR 4
+.IX Xref "USE_THREADS"
+.IX Item "USE_THREADS"
+This symbol, if defined, indicates that Perl should
+be built to use threads. At present, it is a synonym for
+and \f(CW\*(C`USE_ITHREADS\*(C'\fR, but eventually the source ought to be
+changed to use this to mean \f(CW\*(C`_any_\*(C'\fR threading implementation.
+.SH "Sockets configuration values"
+.IX Header "Sockets configuration values"
+.ie n .IP """HAS_SOCKADDR_IN6""" 4
+.el .IP \f(CWHAS_SOCKADDR_IN6\fR 4
+.IX Xref "HAS_SOCKADDR_IN6"
+.IX Item "HAS_SOCKADDR_IN6"
+This symbol, if defined, indicates the availability of
+\&\f(CW\*(C`struct sockaddr_in6\*(C'\fR;
+.ie n .IP """HAS_SOCKADDR_SA_LEN""" 4
+.el .IP \f(CWHAS_SOCKADDR_SA_LEN\fR 4
+.IX Xref "HAS_SOCKADDR_SA_LEN"
+.IX Item "HAS_SOCKADDR_SA_LEN"
+This symbol, if defined, indicates that the \f(CW\*(C`struct sockaddr\*(C'\fR
+structure has a member called \f(CW\*(C`sa_len\*(C'\fR, indicating the length of
+the structure.
+.ie n .IP """HAS_SOCKADDR_STORAGE""" 4
+.el .IP \f(CWHAS_SOCKADDR_STORAGE\fR 4
+.IX Xref "HAS_SOCKADDR_STORAGE"
+.IX Item "HAS_SOCKADDR_STORAGE"
+This symbol, if defined, indicates the availability of
+\&\f(CW\*(C`struct sockaddr_storage\*(C'\fR;
+.ie n .IP """HAS_SOCKATMARK""" 4
+.el .IP \f(CWHAS_SOCKATMARK\fR 4
+.IX Xref "HAS_SOCKATMARK"
+.IX Item "HAS_SOCKATMARK"
+This symbol, if defined, indicates that the \f(CW\*(C`sockatmark\*(C'\fR routine is
+available to test whether a socket is at the out-of-band mark.
+.ie n .IP """HAS_SOCKET""" 4
+.el .IP \f(CWHAS_SOCKET\fR 4
+.IX Xref "HAS_SOCKET"
+.IX Item "HAS_SOCKET"
+This symbol, if defined, indicates that the \f(CW\*(C`BSD\*(C'\fR \f(CW\*(C`socket\*(C'\fR interface is
+supported.
+.ie n .IP """HAS_SOCKETPAIR""" 4
+.el .IP \f(CWHAS_SOCKETPAIR\fR 4
+.IX Xref "HAS_SOCKETPAIR"
+.IX Item "HAS_SOCKETPAIR"
+This symbol, if defined, indicates that the \f(CW\*(C`BSD\*(C'\fR \f(CWsocketpair()\fR call is
+supported.
+.ie n .IP """HAS_SOCKS5_INIT""" 4
+.el .IP \f(CWHAS_SOCKS5_INIT\fR 4
+.IX Xref "HAS_SOCKS5_INIT"
+.IX Item "HAS_SOCKS5_INIT"
+This symbol, if defined, indicates that the \f(CW\*(C`socks5_init\*(C'\fR routine is
+available to initialize \f(CW\*(C`SOCKS\*(C'\fR 5.
+.ie n .IP """I_SOCKS""" 4
+.el .IP \f(CWI_SOCKS\fR 4
+.IX Xref "I_SOCKS"
+.IX Item "I_SOCKS"
+This symbol, if defined, indicates that \fIsocks.h\fR exists and
+should be included.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_SOCKS
+\& #include <socks.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_SYS_SOCKIO""" 4
+.el .IP \f(CWI_SYS_SOCKIO\fR 4
+.IX Xref "I_SYS_SOCKIO"
+.IX Item "I_SYS_SOCKIO"
+This symbol, if defined, indicates the \fIsys/sockio.h\fR should be included
+to get socket ioctl options, like \f(CW\*(C`SIOCATMARK\*(C'\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_SYS_SOCKIO
+\& #include <sys_sockio.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Source Filters"
+.IX Header "Source Filters"
+.ie n .IP """apply_builtin_cv_attributes""" 4
+.el .IP \f(CWapply_builtin_cv_attributes\fR 4
+.IX Xref "apply_builtin_cv_attributes"
+.IX Item "apply_builtin_cv_attributes"
+Given an OP_LIST containing attribute definitions, filter it for known builtin
+attributes to apply to the cv, returning a possibly-smaller list containing
+just the remaining ones.
+.RS 4
+.Sp
+.Vb 1
+\& OP * apply_builtin_cv_attributes(CV *cv, OP *attrlist)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """filter_add""" 4
+.el .IP \f(CWfilter_add\fR 4
+.IX Item "filter_add"
+Described in perlfilter.
+.RS 4
+.Sp
+.Vb 1
+\& SV * filter_add(filter_t funcp, SV *datasv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """filter_del""" 4
+.el .IP \f(CWfilter_del\fR 4
+.IX Xref "filter_del"
+.IX Item "filter_del"
+Delete most recently added instance of the filter function argument
+.RS 4
+.Sp
+.Vb 1
+\& void filter_del(filter_t funcp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """filter_read""" 4
+.el .IP \f(CWfilter_read\fR 4
+.IX Item "filter_read"
+Described in perlfilter.
+.RS 4
+.Sp
+.Vb 1
+\& I32 filter_read(int idx, SV *buf_sv, int maxlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """scan_vstring""" 4
+.el .IP \f(CWscan_vstring\fR 4
+.IX Xref "scan_vstring"
+.IX Item "scan_vstring"
+Returns a pointer to the next character after the parsed
+vstring, as well as updating the passed in sv.
+.Sp
+Function must be called like
+.Sp
+.Vb 2
+\& sv = sv_2mortal(newSV(5));
+\& s = scan_vstring(s,e,sv);
+.Ve
+.Sp
+where s and e are the start and end of the string.
+The sv should already be large enough to store the vstring
+passed in, for performance reasons.
+.Sp
+This function may croak if fatal warnings are enabled in the
+calling scope, hence the sv_2mortal in the example (to prevent
+a leak). Make sure to do SvREFCNT_inc afterwards if you use
+sv_2mortal.
+.RS 4
+.Sp
+.Vb 1
+\& char * scan_vstring(const char *s, const char * const e, SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """start_subparse""" 4
+.el .IP \f(CWstart_subparse\fR 4
+.IX Xref "start_subparse"
+.IX Item "start_subparse"
+Set things up for parsing a subroutine.
+.Sp
+If \f(CW\*(C`is_format\*(C'\fR is non-zero, the input is to be considered a format sub
+(a specialised sub used to implement perl's \f(CW\*(C`format\*(C'\fR feature); else a
+normal \f(CW\*(C`sub\*(C'\fR.
+.Sp
+\&\f(CW\*(C`flags\*(C'\fR are added to the flags for \f(CW\*(C`PL_compcv\*(C'\fR. \f(CW\*(C`flags\*(C'\fR may include the
+\&\f(CW\*(C`CVf_IsMETHOD\*(C'\fR bit, which causes the new subroutine to be a method.
+.Sp
+This returns the value of \f(CW\*(C`PL_savestack_ix\*(C'\fR that was in effect upon entry to
+the function;
+.RS 4
+.Sp
+.Vb 1
+\& I32 start_subparse(I32 is_format, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Stack Manipulation Macros"
+.IX Header "Stack Manipulation Macros"
+.ie n .IP """dMARK""" 4
+.el .IP \f(CWdMARK\fR 4
+.IX Xref "dMARK"
+.IX Item "dMARK"
+Declare a stack marker variable, \f(CW\*(C`mark\*(C'\fR, for the XSUB. See \f(CW"MARK"\fR and
+\&\f(CW"dORIGMARK"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& dMARK;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dORIGMARK""" 4
+.el .IP \f(CWdORIGMARK\fR 4
+.IX Xref "dORIGMARK"
+.IX Item "dORIGMARK"
+Saves the original stack mark for the XSUB. See \f(CW"ORIGMARK"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& dORIGMARK;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dSP""" 4
+.el .IP \f(CWdSP\fR 4
+.IX Xref "dSP"
+.IX Item "dSP"
+Declares a local copy of perl's stack pointer for the XSUB, available via
+the \f(CW\*(C`SP\*(C'\fR macro. See \f(CW"SP"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& dSP;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dTARGET""" 4
+.el .IP \f(CWdTARGET\fR 4
+.IX Xref "dTARGET"
+.IX Item "dTARGET"
+Declare that this function uses \f(CW\*(C`TARG\*(C'\fR, and initializes it
+.RS 4
+.Sp
+.Vb 1
+\& dTARGET;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """EXTEND""" 4
+.el .IP \f(CWEXTEND\fR 4
+.IX Xref "EXTEND"
+.IX Item "EXTEND"
+Used to extend the argument stack for an XSUB's return values. Once
+used, guarantees that there is room for at least \f(CW\*(C`nitems\*(C'\fR to be pushed
+onto the stack.
+.RS 4
+.Sp
+.Vb 1
+\& void EXTEND(SP, SSize_t nitems)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MARK""" 4
+.el .IP \f(CWMARK\fR 4
+.IX Xref "MARK"
+.IX Item "MARK"
+Stack marker variable for the XSUB. See \f(CW"dMARK"\fR.
+.ie n .IP """mPUSHi""" 4
+.el .IP \f(CWmPUSHi\fR 4
+.IX Xref "mPUSHi"
+.IX Item "mPUSHi"
+Push an integer onto the stack. The stack must have room for this element.
+Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"PUSHi"\fR, \f(CW"mXPUSHi"\fR and \f(CW"XPUSHi"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mPUSHi(IV iv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mPUSHn""" 4
+.el .IP \f(CWmPUSHn\fR 4
+.IX Xref "mPUSHn"
+.IX Item "mPUSHn"
+Push a double onto the stack. The stack must have room for this element.
+Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"PUSHn"\fR, \f(CW"mXPUSHn"\fR and \f(CW"XPUSHn"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mPUSHn(NV nv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mPUSHp""" 4
+.el .IP \f(CWmPUSHp\fR 4
+.IX Xref "mPUSHp"
+.IX Item "mPUSHp"
+Push a string onto the stack. The stack must have room for this element.
+The \f(CW\*(C`len\*(C'\fR indicates the length of the string. Does not use \f(CW\*(C`TARG\*(C'\fR.
+See also \f(CW"PUSHp"\fR, \f(CW"mXPUSHp"\fR and \f(CW"XPUSHp"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mPUSHp(char* str, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mPUSHpvs""" 4
+.el .IP \f(CWmPUSHpvs\fR 4
+.IX Xref "mPUSHpvs"
+.IX Item "mPUSHpvs"
+A variation on \f(CW\*(C`mPUSHp\*(C'\fR that takes a literal string and calculates its size
+directly.
+.RS 4
+.Sp
+.Vb 1
+\& void mPUSHpvs("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mPUSHs""" 4
+.el .IP \f(CWmPUSHs\fR 4
+.IX Xref "mPUSHs"
+.IX Item "mPUSHs"
+Push an SV onto the stack and mortalizes the SV. The stack must have room
+for this element. Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"PUSHs"\fR and
+\&\f(CW"mXPUSHs"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mPUSHs(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mPUSHu""" 4
+.el .IP \f(CWmPUSHu\fR 4
+.IX Xref "mPUSHu"
+.IX Item "mPUSHu"
+Push an unsigned integer onto the stack. The stack must have room for this
+element. Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"PUSHu"\fR, \f(CW"mXPUSHu"\fR and
+\&\f(CW"XPUSHu"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mPUSHu(UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mXPUSHi""" 4
+.el .IP \f(CWmXPUSHi\fR 4
+.IX Xref "mXPUSHi"
+.IX Item "mXPUSHi"
+Push an integer onto the stack, extending the stack if necessary.
+Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"XPUSHi"\fR, \f(CW"mPUSHi"\fR and \f(CW"PUSHi"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mXPUSHi(IV iv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mXPUSHn""" 4
+.el .IP \f(CWmXPUSHn\fR 4
+.IX Xref "mXPUSHn"
+.IX Item "mXPUSHn"
+Push a double onto the stack, extending the stack if necessary.
+Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"XPUSHn"\fR, \f(CW"mPUSHn"\fR and \f(CW"PUSHn"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mXPUSHn(NV nv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mXPUSHp""" 4
+.el .IP \f(CWmXPUSHp\fR 4
+.IX Xref "mXPUSHp"
+.IX Item "mXPUSHp"
+Push a string onto the stack, extending the stack if necessary. The \f(CW\*(C`len\*(C'\fR
+indicates the length of the string. Does not use \f(CW\*(C`TARG\*(C'\fR. See also
+\&\f(CW"XPUSHp"\fR, \f(CW\*(C`mPUSHp\*(C'\fR and \f(CW\*(C`PUSHp\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mXPUSHp(char* str, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mXPUSHpvs""" 4
+.el .IP \f(CWmXPUSHpvs\fR 4
+.IX Xref "mXPUSHpvs"
+.IX Item "mXPUSHpvs"
+A variation on \f(CW\*(C`mXPUSHp\*(C'\fR that takes a literal string and calculates its size
+directly.
+.RS 4
+.Sp
+.Vb 1
+\& void mXPUSHpvs("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mXPUSHs""" 4
+.el .IP \f(CWmXPUSHs\fR 4
+.IX Xref "mXPUSHs"
+.IX Item "mXPUSHs"
+Push an SV onto the stack, extending the stack if necessary and mortalizes
+the SV. Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"XPUSHs"\fR and \f(CW"mPUSHs"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mXPUSHs(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """mXPUSHu""" 4
+.el .IP \f(CWmXPUSHu\fR 4
+.IX Xref "mXPUSHu"
+.IX Item "mXPUSHu"
+Push an unsigned integer onto the stack, extending the stack if necessary.
+Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"XPUSHu"\fR, \f(CW"mPUSHu"\fR and \f(CW"PUSHu"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mXPUSHu(UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newXSproto""" 4
+.el .IP \f(CWnewXSproto\fR 4
+.IX Xref "newXSproto"
+.IX Item "newXSproto"
+Used by \f(CW\*(C`xsubpp\*(C'\fR to hook up XSUBs as Perl subs. Adds Perl prototypes to
+the subs.
+.ie n .IP """ORIGMARK""" 4
+.el .IP \f(CWORIGMARK\fR 4
+.IX Xref "ORIGMARK"
+.IX Item "ORIGMARK"
+The original stack mark for the XSUB. See \f(CW"dORIGMARK"\fR.
+.ie n .IP """PL_markstack""" 4
+.el .IP \f(CWPL_markstack\fR 4
+.IX Item "PL_markstack"
+Described in perlguts.
+.ie n .IP """PL_markstack_ptr""" 4
+.el .IP \f(CWPL_markstack_ptr\fR 4
+.IX Item "PL_markstack_ptr"
+Described in perlguts.
+.ie n .IP """PL_savestack""" 4
+.el .IP \f(CWPL_savestack\fR 4
+.IX Item "PL_savestack"
+Described in perlguts.
+.ie n .IP """PL_savestack_ix""" 4
+.el .IP \f(CWPL_savestack_ix\fR 4
+.IX Item "PL_savestack_ix"
+Described in perlguts.
+.ie n .IP """PL_scopestack""" 4
+.el .IP \f(CWPL_scopestack\fR 4
+.IX Item "PL_scopestack"
+Described in perlguts.
+.ie n .IP """PL_scopestack_ix""" 4
+.el .IP \f(CWPL_scopestack_ix\fR 4
+.IX Item "PL_scopestack_ix"
+Described in perlguts.
+.ie n .IP """PL_scopestack_name""" 4
+.el .IP \f(CWPL_scopestack_name\fR 4
+.IX Item "PL_scopestack_name"
+Described in perlguts.
+.ie n .IP """PL_stack_base""" 4
+.el .IP \f(CWPL_stack_base\fR 4
+.IX Item "PL_stack_base"
+Described in perlguts.
+.ie n .IP """PL_stack_sp""" 4
+.el .IP \f(CWPL_stack_sp\fR 4
+.IX Item "PL_stack_sp"
+Described in perlguts.
+.ie n .IP """PL_tmps_floor""" 4
+.el .IP \f(CWPL_tmps_floor\fR 4
+.IX Item "PL_tmps_floor"
+Described in perlguts.
+.ie n .IP """PL_tmps_ix""" 4
+.el .IP \f(CWPL_tmps_ix\fR 4
+.IX Item "PL_tmps_ix"
+Described in perlguts.
+.ie n .IP """PL_tmps_stack""" 4
+.el .IP \f(CWPL_tmps_stack\fR 4
+.IX Item "PL_tmps_stack"
+Described in perlguts.
+.ie n .IP """POPi""" 4
+.el .IP \f(CWPOPi\fR 4
+.IX Xref "POPi"
+.IX Item "POPi"
+Pops an integer off the stack.
+.RS 4
+.Sp
+.Vb 1
+\& IV POPi
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POPl""" 4
+.el .IP \f(CWPOPl\fR 4
+.IX Xref "POPl"
+.IX Item "POPl"
+Pops a long off the stack.
+.RS 4
+.Sp
+.Vb 1
+\& long POPl
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POPn""" 4
+.el .IP \f(CWPOPn\fR 4
+.IX Xref "POPn"
+.IX Item "POPn"
+Pops a double off the stack.
+.RS 4
+.Sp
+.Vb 1
+\& NV POPn
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POPp""" 4
+.el .IP \f(CWPOPp\fR 4
+.IX Xref "POPp"
+.IX Item "POPp"
+Pops a string off the stack.
+.RS 4
+.Sp
+.Vb 1
+\& char* POPp
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POPpbytex""" 4
+.el .IP \f(CWPOPpbytex\fR 4
+.IX Xref "POPpbytex"
+.IX Item "POPpbytex"
+Pops a string off the stack which must consist of bytes i.e. characters < 256.
+.RS 4
+.Sp
+.Vb 1
+\& char* POPpbytex
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POPpx""" 4
+.el .IP \f(CWPOPpx\fR 4
+.IX Xref "POPpx"
+.IX Item "POPpx"
+Pops a string off the stack. Identical to POPp. There are two names for
+historical reasons.
+.RS 4
+.Sp
+.Vb 1
+\& char* POPpx
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POPs""" 4
+.el .IP \f(CWPOPs\fR 4
+.IX Xref "POPs"
+.IX Item "POPs"
+Pops an SV off the stack.
+.RS 4
+.Sp
+.Vb 1
+\& SV* POPs
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POPu""" 4
+.el .IP \f(CWPOPu\fR 4
+.IX Xref "POPu"
+.IX Item "POPu"
+Pops an unsigned integer off the stack.
+.RS 4
+.Sp
+.Vb 1
+\& UV POPu
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """POPul""" 4
+.el .IP \f(CWPOPul\fR 4
+.IX Xref "POPul"
+.IX Item "POPul"
+Pops an unsigned long off the stack.
+.RS 4
+.Sp
+.Vb 1
+\& long POPul
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSHi""" 4
+.el .IP \f(CWPUSHi\fR 4
+.IX Xref "PUSHi"
+.IX Item "PUSHi"
+Push an integer onto the stack. The stack must have room for this element.
+Handles 'set' magic. Uses \f(CW\*(C`TARG\*(C'\fR, so \f(CW\*(C`dTARGET\*(C'\fR or \f(CW\*(C`dXSTARG\*(C'\fR should be
+called to declare it. Do not call multiple \f(CW\*(C`TARG\*(C'\fR\-oriented macros to
+return lists from XSUB's \- see \f(CW"mPUSHi"\fR instead. See also \f(CW"XPUSHi"\fR
+and \f(CW"mXPUSHi"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void PUSHi(IV iv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSHMARK""" 4
+.el .IP \f(CWPUSHMARK\fR 4
+.IX Xref "PUSHMARK"
+.IX Item "PUSHMARK"
+Opening bracket for arguments on a callback. See \f(CW"PUTBACK"\fR and
+perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& void PUSHMARK(SP)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSHmortal""" 4
+.el .IP \f(CWPUSHmortal\fR 4
+.IX Xref "PUSHmortal"
+.IX Item "PUSHmortal"
+Push a new mortal SV onto the stack. The stack must have room for this
+element. Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"PUSHs"\fR, \f(CW"XPUSHmortal"\fR and
+\&\f(CW"XPUSHs"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void PUSHmortal
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSHn""" 4
+.el .IP \f(CWPUSHn\fR 4
+.IX Xref "PUSHn"
+.IX Item "PUSHn"
+Push a double onto the stack. The stack must have room for this element.
+Handles 'set' magic. Uses \f(CW\*(C`TARG\*(C'\fR, so \f(CW\*(C`dTARGET\*(C'\fR or \f(CW\*(C`dXSTARG\*(C'\fR should be
+called to declare it. Do not call multiple \f(CW\*(C`TARG\*(C'\fR\-oriented macros to
+return lists from XSUB's \- see \f(CW"mPUSHn"\fR instead. See also \f(CW"XPUSHn"\fR
+and \f(CW"mXPUSHn"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void PUSHn(NV nv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSHp""" 4
+.el .IP \f(CWPUSHp\fR 4
+.IX Xref "PUSHp"
+.IX Item "PUSHp"
+Push a string onto the stack. The stack must have room for this element.
+The \f(CW\*(C`len\*(C'\fR indicates the length of the string. Handles 'set' magic. Uses
+\&\f(CW\*(C`TARG\*(C'\fR, so \f(CW\*(C`dTARGET\*(C'\fR or \f(CW\*(C`dXSTARG\*(C'\fR should be called to declare it. Do not
+call multiple \f(CW\*(C`TARG\*(C'\fR\-oriented macros to return lists from XSUB's \- see
+\&\f(CW"mPUSHp"\fR instead. See also \f(CW"XPUSHp"\fR and \f(CW"mXPUSHp"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void PUSHp(char* str, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSHpvs""" 4
+.el .IP \f(CWPUSHpvs\fR 4
+.IX Xref "PUSHpvs"
+.IX Item "PUSHpvs"
+A variation on \f(CW\*(C`PUSHp\*(C'\fR that takes a literal string and calculates its size
+directly.
+.RS 4
+.Sp
+.Vb 1
+\& void PUSHpvs("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSHs""" 4
+.el .IP \f(CWPUSHs\fR 4
+.IX Xref "PUSHs"
+.IX Item "PUSHs"
+Push an SV onto the stack. The stack must have room for this element.
+Does not handle 'set' magic. Does not use \f(CW\*(C`TARG\*(C'\fR. See also
+\&\f(CW"PUSHmortal"\fR, \f(CW"XPUSHs"\fR, and \f(CW"XPUSHmortal"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void PUSHs(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUSHu""" 4
+.el .IP \f(CWPUSHu\fR 4
+.IX Xref "PUSHu"
+.IX Item "PUSHu"
+Push an unsigned integer onto the stack. The stack must have room for this
+element. Handles 'set' magic. Uses \f(CW\*(C`TARG\*(C'\fR, so \f(CW\*(C`dTARGET\*(C'\fR or \f(CW\*(C`dXSTARG\*(C'\fR
+should be called to declare it. Do not call multiple \f(CW\*(C`TARG\*(C'\fR\-oriented
+macros to return lists from XSUB's \- see \f(CW"mPUSHu"\fR instead. See also
+\&\f(CW"XPUSHu"\fR and \f(CW"mXPUSHu"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void PUSHu(UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PUTBACK""" 4
+.el .IP \f(CWPUTBACK\fR 4
+.IX Xref "PUTBACK"
+.IX Item "PUTBACK"
+Closing bracket for XSUB arguments. This is usually handled by \f(CW\*(C`xsubpp\*(C'\fR.
+See \f(CW"PUSHMARK"\fR and perlcall for other uses.
+.RS 4
+.Sp
+.Vb 1
+\& PUTBACK;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVEt_INT""" 4
+.el .IP \f(CWSAVEt_INT\fR 4
+.IX Item "SAVEt_INT"
+Described in perlguts.
+.ie n .IP """SP""" 4
+.el .IP \f(CWSP\fR 4
+.IX Xref "SP"
+.IX Item "SP"
+Stack pointer. This is usually handled by \f(CW\*(C`xsubpp\*(C'\fR. See \f(CW"dSP"\fR and
+\&\f(CW\*(C`SPAGAIN\*(C'\fR.
+.ie n .IP """SPAGAIN""" 4
+.el .IP \f(CWSPAGAIN\fR 4
+.IX Xref "SPAGAIN"
+.IX Item "SPAGAIN"
+Refetch the stack pointer. Used after a callback. See perlcall.
+.RS 4
+.Sp
+.Vb 1
+\& SPAGAIN;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SSNEW""" 4
+.el .IP \f(CWSSNEW\fR 4
+.IX Item "SSNEW"
+.PD 0
+.ie n .IP """SSNEWa""" 4
+.el .IP \f(CWSSNEWa\fR 4
+.IX Item "SSNEWa"
+.ie n .IP """SSNEWat""" 4
+.el .IP \f(CWSSNEWat\fR 4
+.IX Item "SSNEWat"
+.ie n .IP """SSNEWt""" 4
+.el .IP \f(CWSSNEWt\fR 4
+.IX Xref "SSNEW SSNEWa SSNEWat SSNEWt"
+.IX Item "SSNEWt"
+.PD
+These temporarily allocates data on the savestack, returning an SSize_t index into
+the savestack, because a pointer would get broken if the savestack is moved on
+reallocation. Use "\f(CW\*(C`SSPTR\*(C'\fR" to convert the returned index into a pointer.
+.Sp
+The forms differ in that plain \f(CW\*(C`SSNEW\*(C'\fR allocates \f(CW\*(C`size\*(C'\fR bytes;
+\&\f(CW\*(C`SSNEWt\*(C'\fR and \f(CW\*(C`SSNEWat\*(C'\fR allocate \f(CW\*(C`size\*(C'\fR objects, each of which is type
+\&\f(CW\*(C`type\*(C'\fR;
+and <SSNEWa> and \f(CW\*(C`SSNEWat\*(C'\fR make sure to align the new data to an \f(CW\*(C`align\*(C'\fR
+boundary. The most useful value for the alignment is likely to be
+"\f(CW\*(C`MEM_ALIGNBYTES\*(C'\fR". The alignment will be preserved through savestack
+reallocation \fBonly\fR if realloc returns data aligned to a size divisible by
+"align"!
+.RS 4
+.Sp
+.Vb 4
+\& SSize_t SSNEW (Size_t size)
+\& SSize_t SSNEWa (Size_t_size, Size_t align)
+\& SSize_t SSNEWat(Size_t_size, type, Size_t align)
+\& SSize_t SSNEWt (Size_t size, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SSPTR""" 4
+.el .IP \f(CWSSPTR\fR 4
+.IX Item "SSPTR"
+.PD 0
+.ie n .IP """SSPTRt""" 4
+.el .IP \f(CWSSPTRt\fR 4
+.IX Xref "SSPTR SSPTRt"
+.IX Item "SSPTRt"
+.PD
+These convert the \f(CW\*(C`index\*(C'\fR returned by L/<\f(CW\*(C`SSNEW\*(C'\fR> and kin into actual pointers.
+.Sp
+The difference is that \f(CW\*(C`SSPTR\*(C'\fR casts the result to \f(CW\*(C`type\*(C'\fR, and \f(CW\*(C`SSPTRt\*(C'\fR
+casts it to a pointer of that \f(CW\*(C`type\*(C'\fR.
+.RS 4
+.Sp
+.Vb 2
+\& type SSPTR (SSize_t index, type)
+\& type * SSPTRt(SSize_t index, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """TARG""" 4
+.el .IP \f(CWTARG\fR 4
+.IX Xref "TARG"
+.IX Item "TARG"
+\&\f(CW\*(C`TARG\*(C'\fR is short for "target". It is an entry in the pad that an OPs
+\&\f(CW\*(C`op_targ\*(C'\fR refers to. It is scratchpad space, often used as a return
+value for the OP, but some use it for other purposes.
+.RS 4
+.Sp
+.Vb 1
+\& TARG;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """TOPs""" 4
+.el .IP \f(CWTOPs\fR 4
+.IX Item "TOPs"
+Described in perlguts.
+.ie n .IP """XPUSHi""" 4
+.el .IP \f(CWXPUSHi\fR 4
+.IX Xref "XPUSHi"
+.IX Item "XPUSHi"
+Push an integer onto the stack, extending the stack if necessary. Handles
+\&'set' magic. Uses \f(CW\*(C`TARG\*(C'\fR, so \f(CW\*(C`dTARGET\*(C'\fR or \f(CW\*(C`dXSTARG\*(C'\fR should be called to
+declare it. Do not call multiple \f(CW\*(C`TARG\*(C'\fR\-oriented macros to return lists
+from XSUB's \- see \f(CW"mXPUSHi"\fR instead. See also \f(CW"PUSHi"\fR and
+\&\f(CW"mPUSHi"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XPUSHi(IV iv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XPUSHmortal""" 4
+.el .IP \f(CWXPUSHmortal\fR 4
+.IX Xref "XPUSHmortal"
+.IX Item "XPUSHmortal"
+Push a new mortal SV onto the stack, extending the stack if necessary.
+Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"XPUSHs"\fR, \f(CW"PUSHmortal"\fR and
+\&\f(CW"PUSHs"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XPUSHmortal
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XPUSHn""" 4
+.el .IP \f(CWXPUSHn\fR 4
+.IX Xref "XPUSHn"
+.IX Item "XPUSHn"
+Push a double onto the stack, extending the stack if necessary. Handles
+\&'set' magic. Uses \f(CW\*(C`TARG\*(C'\fR, so \f(CW\*(C`dTARGET\*(C'\fR or \f(CW\*(C`dXSTARG\*(C'\fR should be called to
+declare it. Do not call multiple \f(CW\*(C`TARG\*(C'\fR\-oriented macros to return lists
+from XSUB's \- see \f(CW"mXPUSHn"\fR instead. See also \f(CW"PUSHn"\fR and
+\&\f(CW"mPUSHn"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XPUSHn(NV nv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XPUSHp""" 4
+.el .IP \f(CWXPUSHp\fR 4
+.IX Xref "XPUSHp"
+.IX Item "XPUSHp"
+Push a string onto the stack, extending the stack if necessary. The \f(CW\*(C`len\*(C'\fR
+indicates the length of the string. Handles 'set' magic. Uses \f(CW\*(C`TARG\*(C'\fR, so
+\&\f(CW\*(C`dTARGET\*(C'\fR or \f(CW\*(C`dXSTARG\*(C'\fR should be called to declare it. Do not call
+multiple \f(CW\*(C`TARG\*(C'\fR\-oriented macros to return lists from XSUB's \- see
+\&\f(CW"mXPUSHp"\fR instead. See also \f(CW"PUSHp"\fR and \f(CW"mPUSHp"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XPUSHp(char* str, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XPUSHpvs""" 4
+.el .IP \f(CWXPUSHpvs\fR 4
+.IX Xref "XPUSHpvs"
+.IX Item "XPUSHpvs"
+A variation on \f(CW\*(C`XPUSHp\*(C'\fR that takes a literal string and calculates its size
+directly.
+.RS 4
+.Sp
+.Vb 1
+\& void XPUSHpvs("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XPUSHs""" 4
+.el .IP \f(CWXPUSHs\fR 4
+.IX Xref "XPUSHs"
+.IX Item "XPUSHs"
+Push an SV onto the stack, extending the stack if necessary. Does not
+handle 'set' magic. Does not use \f(CW\*(C`TARG\*(C'\fR. See also \f(CW"XPUSHmortal"\fR,
+\&\f(CW\*(C`PUSHs\*(C'\fR and \f(CW\*(C`PUSHmortal\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XPUSHs(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XPUSHu""" 4
+.el .IP \f(CWXPUSHu\fR 4
+.IX Xref "XPUSHu"
+.IX Item "XPUSHu"
+Push an unsigned integer onto the stack, extending the stack if necessary.
+Handles 'set' magic. Uses \f(CW\*(C`TARG\*(C'\fR, so \f(CW\*(C`dTARGET\*(C'\fR or \f(CW\*(C`dXSTARG\*(C'\fR should be
+called to declare it. Do not call multiple \f(CW\*(C`TARG\*(C'\fR\-oriented macros to
+return lists from XSUB's \- see \f(CW"mXPUSHu"\fR instead. See also \f(CW"PUSHu"\fR and
+\&\f(CW"mPUSHu"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XPUSHu(UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XS_APIVERSION_BOOTCHECK""" 4
+.el .IP \f(CWXS_APIVERSION_BOOTCHECK\fR 4
+.IX Xref "XS_APIVERSION_BOOTCHECK"
+.IX Item "XS_APIVERSION_BOOTCHECK"
+Macro to verify that the perl api version an XS module has been compiled against
+matches the api version of the perl interpreter it's being loaded into.
+.RS 4
+.Sp
+.Vb 1
+\& XS_APIVERSION_BOOTCHECK;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN""" 4
+.el .IP \f(CWXSRETURN\fR 4
+.IX Xref "XSRETURN"
+.IX Item "XSRETURN"
+Return from XSUB, indicating number of items on the stack. This is usually
+handled by \f(CW\*(C`xsubpp\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XSRETURN(int nitems)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN_EMPTY""" 4
+.el .IP \f(CWXSRETURN_EMPTY\fR 4
+.IX Xref "XSRETURN_EMPTY"
+.IX Item "XSRETURN_EMPTY"
+Return an empty list from an XSUB immediately.
+.RS 4
+.Sp
+.Vb 1
+\& XSRETURN_EMPTY;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN_IV""" 4
+.el .IP \f(CWXSRETURN_IV\fR 4
+.IX Xref "XSRETURN_IV"
+.IX Item "XSRETURN_IV"
+Return an integer from an XSUB immediately. Uses \f(CW\*(C`XST_mIV\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XSRETURN_IV(IV iv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN_NO""" 4
+.el .IP \f(CWXSRETURN_NO\fR 4
+.IX Xref "XSRETURN_NO"
+.IX Item "XSRETURN_NO"
+Return \f(CW&PL_sv_no\fR from an XSUB immediately. Uses \f(CW\*(C`XST_mNO\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& XSRETURN_NO;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN_NV""" 4
+.el .IP \f(CWXSRETURN_NV\fR 4
+.IX Xref "XSRETURN_NV"
+.IX Item "XSRETURN_NV"
+Return a double from an XSUB immediately. Uses \f(CW\*(C`XST_mNV\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XSRETURN_NV(NV nv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN_PV""" 4
+.el .IP \f(CWXSRETURN_PV\fR 4
+.IX Xref "XSRETURN_PV"
+.IX Item "XSRETURN_PV"
+Return a copy of a string from an XSUB immediately. Uses \f(CW\*(C`XST_mPV\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XSRETURN_PV(char* str)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN_UNDEF""" 4
+.el .IP \f(CWXSRETURN_UNDEF\fR 4
+.IX Xref "XSRETURN_UNDEF"
+.IX Item "XSRETURN_UNDEF"
+Return \f(CW&PL_sv_undef\fR from an XSUB immediately. Uses \f(CW\*(C`XST_mUNDEF\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& XSRETURN_UNDEF;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN_UV""" 4
+.el .IP \f(CWXSRETURN_UV\fR 4
+.IX Xref "XSRETURN_UV"
+.IX Item "XSRETURN_UV"
+Return an integer from an XSUB immediately. Uses \f(CW\*(C`XST_mUV\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void XSRETURN_UV(IV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XSRETURN_YES""" 4
+.el .IP \f(CWXSRETURN_YES\fR 4
+.IX Xref "XSRETURN_YES"
+.IX Item "XSRETURN_YES"
+Return \f(CW&PL_sv_yes\fR from an XSUB immediately. Uses \f(CW\*(C`XST_mYES\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& XSRETURN_YES;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XST_mIV""" 4
+.el .IP \f(CWXST_mIV\fR 4
+.IX Xref "XST_mIV"
+.IX Item "XST_mIV"
+Place an integer into the specified position \f(CW\*(C`pos\*(C'\fR on the stack. The
+value is stored in a new mortal SV.
+.RS 4
+.Sp
+.Vb 1
+\& void XST_mIV(int pos, IV iv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XST_mNO""" 4
+.el .IP \f(CWXST_mNO\fR 4
+.IX Xref "XST_mNO"
+.IX Item "XST_mNO"
+Place \f(CW&PL_sv_no\fR into the specified position \f(CW\*(C`pos\*(C'\fR on the
+stack.
+.RS 4
+.Sp
+.Vb 1
+\& void XST_mNO(int pos)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XST_mNV""" 4
+.el .IP \f(CWXST_mNV\fR 4
+.IX Xref "XST_mNV"
+.IX Item "XST_mNV"
+Place a double into the specified position \f(CW\*(C`pos\*(C'\fR on the stack. The value
+is stored in a new mortal SV.
+.RS 4
+.Sp
+.Vb 1
+\& void XST_mNV(int pos, NV nv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XST_mPV""" 4
+.el .IP \f(CWXST_mPV\fR 4
+.IX Xref "XST_mPV"
+.IX Item "XST_mPV"
+Place a copy of a string into the specified position \f(CW\*(C`pos\*(C'\fR on the stack.
+The value is stored in a new mortal SV.
+.RS 4
+.Sp
+.Vb 1
+\& void XST_mPV(int pos, char* str)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XST_mUNDEF""" 4
+.el .IP \f(CWXST_mUNDEF\fR 4
+.IX Xref "XST_mUNDEF"
+.IX Item "XST_mUNDEF"
+Place \f(CW&PL_sv_undef\fR into the specified position \f(CW\*(C`pos\*(C'\fR on the
+stack.
+.RS 4
+.Sp
+.Vb 1
+\& void XST_mUNDEF(int pos)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XST_mUV""" 4
+.el .IP \f(CWXST_mUV\fR 4
+.IX Xref "XST_mUV"
+.IX Item "XST_mUV"
+Place an unsigned integer into the specified position \f(CW\*(C`pos\*(C'\fR on the stack. The
+value is stored in a new mortal SV.
+.RS 4
+.Sp
+.Vb 1
+\& void XST_mUV(int pos, UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XST_mYES""" 4
+.el .IP \f(CWXST_mYES\fR 4
+.IX Xref "XST_mYES"
+.IX Item "XST_mYES"
+Place \f(CW&PL_sv_yes\fR into the specified position \f(CW\*(C`pos\*(C'\fR on the
+stack.
+.RS 4
+.Sp
+.Vb 1
+\& void XST_mYES(int pos)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """XS_VERSION""" 4
+.el .IP \f(CWXS_VERSION\fR 4
+.IX Xref "XS_VERSION"
+.IX Item "XS_VERSION"
+The version identifier for an XS module. This is usually
+handled automatically by \f(CW\*(C`ExtUtils::MakeMaker\*(C'\fR. See
+\&\f(CW"XS_VERSION_BOOTCHECK"\fR.
+.ie n .IP """XS_VERSION_BOOTCHECK""" 4
+.el .IP \f(CWXS_VERSION_BOOTCHECK\fR 4
+.IX Xref "XS_VERSION_BOOTCHECK"
+.IX Item "XS_VERSION_BOOTCHECK"
+Macro to verify that a PM module's \f(CW$VERSION\fR variable matches the XS
+module's \f(CW\*(C`XS_VERSION\*(C'\fR variable. This is usually handled automatically by
+\&\f(CW\*(C`xsubpp\*(C'\fR. See "The VERSIONCHECK: Keyword" in perlxs.
+.RS 4
+.Sp
+.Vb 1
+\& XS_VERSION_BOOTCHECK;
+.Ve
+.RE
+.RS 4
+.RE
+.SH "String Handling"
+.IX Header "String Handling"
+See also \f(CW"Unicode Support"\fR.
+.ie n .IP """CAT2""" 4
+.el .IP \f(CWCAT2\fR 4
+.IX Xref "CAT2"
+.IX Item "CAT2"
+This macro concatenates 2 tokens together.
+.RS 4
+.Sp
+.Vb 1
+\& token CAT2(token x, token y)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Copy""" 4
+.el .IP \f(CWCopy\fR 4
+.IX Item "Copy"
+.PD 0
+.ie n .IP """CopyD""" 4
+.el .IP \f(CWCopyD\fR 4
+.IX Xref "Copy CopyD"
+.IX Item "CopyD"
+.PD
+The XSUB-writer's interface to the C \f(CW\*(C`memcpy\*(C'\fR function. The \f(CW\*(C`src\*(C'\fR is the
+source, \f(CW\*(C`dest\*(C'\fR is the destination, \f(CW\*(C`nitems\*(C'\fR is the number of items, and
+\&\f(CW\*(C`type\*(C'\fR is the type. May fail on overlapping copies. See also \f(CW"Move"\fR.
+.Sp
+\&\f(CW\*(C`CopyD\*(C'\fR is like \f(CW\*(C`Copy\*(C'\fR but returns \f(CW\*(C`dest\*(C'\fR. Useful
+for encouraging compilers to tail-call
+optimise.
+.RS 4
+.Sp
+.Vb 2
+\& void Copy (void* src, void* dest, int nitems, type)
+\& void * CopyD(void* src, void* dest, int nitems, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """delimcpy""" 4
+.el .IP \f(CWdelimcpy\fR 4
+.IX Xref "delimcpy"
+.IX Item "delimcpy"
+Copy a source buffer to a destination buffer, stopping at (but not including)
+the first occurrence in the source of an unescaped (defined below) delimiter
+byte, \f(CW\*(C`delim\*(C'\fR. The source is the bytes between \f(CW\*(C`from\*(C'\fR\ and\ \f(CW\*(C`from_end\*(C'\fR\ \-\ 1. Similarly, the dest is \f(CW\*(C`to\*(C'\fR up to \f(CW\*(C`to_end\*(C'\fR.
+.Sp
+The number of bytes copied is written to \f(CW*retlen\fR.
+.Sp
+Returns the position of the first uncopied \f(CW\*(C`delim\*(C'\fR in the \f(CW\*(C`from\*(C'\fR buffer, but
+if there is no such occurrence before \f(CW\*(C`from_end\*(C'\fR, then \f(CW\*(C`from_end\*(C'\fR is returned,
+and the entire buffer \f(CW\*(C`from\*(C'\fR\ ..\ \f(CW\*(C`from_end\*(C'\fR\ \-\ 1 is copied.
+.Sp
+If there is room in the destination available after the copy, an extra
+terminating safety \f(CW\*(C`NUL\*(C'\fR byte is appended (not included in the returned
+length).
+.Sp
+The error case is if the destination buffer is not large enough to accommodate
+everything that should be copied. In this situation, a value larger than
+\&\f(CW\*(C`to_end\*(C'\fR\ \-\ \f(CW\*(C`to\*(C'\fR is written to \f(CW*retlen\fR, and as much of the source as
+fits will be written to the destination. Not having room for the safety \f(CW\*(C`NUL\*(C'\fR
+is not considered an error.
+.Sp
+In the following examples, let \f(CW\*(C`x\*(C'\fR be the delimiter, and \f(CW0\fR represent a \f(CW\*(C`NUL\*(C'\fR
+byte (\fBNOT\fR the digit \f(CW0\fR). Then we would have
+.Sp
+.Vb 2
+\& Source Destination
+\& abcxdef abc0
+.Ve
+.Sp
+provided the destination buffer is at least 4 bytes long.
+.Sp
+An escaped delimiter is one which is immediately preceded by a single
+backslash. Escaped delimiters are copied, and the copy continues past the
+delimiter; the backslash is not copied:
+.Sp
+.Vb 2
+\& Source Destination
+\& abc\exdef abcxdef0
+.Ve
+.Sp
+(provided the destination buffer is at least 8 bytes long).
+.Sp
+It's actually somewhat more complicated than that. A sequence of any odd number
+of backslashes escapes the following delimiter, and the copy continues with
+exactly one of the backslashes stripped.
+.Sp
+.Vb 4
+\& Source Destination
+\& abc\exdef abcxdef0
+\& abc\e\e\exdef abc\e\exdef0
+\& abc\e\e\e\e\exdef abc\e\e\e\exdef0
+.Ve
+.Sp
+(as always, if the destination is large enough)
+.Sp
+An even number of preceding backslashes does not escape the delimiter, so that
+the copy stops just before it, and includes all the backslashes (no stripping;
+zero is considered even):
+.Sp
+.Vb 4
+\& Source Destination
+\& abcxdef abc0
+\& abc\e\exdef abc\e\e0
+\& abc\e\e\e\exdef abc\e\e\e\e0
+.Ve
+.RS 4
+.Sp
+.Vb 3
+\& char * delimcpy(char *to, const char *to_end, const char *from,
+\& const char *from_end, const int delim,
+\& I32 *retlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """do_join""" 4
+.el .IP \f(CWdo_join\fR 4
+.IX Xref "do_join"
+.IX Item "do_join"
+This performs a Perl \f(CW\*(C`join\*(C'\fR, placing the joined output
+into \f(CW\*(C`sv\*(C'\fR.
+.Sp
+The elements to join are in SVs, stored in a C array of pointers to SVs, from
+\&\f(CW**mark\fR to \f(CW\*(C`**sp\ \-\ 1\*(C'\fR. Hence \f(CW*mark\fR is a reference to the first SV.
+Each SV will be coerced into a PV if not one already.
+.Sp
+\&\f(CW\*(C`delim\*(C'\fR contains the string (or coerced into a string) that is to separate
+each of the joined elements.
+.Sp
+If any component is in UTF\-8, the result will be as well, and all non\-UTF\-8
+components will be converted to UTF\-8 as necessary.
+.Sp
+Magic and tainting are handled.
+.RS 4
+.Sp
+.Vb 1
+\& void do_join(SV *sv, SV *delim, SV **mark, SV **sp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """do_sprintf""" 4
+.el .IP \f(CWdo_sprintf\fR 4
+.IX Xref "do_sprintf"
+.IX Item "do_sprintf"
+This performs a Perl \f(CW\*(C`sprintf\*(C'\fR placing the string output
+into \f(CW\*(C`sv\*(C'\fR.
+.Sp
+The elements to format are in SVs, stored in a C array of pointers to SVs of
+length \f(CW\*(C`len\*(C'\fR> and beginning at \f(CW**sarg\fR. The element referenced by \f(CW*sarg\fR
+is the format.
+.Sp
+Magic and tainting are handled.
+.RS 4
+.Sp
+.Vb 1
+\& void do_sprintf(SV *sv, SSize_t len, SV **sarg)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """fbm_compile""" 4
+.el .IP \f(CWfbm_compile\fR 4
+.IX Xref "fbm_compile"
+.IX Item "fbm_compile"
+Analyzes the string in order to make fast searches on it using \f(CWfbm_instr()\fR
+\&\-\- the Boyer-Moore algorithm.
+.RS 4
+.Sp
+.Vb 1
+\& void fbm_compile(SV *sv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """fbm_instr""" 4
+.el .IP \f(CWfbm_instr\fR 4
+.IX Xref "fbm_instr"
+.IX Item "fbm_instr"
+Returns the location of the SV in the string delimited by \f(CW\*(C`big\*(C'\fR and
+\&\f(CW\*(C`bigend\*(C'\fR (\f(CW\*(C`bigend\*(C'\fR) is the char following the last char).
+It returns \f(CW\*(C`NULL\*(C'\fR if the string can't be found. The \f(CW\*(C`sv\*(C'\fR
+does not have to be \f(CW\*(C`fbm_compiled\*(C'\fR, but the search will not be as fast
+then.
+.RS 4
+.Sp
+.Vb 2
+\& char * fbm_instr(unsigned char *big, unsigned char *bigend,
+\& SV *littlestr, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """foldEQ""" 4
+.el .IP \f(CWfoldEQ\fR 4
+.IX Xref "foldEQ"
+.IX Item "foldEQ"
+Returns true if the leading \f(CW\*(C`len\*(C'\fR bytes of the strings \f(CW\*(C`s1\*(C'\fR and \f(CW\*(C`s2\*(C'\fR are the
+same
+case-insensitively; false otherwise. Uppercase and lowercase ASCII range bytes
+match themselves and their opposite case counterparts. Non-cased and non-ASCII
+range bytes match only themselves.
+.RS 4
+.Sp
+.Vb 1
+\& I32 foldEQ(const char *a, const char *b, I32 len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ibcmp""" 4
+.el .IP \f(CWibcmp\fR 4
+.IX Xref "ibcmp"
+.IX Item "ibcmp"
+This is a synonym for \f(CW\*(C`(!\ foldEQ())\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& I32 ibcmp(const char *a, const char *b, I32 len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ibcmp_locale""" 4
+.el .IP \f(CWibcmp_locale\fR 4
+.IX Xref "ibcmp_locale"
+.IX Item "ibcmp_locale"
+This is a synonym for \f(CW\*(C`(!\ foldEQ_locale())\*(C'\fR
+.RS 4
+.Sp
+.Vb 1
+\& I32 ibcmp_locale(const char *a, const char *b, I32 len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ibcmp_utf8""" 4
+.el .IP \f(CWibcmp_utf8\fR 4
+.IX Xref "ibcmp_utf8"
+.IX Item "ibcmp_utf8"
+This is a synonym for \f(CW\*(C`(!\ foldEQ_utf8())\*(C'\fR
+.RS 4
+.Sp
+.Vb 2
+\& I32 ibcmp_utf8(const char *s1, char **pe1, UV l1, bool u1,
+\& const char *s2, char **pe2, UV l2, bool u2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """instr""" 4
+.el .IP \f(CWinstr\fR 4
+.IX Xref "instr"
+.IX Item "instr"
+Same as \fBstrstr\fR\|(3), which finds and returns a pointer to the first occurrence
+of the NUL-terminated substring \f(CW\*(C`little\*(C'\fR in the NUL-terminated string \f(CW\*(C`big\*(C'\fR,
+returning NULL if not found. The terminating NUL bytes are not compared.
+.RS 4
+.Sp
+.Vb 1
+\& char * instr(const char *big, const char *little)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """memCHRs""" 4
+.el .IP \f(CWmemCHRs\fR 4
+.IX Xref "memCHRs"
+.IX Item "memCHRs"
+Returns the position of the first occurrence of the byte \f(CW\*(C`c\*(C'\fR in the literal
+string \f(CW"list"\fR, or NULL if \f(CW\*(C`c\*(C'\fR doesn't appear in \f(CW"list"\fR. All bytes are
+treated as unsigned char. Thus this macro can be used to determine if \f(CW\*(C`c\*(C'\fR is
+in a set of particular characters. Unlike \fBstrchr\fR\|(3), it works even if \f(CW\*(C`c\*(C'\fR
+is \f(CW\*(C`NUL\*(C'\fR (and the set doesn't include \f(CW\*(C`NUL\*(C'\fR).
+.RS 4
+.Sp
+.Vb 1
+\& bool memCHRs("list", char c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """memEQ""" 4
+.el .IP \f(CWmemEQ\fR 4
+.IX Xref "memEQ"
+.IX Item "memEQ"
+Test two buffers (which may contain embedded \f(CW\*(C`NUL\*(C'\fR characters, to see if they
+are equal. The \f(CW\*(C`len\*(C'\fR parameter indicates the number of bytes to compare.
+Returns true or false. It is undefined behavior if either of the buffers
+doesn't contain at least \f(CW\*(C`len\*(C'\fR bytes.
+.RS 4
+.Sp
+.Vb 1
+\& bool memEQ(char* s1, char* s2, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """memEQs""" 4
+.el .IP \f(CWmemEQs\fR 4
+.IX Xref "memEQs"
+.IX Item "memEQs"
+Like "memEQ", but the second string is a literal enclosed in double quotes,
+\&\f(CW\*(C`l1\*(C'\fR gives the number of bytes in \f(CW\*(C`s1\*(C'\fR.
+Returns true or false.
+.RS 4
+.Sp
+.Vb 1
+\& bool memEQs(char* s1, STRLEN l1, "s2")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """memNE""" 4
+.el .IP \f(CWmemNE\fR 4
+.IX Xref "memNE"
+.IX Item "memNE"
+Test two buffers (which may contain embedded \f(CW\*(C`NUL\*(C'\fR characters, to see if they
+are not equal. The \f(CW\*(C`len\*(C'\fR parameter indicates the number of bytes to compare.
+Returns true or false. It is undefined behavior if either of the buffers
+doesn't contain at least \f(CW\*(C`len\*(C'\fR bytes.
+.RS 4
+.Sp
+.Vb 1
+\& bool memNE(char* s1, char* s2, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """memNEs""" 4
+.el .IP \f(CWmemNEs\fR 4
+.IX Xref "memNEs"
+.IX Item "memNEs"
+Like "memNE", but the second string is a literal enclosed in double quotes,
+\&\f(CW\*(C`l1\*(C'\fR gives the number of bytes in \f(CW\*(C`s1\*(C'\fR.
+Returns true or false.
+.RS 4
+.Sp
+.Vb 1
+\& bool memNEs(char* s1, STRLEN l1, "s2")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Move""" 4
+.el .IP \f(CWMove\fR 4
+.IX Item "Move"
+.PD 0
+.ie n .IP """MoveD""" 4
+.el .IP \f(CWMoveD\fR 4
+.IX Xref "Move MoveD"
+.IX Item "MoveD"
+.PD
+The XSUB-writer's interface to the C \f(CW\*(C`memmove\*(C'\fR function. The \f(CW\*(C`src\*(C'\fR is the
+source, \f(CW\*(C`dest\*(C'\fR is the destination, \f(CW\*(C`nitems\*(C'\fR is the number of items, and
+\&\f(CW\*(C`type\*(C'\fR is the type. Can do overlapping moves. See also \f(CW"Copy"\fR.
+.Sp
+\&\f(CW\*(C`MoveD\*(C'\fR is like \f(CW\*(C`Move\*(C'\fR but returns \f(CW\*(C`dest\*(C'\fR. Useful
+for encouraging compilers to tail-call
+optimise.
+.RS 4
+.Sp
+.Vb 2
+\& void Move (void* src, void* dest, int nitems, type)
+\& void * MoveD(void* src, void* dest, int nitems, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_snprintf""" 4
+.el .IP \f(CWmy_snprintf\fR 4
+.IX Xref "my_snprintf"
+.IX Item "my_snprintf"
+The C library \f(CW\*(C`snprintf\*(C'\fR functionality, if available and
+standards-compliant (uses \f(CW\*(C`vsnprintf\*(C'\fR, actually). However, if the
+\&\f(CW\*(C`vsnprintf\*(C'\fR is not available, will unfortunately use the unsafe
+\&\f(CW\*(C`vsprintf\*(C'\fR which can overrun the buffer (there is an overrun check,
+but that may be too late). Consider using \f(CW\*(C`sv_vcatpvf\*(C'\fR instead, or
+getting \f(CW\*(C`vsnprintf\*(C'\fR.
+.RS 4
+.Sp
+.Vb 2
+\& int my_snprintf(char *buffer, const Size_t len,
+\& const char *format, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_sprintf""" 4
+.el .IP \f(CWmy_sprintf\fR 4
+.IX Xref "my_sprintf"
+.IX Item "my_sprintf"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`my_sprintf\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Do NOT use this due to the possibility of overflowing \f(CW\*(C`buffer\*(C'\fR. Instead use
+\&\fBmy_snprintf()\fR
+.RS 4
+.Sp
+.Vb 1
+\& int my_sprintf(NN char *buffer, NN const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_strnlen""" 4
+.el .IP \f(CWmy_strnlen\fR 4
+.IX Xref "my_strnlen"
+.IX Item "my_strnlen"
+The C library \f(CW\*(C`strnlen\*(C'\fR if available, or a Perl implementation of it.
+.Sp
+\&\f(CWmy_strnlen()\fR computes the length of the string, up to \f(CW\*(C`maxlen\*(C'\fR
+characters. It will never attempt to address more than \f(CW\*(C`maxlen\*(C'\fR
+characters, making it suitable for use with strings that are not
+guaranteed to be NUL-terminated.
+.RS 4
+.Sp
+.Vb 1
+\& Size_t my_strnlen(const char *str, Size_t maxlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_vsnprintf""" 4
+.el .IP \f(CWmy_vsnprintf\fR 4
+.IX Xref "my_vsnprintf"
+.IX Item "my_vsnprintf"
+The C library \f(CW\*(C`vsnprintf\*(C'\fR if available and standards-compliant.
+However, if the \f(CW\*(C`vsnprintf\*(C'\fR is not available, will unfortunately
+use the unsafe \f(CW\*(C`vsprintf\*(C'\fR which can overrun the buffer (there is an
+overrun check, but that may be too late). Consider using
+\&\f(CW\*(C`sv_vcatpvf\*(C'\fR instead, or getting \f(CW\*(C`vsnprintf\*(C'\fR.
+.RS 4
+.Sp
+.Vb 2
+\& int my_vsnprintf(char *buffer, const Size_t len,
+\& const char *format, va_list ap)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """NewCopy""" 4
+.el .IP \f(CWNewCopy\fR 4
+.IX Xref "NewCopy"
+.IX Item "NewCopy"
+Combines \fBNewx()\fR and \fBCopy()\fR into a single macro. Dest will be allocated
+using \fBNewx()\fR and then src will be copied into it.
+.RS 4
+.Sp
+.Vb 1
+\& void NewCopy(void* src, void* dest, int nitems, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ninstr""" 4
+.el .IP \f(CWninstr\fR 4
+.IX Xref "ninstr"
+.IX Item "ninstr"
+Find the first (leftmost) occurrence of a sequence of bytes within another
+sequence. This is the Perl version of \f(CWstrstr()\fR, extended to handle
+arbitrary sequences, potentially containing embedded \f(CW\*(C`NUL\*(C'\fR characters (\f(CW\*(C`NUL\*(C'\fR
+is what the initial \f(CW\*(C`n\*(C'\fR in the function name stands for; some systems have an
+equivalent, \f(CWmemmem()\fR, but with a somewhat different API).
+.Sp
+Another way of thinking about this function is finding a needle in a haystack.
+\&\f(CW\*(C`big\*(C'\fR points to the first byte in the haystack. \f(CW\*(C`big_end\*(C'\fR points to one byte
+beyond the final byte in the haystack. \f(CW\*(C`little\*(C'\fR points to the first byte in
+the needle. \f(CW\*(C`little_end\*(C'\fR points to one byte beyond the final byte in the
+needle. All the parameters must be non\-\f(CW\*(C`NULL\*(C'\fR.
+.Sp
+The function returns \f(CW\*(C`NULL\*(C'\fR if there is no occurrence of \f(CW\*(C`little\*(C'\fR within
+\&\f(CW\*(C`big\*(C'\fR. If \f(CW\*(C`little\*(C'\fR is the empty string, \f(CW\*(C`big\*(C'\fR is returned.
+.Sp
+Because this function operates at the byte level, and because of the inherent
+characteristics of UTF\-8 (or UTF-EBCDIC), it will work properly if both the
+needle and the haystack are strings with the same UTF\-8ness, but not if the
+UTF\-8ness differs.
+.RS 4
+.Sp
+.Vb 2
+\& char * ninstr(const char *big, const char *bigend,
+\& const char *little, const char *lend)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Nullch""" 4
+.el .IP \f(CWNullch\fR 4
+.IX Xref "Nullch"
+.IX Item "Nullch"
+Null character pointer. (No longer available when \f(CW\*(C`PERL_CORE\*(C'\fR is
+defined.)
+.ie n .IP """PL_na""" 4
+.el .IP \f(CWPL_na\fR 4
+.IX Xref "PL_na"
+.IX Item "PL_na"
+A scratch pad variable in which to store a \f(CW\*(C`STRLEN\*(C'\fR value. If would have been
+better named something like \f(CW\*(C`PL_temp_strlen\*(C'\fR.
+.Sp
+It is is typically used with \f(CW\*(C`SvPV\*(C'\fR when one is actually planning to discard
+the returned length, (hence the length is "Not Applicable", which is how this
+variable got its name).
+.Sp
+\&\fBBUT BEWARE\fR, if this is used in a situation where something that is using it
+is in a call stack with something else that is using it, this variable would
+get zapped, leading to hard-to-diagnose errors.
+.Sp
+It is usually more efficient to either declare a local variable and use that
+instead, or to use the \f(CW\*(C`SvPV_nolen\*(C'\fR macro.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN PL_na
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """rninstr""" 4
+.el .IP \f(CWrninstr\fR 4
+.IX Xref "rninstr"
+.IX Item "rninstr"
+Like \f(CW"ninstr"\fR, but instead finds the final (rightmost) occurrence of a
+sequence of bytes within another sequence, returning \f(CW\*(C`NULL\*(C'\fR if there is no
+such occurrence.
+.RS 4
+.Sp
+.Vb 2
+\& char * rninstr(const char *big, const char *bigend,
+\& const char *little, const char *lend)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """savepv""" 4
+.el .IP \f(CWsavepv\fR 4
+.IX Xref "savepv"
+.IX Item "savepv"
+Perl's version of \f(CWstrdup()\fR. Returns a pointer to a newly allocated
+string which is a duplicate of \f(CW\*(C`pv\*(C'\fR. The size of the string is
+determined by \f(CWstrlen()\fR, which means it may not contain embedded \f(CW\*(C`NUL\*(C'\fR
+characters and must have a trailing \f(CW\*(C`NUL\*(C'\fR. To prevent memory leaks, the
+memory allocated for the new string needs to be freed when no longer needed.
+This can be done with the \f(CW"Safefree"\fR function, or
+\&\f(CW\*(C`SAVEFREEPV\*(C'\fR.
+.Sp
+On some platforms, Windows for example, all allocated memory owned by a thread
+is deallocated when that thread ends. So if you need that not to happen, you
+need to use the shared memory functions, such as \f(CW"savesharedpv"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& char * savepv(const char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """savepvn""" 4
+.el .IP \f(CWsavepvn\fR 4
+.IX Xref "savepvn"
+.IX Item "savepvn"
+Perl's version of what \f(CWstrndup()\fR would be if it existed. Returns a
+pointer to a newly allocated string which is a duplicate of the first
+\&\f(CW\*(C`len\*(C'\fR bytes from \f(CW\*(C`pv\*(C'\fR, plus a trailing
+\&\f(CW\*(C`NUL\*(C'\fR byte. The memory allocated for
+the new string can be freed with the \f(CWSafefree()\fR function.
+.Sp
+On some platforms, Windows for example, all allocated memory owned by a thread
+is deallocated when that thread ends. So if you need that not to happen, you
+need to use the shared memory functions, such as \f(CW"savesharedpvn"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& char * savepvn(const char *pv, Size_t len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """savepvs""" 4
+.el .IP \f(CWsavepvs\fR 4
+.IX Xref "savepvs"
+.IX Item "savepvs"
+Like \f(CW\*(C`savepvn\*(C'\fR, but takes a literal string instead of a
+string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& char* savepvs("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """savesharedpv""" 4
+.el .IP \f(CWsavesharedpv\fR 4
+.IX Xref "savesharedpv"
+.IX Item "savesharedpv"
+A version of \f(CWsavepv()\fR which allocates the duplicate string in memory
+which is shared between threads.
+.RS 4
+.Sp
+.Vb 1
+\& char * savesharedpv(const char *pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """savesharedpvn""" 4
+.el .IP \f(CWsavesharedpvn\fR 4
+.IX Xref "savesharedpvn"
+.IX Item "savesharedpvn"
+A version of \f(CWsavepvn()\fR which allocates the duplicate string in memory
+which is shared between threads. (With the specific difference that a \f(CW\*(C`NULL\*(C'\fR
+pointer is not acceptable)
+.RS 4
+.Sp
+.Vb 1
+\& char * savesharedpvn(const char * const pv, const STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """savesharedpvs""" 4
+.el .IP \f(CWsavesharedpvs\fR 4
+.IX Xref "savesharedpvs"
+.IX Item "savesharedpvs"
+A version of \f(CWsavepvs()\fR which allocates the duplicate string in memory
+which is shared between threads.
+.RS 4
+.Sp
+.Vb 1
+\& char* savesharedpvs("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """savesharedsvpv""" 4
+.el .IP \f(CWsavesharedsvpv\fR 4
+.IX Xref "savesharedsvpv"
+.IX Item "savesharedsvpv"
+A version of \f(CWsavesharedpv()\fR which allocates the duplicate string in
+memory which is shared between threads.
+.RS 4
+.Sp
+.Vb 1
+\& char * savesharedsvpv(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """savesvpv""" 4
+.el .IP \f(CWsavesvpv\fR 4
+.IX Xref "savesvpv"
+.IX Item "savesvpv"
+A version of \f(CWsavepv()\fR/\f(CWsavepvn()\fR which gets the string to duplicate from
+the passed in SV using \f(CWSvPV()\fR
+.Sp
+On some platforms, Windows for example, all allocated memory owned by a thread
+is deallocated when that thread ends. So if you need that not to happen, you
+need to use the shared memory functions, such as \f(CW"savesharedsvpv"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& char * savesvpv(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """strEQ""" 4
+.el .IP \f(CWstrEQ\fR 4
+.IX Xref "strEQ"
+.IX Item "strEQ"
+Test two \f(CW\*(C`NUL\*(C'\fR\-terminated strings to see if they are equal. Returns true or
+false.
+.RS 4
+.Sp
+.Vb 1
+\& bool strEQ(char* s1, char* s2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """strGE""" 4
+.el .IP \f(CWstrGE\fR 4
+.IX Xref "strGE"
+.IX Item "strGE"
+Test two \f(CW\*(C`NUL\*(C'\fR\-terminated strings to see if the first, \f(CW\*(C`s1\*(C'\fR, is greater than
+or equal to the second, \f(CW\*(C`s2\*(C'\fR. Returns true or false.
+.RS 4
+.Sp
+.Vb 1
+\& bool strGE(char* s1, char* s2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """strGT""" 4
+.el .IP \f(CWstrGT\fR 4
+.IX Xref "strGT"
+.IX Item "strGT"
+Test two \f(CW\*(C`NUL\*(C'\fR\-terminated strings to see if the first, \f(CW\*(C`s1\*(C'\fR, is greater than
+the second, \f(CW\*(C`s2\*(C'\fR. Returns true or false.
+.RS 4
+.Sp
+.Vb 1
+\& bool strGT(char* s1, char* s2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """STRINGIFY""" 4
+.el .IP \f(CWSTRINGIFY\fR 4
+.IX Xref "STRINGIFY"
+.IX Item "STRINGIFY"
+This macro surrounds its token with double quotes.
+.RS 4
+.Sp
+.Vb 1
+\& string STRINGIFY(token x)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """strLE""" 4
+.el .IP \f(CWstrLE\fR 4
+.IX Xref "strLE"
+.IX Item "strLE"
+Test two \f(CW\*(C`NUL\*(C'\fR\-terminated strings to see if the first, \f(CW\*(C`s1\*(C'\fR, is less than or
+equal to the second, \f(CW\*(C`s2\*(C'\fR. Returns true or false.
+.RS 4
+.Sp
+.Vb 1
+\& bool strLE(char* s1, char* s2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """STRLEN""" 4
+.el .IP \f(CWSTRLEN\fR 4
+.IX Item "STRLEN"
+Described in perlguts.
+.ie n .IP """strLT""" 4
+.el .IP \f(CWstrLT\fR 4
+.IX Xref "strLT"
+.IX Item "strLT"
+Test two \f(CW\*(C`NUL\*(C'\fR\-terminated strings to see if the first, \f(CW\*(C`s1\*(C'\fR, is less than the
+second, \f(CW\*(C`s2\*(C'\fR. Returns true or false.
+.RS 4
+.Sp
+.Vb 1
+\& bool strLT(char* s1, char* s2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """strNE""" 4
+.el .IP \f(CWstrNE\fR 4
+.IX Xref "strNE"
+.IX Item "strNE"
+Test two \f(CW\*(C`NUL\*(C'\fR\-terminated strings to see if they are different. Returns true
+or false.
+.RS 4
+.Sp
+.Vb 1
+\& bool strNE(char* s1, char* s2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """strnEQ""" 4
+.el .IP \f(CWstrnEQ\fR 4
+.IX Xref "strnEQ"
+.IX Item "strnEQ"
+Test two \f(CW\*(C`NUL\*(C'\fR\-terminated strings to see if they are equal. The \f(CW\*(C`len\*(C'\fR
+parameter indicates the number of bytes to compare. Returns true or false. (A
+wrapper for \f(CW\*(C`strncmp\*(C'\fR).
+.RS 4
+.Sp
+.Vb 1
+\& bool strnEQ(char* s1, char* s2, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """strnNE""" 4
+.el .IP \f(CWstrnNE\fR 4
+.IX Xref "strnNE"
+.IX Item "strnNE"
+Test two \f(CW\*(C`NUL\*(C'\fR\-terminated strings to see if they are different. The \f(CW\*(C`len\*(C'\fR
+parameter indicates the number of bytes to compare. Returns true or false. (A
+wrapper for \f(CW\*(C`strncmp\*(C'\fR).
+.RS 4
+.Sp
+.Vb 1
+\& bool strnNE(char* s1, char* s2, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """STR_WITH_LEN""" 4
+.el .IP \f(CWSTR_WITH_LEN\fR 4
+.IX Xref "STR_WITH_LEN"
+.IX Item "STR_WITH_LEN"
+Returns two comma separated tokens of the input literal string, and its length.
+This is convenience macro which helps out in some API calls.
+Note that it can't be used as an argument to macros or functions that under
+some configurations might be macros, which means that it requires the full
+Perl_xxx(aTHX_ ...) form for any API calls where it's used.
+.RS 4
+.Sp
+.Vb 1
+\& pair STR_WITH_LEN("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Zero""" 4
+.el .IP \f(CWZero\fR 4
+.IX Item "Zero"
+.PD 0
+.ie n .IP """ZeroD""" 4
+.el .IP \f(CWZeroD\fR 4
+.IX Xref "Zero ZeroD"
+.IX Item "ZeroD"
+.PD
+The XSUB-writer's interface to the C \f(CW\*(C`memzero\*(C'\fR function. The \f(CW\*(C`dest\*(C'\fR is the
+destination, \f(CW\*(C`nitems\*(C'\fR is the number of items, and \f(CW\*(C`type\*(C'\fR is the type.
+.Sp
+\&\f(CW\*(C`ZeroD\*(C'\fR is like \f(CW\*(C`Zero\*(C'\fR but returns \f(CW\*(C`dest\*(C'\fR. Useful
+for encouraging compilers to tail-call
+optimise.
+.RS 4
+.Sp
+.Vb 2
+\& void Zero (void* dest, int nitems, type)
+\& void * ZeroD(void* dest, int nitems, type)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "SV Flags"
+.IX Header "SV Flags"
+.ie n .IP """SVt_IV""" 4
+.el .IP \f(CWSVt_IV\fR 4
+.IX Xref "SVt_IV"
+.IX Item "SVt_IV"
+Type flag for scalars. See "svtype".
+.ie n .IP """SVt_NULL""" 4
+.el .IP \f(CWSVt_NULL\fR 4
+.IX Xref "SVt_NULL"
+.IX Item "SVt_NULL"
+Type flag for scalars. See "svtype".
+.ie n .IP """SVt_NV""" 4
+.el .IP \f(CWSVt_NV\fR 4
+.IX Xref "SVt_NV"
+.IX Item "SVt_NV"
+Type flag for scalars. See "svtype".
+.ie n .IP """SVt_PV""" 4
+.el .IP \f(CWSVt_PV\fR 4
+.IX Xref "SVt_PV"
+.IX Item "SVt_PV"
+Type flag for scalars. See "svtype".
+.ie n .IP """SVt_PVAV""" 4
+.el .IP \f(CWSVt_PVAV\fR 4
+.IX Xref "SVt_PVAV"
+.IX Item "SVt_PVAV"
+Type flag for arrays. See "svtype".
+.ie n .IP """SVt_PVCV""" 4
+.el .IP \f(CWSVt_PVCV\fR 4
+.IX Xref "SVt_PVCV"
+.IX Item "SVt_PVCV"
+Type flag for subroutines. See "svtype".
+.ie n .IP """SVt_PVFM""" 4
+.el .IP \f(CWSVt_PVFM\fR 4
+.IX Xref "SVt_PVFM"
+.IX Item "SVt_PVFM"
+Type flag for formats. See "svtype".
+.ie n .IP """SVt_PVGV""" 4
+.el .IP \f(CWSVt_PVGV\fR 4
+.IX Xref "SVt_PVGV"
+.IX Item "SVt_PVGV"
+Type flag for typeglobs. See "svtype".
+.ie n .IP """SVt_PVHV""" 4
+.el .IP \f(CWSVt_PVHV\fR 4
+.IX Xref "SVt_PVHV"
+.IX Item "SVt_PVHV"
+Type flag for hashes. See "svtype".
+.ie n .IP """SVt_PVIO""" 4
+.el .IP \f(CWSVt_PVIO\fR 4
+.IX Xref "SVt_PVIO"
+.IX Item "SVt_PVIO"
+Type flag for I/O objects. See "svtype".
+.ie n .IP """SVt_PVIV""" 4
+.el .IP \f(CWSVt_PVIV\fR 4
+.IX Xref "SVt_PVIV"
+.IX Item "SVt_PVIV"
+Type flag for scalars. See "svtype".
+.ie n .IP """SVt_PVLV""" 4
+.el .IP \f(CWSVt_PVLV\fR 4
+.IX Xref "SVt_PVLV"
+.IX Item "SVt_PVLV"
+Type flag for scalars. See "svtype".
+.ie n .IP """SVt_PVMG""" 4
+.el .IP \f(CWSVt_PVMG\fR 4
+.IX Xref "SVt_PVMG"
+.IX Item "SVt_PVMG"
+Type flag for scalars. See "svtype".
+.ie n .IP """SVt_PVNV""" 4
+.el .IP \f(CWSVt_PVNV\fR 4
+.IX Xref "SVt_PVNV"
+.IX Item "SVt_PVNV"
+Type flag for scalars. See "svtype".
+.ie n .IP """SVt_PVOBJ""" 4
+.el .IP \f(CWSVt_PVOBJ\fR 4
+.IX Xref "SVt_PVOBJ"
+.IX Item "SVt_PVOBJ"
+NOTE: \f(CW\*(C`SVt_PVOBJ\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Type flag for object instances. See "svtype".
+.ie n .IP """SVt_REGEXP""" 4
+.el .IP \f(CWSVt_REGEXP\fR 4
+.IX Xref "SVt_REGEXP"
+.IX Item "SVt_REGEXP"
+Type flag for regular expressions. See "svtype".
+.ie n .IP """svtype""" 4
+.el .IP \f(CWsvtype\fR 4
+.IX Xref "svtype"
+.IX Item "svtype"
+An enum of flags for Perl types. These are found in the file \fIsv.h\fR
+in the \f(CW\*(C`svtype\*(C'\fR enum. Test these flags with the \f(CW\*(C`SvTYPE\*(C'\fR macro.
+.Sp
+The types are:
+.Sp
+.Vb 10
+\& SVt_NULL
+\& SVt_IV
+\& SVt_NV
+\& SVt_RV
+\& SVt_PV
+\& SVt_PVIV
+\& SVt_PVNV
+\& SVt_PVMG
+\& SVt_INVLIST
+\& SVt_REGEXP
+\& SVt_PVGV
+\& SVt_PVLV
+\& SVt_PVAV
+\& SVt_PVHV
+\& SVt_PVCV
+\& SVt_PVFM
+\& SVt_PVIO
+\& SVt_PVOBJ
+.Ve
+.Sp
+These are most easily explained from the bottom up.
+.Sp
+\&\f(CW\*(C`SVt_PVOBJ\*(C'\fR is for object instances of the new `use feature 'class'` kind.
+\&\f(CW\*(C`SVt_PVIO\*(C'\fR is for I/O objects, \f(CW\*(C`SVt_PVFM\*(C'\fR for formats, \f(CW\*(C`SVt_PVCV\*(C'\fR for
+subroutines, \f(CW\*(C`SVt_PVHV\*(C'\fR for hashes and \f(CW\*(C`SVt_PVAV\*(C'\fR for arrays.
+.Sp
+All the others are scalar types, that is, things that can be bound to a
+\&\f(CW\*(C`$\*(C'\fR variable. For these, the internal types are mostly orthogonal to
+types in the Perl language.
+.Sp
+Hence, checking \f(CW\*(C`SvTYPE(sv) < SVt_PVAV\*(C'\fR is the best way to see whether
+something is a scalar.
+.Sp
+\&\f(CW\*(C`SVt_PVGV\*(C'\fR represents a typeglob. If \f(CW\*(C`!SvFAKE(sv)\*(C'\fR, then it is a real,
+incoercible typeglob. If \f(CWSvFAKE(sv)\fR, then it is a scalar to which a
+typeglob has been assigned. Assigning to it again will stop it from being
+a typeglob. \f(CW\*(C`SVt_PVLV\*(C'\fR represents a scalar that delegates to another scalar
+behind the scenes. It is used, e.g., for the return value of \f(CW\*(C`substr\*(C'\fR and
+for tied hash and array elements. It can hold any scalar value, including
+a typeglob. \f(CW\*(C`SVt_REGEXP\*(C'\fR is for regular
+expressions. \f(CW\*(C`SVt_INVLIST\*(C'\fR is for Perl
+core internal use only.
+.Sp
+\&\f(CW\*(C`SVt_PVMG\*(C'\fR represents a "normal" scalar (not a typeglob, regular expression,
+or delegate). Since most scalars do not need all the internal fields of a
+PVMG, we save memory by allocating smaller structs when possible. All the
+other types are just simpler forms of \f(CW\*(C`SVt_PVMG\*(C'\fR, with fewer internal fields.
+\&\f(CW\*(C`SVt_NULL\*(C'\fR can only hold undef. \f(CW\*(C`SVt_IV\*(C'\fR can hold undef, an integer, or a
+reference. (\f(CW\*(C`SVt_RV\*(C'\fR is an alias for \f(CW\*(C`SVt_IV\*(C'\fR, which exists for backward
+compatibility.) \f(CW\*(C`SVt_NV\*(C'\fR can hold undef or a double. (In builds that support
+headless NVs, these could also hold a reference via a suitable offset, in the
+same way that SVt_IV does, but this is not currently supported and seems to
+be a rare use case.) \f(CW\*(C`SVt_PV\*(C'\fR can hold \f(CW\*(C`undef\*(C'\fR, a string, or a reference.
+\&\f(CW\*(C`SVt_PVIV\*(C'\fR is a superset of \f(CW\*(C`SVt_PV\*(C'\fR and \f(CW\*(C`SVt_IV\*(C'\fR. \f(CW\*(C`SVt_PVNV\*(C'\fR is a
+superset of \f(CW\*(C`SVt_PV\*(C'\fR and \f(CW\*(C`SVt_NV\*(C'\fR. \f(CW\*(C`SVt_PVMG\*(C'\fR can hold anything \f(CW\*(C`SVt_PVNV\*(C'\fR
+can hold, but it may also be blessed or magical.
+.SH "SV Handling"
+.IX Xref "SV_CATBYTES SV_CATUTF8 SV_COW_DROP_PV SV_FORCE_UTF8_UPGRADE SV_GMAGIC SV_HAS_TRAILING_NUL SV_IMMEDIATE_UNREF SV_NOSTEAL SV_SMAGIC SV_UTF8_NO_ENCODING SVs_TEMP"
+.IX Header "SV Handling"
+.ie n .IP """AV_FROM_REF""" 4
+.el .IP \f(CWAV_FROM_REF\fR 4
+.IX Item "AV_FROM_REF"
+.PD 0
+.ie n .IP """CV_FROM_REF""" 4
+.el .IP \f(CWCV_FROM_REF\fR 4
+.IX Item "CV_FROM_REF"
+.ie n .IP """HV_FROM_REF""" 4
+.el .IP \f(CWHV_FROM_REF\fR 4
+.IX Xref "AV_FROM_REF CV_FROM_REF HV_FROM_REF"
+.IX Item "HV_FROM_REF"
+.PD
+The \f(CW\*(C`\fR\f(CI*\fR\f(CWV_FROM_REF\*(C'\fR macros extract the \f(CWSvRV()\fR from a given reference SV
+and return a suitably-cast to pointer to the referenced SV. When running
+under \f(CW\*(C`\-DDEBUGGING\*(C'\fR, assertions are also applied that check that \fIref\fR is
+definitely a reference SV that refers to an SV of the right type.
+.RS 4
+.Sp
+.Vb 3
+\& AV * AV_FROM_REF(SV * ref)
+\& CV * CV_FROM_REF(SV * ref)
+\& HV * HV_FROM_REF(SV * ref)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """BOOL_INTERNALS_sv_isbool""" 4
+.el .IP \f(CWBOOL_INTERNALS_sv_isbool\fR 4
+.IX Xref "BOOL_INTERNALS_sv_isbool"
+.IX Item "BOOL_INTERNALS_sv_isbool"
+Checks if a \f(CWSvBoolFlagsOK()\fR sv is a bool. \fBNote\fR that it is the
+caller's responsibility to ensure that the sv is \f(CWSvBoolFlagsOK()\fR before
+calling this. This is only useful in specialized logic like
+serialization code where performance is critical and the flags have
+already been checked to be correct. Almost always you should be using
+\&\f(CWsv_isbool(sv)\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& bool BOOL_INTERNALS_sv_isbool(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """BOOL_INTERNALS_sv_isbool_false""" 4
+.el .IP \f(CWBOOL_INTERNALS_sv_isbool_false\fR 4
+.IX Xref "BOOL_INTERNALS_sv_isbool_false"
+.IX Item "BOOL_INTERNALS_sv_isbool_false"
+Checks if a \f(CWSvBoolFlagsOK()\fR sv is a false bool. \fBNote\fR that it is
+the caller's responsibility to ensure that the sv is \f(CWSvBoolFlagsOK()\fR
+before calling this. This is only useful in specialized logic like
+serialization code where performance is critical and the flags have
+already been checked to be correct. This is \fBNOT\fR what you should use
+to check if an SV is "false", for that you should be using
+\&\f(CW\*(C`!SvTRUE(sv)\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& bool BOOL_INTERNALS_sv_isbool_false(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """BOOL_INTERNALS_sv_isbool_true""" 4
+.el .IP \f(CWBOOL_INTERNALS_sv_isbool_true\fR 4
+.IX Xref "BOOL_INTERNALS_sv_isbool_true"
+.IX Item "BOOL_INTERNALS_sv_isbool_true"
+Checks if a \f(CWSvBoolFlagsOK()\fR sv is a true bool. \fBNote\fR that it is
+the caller's responsibility to ensure that the sv is \f(CWSvBoolFlagsOK()\fR
+before calling this. This is only useful in specialized logic like
+serialization code where performance is critical and the flags have
+already been checked to be correct. This is \fBNOT\fR what you should use
+to check if an SV is "true", for that you should be using
+\&\f(CWSvTRUE(sv)\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& bool BOOL_INTERNALS_sv_isbool_true(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """boolSV""" 4
+.el .IP \f(CWboolSV\fR 4
+.IX Xref "boolSV"
+.IX Item "boolSV"
+Returns a true SV if \f(CW\*(C`b\*(C'\fR is a true value, or a false SV if \f(CW\*(C`b\*(C'\fR is 0.
+.Sp
+See also \f(CW"PL_sv_yes"\fR and \f(CW"PL_sv_no"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * boolSV(bool b)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """croak_xs_usage""" 4
+.el .IP \f(CWcroak_xs_usage\fR 4
+.IX Xref "croak_xs_usage"
+.IX Item "croak_xs_usage"
+A specialised variant of \f(CWcroak()\fR for emitting the usage message for xsubs
+.Sp
+.Vb 1
+\& croak_xs_usage(cv, "eee_yow");
+.Ve
+.Sp
+works out the package name and subroutine name from \f(CW\*(C`cv\*(C'\fR, and then calls
+\&\f(CWcroak()\fR. Hence if \f(CW\*(C`cv\*(C'\fR is \f(CW&ouch::awk\fR, it would call \f(CW\*(C`croak\*(C'\fR as:
+.Sp
+.Vb 2
+\& Perl_croak(aTHX_ "Usage: %" SVf "::%" SVf "(%s)", "ouch" "awk",
+\& "eee_yow");
+.Ve
+.RS 4
+.Sp
+.Vb 2
+\& void croak_xs_usage(const CV * const cv,
+\& const char * const params)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """DEFSV""" 4
+.el .IP \f(CWDEFSV\fR 4
+.IX Xref "DEFSV"
+.IX Item "DEFSV"
+Returns the SV associated with \f(CW$_\fR
+.RS 4
+.Sp
+.Vb 1
+\& SV * DEFSV
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """DEFSV_set""" 4
+.el .IP \f(CWDEFSV_set\fR 4
+.IX Xref "DEFSV_set"
+.IX Item "DEFSV_set"
+Associate \f(CW\*(C`sv\*(C'\fR with \f(CW$_\fR
+.RS 4
+.Sp
+.Vb 1
+\& void DEFSV_set(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """get_sv""" 4
+.el .IP \f(CWget_sv\fR 4
+.IX Xref "get_sv"
+.IX Item "get_sv"
+Returns the SV of the specified Perl scalar. \f(CW\*(C`flags\*(C'\fR are passed to
+"\f(CW\*(C`gv_fetchpv\*(C'\fR". If \f(CW\*(C`GV_ADD\*(C'\fR is set and the
+Perl variable does not exist then it will be created. If \f(CW\*(C`flags\*(C'\fR is zero
+and the variable does not exist then NULL is returned.
+.Sp
+NOTE: the \f(CWperl_get_sv()\fR form is \fBdeprecated\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * get_sv(const char *name, I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isGV_with_GP""" 4
+.el .IP \f(CWisGV_with_GP\fR 4
+.IX Xref "isGV_with_GP"
+.IX Item "isGV_with_GP"
+Returns a boolean as to whether or not \f(CW\*(C`sv\*(C'\fR is a GV with a pointer to a GP
+(glob pointer).
+.RS 4
+.Sp
+.Vb 1
+\& bool isGV_with_GP(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """looks_like_number""" 4
+.el .IP \f(CWlooks_like_number\fR 4
+.IX Xref "looks_like_number"
+.IX Item "looks_like_number"
+Test if the content of an SV looks like a number (or is a number).
+\&\f(CW\*(C`Inf\*(C'\fR and \f(CW\*(C`Infinity\*(C'\fR are treated as numbers (so will not issue a
+non-numeric warning), even if your \f(CWatof()\fR doesn't grok them. Get-magic is
+ignored.
+.RS 4
+.Sp
+.Vb 1
+\& I32 looks_like_number(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MUTABLE_AV""" 4
+.el .IP \f(CWMUTABLE_AV\fR 4
+.IX Item "MUTABLE_AV"
+.PD 0
+.ie n .IP """MUTABLE_CV""" 4
+.el .IP \f(CWMUTABLE_CV\fR 4
+.IX Item "MUTABLE_CV"
+.ie n .IP """MUTABLE_GV""" 4
+.el .IP \f(CWMUTABLE_GV\fR 4
+.IX Item "MUTABLE_GV"
+.ie n .IP """MUTABLE_HV""" 4
+.el .IP \f(CWMUTABLE_HV\fR 4
+.IX Item "MUTABLE_HV"
+.ie n .IP """MUTABLE_IO""" 4
+.el .IP \f(CWMUTABLE_IO\fR 4
+.IX Item "MUTABLE_IO"
+.ie n .IP """MUTABLE_PTR""" 4
+.el .IP \f(CWMUTABLE_PTR\fR 4
+.IX Item "MUTABLE_PTR"
+.ie n .IP """MUTABLE_SV""" 4
+.el .IP \f(CWMUTABLE_SV\fR 4
+.IX Xref "MUTABLE_AV MUTABLE_CV MUTABLE_GV MUTABLE_HV MUTABLE_IO MUTABLE_PTR MUTABLE_SV"
+.IX Item "MUTABLE_SV"
+.PD
+The \f(CW\*(C`MUTABLE_\fR\f(CI*\fR\f(CW\*(C'\fR() macros cast pointers to the types shown, in such a way
+(compiler permitting) that casting away const-ness will give a warning;
+e.g.:
+.Sp
+.Vb 4
+\& const SV *sv = ...;
+\& AV *av1 = (AV*)sv; <== BAD: the const has been silently
+\& cast away
+\& AV *av2 = MUTABLE_AV(sv); <== GOOD: it may warn
+.Ve
+.Sp
+\&\f(CW\*(C`MUTABLE_PTR\*(C'\fR is the base macro used to derive new casts. The other
+already-built-in ones return pointers to what their names indicate.
+.RS 4
+.Sp
+.Vb 7
+\& AV * MUTABLE_AV (AV * p)
+\& CV * MUTABLE_CV (CV * p)
+\& GV * MUTABLE_GV (GV * p)
+\& HV * MUTABLE_HV (HV * p)
+\& IO * MUTABLE_IO (IO * p)
+\& void * MUTABLE_PTR(void * p)
+\& SV * MUTABLE_SV (SV * p)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newRV""" 4
+.el .IP \f(CWnewRV\fR 4
+.IX Item "newRV"
+.PD 0
+.ie n .IP """newRV_inc""" 4
+.el .IP \f(CWnewRV_inc\fR 4
+.IX Xref "newRV newRV_inc"
+.IX Item "newRV_inc"
+.PD
+These are identical. They create an RV wrapper for an SV. The reference count
+for the original SV is incremented.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newRV(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newRV_noinc""" 4
+.el .IP \f(CWnewRV_noinc\fR 4
+.IX Xref "newRV_noinc"
+.IX Item "newRV_noinc"
+Creates an RV wrapper for an SV. The reference count for the original
+SV is \fBnot\fR incremented.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newRV_noinc(SV * const tmpRef)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSV""" 4
+.el .IP \f(CWnewSV\fR 4
+.IX Xref "newSV"
+.IX Item "newSV"
+Creates a new SV. A non-zero \f(CW\*(C`len\*(C'\fR parameter indicates the number of
+bytes of preallocated string space the SV should have. An extra byte for a
+trailing \f(CW\*(C`NUL\*(C'\fR is also reserved. (\f(CW\*(C`SvPOK\*(C'\fR is not set for the SV even if string
+space is allocated.) The reference count for the new SV is set to 1.
+.Sp
+In 5.9.3, \f(CWnewSV()\fR replaces the older \f(CWNEWSV()\fR API, and drops the first
+parameter, \fIx\fR, a debug aid which allowed callers to identify themselves.
+This aid has been superseded by a new build option, \f(CW\*(C`PERL_MEM_LOG\*(C'\fR (see
+"PERL_MEM_LOG" in perlhacktips). The older API is still there for use in XS
+modules supporting older perls.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSV(const STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVbool""" 4
+.el .IP \f(CWnewSVbool\fR 4
+.IX Xref "newSVbool"
+.IX Item "newSVbool"
+Creates a new SV boolean.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVbool(const bool bool_val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSV_false""" 4
+.el .IP \f(CWnewSV_false\fR 4
+.IX Xref "newSV_false"
+.IX Item "newSV_false"
+Creates a new SV that is a boolean false.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSV_false()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVhek""" 4
+.el .IP \f(CWnewSVhek\fR 4
+.IX Xref "newSVhek"
+.IX Item "newSVhek"
+Creates a new SV from the hash key structure. It will generate scalars that
+point to the shared string table where possible. Returns a new (undefined)
+SV if \f(CW\*(C`hek\*(C'\fR is NULL.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVhek(const HEK * const hek)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVhek_mortal""" 4
+.el .IP \f(CWnewSVhek_mortal\fR 4
+.IX Xref "newSVhek_mortal"
+.IX Item "newSVhek_mortal"
+Creates a new mortal SV from the hash key structure. It will generate
+scalars that point to the shared string table where possible. Returns
+a new (undefined) SV if \f(CW\*(C`hek\*(C'\fR is NULL.
+.Sp
+This is more efficient than using sv_2mortal(newSVhek( ... ))
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVhek_mortal(const HEK * const hek)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSViv""" 4
+.el .IP \f(CWnewSViv\fR 4
+.IX Xref "newSViv"
+.IX Item "newSViv"
+Creates a new SV and copies an integer into it. The reference count for the
+SV is set to 1.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSViv(const IV i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVnv""" 4
+.el .IP \f(CWnewSVnv\fR 4
+.IX Xref "newSVnv"
+.IX Item "newSVnv"
+Creates a new SV and copies a floating point value into it.
+The reference count for the SV is set to 1.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVnv(const NV n)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpadname""" 4
+.el .IP \f(CWnewSVpadname\fR 4
+.IX Xref "newSVpadname"
+.IX Item "newSVpadname"
+NOTE: \f(CW\*(C`newSVpadname\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Creates a new SV containing the pad name.
+.RS 4
+.Sp
+.Vb 1
+\& SV* newSVpadname(PADNAME *pn)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpv""" 4
+.el .IP \f(CWnewSVpv\fR 4
+.IX Xref "newSVpv"
+.IX Item "newSVpv"
+Creates a new SV and copies a string (which may contain \f(CW\*(C`NUL\*(C'\fR (\f(CW\*(C`\e0\*(C'\fR)
+characters) into it. The reference count for the
+SV is set to 1. If \f(CW\*(C`len\*(C'\fR is zero, Perl will compute the length using
+\&\f(CWstrlen()\fR, (which means if you use this option, that \f(CW\*(C`s\*(C'\fR can't have embedded
+\&\f(CW\*(C`NUL\*(C'\fR characters and has to have a terminating \f(CW\*(C`NUL\*(C'\fR byte).
+.Sp
+This function can cause reliability issues if you are likely to pass in
+empty strings that are not null terminated, because it will run
+strlen on the string and potentially run past valid memory.
+.Sp
+Using "newSVpvn" is a safer alternative for non \f(CW\*(C`NUL\*(C'\fR terminated strings.
+For string literals use "newSVpvs" instead. This function will work fine for
+\&\f(CW\*(C`NUL\*(C'\fR terminated strings, but if you want to avoid the if statement on whether
+to call \f(CW\*(C`strlen\*(C'\fR use \f(CW\*(C`newSVpvn\*(C'\fR instead (calling \f(CW\*(C`strlen\*(C'\fR yourself).
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVpv(const char * const s, const STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvf""" 4
+.el .IP \f(CWnewSVpvf\fR 4
+.IX Xref "newSVpvf"
+.IX Item "newSVpvf"
+Creates a new SV and initializes it with the string formatted like
+\&\f(CW\*(C`sv_catpvf\*(C'\fR.
+.Sp
+NOTE: \f(CW\*(C`newSVpvf\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_newSVpvf\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 1
+\& SV * Perl_newSVpvf(pTHX_ const char * const pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvf_nocontext""" 4
+.el .IP \f(CWnewSVpvf_nocontext\fR 4
+.IX Xref "newSVpvf_nocontext"
+.IX Item "newSVpvf_nocontext"
+Like \f(CW"newSVpvf"\fR but does not take a thread context (\f(CW\*(C`aTHX\*(C'\fR) parameter,
+so is used in situations where the caller doesn't already have the thread
+context.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVpvf_nocontext(const char * const pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvn""" 4
+.el .IP \f(CWnewSVpvn\fR 4
+.IX Xref "newSVpvn"
+.IX Item "newSVpvn"
+Creates a new SV and copies a string into it, which may contain \f(CW\*(C`NUL\*(C'\fR characters
+(\f(CW\*(C`\e0\*(C'\fR) and other binary data. The reference count for the SV is set to 1.
+Note that if \f(CW\*(C`len\*(C'\fR is zero, Perl will create a zero length (Perl) string. You
+are responsible for ensuring that the source buffer is at least
+\&\f(CW\*(C`len\*(C'\fR bytes long. If the \f(CW\*(C`buffer\*(C'\fR argument is NULL the new SV will be
+undefined.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVpvn(const char * const buffer, const STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvn_flags""" 4
+.el .IP \f(CWnewSVpvn_flags\fR 4
+.IX Xref "newSVpvn_flags"
+.IX Item "newSVpvn_flags"
+Creates a new SV and copies a string (which may contain \f(CW\*(C`NUL\*(C'\fR (\f(CW\*(C`\e0\*(C'\fR)
+characters) into it. The reference count for the
+SV is set to 1. Note that if \f(CW\*(C`len\*(C'\fR is zero, Perl will create a zero length
+string. You are responsible for ensuring that the source string is at least
+\&\f(CW\*(C`len\*(C'\fR bytes long. If the \f(CW\*(C`s\*(C'\fR argument is NULL the new SV will be undefined.
+Currently the only flag bits accepted are \f(CW\*(C`SVf_UTF8\*(C'\fR and \f(CW\*(C`SVs_TEMP\*(C'\fR.
+If \f(CW\*(C`SVs_TEMP\*(C'\fR is set, then \f(CWsv_2mortal()\fR is called on the result before
+returning. If \f(CW\*(C`SVf_UTF8\*(C'\fR is set, \f(CW\*(C`s\*(C'\fR
+is considered to be in UTF\-8 and the
+\&\f(CW\*(C`SVf_UTF8\*(C'\fR flag will be set on the new SV.
+\&\f(CWnewSVpvn_utf8()\fR is a convenience wrapper for this function, defined as
+.Sp
+.Vb 2
+\& #define newSVpvn_utf8(s, len, u) \e
+\& newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0)
+.Ve
+.RS 4
+.Sp
+.Vb 2
+\& SV * newSVpvn_flags(const char * const s, const STRLEN len,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvn_share""" 4
+.el .IP \f(CWnewSVpvn_share\fR 4
+.IX Xref "newSVpvn_share"
+.IX Item "newSVpvn_share"
+Creates a new SV with its \f(CW\*(C`SvPVX_const\*(C'\fR pointing to a shared string in the string
+table. If the string does not already exist in the table, it is
+created first. Turns on the \f(CW\*(C`SvIsCOW\*(C'\fR flag (or \f(CW\*(C`READONLY\*(C'\fR
+and \f(CW\*(C`FAKE\*(C'\fR in 5.16 and earlier). If the \f(CW\*(C`hash\*(C'\fR parameter
+is non-zero, that value is used; otherwise the hash is computed.
+The string's hash can later be retrieved from the SV
+with the \f(CW"SvSHARED_HASH"\fR macro. The idea here is
+that as the string table is used for shared hash keys these strings will have
+\&\f(CW\*(C`SvPVX_const == HeKEY\*(C'\fR and hash lookup will avoid string compare.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVpvn_share(const char *s, I32 len, U32 hash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvn_utf8""" 4
+.el .IP \f(CWnewSVpvn_utf8\fR 4
+.IX Xref "newSVpvn_utf8"
+.IX Item "newSVpvn_utf8"
+Creates a new SV and copies a string (which may contain \f(CW\*(C`NUL\*(C'\fR (\f(CW\*(C`\e0\*(C'\fR)
+characters) into it. If \f(CW\*(C`utf8\*(C'\fR is true, calls
+\&\f(CW\*(C`SvUTF8_on\*(C'\fR on the new SV. Implemented as a wrapper around \f(CW\*(C`newSVpvn_flags\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV* newSVpvn_utf8(const char* s, STRLEN len, U32 utf8)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvs""" 4
+.el .IP \f(CWnewSVpvs\fR 4
+.IX Xref "newSVpvs"
+.IX Item "newSVpvs"
+Like \f(CW\*(C`newSVpvn\*(C'\fR, but takes a literal string instead of a
+string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& SV* newSVpvs("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvs_flags""" 4
+.el .IP \f(CWnewSVpvs_flags\fR 4
+.IX Xref "newSVpvs_flags"
+.IX Item "newSVpvs_flags"
+Like \f(CW\*(C`newSVpvn_flags\*(C'\fR, but takes a literal string instead of
+a string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& SV* newSVpvs_flags("literal string", U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpv_share""" 4
+.el .IP \f(CWnewSVpv_share\fR 4
+.IX Xref "newSVpv_share"
+.IX Item "newSVpv_share"
+Like \f(CW\*(C`newSVpvn_share\*(C'\fR, but takes a \f(CW\*(C`NUL\*(C'\fR\-terminated string instead of a
+string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVpv_share(const char *s, U32 hash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVpvs_share""" 4
+.el .IP \f(CWnewSVpvs_share\fR 4
+.IX Xref "newSVpvs_share"
+.IX Item "newSVpvs_share"
+Like \f(CW\*(C`newSVpvn_share\*(C'\fR, but takes a literal string instead of
+a string/length pair and omits the hash parameter.
+.RS 4
+.Sp
+.Vb 1
+\& SV* newSVpvs_share("literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVrv""" 4
+.el .IP \f(CWnewSVrv\fR 4
+.IX Xref "newSVrv"
+.IX Item "newSVrv"
+Creates a new SV for the existing RV, \f(CW\*(C`rv\*(C'\fR, to point to. If \f(CW\*(C`rv\*(C'\fR is not an
+RV then it will be upgraded to one. If \f(CW\*(C`classname\*(C'\fR is non-null then the new
+SV will be blessed in the specified package. The new SV is returned and its
+reference count is 1. The reference count 1 is owned by \f(CW\*(C`rv\*(C'\fR. See also
+\&\fBnewRV_inc()\fR and \fBnewRV_noinc()\fR for creating a new RV properly.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVrv(SV * const rv, const char * const classname)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVsv""" 4
+.el .IP \f(CWnewSVsv\fR 4
+.IX Item "newSVsv"
+.PD 0
+.ie n .IP """newSVsv_flags""" 4
+.el .IP \f(CWnewSVsv_flags\fR 4
+.IX Item "newSVsv_flags"
+.ie n .IP """newSVsv_nomg""" 4
+.el .IP \f(CWnewSVsv_nomg\fR 4
+.IX Xref "newSVsv newSVsv_flags newSVsv_nomg"
+.IX Item "newSVsv_nomg"
+.PD
+These create a new SV which is an exact duplicate of the original SV
+(using \f(CW\*(C`sv_setsv\*(C'\fR.)
+.Sp
+They differ only in that \f(CW\*(C`newSVsv\*(C'\fR performs 'get' magic; \f(CW\*(C`newSVsv_nomg\*(C'\fR skips
+any magic; and \f(CW\*(C`newSVsv_flags\*(C'\fR allows you to explicitly set a \f(CW\*(C`flags\*(C'\fR
+parameter.
+.RS 4
+.Sp
+.Vb 3
+\& SV * newSVsv (SV * const old)
+\& SV * newSVsv_flags(SV * const old, I32 flags)
+\& SV * newSVsv_nomg (SV * const old)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSV_true""" 4
+.el .IP \f(CWnewSV_true\fR 4
+.IX Xref "newSV_true"
+.IX Item "newSV_true"
+Creates a new SV that is a boolean true.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSV_true()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSV_type""" 4
+.el .IP \f(CWnewSV_type\fR 4
+.IX Xref "newSV_type"
+.IX Item "newSV_type"
+Creates a new SV, of the type specified. The reference count for the new SV
+is set to 1.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSV_type(const svtype type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSV_type_mortal""" 4
+.el .IP \f(CWnewSV_type_mortal\fR 4
+.IX Xref "newSV_type_mortal"
+.IX Item "newSV_type_mortal"
+Creates a new mortal SV, of the type specified. The reference count for the
+new SV is set to 1.
+.Sp
+This is equivalent to
+ SV* sv = sv_2mortal(newSV_type(<some type>))
+and
+ SV* sv = \fBsv_newmortal()\fR;
+ sv_upgrade(sv, <some_type>)
+but should be more efficient than both of them. (Unless sv_2mortal is inlined
+at some point in the future.)
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSV_type_mortal(const svtype type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newSVuv""" 4
+.el .IP \f(CWnewSVuv\fR 4
+.IX Xref "newSVuv"
+.IX Item "newSVuv"
+Creates a new SV and copies an unsigned integer into it.
+The reference count for the SV is set to 1.
+.RS 4
+.Sp
+.Vb 1
+\& SV * newSVuv(const UV u)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Nullsv""" 4
+.el .IP \f(CWNullsv\fR 4
+.IX Xref "Nullsv"
+.IX Item "Nullsv"
+Null SV pointer. (No longer available when \f(CW\*(C`PERL_CORE\*(C'\fR is defined.)
+.ie n .IP """PL_sv_no""" 4
+.el .IP \f(CWPL_sv_no\fR 4
+.IX Xref "PL_sv_no"
+.IX Item "PL_sv_no"
+This is the \f(CW\*(C`false\*(C'\fR SV. It is readonly. See \f(CW"PL_sv_yes"\fR. Always refer
+to this as \f(CW&PL_sv_no\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV PL_sv_no
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_sv_undef""" 4
+.el .IP \f(CWPL_sv_undef\fR 4
+.IX Xref "PL_sv_undef"
+.IX Item "PL_sv_undef"
+This is the \f(CW\*(C`undef\*(C'\fR SV. It is readonly. Always refer to this as
+\&\f(CW&PL_sv_undef\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV PL_sv_undef
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_sv_yes""" 4
+.el .IP \f(CWPL_sv_yes\fR 4
+.IX Xref "PL_sv_yes"
+.IX Item "PL_sv_yes"
+This is the \f(CW\*(C`true\*(C'\fR SV. It is readonly. See \f(CW"PL_sv_no"\fR. Always refer to
+this as \f(CW&PL_sv_yes\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV PL_sv_yes
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PL_sv_zero""" 4
+.el .IP \f(CWPL_sv_zero\fR 4
+.IX Xref "PL_sv_zero"
+.IX Item "PL_sv_zero"
+This readonly SV has a zero numeric value and a \f(CW"0"\fR string value. It's
+similar to \f(CW"PL_sv_no"\fR except for its string value. Can be used as a
+cheap alternative to \f(CWmXPUSHi(0)\fR for example. Always refer to this as
+\&\f(CW&PL_sv_zero\fR. Introduced in 5.28.
+.RS 4
+.Sp
+.Vb 1
+\& SV PL_sv_zero
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SAVE_DEFSV""" 4
+.el .IP \f(CWSAVE_DEFSV\fR 4
+.IX Xref "SAVE_DEFSV"
+.IX Item "SAVE_DEFSV"
+Localize \f(CW$_\fR. See "Localizing changes" in perlguts.
+.RS 4
+.Sp
+.Vb 1
+\& void SAVE_DEFSV
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sortsv""" 4
+.el .IP \f(CWsortsv\fR 4
+.IX Xref "sortsv"
+.IX Item "sortsv"
+In-place sort an array of SV pointers with the given comparison routine.
+.Sp
+Currently this always uses mergesort. See \f(CW"sortsv_flags"\fR for a more
+flexible routine.
+.RS 4
+.Sp
+.Vb 1
+\& void sortsv(SV **array, size_t num_elts, SVCOMPARE_t cmp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sortsv_flags""" 4
+.el .IP \f(CWsortsv_flags\fR 4
+.IX Xref "sortsv_flags"
+.IX Item "sortsv_flags"
+In-place sort an array of SV pointers with the given comparison routine,
+with various SORTf_* flag options.
+.RS 4
+.Sp
+.Vb 2
+\& void sortsv_flags(SV **array, size_t num_elts, SVCOMPARE_t cmp,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SV""" 4
+.el .IP \f(CWSV\fR 4
+.IX Item "SV"
+Described in perlguts.
+.ie n .IP """SvAMAGIC""" 4
+.el .IP \f(CWSvAMAGIC\fR 4
+.IX Xref "SvAMAGIC"
+.IX Item "SvAMAGIC"
+Returns a boolean as to whether \f(CW\*(C`sv\*(C'\fR has overloading (active magic) enabled or
+not.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvAMAGIC(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvAMAGIC_off""" 4
+.el .IP \f(CWSvAMAGIC_off\fR 4
+.IX Xref "SvAMAGIC_off"
+.IX Item "SvAMAGIC_off"
+Indicate that \f(CW\*(C`sv\*(C'\fR has overloading (active magic) disabled.
+.RS 4
+.Sp
+.Vb 1
+\& void SvAMAGIC_off(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvAMAGIC_on""" 4
+.el .IP \f(CWSvAMAGIC_on\fR 4
+.IX Xref "SvAMAGIC_on"
+.IX Item "SvAMAGIC_on"
+Indicate that \f(CW\*(C`sv\*(C'\fR has overloading (active magic) enabled.
+.RS 4
+.Sp
+.Vb 1
+\& void SvAMAGIC_on(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_backoff""" 4
+.el .IP \f(CWsv_backoff\fR 4
+.IX Xref "sv_backoff"
+.IX Item "sv_backoff"
+Remove any string offset. You should normally use the \f(CW\*(C`SvOOK_off\*(C'\fR macro
+wrapper instead.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_backoff(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_bless""" 4
+.el .IP \f(CWsv_bless\fR 4
+.IX Xref "sv_bless"
+.IX Item "sv_bless"
+Blesses an SV into a specified package. The SV must be an RV. The package
+must be designated by its stash (see \f(CW"gv_stashpv"\fR). The reference count
+of the SV is unaffected.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_bless(SV * const sv, HV * const stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvBoolFlagsOK""" 4
+.el .IP \f(CWSvBoolFlagsOK\fR 4
+.IX Xref "SvBoolFlagsOK"
+.IX Item "SvBoolFlagsOK"
+Returns a bool indicating whether the SV has the right flags set such
+that it is safe to call \f(CWBOOL_INTERNALS_sv_isbool()\fR or
+\&\f(CWBOOL_INTERNALS_sv_isbool_true()\fR or
+\&\f(CWBOOL_INTERNALS_sv_isbool_false()\fR. Currently equivalent to
+\&\f(CWSvIandPOK(sv)\fR or \f(CW\*(C`SvIOK(sv) && SvPOK(sv)\*(C'\fR. Serialization may want to
+unroll this check. If so you are strongly recommended to add code like
+\&\f(CW\*(C`assert(SvBoolFlagsOK(sv));\*(C'\fR \fBbefore\fR calling using any of the
+BOOL_INTERNALS macros.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvBoolFlagsOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_catpv""" 4
+.el .IP \f(CWsv_catpv\fR 4
+.IX Item "sv_catpv"
+.PD 0
+.ie n .IP """sv_catpv_flags""" 4
+.el .IP \f(CWsv_catpv_flags\fR 4
+.IX Item "sv_catpv_flags"
+.ie n .IP """sv_catpv_mg""" 4
+.el .IP \f(CWsv_catpv_mg\fR 4
+.IX Item "sv_catpv_mg"
+.ie n .IP """sv_catpv_nomg""" 4
+.el .IP \f(CWsv_catpv_nomg\fR 4
+.IX Xref "sv_catpv sv_catpv_flags sv_catpv_mg sv_catpv_nomg"
+.IX Item "sv_catpv_nomg"
+.PD
+These concatenate the \f(CW\*(C`NUL\*(C'\fR\-terminated string \f(CW\*(C`sstr\*(C'\fR onto the end of the
+string which is in the SV.
+If the SV has the UTF\-8 status set, then the bytes appended should be
+valid UTF\-8.
+.Sp
+They differ only in how they handle magic:
+.Sp
+\&\f(CW\*(C`sv_catpv_mg\*(C'\fR performs both 'get' and 'set' magic.
+.Sp
+\&\f(CW\*(C`sv_catpv\*(C'\fR performs only 'get' magic.
+.Sp
+\&\f(CW\*(C`sv_catpv_nomg\*(C'\fR skips all magic.
+.Sp
+\&\f(CW\*(C`sv_catpv_flags\*(C'\fR has an extra \f(CW\*(C`flags\*(C'\fR parameter which allows you to specify
+any combination of magic handling (using \f(CW\*(C`SV_GMAGIC\*(C'\fR and/or \f(CW\*(C`SV_SMAGIC\*(C'\fR), and
+to also override the UTF\-8 handling. By supplying the \f(CW\*(C`SV_CATUTF8\*(C'\fR flag, the
+appended string is forced to be interpreted as UTF\-8; by supplying instead the
+\&\f(CW\*(C`SV_CATBYTES\*(C'\fR flag, it will be interpreted as just bytes. Either the SV or
+the string appended will be upgraded to UTF\-8 if necessary.
+.RS 4
+.Sp
+.Vb 4
+\& void sv_catpv (SV * const dsv, const char *sstr)
+\& void sv_catpv_flags(SV *dsv, const char *sstr, const I32 flags)
+\& void sv_catpv_mg (SV * const dsv, const char * const sstr)
+\& void sv_catpv_nomg (SV * const dsv, const char *sstr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_catpvf""" 4
+.el .IP \f(CWsv_catpvf\fR 4
+.IX Item "sv_catpvf"
+.PD 0
+.ie n .IP """sv_catpvf_mg""" 4
+.el .IP \f(CWsv_catpvf_mg\fR 4
+.IX Item "sv_catpvf_mg"
+.ie n .IP """sv_catpvf_mg_nocontext""" 4
+.el .IP \f(CWsv_catpvf_mg_nocontext\fR 4
+.IX Item "sv_catpvf_mg_nocontext"
+.ie n .IP """sv_catpvf_nocontext""" 4
+.el .IP \f(CWsv_catpvf_nocontext\fR 4
+.IX Xref "sv_catpvf sv_catpvf_mg sv_catpvf_mg_nocontext sv_catpvf_nocontext"
+.IX Item "sv_catpvf_nocontext"
+.PD
+These process their arguments like \f(CW\*(C`sprintf\*(C'\fR, and append the formatted
+output to an SV. As with \f(CW\*(C`sv_vcatpvfn\*(C'\fR, argument reordering is not supporte
+when called with a non-null C\-style variable argument list.
+.Sp
+If the appended data contains "wide" characters
+(including, but not limited to, SVs with a UTF\-8 PV formatted with \f(CW%s\fR,
+and characters >255 formatted with \f(CW%c\fR), the original SV might get
+upgraded to UTF\-8.
+.Sp
+If the original SV was UTF\-8, the pattern should be
+valid UTF\-8; if the original SV was bytes, the pattern should be too.
+.Sp
+All perform 'get' magic, but only \f(CW\*(C`sv_catpvf_mg\*(C'\fR and \f(CW\*(C`sv_catpvf_mg_nocontext\*(C'\fR
+perform 'set' magic.
+.Sp
+\&\f(CW\*(C`sv_catpvf_nocontext\*(C'\fR and \f(CW\*(C`sv_catpvf_mg_nocontext\*(C'\fR do not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter, so are used in situations where the caller
+doesn't already have the thread context.
+.Sp
+NOTE: \f(CW\*(C`sv_catpvf\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_sv_catpvf\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.Sp
+NOTE: \f(CW\*(C`sv_catpvf_mg\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_sv_catpvf_mg\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 8
+\& void Perl_sv_catpvf (pTHX_ SV * const sv,
+\& const char * const pat, ...)
+\& void Perl_sv_catpvf_mg (pTHX_ SV * const sv,
+\& const char * const pat, ...)
+\& void sv_catpvf_mg_nocontext(SV * const sv,
+\& const char * const pat, ...)
+\& void sv_catpvf_nocontext (SV * const sv,
+\& const char * const pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_catpvn""" 4
+.el .IP \f(CWsv_catpvn\fR 4
+.IX Item "sv_catpvn"
+.PD 0
+.ie n .IP """sv_catpvn_flags""" 4
+.el .IP \f(CWsv_catpvn_flags\fR 4
+.IX Item "sv_catpvn_flags"
+.ie n .IP """sv_catpvn_mg""" 4
+.el .IP \f(CWsv_catpvn_mg\fR 4
+.IX Item "sv_catpvn_mg"
+.ie n .IP """sv_catpvn_nomg""" 4
+.el .IP \f(CWsv_catpvn_nomg\fR 4
+.IX Xref "sv_catpvn sv_catpvn_flags sv_catpvn_mg sv_catpvn_nomg"
+.IX Item "sv_catpvn_nomg"
+.PD
+These concatenate the \f(CW\*(C`len\*(C'\fR bytes of the string beginning at \f(CW\*(C`ptr\*(C'\fR onto the
+end of the string which is in \f(CW\*(C`dsv\*(C'\fR. The caller must make sure \f(CW\*(C`ptr\*(C'\fR
+contains at least \f(CW\*(C`len\*(C'\fR bytes.
+.Sp
+For all but \f(CW\*(C`sv_catpvn_flags\*(C'\fR, the string appended is assumed to be valid
+UTF\-8 if the SV has the UTF\-8 status set, and a string of bytes otherwise.
+.Sp
+They differ in that:
+.Sp
+\&\f(CW\*(C`sv_catpvn_mg\*(C'\fR performs both 'get' and 'set' magic on \f(CW\*(C`dsv\*(C'\fR.
+.Sp
+\&\f(CW\*(C`sv_catpvn\*(C'\fR performs only 'get' magic.
+.Sp
+\&\f(CW\*(C`sv_catpvn_nomg\*(C'\fR skips all magic.
+.Sp
+\&\f(CW\*(C`sv_catpvn_flags\*(C'\fR has an extra \f(CW\*(C`flags\*(C'\fR parameter which allows you to specify
+any combination of magic handling (using \f(CW\*(C`SV_GMAGIC\*(C'\fR and/or \f(CW\*(C`SV_SMAGIC\*(C'\fR) and
+to also override the UTF\-8 handling. By supplying the \f(CW\*(C`SV_CATBYTES\*(C'\fR flag, the
+appended string is interpreted as plain bytes; by supplying instead the
+\&\f(CW\*(C`SV_CATUTF8\*(C'\fR flag, it will be interpreted as UTF\-8, and the \f(CW\*(C`dsv\*(C'\fR will be
+upgraded to UTF\-8 if necessary.
+.Sp
+\&\f(CW\*(C`sv_catpvn\*(C'\fR, \f(CW\*(C`sv_catpvn_mg\*(C'\fR, and \f(CW\*(C`sv_catpvn_nomg\*(C'\fR are implemented
+in terms of \f(CW\*(C`sv_catpvn_flags\*(C'\fR.
+.RS 4
+.Sp
+.Vb 5
+\& void sv_catpvn (SV *dsv, const char *sstr, STRLEN len)
+\& void sv_catpvn_flags(SV * const dsv, const char *sstr,
+\& const STRLEN len, const I32 flags)
+\& void sv_catpvn_mg (SV *dsv, const char *sstr, STRLEN len)
+\& void sv_catpvn_nomg (SV *dsv, const char *sstr, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_catpvs""" 4
+.el .IP \f(CWsv_catpvs\fR 4
+.IX Xref "sv_catpvs"
+.IX Item "sv_catpvs"
+Like \f(CW\*(C`sv_catpvn\*(C'\fR, but takes a literal string instead of a
+string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_catpvs(SV* sv, "literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_catpvs_flags""" 4
+.el .IP \f(CWsv_catpvs_flags\fR 4
+.IX Xref "sv_catpvs_flags"
+.IX Item "sv_catpvs_flags"
+Like \f(CW\*(C`sv_catpvn_flags\*(C'\fR, but takes a literal string instead
+of a string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_catpvs_flags(SV* sv, "literal string", I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_catpvs_mg""" 4
+.el .IP \f(CWsv_catpvs_mg\fR 4
+.IX Xref "sv_catpvs_mg"
+.IX Item "sv_catpvs_mg"
+Like \f(CW\*(C`sv_catpvn_mg\*(C'\fR, but takes a literal string instead of a
+string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_catpvs_mg(SV* sv, "literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_catpvs_nomg""" 4
+.el .IP \f(CWsv_catpvs_nomg\fR 4
+.IX Xref "sv_catpvs_nomg"
+.IX Item "sv_catpvs_nomg"
+Like \f(CW\*(C`sv_catpvn_nomg\*(C'\fR, but takes a literal string instead of
+a string/length pair.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_catpvs_nomg(SV* sv, "literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_catsv""" 4
+.el .IP \f(CWsv_catsv\fR 4
+.IX Item "sv_catsv"
+.PD 0
+.ie n .IP """sv_catsv_flags""" 4
+.el .IP \f(CWsv_catsv_flags\fR 4
+.IX Item "sv_catsv_flags"
+.ie n .IP """sv_catsv_mg""" 4
+.el .IP \f(CWsv_catsv_mg\fR 4
+.IX Item "sv_catsv_mg"
+.ie n .IP """sv_catsv_nomg""" 4
+.el .IP \f(CWsv_catsv_nomg\fR 4
+.IX Xref "sv_catsv sv_catsv_flags sv_catsv_mg sv_catsv_nomg"
+.IX Item "sv_catsv_nomg"
+.PD
+These concatenate the string from SV \f(CW\*(C`sstr\*(C'\fR onto the end of the string in SV
+\&\f(CW\*(C`dsv\*(C'\fR. If \f(CW\*(C`sstr\*(C'\fR is null, these are no-ops; otherwise only \f(CW\*(C`dsv\*(C'\fR is
+modified.
+.Sp
+They differ only in what magic they perform:
+.Sp
+\&\f(CW\*(C`sv_catsv_mg\*(C'\fR performs 'get' magic on both SVs before the copy, and 'set' magic
+on \f(CW\*(C`dsv\*(C'\fR afterwards.
+.Sp
+\&\f(CW\*(C`sv_catsv\*(C'\fR performs just 'get' magic, on both SVs.
+.Sp
+\&\f(CW\*(C`sv_catsv_nomg\*(C'\fR skips all magic.
+.Sp
+\&\f(CW\*(C`sv_catsv_flags\*(C'\fR has an extra \f(CW\*(C`flags\*(C'\fR parameter which allows you to use
+\&\f(CW\*(C`SV_GMAGIC\*(C'\fR and/or \f(CW\*(C`SV_SMAGIC\*(C'\fR to specify any combination of magic handling
+(although either both or neither SV will have 'get' magic applied to it.)
+.Sp
+\&\f(CW\*(C`sv_catsv\*(C'\fR, \f(CW\*(C`sv_catsv_mg\*(C'\fR, and \f(CW\*(C`sv_catsv_nomg\*(C'\fR are implemented
+in terms of \f(CW\*(C`sv_catsv_flags\*(C'\fR.
+.RS 4
+.Sp
+.Vb 5
+\& void sv_catsv (SV *dsv, SV *sstr)
+\& void sv_catsv_flags(SV * const dsv, SV * const sstr,
+\& const I32 flags)
+\& void sv_catsv_mg (SV *dsv, SV *sstr)
+\& void sv_catsv_nomg (SV *dsv, SV *sstr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SV_CHECK_THINKFIRST""" 4
+.el .IP \f(CWSV_CHECK_THINKFIRST\fR 4
+.IX Xref "SV_CHECK_THINKFIRST"
+.IX Item "SV_CHECK_THINKFIRST"
+Remove any encumbrances from \f(CW\*(C`sv\*(C'\fR, that need to be taken care of before it
+is modifiable. For example if it is Copy on Write (COW), now is the time to
+make that copy.
+.Sp
+If you know that you are about to change the PV value of \f(CW\*(C`sv\*(C'\fR, instead use
+"\f(CW\*(C`SV_CHECK_THINKFIRST_COW_DROP\*(C'\fR" to avoid the write that would be
+immediately written again.
+.RS 4
+.Sp
+.Vb 1
+\& void SV_CHECK_THINKFIRST(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SV_CHECK_THINKFIRST_COW_DROP""" 4
+.el .IP \f(CWSV_CHECK_THINKFIRST_COW_DROP\fR 4
+.IX Xref "SV_CHECK_THINKFIRST_COW_DROP"
+.IX Item "SV_CHECK_THINKFIRST_COW_DROP"
+Call this when you are about to replace the PV value in \f(CW\*(C`sv\*(C'\fR, which is
+potentially copy-on-write. It stops any sharing with other SVs, so that no
+Copy on Write (COW) actually happens. This COW would be useless, as it would
+immediately get changed to something else. This function also removes any
+other encumbrances that would be problematic when changing \f(CW\*(C`sv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SV_CHECK_THINKFIRST_COW_DROP(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_chop""" 4
+.el .IP \f(CWsv_chop\fR 4
+.IX Xref "sv_chop"
+.IX Item "sv_chop"
+Efficient removal of characters from the beginning of the string buffer.
+\&\f(CWSvPOK(sv)\fR, or at least \f(CWSvPOKp(sv)\fR, must be true and \f(CW\*(C`ptr\*(C'\fR must be a
+pointer to somewhere inside the string buffer. \f(CW\*(C`ptr\*(C'\fR becomes the first
+character of the adjusted string. Uses the \f(CW\*(C`OOK\*(C'\fR hack. On return, only
+\&\f(CWSvPOK(sv)\fR and \f(CWSvPOKp(sv)\fR among the \f(CW\*(C`OK\*(C'\fR flags will be true.
+.Sp
+Beware: after this function returns, \f(CW\*(C`ptr\*(C'\fR and SvPVX_const(sv) may no longer
+refer to the same chunk of data.
+.Sp
+The unfortunate similarity of this function's name to that of Perl's \f(CW\*(C`chop\*(C'\fR
+operator is strictly coincidental. This function works from the left;
+\&\f(CW\*(C`chop\*(C'\fR works from the right.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_chop(SV * const sv, const char * const ptr)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_clear""" 4
+.el .IP \f(CWsv_clear\fR 4
+.IX Xref "sv_clear"
+.IX Item "sv_clear"
+Clear an SV: call any destructors, free up any memory used by the body,
+and free the body itself. The SV's head is \fInot\fR freed, although
+its type is set to all 1's so that it won't inadvertently be assumed
+to be live during global destruction etc.
+This function should only be called when \f(CW\*(C`REFCNT\*(C'\fR is zero. Most of the time
+you'll want to call \f(CW\*(C`SvREFCNT_dec\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_clear(SV * const orig_sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_cmp""" 4
+.el .IP \f(CWsv_cmp\fR 4
+.IX Xref "sv_cmp"
+.IX Item "sv_cmp"
+Compares the strings in two SVs. Returns \-1, 0, or 1 indicating whether the
+string in \f(CW\*(C`sv1\*(C'\fR is less than, equal to, or greater than the string in
+\&\f(CW\*(C`sv2\*(C'\fR. Is UTF\-8 and \f(CW\*(Aquse\ bytes\*(Aq\fR aware, handles get magic, and will
+coerce its args to strings if necessary. See also \f(CW"sv_cmp_locale"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 sv_cmp(SV * const sv1, SV * const sv2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_cmp_flags""" 4
+.el .IP \f(CWsv_cmp_flags\fR 4
+.IX Xref "sv_cmp_flags"
+.IX Item "sv_cmp_flags"
+Compares the strings in two SVs. Returns \-1, 0, or 1 indicating whether the
+string in \f(CW\*(C`sv1\*(C'\fR is less than, equal to, or greater than the string in
+\&\f(CW\*(C`sv2\*(C'\fR. Is UTF\-8 and \f(CW\*(Aquse\ bytes\*(Aq\fR aware and will coerce its args to strings
+if necessary. If the flags has the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit set, it handles get magic. See
+also \f(CW"sv_cmp_locale_flags"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 sv_cmp_flags(SV * const sv1, SV * const sv2, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_cmp_locale""" 4
+.el .IP \f(CWsv_cmp_locale\fR 4
+.IX Xref "sv_cmp_locale"
+.IX Item "sv_cmp_locale"
+Compares the strings in two SVs in a locale-aware manner. Is UTF\-8 and
+\&\f(CW\*(Aquse\ bytes\*(Aq\fR aware, handles get magic, and will coerce its args to strings
+if necessary. See also \f(CW"sv_cmp"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 sv_cmp_locale(SV * const sv1, SV * const sv2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_cmp_locale_flags""" 4
+.el .IP \f(CWsv_cmp_locale_flags\fR 4
+.IX Xref "sv_cmp_locale_flags"
+.IX Item "sv_cmp_locale_flags"
+Compares the strings in two SVs in a locale-aware manner. Is UTF\-8 and
+\&\f(CW\*(Aquse\ bytes\*(Aq\fR aware and will coerce its args to strings if necessary. If
+the flags contain \f(CW\*(C`SV_GMAGIC\*(C'\fR, it handles get magic. See also
+\&\f(CW"sv_cmp_flags"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& I32 sv_cmp_locale_flags(SV * const sv1, SV * const sv2,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_collxfrm""" 4
+.el .IP \f(CWsv_collxfrm\fR 4
+.IX Xref "sv_collxfrm"
+.IX Item "sv_collxfrm"
+This calls \f(CW\*(C`sv_collxfrm_flags\*(C'\fR with the SV_GMAGIC flag. See
+\&\f(CW"sv_collxfrm_flags"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& char * sv_collxfrm(SV * const sv, STRLEN * const nxp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_collxfrm_flags""" 4
+.el .IP \f(CWsv_collxfrm_flags\fR 4
+.IX Xref "sv_collxfrm_flags"
+.IX Item "sv_collxfrm_flags"
+Add Collate Transform magic to an SV if it doesn't already have it. If the
+flags contain \f(CW\*(C`SV_GMAGIC\*(C'\fR, it handles get-magic.
+.Sp
+Any scalar variable may carry \f(CW\*(C`PERL_MAGIC_collxfrm\*(C'\fR magic that contains the
+scalar data of the variable, but transformed to such a format that a normal
+memory comparison can be used to compare the data according to the locale
+settings.
+.RS 4
+.Sp
+.Vb 2
+\& char * sv_collxfrm_flags(SV * const sv, STRLEN * const nxp,
+\& I32 const flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_copypv""" 4
+.el .IP \f(CWsv_copypv\fR 4
+.IX Item "sv_copypv"
+.PD 0
+.ie n .IP """sv_copypv_flags""" 4
+.el .IP \f(CWsv_copypv_flags\fR 4
+.IX Item "sv_copypv_flags"
+.ie n .IP """sv_copypv_nomg""" 4
+.el .IP \f(CWsv_copypv_nomg\fR 4
+.IX Xref "sv_copypv sv_copypv_flags sv_copypv_nomg"
+.IX Item "sv_copypv_nomg"
+.PD
+These copy a stringified representation of the source SV into the
+destination SV. They automatically perform coercion of numeric values into
+strings. Guaranteed to preserve the \f(CW\*(C`UTF8\*(C'\fR flag even from overloaded objects.
+Similar in nature to \f(CW\*(C`sv_2pv[_flags]\*(C'\fR but they operate directly on an SV
+instead of just the string. Mostly they use "\f(CW\*(C`sv_2pv_flags\*(C'\fR" to
+do the work, except when that would lose the UTF\-8'ness of the PV.
+.Sp
+The three forms differ only in whether or not they perform 'get magic' on
+\&\f(CW\*(C`sv\*(C'\fR. \f(CW\*(C`sv_copypv_nomg\*(C'\fR skips 'get magic'; \f(CW\*(C`sv_copypv\*(C'\fR performs it; and
+\&\f(CW\*(C`sv_copypv_flags\*(C'\fR either performs it (if the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit is set in
+\&\f(CW\*(C`flags\*(C'\fR) or doesn't (if that bit is cleared).
+.RS 4
+.Sp
+.Vb 4
+\& void sv_copypv (SV * const dsv, SV * const ssv)
+\& void sv_copypv_flags(SV * const dsv, SV * const ssv,
+\& const I32 flags)
+\& void sv_copypv_nomg (SV * const dsv, SV * const ssv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvCUR""" 4
+.el .IP \f(CWSvCUR\fR 4
+.IX Xref "SvCUR"
+.IX Item "SvCUR"
+Returns the length, in bytes, of the PV inside the SV.
+Note that this may not match Perl's \f(CW\*(C`length\*(C'\fR; for that, use
+\&\f(CWsv_len_utf8(sv)\fR. See \f(CW"SvLEN"\fR also.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN SvCUR(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvCUR_set""" 4
+.el .IP \f(CWSvCUR_set\fR 4
+.IX Xref "SvCUR_set"
+.IX Item "SvCUR_set"
+Sets the current length, in bytes, of the C string which is in the SV.
+See \f(CW"SvCUR"\fR and \f(CW\*(C`SvIV_set\*(C'\fR>.
+.RS 4
+.Sp
+.Vb 1
+\& void SvCUR_set(SV* sv, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2cv""" 4
+.el .IP \f(CWsv_2cv\fR 4
+.IX Xref "sv_2cv"
+.IX Item "sv_2cv"
+Using various gambits, try to get a CV from an SV; in addition, try if
+possible to set \f(CW*st\fR and \f(CW*gvp\fR to the stash and GV associated with it.
+The flags in \f(CW\*(C`lref\*(C'\fR are passed to \f(CW\*(C`gv_fetchsv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 2
+\& CV * sv_2cv(SV *sv, HV ** const st, GV ** const gvp,
+\& const I32 lref)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_dec""" 4
+.el .IP \f(CWsv_dec\fR 4
+.IX Item "sv_dec"
+.PD 0
+.ie n .IP """sv_dec_nomg""" 4
+.el .IP \f(CWsv_dec_nomg\fR 4
+.IX Xref "sv_dec sv_dec_nomg"
+.IX Item "sv_dec_nomg"
+.PD
+These auto-decrement the value in the SV, doing string to numeric conversion
+if necessary. They both handle operator overloading.
+.Sp
+They differ only in that:
+.Sp
+\&\f(CW\*(C`sv_dec\*(C'\fR handles 'get' magic; \f(CW\*(C`sv_dec_nomg\*(C'\fR skips 'get' magic.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_dec(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_derived_from""" 4
+.el .IP \f(CWsv_derived_from\fR 4
+.IX Xref "sv_derived_from"
+.IX Item "sv_derived_from"
+Exactly like "sv_derived_from_pv", but doesn't take a \f(CW\*(C`flags\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_derived_from(SV *sv, const char * const name)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_derived_from_hv""" 4
+.el .IP \f(CWsv_derived_from_hv\fR 4
+.IX Xref "sv_derived_from_hv"
+.IX Item "sv_derived_from_hv"
+Exactly like "sv_derived_from_pvn", but takes the name string as the
+\&\f(CW\*(C`HvNAME\*(C'\fR of the given HV (which would presumably represent a stash).
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_derived_from_hv(SV *sv, HV *hv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_derived_from_pv""" 4
+.el .IP \f(CWsv_derived_from_pv\fR 4
+.IX Xref "sv_derived_from_pv"
+.IX Item "sv_derived_from_pv"
+Exactly like "sv_derived_from_pvn", but takes a nul-terminated string
+instead of a string/length pair.
+.RS 4
+.Sp
+.Vb 2
+\& bool sv_derived_from_pv(SV *sv, const char * const name,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_derived_from_pvn""" 4
+.el .IP \f(CWsv_derived_from_pvn\fR 4
+.IX Xref "sv_derived_from_pvn"
+.IX Item "sv_derived_from_pvn"
+Returns a boolean indicating whether the SV is derived from the specified class
+\&\fIat the C level\fR. To check derivation at the Perl level, call \f(CWisa()\fR as a
+normal Perl method.
+.Sp
+Currently, the only significant value for \f(CW\*(C`flags\*(C'\fR is SVf_UTF8.
+.RS 4
+.Sp
+.Vb 2
+\& bool sv_derived_from_pvn(SV *sv, const char * const name,
+\& const STRLEN len, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_derived_from_sv""" 4
+.el .IP \f(CWsv_derived_from_sv\fR 4
+.IX Xref "sv_derived_from_sv"
+.IX Item "sv_derived_from_sv"
+Exactly like "sv_derived_from_pvn", but takes the name string in the form
+of an SV instead of a string/length pair. This is the advised form.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_derived_from_sv(SV *sv, SV *namesv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_does""" 4
+.el .IP \f(CWsv_does\fR 4
+.IX Xref "sv_does"
+.IX Item "sv_does"
+Like "sv_does_pv", but doesn't take a \f(CW\*(C`flags\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_does(SV *sv, const char * const name)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_does_pv""" 4
+.el .IP \f(CWsv_does_pv\fR 4
+.IX Xref "sv_does_pv"
+.IX Item "sv_does_pv"
+Like "sv_does_sv", but takes a nul-terminated string instead of an SV.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_does_pv(SV *sv, const char * const name, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_does_pvn""" 4
+.el .IP \f(CWsv_does_pvn\fR 4
+.IX Xref "sv_does_pvn"
+.IX Item "sv_does_pvn"
+Like "sv_does_sv", but takes a string/length pair instead of an SV.
+.RS 4
+.Sp
+.Vb 2
+\& bool sv_does_pvn(SV *sv, const char * const name,
+\& const STRLEN len, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_does_sv""" 4
+.el .IP \f(CWsv_does_sv\fR 4
+.IX Xref "sv_does_sv"
+.IX Item "sv_does_sv"
+Returns a boolean indicating whether the SV performs a specific, named role.
+The SV can be a Perl object or the name of a Perl class.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_does_sv(SV *sv, SV *namesv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvEND""" 4
+.el .IP \f(CWSvEND\fR 4
+.IX Xref "SvEND"
+.IX Item "SvEND"
+Returns a pointer to the spot just after the last character in
+the string which is in the SV, where there is usually a trailing
+\&\f(CW\*(C`NUL\*(C'\fR character (even though Perl scalars do not strictly require it).
+See \f(CW"SvCUR"\fR. Access the character as \f(CW\*(C`*(SvEND(sv))\*(C'\fR.
+.Sp
+Warning: If \f(CW\*(C`SvCUR\*(C'\fR is equal to \f(CW\*(C`SvLEN\*(C'\fR, then \f(CW\*(C`SvEND\*(C'\fR points to
+unallocated memory.
+.RS 4
+.Sp
+.Vb 1
+\& char* SvEND(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_eq""" 4
+.el .IP \f(CWsv_eq\fR 4
+.IX Xref "sv_eq"
+.IX Item "sv_eq"
+Returns a boolean indicating whether the strings in the two SVs are
+identical. Is UTF\-8 and \f(CW\*(Aquse\ bytes\*(Aq\fR aware, handles get magic, and will
+coerce its args to strings if necessary.
+.Sp
+This function does not handle operator overloading. For a version that does,
+see instead \f(CW\*(C`sv_streq\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 sv_eq(SV *sv1, SV *sv2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_eq_flags""" 4
+.el .IP \f(CWsv_eq_flags\fR 4
+.IX Xref "sv_eq_flags"
+.IX Item "sv_eq_flags"
+Returns a boolean indicating whether the strings in the two SVs are
+identical. Is UTF\-8 and \f(CW\*(Aquse\ bytes\*(Aq\fR aware and coerces its args to strings
+if necessary. If the flags has the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit set, it handles get-magic, too.
+.Sp
+This function does not handle operator overloading. For a version that does,
+see instead \f(CW\*(C`sv_streq_flags\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& I32 sv_eq_flags(SV *sv1, SV *sv2, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_force_normal""" 4
+.el .IP \f(CWsv_force_normal\fR 4
+.IX Xref "sv_force_normal"
+.IX Item "sv_force_normal"
+Undo various types of fakery on an SV: if the PV is a shared string, make
+a private copy; if we're a ref, stop refing; if we're a glob, downgrade to
+an \f(CW\*(C`xpvmg\*(C'\fR. See also \f(CW"sv_force_normal_flags"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_force_normal(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_force_normal_flags""" 4
+.el .IP \f(CWsv_force_normal_flags\fR 4
+.IX Xref "sv_force_normal_flags"
+.IX Item "sv_force_normal_flags"
+Undo various types of fakery on an SV, where fakery means
+"more than" a string: if the PV is a shared string, make
+a private copy; if we're a ref, stop refing; if we're a glob, downgrade to
+an \f(CW\*(C`xpvmg\*(C'\fR; if we're a copy-on-write scalar, this is the on-write time when
+we do the copy, and is also used locally; if this is a
+vstring, drop the vstring magic. If \f(CW\*(C`SV_COW_DROP_PV\*(C'\fR is set
+then a copy-on-write scalar drops its PV buffer (if any) and becomes
+\&\f(CW\*(C`SvPOK_off\*(C'\fR rather than making a copy. (Used where this
+scalar is about to be set to some other value.) In addition,
+the \f(CW\*(C`flags\*(C'\fR parameter gets passed to \f(CWsv_unref_flags()\fR
+when unreffing. \f(CW\*(C`sv_force_normal\*(C'\fR calls this function
+with flags set to 0.
+.Sp
+This function is expected to be used to signal to perl that this SV is
+about to be written to, and any extra book-keeping needs to be taken care
+of. Hence, it croaks on read-only values.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_force_normal_flags(SV * const sv, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_free""" 4
+.el .IP \f(CWsv_free\fR 4
+.IX Xref "sv_free"
+.IX Item "sv_free"
+Decrement an SV's reference count, and if it drops to zero, call
+\&\f(CW\*(C`sv_clear\*(C'\fR to invoke destructors and free up any memory used by
+the body; finally, deallocating the SV's head itself.
+Normally called via a wrapper macro \f(CW\*(C`SvREFCNT_dec\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_free(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvGAMAGIC""" 4
+.el .IP \f(CWSvGAMAGIC\fR 4
+.IX Xref "SvGAMAGIC"
+.IX Item "SvGAMAGIC"
+Returns true if the SV has get magic or
+overloading. If either is true then
+the scalar is active data, and has the potential to return a new value every
+time it is accessed. Hence you must be careful to
+only read it once per user logical operation and work
+with that returned value. If neither is true then
+the scalar's value cannot change unless written to.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvGAMAGIC(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_get_backrefs""" 4
+.el .IP \f(CWsv_get_backrefs\fR 4
+.IX Xref "sv_get_backrefs"
+.IX Item "sv_get_backrefs"
+NOTE: \f(CW\*(C`sv_get_backrefs\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+If \f(CW\*(C`sv\*(C'\fR is the target of a weak reference then it returns the back
+references structure associated with the sv; otherwise return \f(CW\*(C`NULL\*(C'\fR.
+.Sp
+When returning a non-null result the type of the return is relevant. If it
+is an AV then the elements of the AV are the weak reference RVs which
+point at this item. If it is any other type then the item itself is the
+weak reference.
+.Sp
+See also \f(CWPerl_sv_add_backref()\fR, \f(CWPerl_sv_del_backref()\fR,
+\&\f(CWPerl_sv_kill_backrefs()\fR
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_get_backrefs(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvGETMAGIC""" 4
+.el .IP \f(CWSvGETMAGIC\fR 4
+.IX Xref "SvGETMAGIC"
+.IX Item "SvGETMAGIC"
+Invokes \f(CW"mg_get"\fR on an SV if it has 'get' magic. For example, this
+will call \f(CW\*(C`FETCH\*(C'\fR on a tied variable. As of 5.37.1, this function is
+guaranteed to evaluate its argument exactly once.
+.RS 4
+.Sp
+.Vb 1
+\& void SvGETMAGIC(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_gets""" 4
+.el .IP \f(CWsv_gets\fR 4
+.IX Xref "sv_gets"
+.IX Item "sv_gets"
+Get a line from the filehandle and store it into the SV, optionally
+appending to the currently-stored string. If \f(CW\*(C`append\*(C'\fR is not 0, the
+line is appended to the SV instead of overwriting it. \f(CW\*(C`append\*(C'\fR should
+be set to the byte offset that the appended string should start at
+in the SV (typically, \f(CWSvCUR(sv)\fR is a suitable choice).
+.RS 4
+.Sp
+.Vb 1
+\& char * sv_gets(SV * const sv, PerlIO * const fp, I32 append)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvGROW""" 4
+.el .IP \f(CWSvGROW\fR 4
+.IX Xref "SvGROW"
+.IX Item "SvGROW"
+Expands the character buffer in the SV so that it has room for the
+indicated number of bytes (remember to reserve space for an extra trailing
+\&\f(CW\*(C`NUL\*(C'\fR character). Calls \f(CW\*(C`sv_grow\*(C'\fR to perform the expansion if necessary.
+Returns a pointer to the character
+buffer. SV must be of type >= \f(CW\*(C`SVt_PV\*(C'\fR. One
+alternative is to call \f(CW\*(C`sv_grow\*(C'\fR if you are not sure of the type of SV.
+.Sp
+You might mistakenly think that \f(CW\*(C`len\*(C'\fR is the number of bytes to add to the
+existing size, but instead it is the total size \f(CW\*(C`sv\*(C'\fR should be.
+.RS 4
+.Sp
+.Vb 1
+\& char * SvGROW(SV* sv, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIandPOK""" 4
+.el .IP \f(CWSvIandPOK\fR 4
+.IX Xref "SvIandPOK"
+.IX Item "SvIandPOK"
+Returns a bool indicating whether the SV is both \f(CWSvPOK()\fR and
+\&\f(CWSvIOK()\fR at the same time. Equivalent to \f(CW\*(C`SvIOK(sv) && SvPOK(sv)\*(C'\fR but
+more efficient.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvIandPOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIandPOK_off""" 4
+.el .IP \f(CWSvIandPOK_off\fR 4
+.IX Xref "SvIandPOK_off"
+.IX Item "SvIandPOK_off"
+Unsets the PV and IV status of an SV in one operation. Equivalent to
+\&\f(CW\*(C`SvIOK_off(sv); SvPK_off(v);\*(C'\fR but more efficient.
+.RS 4
+.Sp
+.Vb 1
+\& void SvIandPOK_off(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIandPOK_on""" 4
+.el .IP \f(CWSvIandPOK_on\fR 4
+.IX Xref "SvIandPOK_on"
+.IX Item "SvIandPOK_on"
+Tells an SV that is a string and a number in one operation. Equivalent
+to \f(CW\*(C`SvIOK_on(sv); SvPOK_on(sv);\*(C'\fR but more efficient.
+.RS 4
+.Sp
+.Vb 1
+\& void SvIandPOK_on(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_inc""" 4
+.el .IP \f(CWsv_inc\fR 4
+.IX Item "sv_inc"
+.PD 0
+.ie n .IP """sv_inc_nomg""" 4
+.el .IP \f(CWsv_inc_nomg\fR 4
+.IX Xref "sv_inc sv_inc_nomg"
+.IX Item "sv_inc_nomg"
+.PD
+These auto-increment the value in the SV, doing string to numeric conversion
+if necessary. They both handle operator overloading.
+.Sp
+They differ only in that \f(CW\*(C`sv_inc\*(C'\fR performs 'get' magic; \f(CW\*(C`sv_inc_nomg\*(C'\fR skips
+any magic.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_inc(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_insert""" 4
+.el .IP \f(CWsv_insert\fR 4
+.IX Xref "sv_insert"
+.IX Item "sv_insert"
+Inserts and/or replaces a string at the specified offset/length within the SV.
+Similar to the Perl \f(CWsubstr()\fR function, with \f(CW\*(C`littlelen\*(C'\fR bytes starting at
+\&\f(CW\*(C`little\*(C'\fR replacing \f(CW\*(C`len\*(C'\fR bytes of the string in \f(CW\*(C`bigstr\*(C'\fR starting at
+\&\f(CW\*(C`offset\*(C'\fR. Handles get magic.
+.RS 4
+.Sp
+.Vb 3
+\& void sv_insert(SV * const bigstr, const STRLEN offset,
+\& const STRLEN len, const char * const little,
+\& const STRLEN littlelen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_insert_flags""" 4
+.el .IP \f(CWsv_insert_flags\fR 4
+.IX Xref "sv_insert_flags"
+.IX Item "sv_insert_flags"
+Same as \f(CW\*(C`sv_insert\*(C'\fR, but the extra \f(CW\*(C`flags\*(C'\fR are passed to the
+\&\f(CW\*(C`SvPV_force_flags\*(C'\fR that applies to \f(CW\*(C`bigstr\*(C'\fR.
+.RS 4
+.Sp
+.Vb 3
+\& void sv_insert_flags(SV * const bigstr, const STRLEN offset,
+\& const STRLEN len, const char *little,
+\& const STRLEN littlelen, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2io""" 4
+.el .IP \f(CWsv_2io\fR 4
+.IX Xref "sv_2io"
+.IX Item "sv_2io"
+Using various gambits, try to get an IO from an SV: the IO slot if its a
+GV; or the recursive result if we're an RV; or the IO slot of the symbol
+named after the PV if we're a string.
+.Sp
+\&'Get' magic is ignored on the \f(CW\*(C`sv\*(C'\fR passed in, but will be called on
+\&\f(CWSvRV(sv)\fR if \f(CW\*(C`sv\*(C'\fR is an RV.
+.RS 4
+.Sp
+.Vb 1
+\& IO * sv_2io(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIOK""" 4
+.el .IP \f(CWSvIOK\fR 4
+.IX Xref "SvIOK"
+.IX Item "SvIOK"
+Returns a U32 value indicating whether the SV contains an integer.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvIOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIOK_notUV""" 4
+.el .IP \f(CWSvIOK_notUV\fR 4
+.IX Xref "SvIOK_notUV"
+.IX Item "SvIOK_notUV"
+Returns a boolean indicating whether the SV contains a signed integer.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvIOK_notUV(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIOK_off""" 4
+.el .IP \f(CWSvIOK_off\fR 4
+.IX Xref "SvIOK_off"
+.IX Item "SvIOK_off"
+Unsets the IV status of an SV.
+.RS 4
+.Sp
+.Vb 1
+\& void SvIOK_off(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIOK_on""" 4
+.el .IP \f(CWSvIOK_on\fR 4
+.IX Xref "SvIOK_on"
+.IX Item "SvIOK_on"
+Tells an SV that it is an integer.
+.RS 4
+.Sp
+.Vb 1
+\& void SvIOK_on(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIOK_only""" 4
+.el .IP \f(CWSvIOK_only\fR 4
+.IX Xref "SvIOK_only"
+.IX Item "SvIOK_only"
+Tells an SV that it is an integer and disables all other \f(CW\*(C`OK\*(C'\fR bits.
+.RS 4
+.Sp
+.Vb 1
+\& void SvIOK_only(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIOK_only_UV""" 4
+.el .IP \f(CWSvIOK_only_UV\fR 4
+.IX Xref "SvIOK_only_UV"
+.IX Item "SvIOK_only_UV"
+Tells an SV that it is an unsigned integer and disables all other \f(CW\*(C`OK\*(C'\fR bits.
+.RS 4
+.Sp
+.Vb 1
+\& void SvIOK_only_UV(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIOKp""" 4
+.el .IP \f(CWSvIOKp\fR 4
+.IX Xref "SvIOKp"
+.IX Item "SvIOKp"
+Returns a U32 value indicating whether the SV contains an integer. Checks
+the \fBprivate\fR setting. Use \f(CW\*(C`SvIOK\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvIOKp(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIOK_UV""" 4
+.el .IP \f(CWSvIOK_UV\fR 4
+.IX Xref "SvIOK_UV"
+.IX Item "SvIOK_UV"
+Returns a boolean indicating whether the SV contains an integer that must be
+interpreted as unsigned. A non-negative integer whose value is within the
+range of both an IV and a UV may be flagged as either \f(CW\*(C`SvUOK\*(C'\fR or \f(CW\*(C`SvIOK\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvIOK_UV(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_isa""" 4
+.el .IP \f(CWsv_isa\fR 4
+.IX Xref "sv_isa"
+.IX Item "sv_isa"
+Returns a boolean indicating whether the SV is blessed into the specified
+class.
+.Sp
+This does not check for subtypes or method overloading. Use \f(CW\*(C`sv_isa_sv\*(C'\fR to
+verify an inheritance relationship in the same way as the \f(CW\*(C`isa\*(C'\fR operator by
+respecting any \f(CWisa()\fR method overloading; or \f(CW\*(C`sv_derived_from_sv\*(C'\fR to test
+directly on the actual object type.
+.RS 4
+.Sp
+.Vb 1
+\& int sv_isa(SV *sv, const char * const name)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_isa_sv""" 4
+.el .IP \f(CWsv_isa_sv\fR 4
+.IX Xref "sv_isa_sv"
+.IX Item "sv_isa_sv"
+NOTE: \f(CW\*(C`sv_isa_sv\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Returns a boolean indicating whether the SV is an object reference and is
+derived from the specified class, respecting any \f(CWisa()\fR method overloading
+it may have. Returns false if \f(CW\*(C`sv\*(C'\fR is not a reference to an object, or is
+not derived from the specified class.
+.Sp
+This is the function used to implement the behaviour of the \f(CW\*(C`isa\*(C'\fR operator.
+.Sp
+Does not invoke magic on \f(CW\*(C`sv\*(C'\fR.
+.Sp
+Not to be confused with the older \f(CW\*(C`sv_isa\*(C'\fR function, which does not use an
+overloaded \f(CWisa()\fR method, nor will check subclassing.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_isa_sv(SV *sv, SV *namesv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIsBOOL""" 4
+.el .IP \f(CWSvIsBOOL\fR 4
+.IX Xref "SvIsBOOL"
+.IX Item "SvIsBOOL"
+Returns true if the SV is one of the special boolean constants (PL_sv_yes or
+PL_sv_no), or is a regular SV whose last assignment stored a copy of one.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvIsBOOL(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIsCOW""" 4
+.el .IP \f(CWSvIsCOW\fR 4
+.IX Xref "SvIsCOW"
+.IX Item "SvIsCOW"
+Returns a U32 value indicating whether the SV is Copy-On-Write (either shared
+hash key scalars, or full Copy On Write scalars if 5.9.0 is configured for
+COW).
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvIsCOW(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIsCOW_shared_hash""" 4
+.el .IP \f(CWSvIsCOW_shared_hash\fR 4
+.IX Xref "SvIsCOW_shared_hash"
+.IX Item "SvIsCOW_shared_hash"
+Returns a boolean indicating whether the SV is Copy-On-Write shared hash key
+scalar.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvIsCOW_shared_hash(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_isobject""" 4
+.el .IP \f(CWsv_isobject\fR 4
+.IX Xref "sv_isobject"
+.IX Item "sv_isobject"
+Returns a boolean indicating whether the SV is an RV pointing to a blessed
+object. If the SV is not an RV, or if the object is not blessed, then this
+will return false.
+.RS 4
+.Sp
+.Vb 1
+\& int sv_isobject(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIV""" 4
+.el .IP \f(CWSvIV\fR 4
+.IX Item "SvIV"
+.PD 0
+.ie n .IP """SvIV_nomg""" 4
+.el .IP \f(CWSvIV_nomg\fR 4
+.IX Item "SvIV_nomg"
+.ie n .IP """SvIVx""" 4
+.el .IP \f(CWSvIVx\fR 4
+.IX Xref "SvIV SvIV_nomg SvIVx"
+.IX Item "SvIVx"
+.PD
+These each coerce the given SV to IV and return it. The returned value in many
+circumstances will get stored in \f(CW\*(C`sv\*(C'\fR's IV slot, but not in all cases. (Use
+\&\f(CW"sv_setiv"\fR to make sure it does).
+.Sp
+As of 5.37.1, all are guaranteed to evaluate \f(CW\*(C`sv\*(C'\fR only once.
+.Sp
+\&\f(CW\*(C`SvIVx\*(C'\fR is now identical to \f(CW\*(C`SvIV\*(C'\fR, but prior to 5.37.1, it was the only form
+guaranteed to evaluate \f(CW\*(C`sv\*(C'\fR only once.
+.Sp
+\&\f(CW\*(C`SvIV_nomg\*(C'\fR is the same as \f(CW\*(C`SvIV\*(C'\fR, but does not perform 'get' magic.
+.RS 4
+.Sp
+.Vb 1
+\& IV SvIV(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2iv_flags""" 4
+.el .IP \f(CWsv_2iv_flags\fR 4
+.IX Xref "sv_2iv_flags"
+.IX Item "sv_2iv_flags"
+Return the integer value of an SV, doing any necessary string
+conversion. If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit set, does an \f(CWmg_get()\fR first.
+Normally used via the \f(CWSvIV(sv)\fR and \f(CWSvIVx(sv)\fR macros.
+.RS 4
+.Sp
+.Vb 1
+\& IV sv_2iv_flags(SV * const sv, const I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIV_set""" 4
+.el .IP \f(CWSvIV_set\fR 4
+.IX Xref "SvIV_set"
+.IX Item "SvIV_set"
+Set the value of the IV pointer in sv to val. It is possible to perform
+the same function of this macro with an lvalue assignment to \f(CW\*(C`SvIVX\*(C'\fR.
+With future Perls, however, it will be more efficient to use
+\&\f(CW\*(C`SvIV_set\*(C'\fR instead of the lvalue assignment to \f(CW\*(C`SvIVX\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvIV_set(SV* sv, IV val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvIVX""" 4
+.el .IP \f(CWSvIVX\fR 4
+.IX Xref "SvIVX"
+.IX Item "SvIVX"
+Returns the raw value in the SV's IV slot, without checks or conversions.
+Only use when you are sure \f(CW\*(C`SvIOK\*(C'\fR is true. See also \f(CW"SvIV"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& IV SvIVX(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvLEN""" 4
+.el .IP \f(CWSvLEN\fR 4
+.IX Xref "SvLEN"
+.IX Item "SvLEN"
+Returns the size of the string buffer in the SV, not including any part
+attributable to \f(CW\*(C`SvOOK\*(C'\fR. See \f(CW"SvCUR"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN SvLEN(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_len""" 4
+.el .IP \f(CWsv_len\fR 4
+.IX Xref "sv_len"
+.IX Item "sv_len"
+Returns the length of the string in the SV. Handles magic and type
+coercion and sets the UTF8 flag appropriately. See also \f(CW"SvCUR"\fR, which
+gives raw access to the \f(CW\*(C`xpv_cur\*(C'\fR slot.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN sv_len(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvLEN_set""" 4
+.el .IP \f(CWSvLEN_set\fR 4
+.IX Xref "SvLEN_set"
+.IX Item "SvLEN_set"
+Set the size of the string buffer for the SV. See \f(CW"SvLEN"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvLEN_set(SV* sv, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_len_utf8""" 4
+.el .IP \f(CWsv_len_utf8\fR 4
+.IX Item "sv_len_utf8"
+.PD 0
+.ie n .IP """sv_len_utf8_nomg""" 4
+.el .IP \f(CWsv_len_utf8_nomg\fR 4
+.IX Xref "sv_len_utf8 sv_len_utf8_nomg"
+.IX Item "sv_len_utf8_nomg"
+.PD
+These return the number of characters in the string in an SV, counting wide
+UTF\-8 bytes as a single character. Both handle type coercion.
+They differ only in that \f(CW\*(C`sv_len_utf8\*(C'\fR performs 'get' magic;
+\&\f(CW\*(C`sv_len_utf8_nomg\*(C'\fR skips any magic.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN sv_len_utf8(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvLOCK""" 4
+.el .IP \f(CWSvLOCK\fR 4
+.IX Xref "SvLOCK"
+.IX Item "SvLOCK"
+Arranges for a mutual exclusion lock to be obtained on \f(CW\*(C`sv\*(C'\fR if a suitable module
+has been loaded.
+.RS 4
+.Sp
+.Vb 1
+\& void SvLOCK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_magic""" 4
+.el .IP \f(CWsv_magic\fR 4
+.IX Xref "sv_magic"
+.IX Item "sv_magic"
+Adds magic to an SV. First upgrades \f(CW\*(C`sv\*(C'\fR to type \f(CW\*(C`SVt_PVMG\*(C'\fR if
+necessary, then adds a new magic item of type \f(CW\*(C`how\*(C'\fR to the head of the
+magic list.
+.Sp
+See \f(CW"sv_magicext"\fR (which \f(CW\*(C`sv_magic\*(C'\fR now calls) for a description of the
+handling of the \f(CW\*(C`name\*(C'\fR and \f(CW\*(C`namlen\*(C'\fR arguments.
+.Sp
+You need to use \f(CW\*(C`sv_magicext\*(C'\fR to add magic to \f(CW\*(C`SvREADONLY\*(C'\fR SVs and also
+to add more than one instance of the same \f(CW\*(C`how\*(C'\fR.
+.RS 4
+.Sp
+.Vb 2
+\& void sv_magic(SV * const sv, SV * const obj, const int how,
+\& const char * const name, const I32 namlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_magicext""" 4
+.el .IP \f(CWsv_magicext\fR 4
+.IX Xref "sv_magicext"
+.IX Item "sv_magicext"
+Adds magic to an SV, upgrading it if necessary. Applies the
+supplied \f(CW\*(C`vtable\*(C'\fR and returns a pointer to the magic added.
+.Sp
+Note that \f(CW\*(C`sv_magicext\*(C'\fR will allow things that \f(CW\*(C`sv_magic\*(C'\fR will not.
+In particular, you can add magic to \f(CW\*(C`SvREADONLY\*(C'\fR SVs, and add more than
+one instance of the same \f(CW\*(C`how\*(C'\fR.
+.Sp
+If \f(CW\*(C`namlen\*(C'\fR is greater than zero then a \f(CW\*(C`savepvn\*(C'\fR \fIcopy\fR of \f(CW\*(C`name\*(C'\fR is
+stored, if \f(CW\*(C`namlen\*(C'\fR is zero then \f(CW\*(C`name\*(C'\fR is stored as-is and \- as another
+special case \- if \f(CW\*(C`(name && namlen == HEf_SVKEY)\*(C'\fR then \f(CW\*(C`name\*(C'\fR is assumed
+to contain an SV* and is stored as-is with its \f(CW\*(C`REFCNT\*(C'\fR incremented.
+.Sp
+(This is now used as a subroutine by \f(CW\*(C`sv_magic\*(C'\fR.)
+.RS 4
+.Sp
+.Vb 3
+\& MAGIC * sv_magicext(SV * const sv, SV * const obj, const int how,
+\& const MGVTBL * const vtbl,
+\& const char * const name, const I32 namlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvMAGIC_set""" 4
+.el .IP \f(CWSvMAGIC_set\fR 4
+.IX Xref "SvMAGIC_set"
+.IX Item "SvMAGIC_set"
+Set the value of the MAGIC pointer in \f(CW\*(C`sv\*(C'\fR to val. See \f(CW"SvIV_set"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvMAGIC_set(SV* sv, MAGIC* val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2mortal""" 4
+.el .IP \f(CWsv_2mortal\fR 4
+.IX Xref "sv_2mortal"
+.IX Item "sv_2mortal"
+Marks an existing SV as mortal. The SV will be destroyed "soon", either
+by an explicit call to \f(CW\*(C`FREETMPS\*(C'\fR, or by an implicit call at places such as
+statement boundaries. \f(CWSvTEMP()\fR is turned on which means that the SV's
+string buffer can be "stolen" if this SV is copied. See also
+\&\f(CW"sv_newmortal"\fR and \f(CW"sv_mortalcopy"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_2mortal(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_mortalcopy""" 4
+.el .IP \f(CWsv_mortalcopy\fR 4
+.IX Xref "sv_mortalcopy"
+.IX Item "sv_mortalcopy"
+Creates a new SV which is a copy of the original SV (using \f(CW\*(C`sv_setsv\*(C'\fR).
+The new SV is marked as mortal. It will be destroyed "soon", either by an
+explicit call to \f(CW\*(C`FREETMPS\*(C'\fR, or by an implicit call at places such as
+statement boundaries. See also \f(CW"sv_newmortal"\fR and \f(CW"sv_2mortal"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_mortalcopy(SV * const oldsv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_mortalcopy_flags""" 4
+.el .IP \f(CWsv_mortalcopy_flags\fR 4
+.IX Xref "sv_mortalcopy_flags"
+.IX Item "sv_mortalcopy_flags"
+Like \f(CW\*(C`sv_mortalcopy\*(C'\fR, but the extra \f(CW\*(C`flags\*(C'\fR are passed to the
+\&\f(CW\*(C`sv_setsv_flags\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_mortalcopy_flags(SV * const oldsv, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_newmortal""" 4
+.el .IP \f(CWsv_newmortal\fR 4
+.IX Xref "sv_newmortal"
+.IX Item "sv_newmortal"
+Creates a new null SV which is mortal. The reference count of the SV is
+set to 1. It will be destroyed "soon", either by an explicit call to
+\&\f(CW\*(C`FREETMPS\*(C'\fR, or by an implicit call at places such as statement boundaries.
+See also \f(CW"sv_mortalcopy"\fR and \f(CW"sv_2mortal"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_newmortal()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNIOK""" 4
+.el .IP \f(CWSvNIOK\fR 4
+.IX Xref "SvNIOK"
+.IX Item "SvNIOK"
+Returns a U32 value indicating whether the SV contains a number, integer or
+double.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvNIOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNIOK_off""" 4
+.el .IP \f(CWSvNIOK_off\fR 4
+.IX Xref "SvNIOK_off"
+.IX Item "SvNIOK_off"
+Unsets the NV/IV status of an SV.
+.RS 4
+.Sp
+.Vb 1
+\& void SvNIOK_off(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNIOKp""" 4
+.el .IP \f(CWSvNIOKp\fR 4
+.IX Xref "SvNIOKp"
+.IX Item "SvNIOKp"
+Returns a U32 value indicating whether the SV contains a number, integer or
+double. Checks the \fBprivate\fR setting. Use \f(CW\*(C`SvNIOK\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvNIOKp(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNOK""" 4
+.el .IP \f(CWSvNOK\fR 4
+.IX Xref "SvNOK"
+.IX Item "SvNOK"
+Returns a U32 value indicating whether the SV contains a double.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvNOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNOK_off""" 4
+.el .IP \f(CWSvNOK_off\fR 4
+.IX Xref "SvNOK_off"
+.IX Item "SvNOK_off"
+Unsets the NV status of an SV.
+.RS 4
+.Sp
+.Vb 1
+\& void SvNOK_off(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNOK_on""" 4
+.el .IP \f(CWSvNOK_on\fR 4
+.IX Xref "SvNOK_on"
+.IX Item "SvNOK_on"
+Tells an SV that it is a double.
+.RS 4
+.Sp
+.Vb 1
+\& void SvNOK_on(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNOK_only""" 4
+.el .IP \f(CWSvNOK_only\fR 4
+.IX Xref "SvNOK_only"
+.IX Item "SvNOK_only"
+Tells an SV that it is a double and disables all other OK bits.
+.RS 4
+.Sp
+.Vb 1
+\& void SvNOK_only(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNOKp""" 4
+.el .IP \f(CWSvNOKp\fR 4
+.IX Xref "SvNOKp"
+.IX Item "SvNOKp"
+Returns a U32 value indicating whether the SV contains a double. Checks the
+\&\fBprivate\fR setting. Use \f(CW\*(C`SvNOK\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvNOKp(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_nolocking""" 4
+.el .IP \f(CWsv_nolocking\fR 4
+.IX Xref "sv_nolocking"
+.IX Item "sv_nolocking"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`sv_nolocking\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Dummy routine which "locks" an SV when there is no locking module present.
+Exists to avoid test for a \f(CW\*(C`NULL\*(C'\fR function pointer and because it could
+potentially warn under some level of strict-ness.
+.Sp
+"Superseded" by \f(CWsv_nosharing()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_nolocking(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_nounlocking""" 4
+.el .IP \f(CWsv_nounlocking\fR 4
+.IX Xref "sv_nounlocking"
+.IX Item "sv_nounlocking"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`sv_nounlocking\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Dummy routine which "unlocks" an SV when there is no locking module present.
+Exists to avoid test for a \f(CW\*(C`NULL\*(C'\fR function pointer and because it could
+potentially warn under some level of strict-ness.
+.Sp
+"Superseded" by \f(CWsv_nosharing()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_nounlocking(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_numeq""" 4
+.el .IP \f(CWsv_numeq\fR 4
+.IX Xref "sv_numeq"
+.IX Item "sv_numeq"
+A convenient shortcut for calling \f(CW\*(C`sv_numeq_flags\*(C'\fR with the \f(CW\*(C`SV_GMAGIC\*(C'\fR
+flag. This function basically behaves like the Perl code \f(CW\*(C`$sv1 == $sv2\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_numeq(SV *sv1, SV *sv2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_numeq_flags""" 4
+.el .IP \f(CWsv_numeq_flags\fR 4
+.IX Xref "sv_numeq_flags"
+.IX Item "sv_numeq_flags"
+Returns a boolean indicating whether the numbers in the two SVs are
+identical. If the flags argument has the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit set, it handles
+get-magic too. Will coerce its args to numbers if necessary. Treats
+\&\f(CW\*(C`NULL\*(C'\fR as undef.
+.Sp
+If flags does not have the \f(CW\*(C`SV_SKIP_OVERLOAD\*(C'\fR bit set, an attempt to use
+\&\f(CW\*(C`==\*(C'\fR overloading will be made. If such overloading does not exist or the
+flag is set, then regular numerical comparison will be used instead.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_numeq_flags(SV *sv1, SV *sv2, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNV""" 4
+.el .IP \f(CWSvNV\fR 4
+.IX Item "SvNV"
+.PD 0
+.ie n .IP """SvNV_nomg""" 4
+.el .IP \f(CWSvNV_nomg\fR 4
+.IX Item "SvNV_nomg"
+.ie n .IP """SvNVx""" 4
+.el .IP \f(CWSvNVx\fR 4
+.IX Xref "SvNV SvNV_nomg SvNVx"
+.IX Item "SvNVx"
+.PD
+These each coerce the given SV to NV and return it. The returned value in many
+circumstances will get stored in \f(CW\*(C`sv\*(C'\fR's NV slot, but not in all cases. (Use
+\&\f(CW"sv_setnv"\fR to make sure it does).
+.Sp
+As of 5.37.1, all are guaranteed to evaluate \f(CW\*(C`sv\*(C'\fR only once.
+.Sp
+\&\f(CW\*(C`SvNVx\*(C'\fR is now identical to \f(CW\*(C`SvNV\*(C'\fR, but prior to 5.37.1, it was the only form
+guaranteed to evaluate \f(CW\*(C`sv\*(C'\fR only once.
+.Sp
+\&\f(CW\*(C`SvNV_nomg\*(C'\fR is the same as \f(CW\*(C`SvNV\*(C'\fR, but does not perform 'get' magic.
+.RS 4
+.Sp
+.Vb 1
+\& NV SvNV(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2nv_flags""" 4
+.el .IP \f(CWsv_2nv_flags\fR 4
+.IX Xref "sv_2nv_flags"
+.IX Item "sv_2nv_flags"
+Return the num value of an SV, doing any necessary string or integer
+conversion. If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit set, does an \f(CWmg_get()\fR first.
+Normally used via the \f(CWSvNV(sv)\fR and \f(CWSvNVx(sv)\fR macros.
+.RS 4
+.Sp
+.Vb 1
+\& NV sv_2nv_flags(SV * const sv, const I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNV_set""" 4
+.el .IP \f(CWSvNV_set\fR 4
+.IX Xref "SvNV_set"
+.IX Item "SvNV_set"
+Set the value of the NV pointer in \f(CW\*(C`sv\*(C'\fR to val. See \f(CW"SvIV_set"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvNV_set(SV* sv, NV val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvNVX""" 4
+.el .IP \f(CWSvNVX\fR 4
+.IX Xref "SvNVX"
+.IX Item "SvNVX"
+Returns the raw value in the SV's NV slot, without checks or conversions.
+Only use when you are sure \f(CW\*(C`SvNOK\*(C'\fR is true. See also \f(CW"SvNV"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& NV SvNVX(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvOK""" 4
+.el .IP \f(CWSvOK\fR 4
+.IX Xref "SvOK"
+.IX Item "SvOK"
+Returns a U32 value indicating whether the value is defined. This is
+only meaningful for scalars.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvOOK""" 4
+.el .IP \f(CWSvOOK\fR 4
+.IX Xref "SvOOK"
+.IX Item "SvOOK"
+Returns a U32 indicating whether the pointer to the string buffer is offset.
+This hack is used internally to speed up removal of characters from the
+beginning of a \f(CW"SvPV"\fR. When \f(CW\*(C`SvOOK\*(C'\fR is true, then the start of the
+allocated string buffer is actually \f(CWSvOOK_offset()\fR bytes before \f(CW\*(C`SvPVX\*(C'\fR.
+This offset used to be stored in \f(CW\*(C`SvIVX\*(C'\fR, but is now stored within the spare
+part of the buffer.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvOOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvOOK_off""" 4
+.el .IP \f(CWSvOOK_off\fR 4
+.IX Xref "SvOOK_off"
+.IX Item "SvOOK_off"
+Remove any string offset.
+.RS 4
+.Sp
+.Vb 1
+\& void SvOOK_off(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvOOK_offset""" 4
+.el .IP \f(CWSvOOK_offset\fR 4
+.IX Xref "SvOOK_offset"
+.IX Item "SvOOK_offset"
+Reads into \f(CW\*(C`len\*(C'\fR the offset from \f(CW\*(C`SvPVX\*(C'\fR back to the true start of the
+allocated buffer, which will be non-zero if \f(CW\*(C`sv_chop\*(C'\fR has been used to
+efficiently remove characters from start of the buffer. Implemented as a
+macro, which takes the address of \f(CW\*(C`len\*(C'\fR, which must be of type \f(CW\*(C`STRLEN\*(C'\fR.
+Evaluates \f(CW\*(C`sv\*(C'\fR more than once. Sets \f(CW\*(C`len\*(C'\fR to 0 if \f(CWSvOOK(sv)\fR is false.
+.RS 4
+.Sp
+.Vb 1
+\& void SvOOK_offset(SV*sv, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPOK""" 4
+.el .IP \f(CWSvPOK\fR 4
+.IX Xref "SvPOK"
+.IX Item "SvPOK"
+Returns a U32 value indicating whether the SV contains a character
+string.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvPOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPOK_off""" 4
+.el .IP \f(CWSvPOK_off\fR 4
+.IX Xref "SvPOK_off"
+.IX Item "SvPOK_off"
+Unsets the PV status of an SV.
+.RS 4
+.Sp
+.Vb 1
+\& void SvPOK_off(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPOK_on""" 4
+.el .IP \f(CWSvPOK_on\fR 4
+.IX Xref "SvPOK_on"
+.IX Item "SvPOK_on"
+Tells an SV that it is a string.
+.RS 4
+.Sp
+.Vb 1
+\& void SvPOK_on(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPOK_only""" 4
+.el .IP \f(CWSvPOK_only\fR 4
+.IX Xref "SvPOK_only"
+.IX Item "SvPOK_only"
+Tells an SV that it is a string and disables all other \f(CW\*(C`OK\*(C'\fR bits.
+Will also turn off the UTF\-8 status.
+.RS 4
+.Sp
+.Vb 1
+\& void SvPOK_only(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPOK_only_UTF8""" 4
+.el .IP \f(CWSvPOK_only_UTF8\fR 4
+.IX Xref "SvPOK_only_UTF8"
+.IX Item "SvPOK_only_UTF8"
+Tells an SV that it is a string and disables all other \f(CW\*(C`OK\*(C'\fR bits,
+and leaves the UTF\-8 status as it was.
+.RS 4
+.Sp
+.Vb 1
+\& void SvPOK_only_UTF8(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPOKp""" 4
+.el .IP \f(CWSvPOKp\fR 4
+.IX Xref "SvPOKp"
+.IX Item "SvPOKp"
+Returns a U32 value indicating whether the SV contains a character string.
+Checks the \fBprivate\fR setting. Use \f(CW\*(C`SvPOK\*(C'\fR instead.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvPOKp(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_pos_b2u""" 4
+.el .IP \f(CWsv_pos_b2u\fR 4
+.IX Xref "sv_pos_b2u"
+.IX Item "sv_pos_b2u"
+Converts the value pointed to by \f(CW\*(C`offsetp\*(C'\fR from a count of bytes from the
+start of the string, to a count of the equivalent number of UTF\-8 chars.
+Handles magic and type coercion.
+.Sp
+Use \f(CW\*(C`sv_pos_b2u_flags\*(C'\fR in preference, which correctly handles strings
+longer than 2Gb.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_pos_b2u(SV * const sv, I32 * const offsetp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_pos_b2u_flags""" 4
+.el .IP \f(CWsv_pos_b2u_flags\fR 4
+.IX Xref "sv_pos_b2u_flags"
+.IX Item "sv_pos_b2u_flags"
+Converts \f(CW\*(C`offset\*(C'\fR from a count of bytes from the start of the string, to
+a count of the equivalent number of UTF\-8 chars. Handles type coercion.
+\&\f(CW\*(C`flags\*(C'\fR is passed to \f(CW\*(C`SvPV_flags\*(C'\fR, and usually should be
+\&\f(CW\*(C`SV_GMAGIC|SV_CONST_RETURN\*(C'\fR to handle magic.
+.RS 4
+.Sp
+.Vb 2
+\& STRLEN sv_pos_b2u_flags(SV * const sv, STRLEN const offset,
+\& U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_pos_u2b""" 4
+.el .IP \f(CWsv_pos_u2b\fR 4
+.IX Xref "sv_pos_u2b"
+.IX Item "sv_pos_u2b"
+Converts the value pointed to by \f(CW\*(C`offsetp\*(C'\fR from a count of UTF\-8 chars from
+the start of the string, to a count of the equivalent number of bytes; if
+\&\f(CW\*(C`lenp\*(C'\fR is non-zero, it does the same to \f(CW\*(C`lenp\*(C'\fR, but this time starting from
+the offset, rather than from the start of the string. Handles magic and
+type coercion.
+.Sp
+Use \f(CW\*(C`sv_pos_u2b_flags\*(C'\fR in preference, which correctly handles strings longer
+than 2Gb.
+.RS 4
+.Sp
+.Vb 2
+\& void sv_pos_u2b(SV * const sv, I32 * const offsetp,
+\& I32 * const lenp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_pos_u2b_flags""" 4
+.el .IP \f(CWsv_pos_u2b_flags\fR 4
+.IX Xref "sv_pos_u2b_flags"
+.IX Item "sv_pos_u2b_flags"
+Converts the offset from a count of UTF\-8 chars from
+the start of the string, to a count of the equivalent number of bytes; if
+\&\f(CW\*(C`lenp\*(C'\fR is non-zero, it does the same to \f(CW\*(C`lenp\*(C'\fR, but this time starting from
+\&\f(CW\*(C`offset\*(C'\fR, rather than from the start
+of the string. Handles type coercion.
+\&\f(CW\*(C`flags\*(C'\fR is passed to \f(CW\*(C`SvPV_flags\*(C'\fR, and usually should be
+\&\f(CW\*(C`SV_GMAGIC|SV_CONST_RETURN\*(C'\fR to handle magic.
+.RS 4
+.Sp
+.Vb 2
+\& STRLEN sv_pos_u2b_flags(SV * const sv, STRLEN uoffset,
+\& STRLEN * const lenp, U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPV""" 4
+.el .IP \f(CWSvPV\fR 4
+.IX Item "SvPV"
+.PD 0
+.ie n .IP """SvPV_const""" 4
+.el .IP \f(CWSvPV_const\fR 4
+.IX Item "SvPV_const"
+.ie n .IP """SvPV_flags""" 4
+.el .IP \f(CWSvPV_flags\fR 4
+.IX Item "SvPV_flags"
+.ie n .IP """SvPV_flags_const""" 4
+.el .IP \f(CWSvPV_flags_const\fR 4
+.IX Item "SvPV_flags_const"
+.ie n .IP """SvPV_flags_mutable""" 4
+.el .IP \f(CWSvPV_flags_mutable\fR 4
+.IX Item "SvPV_flags_mutable"
+.ie n .IP """SvPV_mutable""" 4
+.el .IP \f(CWSvPV_mutable\fR 4
+.IX Item "SvPV_mutable"
+.ie n .IP """SvPV_nolen""" 4
+.el .IP \f(CWSvPV_nolen\fR 4
+.IX Item "SvPV_nolen"
+.ie n .IP """SvPV_nolen_const""" 4
+.el .IP \f(CWSvPV_nolen_const\fR 4
+.IX Item "SvPV_nolen_const"
+.ie n .IP """SvPV_nomg""" 4
+.el .IP \f(CWSvPV_nomg\fR 4
+.IX Item "SvPV_nomg"
+.ie n .IP """SvPV_nomg_const""" 4
+.el .IP \f(CWSvPV_nomg_const\fR 4
+.IX Item "SvPV_nomg_const"
+.ie n .IP """SvPV_nomg_const_nolen""" 4
+.el .IP \f(CWSvPV_nomg_const_nolen\fR 4
+.IX Item "SvPV_nomg_const_nolen"
+.ie n .IP """SvPV_nomg_nolen""" 4
+.el .IP \f(CWSvPV_nomg_nolen\fR 4
+.IX Item "SvPV_nomg_nolen"
+.ie n .IP """SvPVbyte""" 4
+.el .IP \f(CWSvPVbyte\fR 4
+.IX Item "SvPVbyte"
+.ie n .IP """SvPVbyte_nolen""" 4
+.el .IP \f(CWSvPVbyte_nolen\fR 4
+.IX Item "SvPVbyte_nolen"
+.ie n .IP """SvPVbyte_nomg""" 4
+.el .IP \f(CWSvPVbyte_nomg\fR 4
+.IX Item "SvPVbyte_nomg"
+.ie n .IP """SvPVbyte_or_null""" 4
+.el .IP \f(CWSvPVbyte_or_null\fR 4
+.IX Item "SvPVbyte_or_null"
+.ie n .IP """SvPVbyte_or_null_nomg""" 4
+.el .IP \f(CWSvPVbyte_or_null_nomg\fR 4
+.IX Item "SvPVbyte_or_null_nomg"
+.ie n .IP """SvPVbytex""" 4
+.el .IP \f(CWSvPVbytex\fR 4
+.IX Item "SvPVbytex"
+.ie n .IP """SvPVbytex_nolen""" 4
+.el .IP \f(CWSvPVbytex_nolen\fR 4
+.IX Item "SvPVbytex_nolen"
+.ie n .IP """SvPVutf8""" 4
+.el .IP \f(CWSvPVutf8\fR 4
+.IX Item "SvPVutf8"
+.ie n .IP """SvPVutf8_nolen""" 4
+.el .IP \f(CWSvPVutf8_nolen\fR 4
+.IX Item "SvPVutf8_nolen"
+.ie n .IP """SvPVutf8_nomg""" 4
+.el .IP \f(CWSvPVutf8_nomg\fR 4
+.IX Item "SvPVutf8_nomg"
+.ie n .IP """SvPVutf8_or_null""" 4
+.el .IP \f(CWSvPVutf8_or_null\fR 4
+.IX Item "SvPVutf8_or_null"
+.ie n .IP """SvPVutf8_or_null_nomg""" 4
+.el .IP \f(CWSvPVutf8_or_null_nomg\fR 4
+.IX Item "SvPVutf8_or_null_nomg"
+.ie n .IP """SvPVutf8x""" 4
+.el .IP \f(CWSvPVutf8x\fR 4
+.IX Item "SvPVutf8x"
+.ie n .IP """SvPVx""" 4
+.el .IP \f(CWSvPVx\fR 4
+.IX Item "SvPVx"
+.ie n .IP """SvPVx_const""" 4
+.el .IP \f(CWSvPVx_const\fR 4
+.IX Item "SvPVx_const"
+.ie n .IP """SvPVx_nolen""" 4
+.el .IP \f(CWSvPVx_nolen\fR 4
+.IX Item "SvPVx_nolen"
+.ie n .IP """SvPVx_nolen_const""" 4
+.el .IP \f(CWSvPVx_nolen_const\fR 4
+.IX Xref "SvPV SvPV_const SvPV_flags SvPV_flags_const SvPV_flags_mutable SvPV_mutable SvPV_nolen SvPV_nolen_const SvPV_nomg SvPV_nomg_const SvPV_nomg_const_nolen SvPV_nomg_nolen SvPVbyte SvPVbyte_nolen SvPVbyte_nomg SvPVbyte_or_null SvPVbyte_or_null_nomg SvPVbytex SvPVbytex_nolen SvPVutf8 SvPVutf8_nolen SvPVutf8_nomg SvPVutf8_or_null SvPVutf8_or_null_nomg SvPVutf8x SvPVx SvPVx_const SvPVx_nolen SvPVx_nolen_const"
+.IX Item "SvPVx_nolen_const"
+.PD
+These each return a pointer to the string in \f(CW\*(C`sv\*(C'\fR, or a stringified form of
+\&\f(CW\*(C`sv\*(C'\fR if it does not contain a string. The SV may cache the stringified
+version becoming \f(CW\*(C`SvPOK\*(C'\fR.
+.Sp
+This is a very basic and common operation, so there are lots of slightly
+different versions of it.
+.Sp
+Note that there is no guarantee that the return value of \f(CWSvPV(sv)\fR, for
+example, is equal to \f(CWSvPVX(sv)\fR, or that \f(CWSvPVX(sv)\fR contains valid data, or
+that successive calls to \f(CWSvPV(sv)\fR (or another of these forms) will return
+the same pointer value each time. This is due to the way that things like
+overloading and Copy-On-Write are handled. In these cases, the return value
+may point to a temporary buffer or similar. If you absolutely need the
+\&\f(CW\*(C`SvPVX\*(C'\fR field to be valid (for example, if you intend to write to it), then
+see \f(CW"SvPV_force"\fR.
+.Sp
+The differences between the forms are:
+.Sp
+The forms with neither \f(CW\*(C`byte\*(C'\fR nor \f(CW\*(C`utf8\*(C'\fR in their names (e.g., \f(CW\*(C`SvPV\*(C'\fR or
+\&\f(CW\*(C`SvPV_nolen\*(C'\fR) can expose the SV's internal string buffer. If
+that buffer consists entirely of bytes 0\-255 and includes any bytes above
+127, then you \fBMUST\fR consult \f(CW\*(C`SvUTF8\*(C'\fR to determine the actual code points
+the string is meant to contain. Generally speaking, it is probably safer to
+prefer \f(CW\*(C`SvPVbyte\*(C'\fR, \f(CW\*(C`SvPVutf8\*(C'\fR, and the like. See
+"How do I pass a Perl string to a C library?" in perlguts for more details.
+.Sp
+The forms with \f(CW\*(C`flags\*(C'\fR in their names allow you to use the \f(CW\*(C`flags\*(C'\fR parameter
+to specify to process 'get' magic (by setting the \f(CW\*(C`SV_GMAGIC\*(C'\fR flag) or to skip
+\&'get' magic (by clearing it). The other forms process 'get' magic, except for
+the ones with \f(CW\*(C`nomg\*(C'\fR in their names, which skip 'get' magic.
+.Sp
+The forms that take a \f(CW\*(C`len\*(C'\fR parameter will set that variable to the byte
+length of the resultant string (these are macros, so don't use \f(CW&len\fR).
+.Sp
+The forms with \f(CW\*(C`nolen\*(C'\fR in their names indicate they don't have a \f(CW\*(C`len\*(C'\fR
+parameter. They should be used only when it is known that the PV is a C
+string, terminated by a NUL byte, and without intermediate NUL characters; or
+when you don't care about its length.
+.Sp
+The forms with \f(CW\*(C`const\*(C'\fR in their names return \f(CW\*(C`const\ char\ *\*(C'\fR so that the
+compiler will hopefully complain if you were to try to modify the contents of
+the string (unless you cast away const yourself).
+.Sp
+The other forms return a mutable pointer so that the string is modifiable by
+the caller; this is emphasized for the ones with \f(CW\*(C`mutable\*(C'\fR in their names.
+.Sp
+As of 5.38, all forms are guaranteed to evaluate \f(CW\*(C`sv\*(C'\fR exactly once. For
+earlier Perls, use a form whose name ends with \f(CW\*(C`x\*(C'\fR for single evaluation.
+.Sp
+\&\f(CW\*(C`SvPVutf8\*(C'\fR is like \f(CW\*(C`SvPV\*(C'\fR, but converts \f(CW\*(C`sv\*(C'\fR to UTF\-8 first if not already
+UTF\-8. Similarly, the other forms with \f(CW\*(C`utf8\*(C'\fR in their names correspond to
+their respective forms without.
+.Sp
+\&\f(CW\*(C`SvPVutf8_or_null\*(C'\fR and \f(CW\*(C`SvPVutf8_or_null_nomg\*(C'\fR don't have corresponding
+non\-\f(CW\*(C`utf8\*(C'\fR forms. Instead they are like \f(CW\*(C`SvPVutf8_nomg\*(C'\fR, but when \f(CW\*(C`sv\*(C'\fR is
+undef, they return \f(CW\*(C`NULL\*(C'\fR.
+.Sp
+\&\f(CW\*(C`SvPVbyte\*(C'\fR is like \f(CW\*(C`SvPV\*(C'\fR, but converts \f(CW\*(C`sv\*(C'\fR to byte representation first if
+currently encoded as UTF\-8. If \f(CW\*(C`sv\*(C'\fR cannot be downgraded from UTF\-8, it
+croaks. Similarly, the other forms with \f(CW\*(C`byte\*(C'\fR in their names correspond to
+their respective forms without.
+.Sp
+\&\f(CW\*(C`SvPVbyte_or_null\*(C'\fR doesn't have a corresponding non\-\f(CW\*(C`byte\*(C'\fR form. Instead it
+is like \f(CW\*(C`SvPVbyte\*(C'\fR, but when \f(CW\*(C`sv\*(C'\fR is undef, it returns \f(CW\*(C`NULL\*(C'\fR.
+.RS 4
+.Sp
+.Vb 10
+\& char* SvPV (SV* sv, STRLEN len)
+\& const char* SvPV_const (SV* sv, STRLEN len)
+\& char* SvPV_flags (SV* sv, STRLEN len, U32 flags)
+\& const char* SvPV_flags_const (SV* sv, STRLEN len, U32 flags)
+\& char* SvPV_flags_mutable (SV* sv, STRLEN len, U32 flags)
+\& char* SvPV_mutable (SV* sv, STRLEN len)
+\& char* SvPV_nolen (SV* sv)
+\& const char* SvPV_nolen_const (SV* sv)
+\& char* SvPV_nomg (SV* sv, STRLEN len)
+\& const char* SvPV_nomg_const (SV* sv, STRLEN len)
+\& const char* SvPV_nomg_const_nolen(SV* sv)
+\& char* SvPV_nomg_nolen (SV* sv)
+\& char* SvPVbyte (SV* sv, STRLEN len)
+\& char* SvPVbyte_nolen (SV* sv)
+\& char* SvPVbyte_nomg (SV* sv, STRLEN len)
+\& char* SvPVbyte_or_null (SV* sv, STRLEN len)
+\& char* SvPVbyte_or_null_nomg(SV* sv, STRLEN len)
+\& char* SvPVbytex (SV* sv, STRLEN len)
+\& char* SvPVbytex_nolen (SV* sv)
+\& char* SvPVutf8 (SV* sv, STRLEN len)
+\& char* SvPVutf8_nolen (SV* sv)
+\& char* SvPVutf8_nomg (SV* sv, STRLEN len)
+\& char* SvPVutf8_or_null (SV* sv, STRLEN len)
+\& char* SvPVutf8_or_null_nomg(SV* sv, STRLEN len)
+\& char* SvPVutf8x (SV* sv, STRLEN len)
+\& char* SvPVx (SV* sv, STRLEN len)
+\& const char* SvPVx_const (SV* sv, STRLEN len)
+\& char* SvPVx_nolen (SV* sv)
+\& const char* SvPVx_nolen_const (SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2pv""" 4
+.el .IP \f(CWsv_2pv\fR 4
+.IX Item "sv_2pv"
+.PD 0
+.ie n .IP """sv_2pv_flags""" 4
+.el .IP \f(CWsv_2pv_flags\fR 4
+.IX Xref "sv_2pv sv_2pv_flags"
+.IX Item "sv_2pv_flags"
+.PD
+These implement the various forms of the "\f(CW\*(C`SvPV\*(C'\fR" in perlapi macros.
+The macros are the preferred interface.
+.Sp
+These return a pointer to the string value of an SV (coercing it to a string if
+necessary), and set \f(CW*lp\fR to its length in bytes.
+.Sp
+The forms differ in that plain \f(CW\*(C`sv_2pvbyte\*(C'\fR always processes 'get' magic; and
+\&\f(CW\*(C`sv_2pvbyte_flags\*(C'\fR processes 'get' magic if and only if \f(CW\*(C`flags\*(C'\fR contains
+\&\f(CW\*(C`SV_GMAGIC\*(C'\fR.
+.RS 4
+.Sp
+.Vb 3
+\& char * sv_2pv (SV *sv, STRLEN *lp)
+\& char * sv_2pv_flags(SV * const sv, STRLEN * const lp,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2pvbyte""" 4
+.el .IP \f(CWsv_2pvbyte\fR 4
+.IX Item "sv_2pvbyte"
+.PD 0
+.ie n .IP """sv_2pvbyte_flags""" 4
+.el .IP \f(CWsv_2pvbyte_flags\fR 4
+.IX Xref "sv_2pvbyte sv_2pvbyte_flags"
+.IX Item "sv_2pvbyte_flags"
+.PD
+These implement the various forms of the "\f(CW\*(C`SvPVbyte\*(C'\fR" in perlapi macros.
+The macros are the preferred interface.
+.Sp
+These return a pointer to the byte-encoded representation of the SV, and set
+\&\f(CW*lp\fR to its length. If the SV is marked as being encoded as UTF\-8, it will
+be downgraded, if possible, to a byte string. If the SV cannot be downgraded,
+they croak.
+.Sp
+The forms differ in that plain \f(CW\*(C`sv_2pvbyte\*(C'\fR always processes 'get' magic; and
+\&\f(CW\*(C`sv_2pvbyte_flags\*(C'\fR processes 'get' magic if and only if \f(CW\*(C`flags\*(C'\fR contains
+\&\f(CW\*(C`SV_GMAGIC\*(C'\fR.
+.RS 4
+.Sp
+.Vb 3
+\& char * sv_2pvbyte (SV *sv, STRLEN * const lp)
+\& char * sv_2pvbyte_flags(SV *sv, STRLEN * const lp,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPVCLEAR""" 4
+.el .IP \f(CWSvPVCLEAR\fR 4
+.IX Xref "SvPVCLEAR"
+.IX Item "SvPVCLEAR"
+Ensures that sv is a SVt_PV and that its SvCUR is 0, and that it is
+properly null terminated. Equivalent to sv_setpvs(""), but more efficient.
+.RS 4
+.Sp
+.Vb 1
+\& char * SvPVCLEAR(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPVCLEAR_FRESH""" 4
+.el .IP \f(CWSvPVCLEAR_FRESH\fR 4
+.IX Xref "SvPVCLEAR_FRESH"
+.IX Item "SvPVCLEAR_FRESH"
+Like SvPVCLEAR, but optimized for newly-minted SVt_PV/PVIV/PVNV/PVMG
+that already have a PV buffer allocated, but no SvTHINKFIRST.
+.RS 4
+.Sp
+.Vb 1
+\& char * SvPVCLEAR_FRESH(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPV_force""" 4
+.el .IP \f(CWSvPV_force\fR 4
+.IX Item "SvPV_force"
+.PD 0
+.ie n .IP """SvPV_force_flags""" 4
+.el .IP \f(CWSvPV_force_flags\fR 4
+.IX Item "SvPV_force_flags"
+.ie n .IP """SvPV_force_flags_mutable""" 4
+.el .IP \f(CWSvPV_force_flags_mutable\fR 4
+.IX Item "SvPV_force_flags_mutable"
+.ie n .IP """SvPV_force_flags_nolen""" 4
+.el .IP \f(CWSvPV_force_flags_nolen\fR 4
+.IX Item "SvPV_force_flags_nolen"
+.ie n .IP """SvPV_force_mutable""" 4
+.el .IP \f(CWSvPV_force_mutable\fR 4
+.IX Item "SvPV_force_mutable"
+.ie n .IP """SvPV_force_nolen""" 4
+.el .IP \f(CWSvPV_force_nolen\fR 4
+.IX Item "SvPV_force_nolen"
+.ie n .IP """SvPV_force_nomg""" 4
+.el .IP \f(CWSvPV_force_nomg\fR 4
+.IX Item "SvPV_force_nomg"
+.ie n .IP """SvPV_force_nomg_nolen""" 4
+.el .IP \f(CWSvPV_force_nomg_nolen\fR 4
+.IX Item "SvPV_force_nomg_nolen"
+.ie n .IP """SvPVbyte_force""" 4
+.el .IP \f(CWSvPVbyte_force\fR 4
+.IX Item "SvPVbyte_force"
+.ie n .IP """SvPVbytex_force""" 4
+.el .IP \f(CWSvPVbytex_force\fR 4
+.IX Item "SvPVbytex_force"
+.ie n .IP """SvPVutf8_force""" 4
+.el .IP \f(CWSvPVutf8_force\fR 4
+.IX Item "SvPVutf8_force"
+.ie n .IP """SvPVutf8x_force""" 4
+.el .IP \f(CWSvPVutf8x_force\fR 4
+.IX Item "SvPVutf8x_force"
+.ie n .IP """SvPVx_force""" 4
+.el .IP \f(CWSvPVx_force\fR 4
+.IX Xref "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 SvPVbyte_force SvPVbytex_force SvPVutf8_force SvPVutf8x_force SvPVx_force"
+.IX Item "SvPVx_force"
+.PD
+These are like \f(CW"SvPV"\fR, returning the string in the SV, but will force the
+SV into containing a string (\f(CW"SvPOK"\fR), and only a string
+(\f(CW"SvPOK_only"\fR), by hook or by crook. You need to use one of these
+\&\f(CW\*(C`force\*(C'\fR routines if you are going to update the \f(CW"SvPVX"\fR directly.
+.Sp
+Note that coercing an arbitrary scalar into a plain PV will potentially
+strip useful data from it. For example if the SV was \f(CW\*(C`SvROK\*(C'\fR, then the
+referent will have its reference count decremented, and the SV itself may
+be converted to an \f(CW\*(C`SvPOK\*(C'\fR scalar with a string buffer containing a value
+such as \f(CW"ARRAY(0x1234)"\fR.
+.Sp
+The differences between the forms are:
+.Sp
+The forms with \f(CW\*(C`flags\*(C'\fR in their names allow you to use the \f(CW\*(C`flags\*(C'\fR parameter
+to specify to perform 'get' magic (by setting the \f(CW\*(C`SV_GMAGIC\*(C'\fR flag) or to skip
+\&'get' magic (by clearing it). The other forms do perform 'get' magic, except
+for the ones with \f(CW\*(C`nomg\*(C'\fR in their names, which skip 'get' magic.
+.Sp
+The forms that take a \f(CW\*(C`len\*(C'\fR parameter will set that variable to the byte
+length of the resultant string (these are macros, so don't use \f(CW&len\fR).
+.Sp
+The forms with \f(CW\*(C`nolen\*(C'\fR in their names indicate they don't have a \f(CW\*(C`len\*(C'\fR
+parameter. They should be used only when it is known that the PV is a C
+string, terminated by a NUL byte, and without intermediate NUL characters; or
+when you don't care about its length.
+.Sp
+The forms with \f(CW\*(C`mutable\*(C'\fR in their names are effectively the same as those without,
+but the name emphasizes that the string is modifiable by the caller, which it is
+in all the forms.
+.Sp
+\&\f(CW\*(C`SvPVutf8_force\*(C'\fR is like \f(CW\*(C`SvPV_force\*(C'\fR, but converts \f(CW\*(C`sv\*(C'\fR to UTF\-8 first if
+not already UTF\-8.
+.Sp
+\&\f(CW\*(C`SvPVutf8x_force\*(C'\fR is like \f(CW\*(C`SvPVutf8_force\*(C'\fR, but guarantees to evaluate \f(CW\*(C`sv\*(C'\fR
+only once; use the more efficient \f(CW\*(C`SvPVutf8_force\*(C'\fR otherwise.
+.Sp
+\&\f(CW\*(C`SvPVbyte_force\*(C'\fR is like \f(CW\*(C`SvPV_force\*(C'\fR, but converts \f(CW\*(C`sv\*(C'\fR to byte
+representation first if currently encoded as UTF\-8. If the SV cannot be
+downgraded from UTF\-8, this croaks.
+.Sp
+\&\f(CW\*(C`SvPVbytex_force\*(C'\fR is like \f(CW\*(C`SvPVbyte_force\*(C'\fR, but guarantees to evaluate \f(CW\*(C`sv\*(C'\fR
+only once; use the more efficient \f(CW\*(C`SvPVbyte_force\*(C'\fR otherwise.
+.RS 4
+.Sp
+.Vb 10
+\& char* SvPV_force (SV* sv, STRLEN len)
+\& char* SvPV_force_flags (SV * sv, STRLEN len, U32 flags)
+\& char* SvPV_force_flags_mutable(SV * sv, STRLEN len, U32 flags)
+\& char* SvPV_force_flags_nolen (SV * sv, U32 flags)
+\& char* SvPV_force_mutable (SV * sv, STRLEN len)
+\& char* SvPV_force_nolen (SV* sv)
+\& char* SvPV_force_nomg (SV* sv, STRLEN len)
+\& char* SvPV_force_nomg_nolen (SV * sv)
+\& char* SvPVbyte_force (SV * sv, STRLEN len)
+\& char* SvPVbytex_force (SV * sv, STRLEN len)
+\& char* SvPVutf8_force (SV * sv, STRLEN len)
+\& char* SvPVutf8x_force (SV * sv, STRLEN len)
+\& char* SvPVx_force (SV* sv, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPV_free""" 4
+.el .IP \f(CWSvPV_free\fR 4
+.IX Xref "SvPV_free"
+.IX Item "SvPV_free"
+Frees the PV buffer in \f(CW\*(C`sv\*(C'\fR, leaving things in a precarious state, so should
+only be used as part of a larger operation
+.RS 4
+.Sp
+.Vb 1
+\& void SvPV_free(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_pvn_force_flags""" 4
+.el .IP \f(CWsv_pvn_force_flags\fR 4
+.IX Xref "sv_pvn_force_flags"
+.IX Item "sv_pvn_force_flags"
+Get a sensible string out of the SV somehow.
+If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit set, will \f(CW"mg_get"\fR on \f(CW\*(C`sv\*(C'\fR if
+appropriate, else not. \f(CW\*(C`sv_pvn_force\*(C'\fR and \f(CW\*(C`sv_pvn_force_nomg\*(C'\fR are
+implemented in terms of this function.
+You normally want to use the various wrapper macros instead: see
+\&\f(CW"SvPV_force"\fR and \f(CW"SvPV_force_nomg"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& char * sv_pvn_force_flags(SV * const sv, STRLEN * const lp,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPV_renew""" 4
+.el .IP \f(CWSvPV_renew\fR 4
+.IX Xref "SvPV_renew"
+.IX Item "SvPV_renew"
+Low level micro optimization of \f(CW"SvGROW"\fR. It is generally better to use
+\&\f(CW\*(C`SvGROW\*(C'\fR instead. This is because \f(CW\*(C`SvPV_renew\*(C'\fR ignores potential issues that
+\&\f(CW\*(C`SvGROW\*(C'\fR handles. \f(CW\*(C`sv\*(C'\fR needs to have a real \f(CW\*(C`PV\*(C'\fR that is unencumbered by
+things like COW. Using \f(CW\*(C`SV_CHECK_THINKFIRST\*(C'\fR or
+\&\f(CW\*(C`SV_CHECK_THINKFIRST_COW_DROP\*(C'\fR before calling this should clean it up, but
+why not just use \f(CW\*(C`SvGROW\*(C'\fR if you're not sure about the provenance?
+.RS 4
+.Sp
+.Vb 1
+\& void SvPV_renew(SV* sv, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPV_set""" 4
+.el .IP \f(CWSvPV_set\fR 4
+.IX Xref "SvPV_set"
+.IX Item "SvPV_set"
+This is probably not what you want to use, you probably wanted
+"sv_usepvn_flags" or "sv_setpvn" or "sv_setpvs".
+.Sp
+Set the value of the PV pointer in \f(CW\*(C`sv\*(C'\fR to the Perl allocated
+\&\f(CW\*(C`NUL\*(C'\fR\-terminated string \f(CW\*(C`val\*(C'\fR. See also \f(CW"SvIV_set"\fR.
+.Sp
+Remember to free the previous PV buffer. There are many things to check.
+Beware that the existing pointer may be involved in copy-on-write or other
+mischief, so do \f(CWSvOOK_off(sv)\fR and use \f(CW\*(C`sv_force_normal\*(C'\fR or
+\&\f(CW\*(C`SvPV_force\*(C'\fR (or check the \f(CW\*(C`SvIsCOW\*(C'\fR flag) first to make sure this
+modification is safe. Then finally, if it is not a COW, call
+\&\f(CW"SvPV_free"\fR to free the previous PV buffer.
+.RS 4
+.Sp
+.Vb 1
+\& void SvPV_set(SV* sv, char* val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPV_shrink_to_cur""" 4
+.el .IP \f(CWSvPV_shrink_to_cur\fR 4
+.IX Xref "SvPV_shrink_to_cur"
+.IX Item "SvPV_shrink_to_cur"
+Trim any trailing unused memory in the PV of \f(CW\*(C`sv\*(C'\fR, which needs to have a real
+\&\f(CW\*(C`PV\*(C'\fR that is unencumbered by things like COW. Think first before using this
+functionality. Is the space saving really worth giving up COW? Will the
+needed size of \f(CW\*(C`sv\*(C'\fR stay the same?
+.Sp
+If the answers are both yes, then use "\f(CW\*(C`SV_CHECK_THINKFIRST\*(C'\fR" or
+"\f(CW\*(C`SV_CHECK_THINKFIRST_COW_DROP\*(C'\fR" before calling this.
+.RS 4
+.Sp
+.Vb 1
+\& void SvPV_shrink_to_cur(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2pvutf8""" 4
+.el .IP \f(CWsv_2pvutf8\fR 4
+.IX Item "sv_2pvutf8"
+.PD 0
+.ie n .IP """sv_2pvutf8_flags""" 4
+.el .IP \f(CWsv_2pvutf8_flags\fR 4
+.IX Xref "sv_2pvutf8 sv_2pvutf8_flags"
+.IX Item "sv_2pvutf8_flags"
+.PD
+These implement the various forms of the "\f(CW\*(C`SvPVutf8\*(C'\fR" in perlapi macros.
+The macros are the preferred interface.
+.Sp
+These return a pointer to the UTF\-8\-encoded representation of the SV, and set
+\&\f(CW*lp\fR to its length in bytes. They may cause the SV to be upgraded to UTF\-8
+as a side-effect.
+.Sp
+The forms differ in that plain \f(CW\*(C`sv_2pvutf8\*(C'\fR always processes 'get' magic; and
+\&\f(CW\*(C`sv_2pvutf8_flags\*(C'\fR processes 'get' magic if and only if \f(CW\*(C`flags\*(C'\fR contains
+\&\f(CW\*(C`SV_GMAGIC\*(C'\fR.
+.RS 4
+.Sp
+.Vb 3
+\& char * sv_2pvutf8 (SV *sv, STRLEN * const lp)
+\& char * sv_2pvutf8_flags(SV *sv, STRLEN * const lp,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPVX""" 4
+.el .IP \f(CWSvPVX\fR 4
+.IX Item "SvPVX"
+.PD 0
+.ie n .IP """SvPVX_const""" 4
+.el .IP \f(CWSvPVX_const\fR 4
+.IX Item "SvPVX_const"
+.ie n .IP """SvPVX_mutable""" 4
+.el .IP \f(CWSvPVX_mutable\fR 4
+.IX Item "SvPVX_mutable"
+.ie n .IP """SvPVXx""" 4
+.el .IP \f(CWSvPVXx\fR 4
+.IX Xref "SvPVX SvPVX_const SvPVX_mutable SvPVXx"
+.IX Item "SvPVXx"
+.PD
+These return a pointer to the physical string in the SV. The SV must contain a
+string. Prior to 5.9.3 it is not safe to execute these unless the SV's
+type >= \f(CW\*(C`SVt_PV\*(C'\fR.
+.Sp
+These are also used to store the name of an autoloaded subroutine in an XS
+AUTOLOAD routine. See "Autoloading with XSUBs" in perlguts.
+.Sp
+\&\f(CW\*(C`SvPVXx\*(C'\fR is identical to \f(CW\*(C`SvPVX\*(C'\fR.
+.Sp
+\&\f(CW\*(C`SvPVX_mutable\*(C'\fR is merely a synonym for \f(CW\*(C`SvPVX\*(C'\fR, but its name emphasizes that
+the string is modifiable by the caller.
+.Sp
+\&\f(CW\*(C`SvPVX_const\*(C'\fR differs in that the return value has been cast so that the
+compiler will complain if you were to try to modify the contents of the string,
+(unless you cast away const yourself).
+.RS 4
+.Sp
+.Vb 4
+\& char* SvPVX (SV* sv)
+\& const char* SvPVX_const (SV* sv)
+\& char* SvPVX_mutable(SV* sv)
+\& char* SvPVXx (SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvPVXtrue""" 4
+.el .IP \f(CWSvPVXtrue\fR 4
+.IX Xref "SvPVXtrue"
+.IX Item "SvPVXtrue"
+Returns a boolean as to whether or not \f(CW\*(C`sv\*(C'\fR contains a PV that is considered
+TRUE. FALSE is returned if \f(CW\*(C`sv\*(C'\fR doesn't contain a PV, or if the PV it does
+contain is zero length, or consists of just the single character '0'. Every
+other PV value is considered TRUE.
+.Sp
+As of Perl v5.37.1, \f(CW\*(C`sv\*(C'\fR is evaluated exactly once; in earlier releases, it
+could be evaluated more than once.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvPVXtrue(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvREADONLY""" 4
+.el .IP \f(CWSvREADONLY\fR 4
+.IX Xref "SvREADONLY"
+.IX Item "SvREADONLY"
+Returns true if the argument is readonly, otherwise returns false.
+Exposed to perl code via \fBInternals::SvREADONLY()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvREADONLY(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvREADONLY_off""" 4
+.el .IP \f(CWSvREADONLY_off\fR 4
+.IX Xref "SvREADONLY_off"
+.IX Item "SvREADONLY_off"
+Mark an object as not-readonly. Exactly what this mean depends on the
+object type. Exposed to perl code via \fBInternals::SvREADONLY()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvREADONLY_off(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvREADONLY_on""" 4
+.el .IP \f(CWSvREADONLY_on\fR 4
+.IX Xref "SvREADONLY_on"
+.IX Item "SvREADONLY_on"
+Mark an object as readonly. Exactly what this means depends on the object
+type. Exposed to perl code via \fBInternals::SvREADONLY()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvREADONLY_on(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_ref""" 4
+.el .IP \f(CWsv_ref\fR 4
+.IX Xref "sv_ref"
+.IX Item "sv_ref"
+Returns a SV describing what the SV passed in is a reference to.
+.Sp
+dst can be a SV to be set to the description or NULL, in which case a
+mortal SV is returned.
+.Sp
+If ob is true and the SV is blessed, the description is the class
+name, otherwise it is the type of the SV, "SCALAR", "ARRAY" etc.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_ref(SV *dst, const SV * const sv, const int ob)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvREFCNT""" 4
+.el .IP \f(CWSvREFCNT\fR 4
+.IX Xref "SvREFCNT"
+.IX Item "SvREFCNT"
+Returns the value of the object's reference count. Exposed
+to perl code via \fBInternals::SvREFCNT()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvREFCNT(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvREFCNT_dec""" 4
+.el .IP \f(CWSvREFCNT_dec\fR 4
+.IX Item "SvREFCNT_dec"
+.PD 0
+.ie n .IP """SvREFCNT_dec_set_NULL""" 4
+.el .IP \f(CWSvREFCNT_dec_set_NULL\fR 4
+.IX Item "SvREFCNT_dec_set_NULL"
+.ie n .IP """SvREFCNT_dec_ret_NULL""" 4
+.el .IP \f(CWSvREFCNT_dec_ret_NULL\fR 4
+.IX Item "SvREFCNT_dec_ret_NULL"
+.ie n .IP """SvREFCNT_dec_NN""" 4
+.el .IP \f(CWSvREFCNT_dec_NN\fR 4
+.IX Xref "SvREFCNT_dec SvREFCNT_dec_set_NULL SvREFCNT_dec_ret_NULL SvREFCNT_dec_NN"
+.IX Item "SvREFCNT_dec_NN"
+.PD
+These decrement the reference count of the given SV.
+.Sp
+\&\f(CW\*(C`SvREFCNT_dec_NN\*(C'\fR may only be used when \f(CW\*(C`sv\*(C'\fR is known to not be \f(CW\*(C`NULL\*(C'\fR.
+.Sp
+The function \f(CWSvREFCNT_dec_ret_NULL()\fR is identical to the
+\&\f(CWSvREFCNT_dec()\fR except it returns a NULL \f(CW\*(C`SV *\*(C'\fR. It is used by
+\&\f(CWSvREFCNT_dec_set_NULL()\fR which is a macro which will, when passed a
+non-NULL argument, decrement the reference count of its argument and
+then set it to NULL. You can replace code of the following form:
+.Sp
+.Vb 4
+\& if (sv) {
+\& SvREFCNT_dec_NN(sv);
+\& sv = NULL;
+\& }
+.Ve
+.Sp
+with
+.Sp
+.Vb 1
+\& SvREFCNT_dec_set_NULL(sv);
+.Ve
+.RS 4
+.Sp
+.Vb 4
+\& void SvREFCNT_dec (SV *sv)
+\& void SvREFCNT_dec_set_NULL(SV *sv)
+\& SV * SvREFCNT_dec_ret_NULL(SV *sv)
+\& void SvREFCNT_dec_NN (SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvREFCNT_inc""" 4
+.el .IP \f(CWSvREFCNT_inc\fR 4
+.IX Item "SvREFCNT_inc"
+.PD 0
+.ie n .IP """SvREFCNT_inc_NN""" 4
+.el .IP \f(CWSvREFCNT_inc_NN\fR 4
+.IX Item "SvREFCNT_inc_NN"
+.ie n .IP """SvREFCNT_inc_simple""" 4
+.el .IP \f(CWSvREFCNT_inc_simple\fR 4
+.IX Item "SvREFCNT_inc_simple"
+.ie n .IP """SvREFCNT_inc_simple_NN""" 4
+.el .IP \f(CWSvREFCNT_inc_simple_NN\fR 4
+.IX Item "SvREFCNT_inc_simple_NN"
+.ie n .IP """SvREFCNT_inc_simple_void""" 4
+.el .IP \f(CWSvREFCNT_inc_simple_void\fR 4
+.IX Item "SvREFCNT_inc_simple_void"
+.ie n .IP """SvREFCNT_inc_simple_void_NN""" 4
+.el .IP \f(CWSvREFCNT_inc_simple_void_NN\fR 4
+.IX Item "SvREFCNT_inc_simple_void_NN"
+.ie n .IP """SvREFCNT_inc_void""" 4
+.el .IP \f(CWSvREFCNT_inc_void\fR 4
+.IX Item "SvREFCNT_inc_void"
+.ie n .IP """SvREFCNT_inc_void_NN""" 4
+.el .IP \f(CWSvREFCNT_inc_void_NN\fR 4
+.IX Xref "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"
+.IX Item "SvREFCNT_inc_void_NN"
+.PD
+These all increment the reference count of the given SV.
+The ones without \f(CW\*(C`void\*(C'\fR in their names return the SV.
+.Sp
+\&\f(CW\*(C`SvREFCNT_inc\*(C'\fR is the base operation; the rest are optimizations if various
+input constraints are known to be true; hence, all can be replaced with
+\&\f(CW\*(C`SvREFCNT_inc\*(C'\fR.
+.Sp
+\&\f(CW\*(C`SvREFCNT_inc_NN\*(C'\fR can only be used if you know \f(CW\*(C`sv\*(C'\fR is not \f(CW\*(C`NULL\*(C'\fR. Since we
+don't have to check the NULLness, it's faster and smaller.
+.Sp
+\&\f(CW\*(C`SvREFCNT_inc_void\*(C'\fR can only be used if you don't need the
+return value. The macro doesn't need to return a meaningful value.
+.Sp
+\&\f(CW\*(C`SvREFCNT_inc_void_NN\*(C'\fR can only be used if you both don't need the return
+value, and you know that \f(CW\*(C`sv\*(C'\fR is not \f(CW\*(C`NULL\*(C'\fR. The macro doesn't need to
+return a meaningful value, or check for NULLness, so it's smaller and faster.
+.Sp
+\&\f(CW\*(C`SvREFCNT_inc_simple\*(C'\fR can only be used with expressions without side
+effects. Since we don't have to store a temporary value, it's faster.
+.Sp
+\&\f(CW\*(C`SvREFCNT_inc_simple_NN\*(C'\fR can only be used with expressions without side
+effects and you know \f(CW\*(C`sv\*(C'\fR is not \f(CW\*(C`NULL\*(C'\fR. Since we don't have to store a
+temporary value, nor check for NULLness, it's faster and smaller.
+.Sp
+\&\f(CW\*(C`SvREFCNT_inc_simple_void\*(C'\fR can only be used with expressions without side
+effects and you don't need the return value.
+.Sp
+\&\f(CW\*(C`SvREFCNT_inc_simple_void_NN\*(C'\fR can only be used with expressions without side
+effects, you don't need the return value, and you know \f(CW\*(C`sv\*(C'\fR is not \f(CW\*(C`NULL\*(C'\fR.
+.RS 4
+.Sp
+.Vb 8
+\& SV * SvREFCNT_inc (SV *sv)
+\& SV * SvREFCNT_inc_NN (SV *sv)
+\& SV* SvREFCNT_inc_simple (SV* sv)
+\& SV* SvREFCNT_inc_simple_NN (SV* sv)
+\& void SvREFCNT_inc_simple_void (SV* sv)
+\& void SvREFCNT_inc_simple_void_NN(SV* sv)
+\& void SvREFCNT_inc_void (SV *sv)
+\& void SvREFCNT_inc_void_NN (SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_reftype""" 4
+.el .IP \f(CWsv_reftype\fR 4
+.IX Xref "sv_reftype"
+.IX Item "sv_reftype"
+Returns a string describing what the SV is a reference to.
+.Sp
+If ob is true and the SV is blessed, the string is the class name,
+otherwise it is the type of the SV, "SCALAR", "ARRAY" etc.
+.RS 4
+.Sp
+.Vb 1
+\& const char * sv_reftype(const SV * const sv, const int ob)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_replace""" 4
+.el .IP \f(CWsv_replace\fR 4
+.IX Xref "sv_replace"
+.IX Item "sv_replace"
+Make the first argument a copy of the second, then delete the original.
+The target SV physically takes over ownership of the body of the source SV
+and inherits its flags; however, the target keeps any magic it owns,
+and any magic in the source is discarded.
+Note that this is a rather specialist SV copying operation; most of the
+time you'll want to use \f(CW\*(C`sv_setsv\*(C'\fR or one of its many macro front-ends.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_replace(SV * const sv, SV * const nsv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_report_used""" 4
+.el .IP \f(CWsv_report_used\fR 4
+.IX Xref "sv_report_used"
+.IX Item "sv_report_used"
+Dump the contents of all SVs not yet freed (debugging aid).
+.RS 4
+.Sp
+.Vb 1
+\& void sv_report_used()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_reset""" 4
+.el .IP \f(CWsv_reset\fR 4
+.IX Xref "sv_reset"
+.IX Item "sv_reset"
+Underlying implementation for the \f(CW\*(C`reset\*(C'\fR Perl function.
+Note that the perl-level function is vaguely deprecated.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_reset(const char *s, HV * const stash)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvROK""" 4
+.el .IP \f(CWSvROK\fR 4
+.IX Xref "SvROK"
+.IX Item "SvROK"
+Tests if the SV is an RV.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvROK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvROK_off""" 4
+.el .IP \f(CWSvROK_off\fR 4
+.IX Xref "SvROK_off"
+.IX Item "SvROK_off"
+Unsets the RV status of an SV.
+.RS 4
+.Sp
+.Vb 1
+\& void SvROK_off(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvROK_on""" 4
+.el .IP \f(CWSvROK_on\fR 4
+.IX Xref "SvROK_on"
+.IX Item "SvROK_on"
+Tells an SV that it is an RV.
+.RS 4
+.Sp
+.Vb 1
+\& void SvROK_on(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvRV""" 4
+.el .IP \f(CWSvRV\fR 4
+.IX Xref "SvRV"
+.IX Item "SvRV"
+Dereferences an RV to return the SV.
+.RS 4
+.Sp
+.Vb 1
+\& SV* SvRV(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvRV_set""" 4
+.el .IP \f(CWSvRV_set\fR 4
+.IX Xref "SvRV_set"
+.IX Item "SvRV_set"
+Set the value of the RV pointer in \f(CW\*(C`sv\*(C'\fR to val. See \f(CW"SvIV_set"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvRV_set(SV* sv, SV* val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_rvunweaken""" 4
+.el .IP \f(CWsv_rvunweaken\fR 4
+.IX Xref "sv_rvunweaken"
+.IX Item "sv_rvunweaken"
+Unweaken a reference: Clear the \f(CW\*(C`SvWEAKREF\*(C'\fR flag on this RV; remove
+the backreference to this RV from the array of backreferences
+associated with the target SV, increment the refcount of the target.
+Silently ignores \f(CW\*(C`undef\*(C'\fR and warns on non-weak references.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_rvunweaken(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_rvweaken""" 4
+.el .IP \f(CWsv_rvweaken\fR 4
+.IX Xref "sv_rvweaken"
+.IX Item "sv_rvweaken"
+Weaken a reference: set the \f(CW\*(C`SvWEAKREF\*(C'\fR flag on this RV; give the
+referred-to SV \f(CW\*(C`PERL_MAGIC_backref\*(C'\fR magic if it hasn't already; and
+push a back-reference to this RV onto the array of backreferences
+associated with that magic. If the RV is magical, set magic will be
+called after the RV is cleared. Silently ignores \f(CW\*(C`undef\*(C'\fR and warns
+on already-weak references.
+.RS 4
+.Sp
+.Vb 1
+\& SV * sv_rvweaken(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setbool""" 4
+.el .IP \f(CWsv_setbool\fR 4
+.IX Item "sv_setbool"
+.PD 0
+.ie n .IP """sv_setbool_mg""" 4
+.el .IP \f(CWsv_setbool_mg\fR 4
+.IX Xref "sv_setbool sv_setbool_mg"
+.IX Item "sv_setbool_mg"
+.PD
+These set an SV to a true or false boolean value, upgrading first if necessary.
+.Sp
+They differ only in that \f(CW\*(C`sv_setbool_mg\*(C'\fR handles 'set' magic; \f(CW\*(C`sv_setbool\*(C'\fR
+does not.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_setbool(SV *sv, bool b)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_set_bool""" 4
+.el .IP \f(CWsv_set_bool\fR 4
+.IX Xref "sv_set_bool"
+.IX Item "sv_set_bool"
+Equivalent to \f(CW\*(C`sv_setsv(sv, bool_val ? &Pl_sv_yes : &PL_sv_no)\*(C'\fR, but
+may be made more efficient in the future. Doesn't handle set magic.
+.Sp
+The perl equivalent is \f(CW\*(C`$sv = !!$expr;\*(C'\fR.
+.Sp
+Introduced in perl 5.35.11.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_set_bool(SV *sv, const bool bool_val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_set_false""" 4
+.el .IP \f(CWsv_set_false\fR 4
+.IX Xref "sv_set_false"
+.IX Item "sv_set_false"
+Equivalent to \f(CW\*(C`sv_setsv(sv, &PL_sv_no)\*(C'\fR, but may be made more
+efficient in the future. Doesn't handle set magic.
+.Sp
+The perl equivalent is \f(CW\*(C`$sv = !1;\*(C'\fR.
+.Sp
+Introduced in perl 5.35.11.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_set_false(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setiv""" 4
+.el .IP \f(CWsv_setiv\fR 4
+.IX Item "sv_setiv"
+.PD 0
+.ie n .IP """sv_setiv_mg""" 4
+.el .IP \f(CWsv_setiv_mg\fR 4
+.IX Xref "sv_setiv sv_setiv_mg"
+.IX Item "sv_setiv_mg"
+.PD
+These copy an integer into the given SV, upgrading first if necessary.
+.Sp
+They differ only in that \f(CW\*(C`sv_setiv_mg\*(C'\fR handles 'set' magic; \f(CW\*(C`sv_setiv\*(C'\fR does
+not.
+.RS 4
+.Sp
+.Vb 2
+\& void sv_setiv (SV * const sv, const IV num)
+\& void sv_setiv_mg(SV * const sv, const IV i)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvSETMAGIC""" 4
+.el .IP \f(CWSvSETMAGIC\fR 4
+.IX Xref "SvSETMAGIC"
+.IX Item "SvSETMAGIC"
+Invokes \f(CW"mg_set"\fR on an SV if it has 'set' magic. This is necessary
+after modifying a scalar, in case it is a magical variable like \f(CW$|\fR
+or a tied variable (it calls \f(CW\*(C`STORE\*(C'\fR). This macro evaluates its
+argument more than once.
+.RS 4
+.Sp
+.Vb 1
+\& void SvSETMAGIC(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvSetMagicSV""" 4
+.el .IP \f(CWSvSetMagicSV\fR 4
+.IX Item "SvSetMagicSV"
+.PD 0
+.ie n .IP """SvSetMagicSV_nosteal""" 4
+.el .IP \f(CWSvSetMagicSV_nosteal\fR 4
+.IX Item "SvSetMagicSV_nosteal"
+.ie n .IP """SvSetSV""" 4
+.el .IP \f(CWSvSetSV\fR 4
+.IX Item "SvSetSV"
+.ie n .IP """SvSetSV_nosteal""" 4
+.el .IP \f(CWSvSetSV_nosteal\fR 4
+.IX Xref "SvSetMagicSV SvSetMagicSV_nosteal SvSetSV SvSetSV_nosteal"
+.IX Item "SvSetSV_nosteal"
+.PD
+if \f(CW\*(C`dsv\*(C'\fR is the same as \f(CW\*(C`ssv\*(C'\fR, these do nothing. Otherwise they all call
+some form of \f(CW"sv_setsv"\fR. They may evaluate their arguments more than
+once.
+.Sp
+The only differences are:
+.Sp
+\&\f(CW\*(C`SvSetMagicSV\*(C'\fR and \f(CW\*(C`SvSetMagicSV_nosteal\*(C'\fR perform any required 'set' magic
+afterwards on the destination SV; \f(CW\*(C`SvSetSV\*(C'\fR and \f(CW\*(C`SvSetSV_nosteal\*(C'\fR do not.
+.Sp
+\&\f(CW\*(C`SvSetSV_nosteal\*(C'\fR \f(CW\*(C`SvSetMagicSV_nosteal\*(C'\fR call a non-destructive version of
+\&\f(CW\*(C`sv_setsv\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvSetMagicSV(SV* dsv, SV* ssv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setnv""" 4
+.el .IP \f(CWsv_setnv\fR 4
+.IX Item "sv_setnv"
+.PD 0
+.ie n .IP """sv_setnv_mg""" 4
+.el .IP \f(CWsv_setnv_mg\fR 4
+.IX Xref "sv_setnv sv_setnv_mg"
+.IX Item "sv_setnv_mg"
+.PD
+These copy a double into the given SV, upgrading first if necessary.
+.Sp
+They differ only in that \f(CW\*(C`sv_setnv_mg\*(C'\fR handles 'set' magic; \f(CW\*(C`sv_setnv\*(C'\fR does
+not.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_setnv(SV * const sv, const NV num)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setpv""" 4
+.el .IP \f(CWsv_setpv\fR 4
+.IX Item "sv_setpv"
+.PD 0
+.ie n .IP """sv_setpv_mg""" 4
+.el .IP \f(CWsv_setpv_mg\fR 4
+.IX Item "sv_setpv_mg"
+.ie n .IP """sv_setpvn""" 4
+.el .IP \f(CWsv_setpvn\fR 4
+.IX Item "sv_setpvn"
+.ie n .IP """sv_setpvn_fresh""" 4
+.el .IP \f(CWsv_setpvn_fresh\fR 4
+.IX Item "sv_setpvn_fresh"
+.ie n .IP """sv_setpvn_mg""" 4
+.el .IP \f(CWsv_setpvn_mg\fR 4
+.IX Item "sv_setpvn_mg"
+.ie n .IP """sv_setpvs""" 4
+.el .IP \f(CWsv_setpvs\fR 4
+.IX Item "sv_setpvs"
+.ie n .IP """sv_setpvs_mg""" 4
+.el .IP \f(CWsv_setpvs_mg\fR 4
+.IX Xref "sv_setpv sv_setpv_mg sv_setpvn sv_setpvn_fresh sv_setpvn_mg sv_setpvs sv_setpvs_mg"
+.IX Item "sv_setpvs_mg"
+.PD
+These copy a string into the SV \f(CW\*(C`sv\*(C'\fR, making sure it is \f(CW"SvPOK_only"\fR.
+.Sp
+In the \f(CW\*(C`pvs\*(C'\fR forms, the string must be a C literal string, enclosed in double
+quotes.
+.Sp
+In the \f(CW\*(C`pvn\*(C'\fR forms, the first byte of the string is pointed to by \f(CW\*(C`ptr\*(C'\fR, and
+\&\f(CW\*(C`len\*(C'\fR indicates the number of bytes to be copied, potentially including
+embedded \f(CW\*(C`NUL\*(C'\fR characters.
+.Sp
+In the plain \f(CW\*(C`pv\*(C'\fR forms, \f(CW\*(C`ptr\*(C'\fR points to a NUL-terminated C string. That is,
+it points to the first byte of the string, and the copy proceeds up through the
+first encountered \f(CW\*(C`NUL\*(C'\fR byte.
+.Sp
+In the forms that take a \f(CW\*(C`ptr\*(C'\fR argument, if it is NULL, the SV will become
+undefined.
+.Sp
+The UTF\-8 flag is not changed by these functions. A terminating NUL byte is
+guaranteed in the result.
+.Sp
+The \f(CW\*(C`_mg\*(C'\fR forms handle 'set' magic; the other forms skip all magic.
+.Sp
+\&\f(CW\*(C`sv_setpvn_fresh\*(C'\fR is a cut-down alternative to \f(CW\*(C`sv_setpvn\*(C'\fR, intended ONLY
+to be used with a fresh sv that has been upgraded to a SVt_PV, SVt_PVIV,
+SVt_PVNV, or SVt_PVMG.
+.RS 4
+.Sp
+.Vb 10
+\& void sv_setpv (SV * const sv, const char * const ptr)
+\& void sv_setpv_mg (SV * const sv, const char * const ptr)
+\& void sv_setpvn (SV * const sv, const char * const ptr,
+\& const STRLEN len)
+\& void sv_setpvn_fresh(SV * const sv, const char * const ptr,
+\& const STRLEN len)
+\& void sv_setpvn_mg (SV * const sv, const char * const ptr,
+\& const STRLEN len)
+\& void sv_setpvs (SV* sv, "literal string")
+\& void sv_setpvs_mg (SV* sv, "literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setpv_bufsize""" 4
+.el .IP \f(CWsv_setpv_bufsize\fR 4
+.IX Xref "sv_setpv_bufsize"
+.IX Item "sv_setpv_bufsize"
+Sets the SV to be a string of cur bytes length, with at least
+len bytes available. Ensures that there is a null byte at SvEND.
+Returns a char * pointer to the SvPV buffer.
+.RS 4
+.Sp
+.Vb 2
+\& char * sv_setpv_bufsize(SV * const sv, const STRLEN cur,
+\& const STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setpvf""" 4
+.el .IP \f(CWsv_setpvf\fR 4
+.IX Item "sv_setpvf"
+.PD 0
+.ie n .IP """sv_setpvf_mg""" 4
+.el .IP \f(CWsv_setpvf_mg\fR 4
+.IX Item "sv_setpvf_mg"
+.ie n .IP """sv_setpvf_mg_nocontext""" 4
+.el .IP \f(CWsv_setpvf_mg_nocontext\fR 4
+.IX Item "sv_setpvf_mg_nocontext"
+.ie n .IP """sv_setpvf_nocontext""" 4
+.el .IP \f(CWsv_setpvf_nocontext\fR 4
+.IX Xref "sv_setpvf sv_setpvf_mg sv_setpvf_mg_nocontext sv_setpvf_nocontext"
+.IX Item "sv_setpvf_nocontext"
+.PD
+These work like \f(CW"sv_catpvf"\fR but copy the text into the SV instead of
+appending it.
+.Sp
+The differences between these are:
+.Sp
+\&\f(CW\*(C`sv_setpvf_mg\*(C'\fR and \f(CW\*(C`sv_setpvf_mg_nocontext\*(C'\fR perform 'set' magic; \f(CW\*(C`sv_setpvf\*(C'\fR
+and \f(CW\*(C`sv_setpvf_nocontext\*(C'\fR skip all magic.
+.Sp
+\&\f(CW\*(C`sv_setpvf_nocontext\*(C'\fR and \f(CW\*(C`sv_setpvf_mg_nocontext\*(C'\fR do not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter, so are used in situations where the caller
+doesn't already have the thread context.
+.Sp
+NOTE: \f(CW\*(C`sv_setpvf\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_sv_setpvf\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.Sp
+NOTE: \f(CW\*(C`sv_setpvf_mg\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_sv_setpvf_mg\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 8
+\& void Perl_sv_setpvf (pTHX_ SV * const sv,
+\& const char * const pat, ...)
+\& void Perl_sv_setpvf_mg (pTHX_ SV * const sv,
+\& const char * const pat, ...)
+\& void sv_setpvf_mg_nocontext(SV * const sv,
+\& const char * const pat, ...)
+\& void sv_setpvf_nocontext (SV * const sv,
+\& const char * const pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setref_iv""" 4
+.el .IP \f(CWsv_setref_iv\fR 4
+.IX Xref "sv_setref_iv"
+.IX Item "sv_setref_iv"
+Copies an integer into a new SV, optionally blessing the SV. The \f(CW\*(C`rv\*(C'\fR
+argument will be upgraded to an RV. That RV will be modified to point to
+the new SV. The \f(CW\*(C`classname\*(C'\fR argument indicates the package for the
+blessing. Set \f(CW\*(C`classname\*(C'\fR to \f(CW\*(C`NULL\*(C'\fR to avoid the blessing. The new SV
+will have a reference count of 1, and the RV will be returned.
+.RS 4
+.Sp
+.Vb 2
+\& SV * sv_setref_iv(SV * const rv, const char * const classname,
+\& const IV iv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setref_nv""" 4
+.el .IP \f(CWsv_setref_nv\fR 4
+.IX Xref "sv_setref_nv"
+.IX Item "sv_setref_nv"
+Copies a double into a new SV, optionally blessing the SV. The \f(CW\*(C`rv\*(C'\fR
+argument will be upgraded to an RV. That RV will be modified to point to
+the new SV. The \f(CW\*(C`classname\*(C'\fR argument indicates the package for the
+blessing. Set \f(CW\*(C`classname\*(C'\fR to \f(CW\*(C`NULL\*(C'\fR to avoid the blessing. The new SV
+will have a reference count of 1, and the RV will be returned.
+.RS 4
+.Sp
+.Vb 2
+\& SV * sv_setref_nv(SV * const rv, const char * const classname,
+\& const NV nv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setref_pv""" 4
+.el .IP \f(CWsv_setref_pv\fR 4
+.IX Xref "sv_setref_pv"
+.IX Item "sv_setref_pv"
+Copies a pointer into a new SV, optionally blessing the SV. The \f(CW\*(C`rv\*(C'\fR
+argument will be upgraded to an RV. That RV will be modified to point to
+the new SV. If the \f(CW\*(C`pv\*(C'\fR argument is \f(CW\*(C`NULL\*(C'\fR, then \f(CW\*(C`PL_sv_undef\*(C'\fR will be placed
+into the SV. The \f(CW\*(C`classname\*(C'\fR argument indicates the package for the
+blessing. Set \f(CW\*(C`classname\*(C'\fR to \f(CW\*(C`NULL\*(C'\fR to avoid the blessing. The new SV
+will have a reference count of 1, and the RV will be returned.
+.Sp
+Do not use with other Perl types such as HV, AV, SV, CV, because those
+objects will become corrupted by the pointer copy process.
+.Sp
+Note that \f(CW\*(C`sv_setref_pvn\*(C'\fR copies the string while this copies the pointer.
+.RS 4
+.Sp
+.Vb 2
+\& SV * sv_setref_pv(SV * const rv, const char * const classname,
+\& void * const pv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setref_pvn""" 4
+.el .IP \f(CWsv_setref_pvn\fR 4
+.IX Xref "sv_setref_pvn"
+.IX Item "sv_setref_pvn"
+Copies a string into a new SV, optionally blessing the SV. The length of the
+string must be specified with \f(CW\*(C`n\*(C'\fR. The \f(CW\*(C`rv\*(C'\fR argument will be upgraded to
+an RV. That RV will be modified to point to the new SV. The \f(CW\*(C`classname\*(C'\fR
+argument indicates the package for the blessing. Set \f(CW\*(C`classname\*(C'\fR to
+\&\f(CW\*(C`NULL\*(C'\fR to avoid the blessing. The new SV will have a reference count
+of 1, and the RV will be returned.
+.Sp
+Note that \f(CW\*(C`sv_setref_pv\*(C'\fR copies the pointer while this copies the string.
+.RS 4
+.Sp
+.Vb 2
+\& SV * sv_setref_pvn(SV * const rv, const char * const classname,
+\& const char * const pv, const STRLEN n)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setref_pvs""" 4
+.el .IP \f(CWsv_setref_pvs\fR 4
+.IX Xref "sv_setref_pvs"
+.IX Item "sv_setref_pvs"
+Like \f(CW\*(C`sv_setref_pvn\*(C'\fR, but takes a literal string instead of
+a string/length pair.
+.RS 4
+.Sp
+.Vb 2
+\& SV * sv_setref_pvs(SV *const rv, const char *const classname,
+\& "literal string")
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setref_uv""" 4
+.el .IP \f(CWsv_setref_uv\fR 4
+.IX Xref "sv_setref_uv"
+.IX Item "sv_setref_uv"
+Copies an unsigned integer into a new SV, optionally blessing the SV. The \f(CW\*(C`rv\*(C'\fR
+argument will be upgraded to an RV. That RV will be modified to point to
+the new SV. The \f(CW\*(C`classname\*(C'\fR argument indicates the package for the
+blessing. Set \f(CW\*(C`classname\*(C'\fR to \f(CW\*(C`NULL\*(C'\fR to avoid the blessing. The new SV
+will have a reference count of 1, and the RV will be returned.
+.RS 4
+.Sp
+.Vb 2
+\& SV * sv_setref_uv(SV * const rv, const char * const classname,
+\& const UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setrv_inc""" 4
+.el .IP \f(CWsv_setrv_inc\fR 4
+.IX Item "sv_setrv_inc"
+.PD 0
+.ie n .IP """sv_setrv_inc_mg""" 4
+.el .IP \f(CWsv_setrv_inc_mg\fR 4
+.IX Xref "sv_setrv_inc sv_setrv_inc_mg"
+.IX Item "sv_setrv_inc_mg"
+.PD
+As \f(CW\*(C`sv_setrv_noinc\*(C'\fR but increments the reference count of \fIref\fR.
+.Sp
+\&\f(CW\*(C`sv_setrv_inc_mg\*(C'\fR will invoke 'set' magic on the SV; \f(CW\*(C`sv_setrv_inc\*(C'\fR will
+not.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_setrv_inc(SV * const sv, SV * const ref)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setrv_noinc""" 4
+.el .IP \f(CWsv_setrv_noinc\fR 4
+.IX Item "sv_setrv_noinc"
+.PD 0
+.ie n .IP """sv_setrv_noinc_mg""" 4
+.el .IP \f(CWsv_setrv_noinc_mg\fR 4
+.IX Xref "sv_setrv_noinc sv_setrv_noinc_mg"
+.IX Item "sv_setrv_noinc_mg"
+.PD
+Copies an SV pointer into the given SV as an SV reference, upgrading it if
+necessary. After this, \f(CWSvRV(sv)\fR is equal to \fIref\fR. This does not adjust
+the reference count of \fIref\fR. The reference \fIref\fR must not be NULL.
+.Sp
+\&\f(CW\*(C`sv_setrv_noinc_mg\*(C'\fR will invoke 'set' magic on the SV; \f(CW\*(C`sv_setrv_noinc\*(C'\fR will
+not.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_setrv_noinc(SV * const sv, SV * const ref)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setsv""" 4
+.el .IP \f(CWsv_setsv\fR 4
+.IX Item "sv_setsv"
+.PD 0
+.ie n .IP """sv_setsv_flags""" 4
+.el .IP \f(CWsv_setsv_flags\fR 4
+.IX Item "sv_setsv_flags"
+.ie n .IP """sv_setsv_mg""" 4
+.el .IP \f(CWsv_setsv_mg\fR 4
+.IX Item "sv_setsv_mg"
+.ie n .IP """sv_setsv_nomg""" 4
+.el .IP \f(CWsv_setsv_nomg\fR 4
+.IX Xref "sv_setsv sv_setsv_flags sv_setsv_mg sv_setsv_nomg"
+.IX Item "sv_setsv_nomg"
+.PD
+These copy the contents of the source SV \f(CW\*(C`ssv\*(C'\fR into the destination SV \f(CW\*(C`dsv\*(C'\fR.
+\&\f(CW\*(C`ssv\*(C'\fR may be destroyed if it is mortal, so don't use these functions if
+the source SV needs to be reused.
+Loosely speaking, they perform a copy-by-value, obliterating any previous
+content of the destination.
+.Sp
+They differ only in that:
+.Sp
+\&\f(CW\*(C`sv_setsv\*(C'\fR calls 'get' magic on \f(CW\*(C`ssv\*(C'\fR, but skips 'set' magic on \f(CW\*(C`dsv\*(C'\fR.
+.Sp
+\&\f(CW\*(C`sv_setsv_mg\*(C'\fR calls both 'get' magic on \f(CW\*(C`ssv\*(C'\fR and 'set' magic on \f(CW\*(C`dsv\*(C'\fR.
+.Sp
+\&\f(CW\*(C`sv_setsv_nomg\*(C'\fR skips all magic.
+.Sp
+\&\f(CW\*(C`sv_setsv_flags\*(C'\fR has a \f(CW\*(C`flags\*(C'\fR parameter which you can use to specify any
+combination of magic handling, and also you can specify \f(CW\*(C`SV_NOSTEAL\*(C'\fR so that
+the buffers of temps will not be stolen.
+.Sp
+You probably want to instead use one of the assortment of wrappers, such as
+\&\f(CW"SvSetSV"\fR, \f(CW"SvSetSV_nosteal"\fR, \f(CW"SvSetMagicSV"\fR and
+\&\f(CW"SvSetMagicSV_nosteal"\fR.
+.Sp
+\&\f(CW\*(C`sv_setsv_flags\*(C'\fR is the primary function for copying scalars, and most other
+copy-ish functions and macros use it underneath.
+.RS 4
+.Sp
+.Vb 4
+\& void sv_setsv (SV *dsv, SV *ssv)
+\& void sv_setsv_flags(SV *dsv, SV *ssv, const I32 flags)
+\& void sv_setsv_mg (SV * const dsv, SV * const ssv)
+\& void sv_setsv_nomg (SV *dsv, SV *ssv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_set_true""" 4
+.el .IP \f(CWsv_set_true\fR 4
+.IX Xref "sv_set_true"
+.IX Item "sv_set_true"
+Equivalent to \f(CW\*(C`sv_setsv(sv, &PL_sv_yes)\*(C'\fR, but may be made more
+efficient in the future. Doesn't handle set magic.
+.Sp
+The perl equivalent is \f(CW\*(C`$sv = !0;\*(C'\fR.
+.Sp
+Introduced in perl 5.35.11.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_set_true(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_set_undef""" 4
+.el .IP \f(CWsv_set_undef\fR 4
+.IX Xref "sv_set_undef"
+.IX Item "sv_set_undef"
+Equivalent to \f(CW\*(C`sv_setsv(sv, &PL_sv_undef)\*(C'\fR, but more efficient.
+Doesn't handle set magic.
+.Sp
+The perl equivalent is \f(CW\*(C`$sv = undef;\*(C'\fR. Note that it doesn't free any string
+buffer, unlike \f(CW\*(C`undef $sv\*(C'\fR.
+.Sp
+Introduced in perl 5.25.12.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_set_undef(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_setuv""" 4
+.el .IP \f(CWsv_setuv\fR 4
+.IX Item "sv_setuv"
+.PD 0
+.ie n .IP """sv_setuv_mg""" 4
+.el .IP \f(CWsv_setuv_mg\fR 4
+.IX Xref "sv_setuv sv_setuv_mg"
+.IX Item "sv_setuv_mg"
+.PD
+These copy an unsigned integer into the given SV, upgrading first if necessary.
+.Sp
+They differ only in that \f(CW\*(C`sv_setuv_mg\*(C'\fR handles 'set' magic; \f(CW\*(C`sv_setuv\*(C'\fR does
+not.
+.RS 4
+.Sp
+.Vb 2
+\& void sv_setuv (SV * const sv, const UV num)
+\& void sv_setuv_mg(SV * const sv, const UV u)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvSHARE""" 4
+.el .IP \f(CWSvSHARE\fR 4
+.IX Xref "SvSHARE"
+.IX Item "SvSHARE"
+Arranges for \f(CW\*(C`sv\*(C'\fR to be shared between threads if a suitable module
+has been loaded.
+.RS 4
+.Sp
+.Vb 1
+\& void SvSHARE(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvSHARED_HASH""" 4
+.el .IP \f(CWSvSHARED_HASH\fR 4
+.IX Xref "SvSHARED_HASH"
+.IX Item "SvSHARED_HASH"
+Returns the hash for \f(CW\*(C`sv\*(C'\fR created by \f(CW"newSVpvn_share"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& struct hek* SvSHARED_HASH(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvSTASH""" 4
+.el .IP \f(CWSvSTASH\fR 4
+.IX Xref "SvSTASH"
+.IX Item "SvSTASH"
+Returns the stash of the SV.
+.RS 4
+.Sp
+.Vb 1
+\& HV* SvSTASH(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvSTASH_set""" 4
+.el .IP \f(CWSvSTASH_set\fR 4
+.IX Xref "SvSTASH_set"
+.IX Item "SvSTASH_set"
+Set the value of the STASH pointer in \f(CW\*(C`sv\*(C'\fR to val. See \f(CW"SvIV_set"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvSTASH_set(SV* sv, HV* val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_streq""" 4
+.el .IP \f(CWsv_streq\fR 4
+.IX Xref "sv_streq"
+.IX Item "sv_streq"
+A convenient shortcut for calling \f(CW\*(C`sv_streq_flags\*(C'\fR with the \f(CW\*(C`SV_GMAGIC\*(C'\fR
+flag. This function basically behaves like the Perl code \f(CW\*(C`$sv1 eq $sv2\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_streq(SV *sv1, SV *sv2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_streq_flags""" 4
+.el .IP \f(CWsv_streq_flags\fR 4
+.IX Xref "sv_streq_flags"
+.IX Item "sv_streq_flags"
+Returns a boolean indicating whether the strings in the two SVs are
+identical. If the flags argument has the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit set, it handles
+get-magic too. Will coerce its args to strings if necessary. Treats
+\&\f(CW\*(C`NULL\*(C'\fR as undef. Correctly handles the UTF8 flag.
+.Sp
+If flags does not have the \f(CW\*(C`SV_SKIP_OVERLOAD\*(C'\fR bit set, an attempt to use
+\&\f(CW\*(C`eq\*(C'\fR overloading will be made. If such overloading does not exist or the
+flag is set, then regular string comparison will be used instead.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_streq_flags(SV *sv1, SV *sv2, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvTRUE""" 4
+.el .IP \f(CWSvTRUE\fR 4
+.IX Item "SvTRUE"
+.PD 0
+.ie n .IP """SvTRUE_NN""" 4
+.el .IP \f(CWSvTRUE_NN\fR 4
+.IX Item "SvTRUE_NN"
+.ie n .IP """SvTRUE_nomg""" 4
+.el .IP \f(CWSvTRUE_nomg\fR 4
+.IX Item "SvTRUE_nomg"
+.ie n .IP """SvTRUE_nomg_NN""" 4
+.el .IP \f(CWSvTRUE_nomg_NN\fR 4
+.IX Item "SvTRUE_nomg_NN"
+.ie n .IP """SvTRUEx""" 4
+.el .IP \f(CWSvTRUEx\fR 4
+.IX Xref "SvTRUE SvTRUE_NN SvTRUE_nomg SvTRUE_nomg_NN SvTRUEx"
+.IX Item "SvTRUEx"
+.PD
+These return a boolean indicating whether Perl would evaluate the SV as true or
+false. See \f(CW"SvOK"\fR for a defined/undefined test.
+.Sp
+As of Perl 5.32, all are guaranteed to evaluate \f(CW\*(C`sv\*(C'\fR only once. Prior to that
+release, only \f(CW\*(C`SvTRUEx\*(C'\fR guaranteed single evaluation; now \f(CW\*(C`SvTRUEx\*(C'\fR is
+identical to \f(CW\*(C`SvTRUE\*(C'\fR.
+.Sp
+\&\f(CW\*(C`SvTRUE_nomg\*(C'\fR and \f(CW\*(C`TRUE_nomg_NN\*(C'\fR do not perform 'get' magic; the others do
+unless the scalar is already \f(CW\*(C`SvPOK\*(C'\fR, \f(CW\*(C`SvIOK\*(C'\fR, or \f(CW\*(C`SvNOK\*(C'\fR (the public, not
+the private flags).
+.Sp
+\&\f(CW\*(C`SvTRUE_NN\*(C'\fR is like \f(CW"SvTRUE"\fR, but \f(CW\*(C`sv\*(C'\fR is assumed to be
+non-null (NN). If there is a possibility that it is NULL, use plain
+\&\f(CW\*(C`SvTRUE\*(C'\fR.
+.Sp
+\&\f(CW\*(C`SvTRUE_nomg_NN\*(C'\fR is like \f(CW"SvTRUE_nomg"\fR, but \f(CW\*(C`sv\*(C'\fR is assumed to be
+non-null (NN). If there is a possibility that it is NULL, use plain
+\&\f(CW\*(C`SvTRUE_nomg\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvTRUE(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvTYPE""" 4
+.el .IP \f(CWSvTYPE\fR 4
+.IX Xref "SvTYPE"
+.IX Item "SvTYPE"
+Returns the type of the SV. See \f(CW"svtype"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& svtype SvTYPE(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUNLOCK""" 4
+.el .IP \f(CWSvUNLOCK\fR 4
+.IX Xref "SvUNLOCK"
+.IX Item "SvUNLOCK"
+Releases a mutual exclusion lock on \f(CW\*(C`sv\*(C'\fR if a suitable module
+has been loaded.
+.RS 4
+.Sp
+.Vb 1
+\& void SvUNLOCK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_unmagic""" 4
+.el .IP \f(CWsv_unmagic\fR 4
+.IX Xref "sv_unmagic"
+.IX Item "sv_unmagic"
+Removes all magic of type \f(CW\*(C`type\*(C'\fR from an SV.
+.RS 4
+.Sp
+.Vb 1
+\& int sv_unmagic(SV * const sv, const int type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_unmagicext""" 4
+.el .IP \f(CWsv_unmagicext\fR 4
+.IX Xref "sv_unmagicext"
+.IX Item "sv_unmagicext"
+Removes all magic of type \f(CW\*(C`type\*(C'\fR with the specified \f(CW\*(C`vtbl\*(C'\fR from an SV.
+.RS 4
+.Sp
+.Vb 2
+\& int sv_unmagicext(SV * const sv, const int type,
+\& const MGVTBL *vtbl)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_unref""" 4
+.el .IP \f(CWsv_unref\fR 4
+.IX Xref "sv_unref"
+.IX Item "sv_unref"
+Unsets the RV status of the SV, and decrements the reference count of
+whatever was being referenced by the RV. This can almost be thought of
+as a reversal of \f(CW\*(C`newSVrv\*(C'\fR. This is \f(CW\*(C`sv_unref_flags\*(C'\fR with the \f(CW\*(C`flag\*(C'\fR
+being zero. See \f(CW"SvROK_off"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_unref(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_unref_flags""" 4
+.el .IP \f(CWsv_unref_flags\fR 4
+.IX Xref "sv_unref_flags"
+.IX Item "sv_unref_flags"
+Unsets the RV status of the SV, and decrements the reference count of
+whatever was being referenced by the RV. This can almost be thought of
+as a reversal of \f(CW\*(C`newSVrv\*(C'\fR. The \f(CW\*(C`cflags\*(C'\fR argument can contain
+\&\f(CW\*(C`SV_IMMEDIATE_UNREF\*(C'\fR to force the reference count to be decremented
+(otherwise the decrementing is conditional on the reference count being
+different from one or the reference being a readonly SV).
+See \f(CW"SvROK_off"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_unref_flags(SV * const ref, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUOK""" 4
+.el .IP \f(CWSvUOK\fR 4
+.IX Xref "SvUOK"
+.IX Item "SvUOK"
+Returns a boolean indicating whether the SV contains an integer that must be
+interpreted as unsigned. A non-negative integer whose value is within the
+range of both an IV and a UV may be flagged as either \f(CW\*(C`SvUOK\*(C'\fR or \f(CW\*(C`SvIOK\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvUOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUPGRADE""" 4
+.el .IP \f(CWSvUPGRADE\fR 4
+.IX Xref "SvUPGRADE"
+.IX Item "SvUPGRADE"
+Used to upgrade an SV to a more complex form. Uses \f(CW\*(C`sv_upgrade\*(C'\fR to
+perform the upgrade if necessary. See \f(CW"svtype"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvUPGRADE(SV* sv, svtype type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_upgrade""" 4
+.el .IP \f(CWsv_upgrade\fR 4
+.IX Xref "sv_upgrade"
+.IX Item "sv_upgrade"
+Upgrade an SV to a more complex form. Generally adds a new body type to the
+SV, then copies across as much information as possible from the old body.
+It croaks if the SV is already in a more complex form than requested. You
+generally want to use the \f(CW\*(C`SvUPGRADE\*(C'\fR macro wrapper, which checks the type
+before calling \f(CW\*(C`sv_upgrade\*(C'\fR, and hence does not croak. See also
+\&\f(CW"svtype"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_upgrade(SV * const sv, svtype new_type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_usepvn""" 4
+.el .IP \f(CWsv_usepvn\fR 4
+.IX Item "sv_usepvn"
+.PD 0
+.ie n .IP """sv_usepvn_flags""" 4
+.el .IP \f(CWsv_usepvn_flags\fR 4
+.IX Item "sv_usepvn_flags"
+.ie n .IP """sv_usepvn_mg""" 4
+.el .IP \f(CWsv_usepvn_mg\fR 4
+.IX Xref "sv_usepvn sv_usepvn_flags sv_usepvn_mg"
+.IX Item "sv_usepvn_mg"
+.PD
+These tell an SV to use \f(CW\*(C`ptr\*(C'\fR for its string value. Normally SVs have
+their string stored inside the SV, but these tell the SV to use an
+external string instead.
+.Sp
+\&\f(CW\*(C`ptr\*(C'\fR should point to memory that was allocated
+by "\f(CW\*(C`Newx\*(C'\fR". It must be
+the start of a \f(CW\*(C`Newx\*(C'\fR\-ed block of memory, and not a pointer to the
+middle of it (beware of \f(CW\*(C`OOK\*(C'\fR and copy-on-write),
+and not be from a non\-\f(CW\*(C`Newx\*(C'\fR memory allocator like \f(CW\*(C`malloc\*(C'\fR. The
+string length, \f(CW\*(C`len\*(C'\fR, must be supplied. By default this function
+will "\f(CW\*(C`Renew\*(C'\fR" (i.e. realloc, move) the memory pointed to by \f(CW\*(C`ptr\*(C'\fR,
+so that the pointer should not be freed or used by the programmer after giving
+it to \f(CW\*(C`sv_usepvn\*(C'\fR, and neither should any pointers from "behind" that pointer
+(\fIe.g.\fR, \f(CW\*(C`ptr\*(C'\fR\ +\ 1) be used.
+.Sp
+In the \f(CW\*(C`sv_usepvn_flags\*(C'\fR form, if \f(CW\*(C`flags\ &\ SV_SMAGIC\*(C'\fR is true,
+\&\f(CW\*(C`SvSETMAGIC\*(C'\fR is called before returning.
+And if \f(CW\*(C`flags\ &\ SV_HAS_TRAILING_NUL\*(C'\fR is true, then \f(CW\*(C`ptr[len]\*(C'\fR must be
+\&\f(CW\*(C`NUL\*(C'\fR, and the realloc will be skipped (\fIi.e.\fR, the buffer is actually at
+least 1 byte longer than \f(CW\*(C`len\*(C'\fR, and already meets the requirements for storing
+in \f(CW\*(C`SvPVX\*(C'\fR).
+.Sp
+\&\f(CW\*(C`sv_usepvn\*(C'\fR is merely \f(CW\*(C`sv_usepvn_flags\*(C'\fR with \f(CW\*(C`flags\*(C'\fR set to 0, so 'set'
+magic is skipped.
+.Sp
+\&\f(CW\*(C`sv_usepvn_mg\*(C'\fR is merely \f(CW\*(C`sv_usepvn_flags\*(C'\fR with \f(CW\*(C`flags\*(C'\fR set to \f(CW\*(C`SV_SMAGIC\*(C'\fR,
+so 'set' magic is performed.
+.RS 4
+.Sp
+.Vb 4
+\& void sv_usepvn (SV *sv, char *ptr, STRLEN len)
+\& void sv_usepvn_flags(SV * const sv, char *ptr, const STRLEN len,
+\& const U32 flags)
+\& void sv_usepvn_mg (SV *sv, char *ptr, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_utf8_decode""" 4
+.el .IP \f(CWsv_utf8_decode\fR 4
+.IX Xref "sv_utf8_decode"
+.IX Item "sv_utf8_decode"
+If the PV of the SV is an octet sequence in Perl's extended UTF\-8
+and contains a multiple-byte character, the \f(CW\*(C`SvUTF8\*(C'\fR flag is turned on
+so that it looks like a character. If the PV contains only single-byte
+characters, the \f(CW\*(C`SvUTF8\*(C'\fR flag stays off.
+Scans PV for validity and returns FALSE if the PV is invalid UTF\-8.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_utf8_decode(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_utf8_downgrade""" 4
+.el .IP \f(CWsv_utf8_downgrade\fR 4
+.IX Item "sv_utf8_downgrade"
+.PD 0
+.ie n .IP """sv_utf8_downgrade_flags""" 4
+.el .IP \f(CWsv_utf8_downgrade_flags\fR 4
+.IX Item "sv_utf8_downgrade_flags"
+.ie n .IP """sv_utf8_downgrade_nomg""" 4
+.el .IP \f(CWsv_utf8_downgrade_nomg\fR 4
+.IX Xref "sv_utf8_downgrade sv_utf8_downgrade_flags sv_utf8_downgrade_nomg"
+.IX Item "sv_utf8_downgrade_nomg"
+.PD
+These attempt to convert the PV of an SV from characters to bytes. If the PV
+contains a character that cannot fit in a byte, this conversion will fail; in
+this case, \f(CW\*(C`FALSE\*(C'\fR is returned if \f(CW\*(C`fail_ok\*(C'\fR is true; otherwise they croak.
+.Sp
+They are not a general purpose Unicode to byte encoding interface:
+use the \f(CW\*(C`Encode\*(C'\fR extension for that.
+.Sp
+They differ only in that:
+.Sp
+\&\f(CW\*(C`sv_utf8_downgrade\*(C'\fR processes 'get' magic on \f(CW\*(C`sv\*(C'\fR.
+.Sp
+\&\f(CW\*(C`sv_utf8_downgrade_nomg\*(C'\fR does not.
+.Sp
+\&\f(CW\*(C`sv_utf8_downgrade_flags\*(C'\fR has an additional \f(CW\*(C`flags\*(C'\fR parameter in which you can specify
+\&\f(CW\*(C`SV_GMAGIC\*(C'\fR to process 'get' magic, or leave it cleared to not process 'get' magic.
+.RS 4
+.Sp
+.Vb 4
+\& bool sv_utf8_downgrade (SV * const sv, const bool fail_ok)
+\& bool sv_utf8_downgrade_flags(SV * const sv, const bool fail_ok,
+\& const U32 flags)
+\& bool sv_utf8_downgrade_nomg (SV * const sv, const bool fail_ok)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_utf8_encode""" 4
+.el .IP \f(CWsv_utf8_encode\fR 4
+.IX Xref "sv_utf8_encode"
+.IX Item "sv_utf8_encode"
+Converts the PV of an SV to UTF\-8, but then turns the \f(CW\*(C`SvUTF8\*(C'\fR
+flag off so that it looks like octets again.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_utf8_encode(SV * const sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUTF8_off""" 4
+.el .IP \f(CWSvUTF8_off\fR 4
+.IX Xref "SvUTF8_off"
+.IX Item "SvUTF8_off"
+Unsets the UTF\-8 status of an SV (the data is not changed, just the flag).
+Do not use frivolously.
+.RS 4
+.Sp
+.Vb 1
+\& void SvUTF8_off(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUTF8_on""" 4
+.el .IP \f(CWSvUTF8_on\fR 4
+.IX Xref "SvUTF8_on"
+.IX Item "SvUTF8_on"
+Turn on the UTF\-8 status of an SV (the data is not changed, just the flag).
+Do not use frivolously.
+.RS 4
+.Sp
+.Vb 1
+\& void SvUTF8_on(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_utf8_upgrade""" 4
+.el .IP \f(CWsv_utf8_upgrade\fR 4
+.IX Item "sv_utf8_upgrade"
+.PD 0
+.ie n .IP """sv_utf8_upgrade_flags""" 4
+.el .IP \f(CWsv_utf8_upgrade_flags\fR 4
+.IX Item "sv_utf8_upgrade_flags"
+.ie n .IP """sv_utf8_upgrade_flags_grow""" 4
+.el .IP \f(CWsv_utf8_upgrade_flags_grow\fR 4
+.IX Item "sv_utf8_upgrade_flags_grow"
+.ie n .IP """sv_utf8_upgrade_nomg""" 4
+.el .IP \f(CWsv_utf8_upgrade_nomg\fR 4
+.IX Xref "sv_utf8_upgrade sv_utf8_upgrade_flags sv_utf8_upgrade_flags_grow sv_utf8_upgrade_nomg"
+.IX Item "sv_utf8_upgrade_nomg"
+.PD
+These convert the PV of an SV to its UTF\-8\-encoded form.
+The SV is forced to string form if it is not already.
+They always set the \f(CW\*(C`SvUTF8\*(C'\fR flag to avoid future validity checks even if the
+whole string is the same in UTF\-8 as not.
+They return the number of bytes in the converted string
+.Sp
+The forms differ in just two ways. The main difference is whether or not they
+perform 'get magic' on \f(CW\*(C`sv\*(C'\fR. \f(CW\*(C`sv_utf8_upgrade_nomg\*(C'\fR skips 'get magic';
+\&\f(CW\*(C`sv_utf8_upgrade\*(C'\fR performs it; and \f(CW\*(C`sv_utf8_upgrade_flags\*(C'\fR and
+\&\f(CW\*(C`sv_utf8_upgrade_flags_grow\*(C'\fR either perform it (if the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit is set
+in \f(CW\*(C`flags\*(C'\fR) or don't (if that bit is cleared).
+.Sp
+The other difference is that \f(CW\*(C`sv_utf8_upgrade_flags_grow\*(C'\fR has an additional
+parameter, \f(CW\*(C`extra\*(C'\fR, which allows the caller to specify an amount of space to
+be reserved as spare beyond what is needed for the actual conversion. This is
+used when the caller knows it will soon be needing yet more space, and it is
+more efficient to request space from the system in a single call.
+This form is otherwise identical to \f(CW\*(C`sv_utf8_upgrade_flags\*(C'\fR.
+.Sp
+These are not a general purpose byte encoding to Unicode interface: use the
+Encode extension for that.
+.Sp
+The \f(CW\*(C`SV_FORCE_UTF8_UPGRADE\*(C'\fR flag is now ignored.
+.RS 4
+.Sp
+.Vb 5
+\& STRLEN sv_utf8_upgrade (SV *sv)
+\& STRLEN sv_utf8_upgrade_flags (SV * const sv, const I32 flags)
+\& STRLEN sv_utf8_upgrade_flags_grow(SV * const sv, const I32 flags,
+\& STRLEN extra)
+\& STRLEN sv_utf8_upgrade_nomg (SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUTF8""" 4
+.el .IP \f(CWSvUTF8\fR 4
+.IX Xref "SvUTF8"
+.IX Item "SvUTF8"
+Returns a U32 value indicating the UTF\-8 status of an SV. If things are set-up
+properly, this indicates whether or not the SV contains UTF\-8 encoded data.
+You should use this \fIafter\fR a call to \f(CW"SvPV"\fR or one of its variants, in
+case any call to string overloading updates the internal flag.
+.Sp
+If you want to take into account the bytes pragma, use \f(CW"DO_UTF8"\fR
+instead.
+.RS 4
+.Sp
+.Vb 1
+\& U32 SvUTF8(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUV""" 4
+.el .IP \f(CWSvUV\fR 4
+.IX Item "SvUV"
+.PD 0
+.ie n .IP """SvUV_nomg""" 4
+.el .IP \f(CWSvUV_nomg\fR 4
+.IX Item "SvUV_nomg"
+.ie n .IP """SvUVx""" 4
+.el .IP \f(CWSvUVx\fR 4
+.IX Xref "SvUV SvUV_nomg SvUVx"
+.IX Item "SvUVx"
+.PD
+These each coerce the given SV to UV and return it. The returned value in many
+circumstances will get stored in \f(CW\*(C`sv\*(C'\fR's UV slot, but not in all cases. (Use
+\&\f(CW"sv_setuv"\fR to make sure it does).
+.Sp
+As of 5.37.1, all are guaranteed to evaluate \f(CW\*(C`sv\*(C'\fR only once.
+.Sp
+\&\f(CW\*(C`SvUVx\*(C'\fR is now identical to \f(CW\*(C`SvUV\*(C'\fR, but prior to 5.37.1, it was the only form
+guaranteed to evaluate \f(CW\*(C`sv\*(C'\fR only once.
+.RS 4
+.Sp
+.Vb 1
+\& UV SvUV(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_2uv_flags""" 4
+.el .IP \f(CWsv_2uv_flags\fR 4
+.IX Xref "sv_2uv_flags"
+.IX Item "sv_2uv_flags"
+Return the unsigned integer value of an SV, doing any necessary string
+conversion. If \f(CW\*(C`flags\*(C'\fR has the \f(CW\*(C`SV_GMAGIC\*(C'\fR bit set, does an \f(CWmg_get()\fR first.
+Normally used via the \f(CWSvUV(sv)\fR and \f(CWSvUVx(sv)\fR macros.
+.RS 4
+.Sp
+.Vb 1
+\& UV sv_2uv_flags(SV * const sv, const I32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUV_set""" 4
+.el .IP \f(CWSvUV_set\fR 4
+.IX Xref "SvUV_set"
+.IX Item "SvUV_set"
+Set the value of the UV pointer in \f(CW\*(C`sv\*(C'\fR to val. See \f(CW"SvIV_set"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void SvUV_set(SV* sv, UV val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUVX""" 4
+.el .IP \f(CWSvUVX\fR 4
+.IX Xref "SvUVX"
+.IX Item "SvUVX"
+Returns the raw value in the SV's UV slot, without checks or conversions.
+Only use when you are sure \f(CW\*(C`SvIOK\*(C'\fR is true. See also \f(CW"SvUV"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& UV SvUVX(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvUVXx""" 4
+.el .IP \f(CWSvUVXx\fR 4
+.IX Xref "SvUVXx"
+.IX Item "SvUVXx"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`SvUVXx\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+This is an unnecessary synonym for "SvUVX"
+.RS 4
+.Sp
+.Vb 1
+\& UV SvUVXx(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_vcatpvf""" 4
+.el .IP \f(CWsv_vcatpvf\fR 4
+.IX Item "sv_vcatpvf"
+.PD 0
+.ie n .IP """sv_vcatpvf_mg""" 4
+.el .IP \f(CWsv_vcatpvf_mg\fR 4
+.IX Xref "sv_vcatpvf sv_vcatpvf_mg"
+.IX Item "sv_vcatpvf_mg"
+.PD
+These process their arguments like \f(CW\*(C`sv_vcatpvfn\*(C'\fR called with a non-null
+C\-style variable argument list, and append the formatted output to \f(CW\*(C`sv\*(C'\fR.
+.Sp
+They differ only in that \f(CW\*(C`sv_vcatpvf_mg\*(C'\fR performs 'set' magic;
+\&\f(CW\*(C`sv_vcatpvf\*(C'\fR skips 'set' magic.
+.Sp
+Both perform 'get' magic.
+.Sp
+They are usually accessed via their frontends \f(CW"sv_catpvf"\fR and
+\&\f(CW"sv_catpvf_mg"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& void sv_vcatpvf(SV * const sv, const char * const pat,
+\& va_list * const args)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_vcatpvfn""" 4
+.el .IP \f(CWsv_vcatpvfn\fR 4
+.IX Item "sv_vcatpvfn"
+.PD 0
+.ie n .IP """sv_vcatpvfn_flags""" 4
+.el .IP \f(CWsv_vcatpvfn_flags\fR 4
+.IX Xref "sv_vcatpvfn sv_vcatpvfn_flags"
+.IX Item "sv_vcatpvfn_flags"
+.PD
+These process their arguments like \f(CWvsprintf(3)\fR and append the formatted output
+to an SV. They use an array of SVs if the C\-style variable argument list is
+missing (\f(CW\*(C`NULL\*(C'\fR). Argument reordering (using format specifiers like \f(CW\*(C`%2$d\*(C'\fR or
+\&\f(CW\*(C`%*2$d\*(C'\fR) is supported only when using an array of SVs; using a C\-style
+\&\f(CW\*(C`va_list\*(C'\fR argument list with a format string that uses argument reordering
+will yield an exception.
+.Sp
+When running with taint checks enabled, they indicate via \f(CW\*(C`maybe_tainted\*(C'\fR if
+results are untrustworthy (often due to the use of locales).
+.Sp
+They assume that \f(CW\*(C`pat\*(C'\fR has the same utf8\-ness as \f(CW\*(C`sv\*(C'\fR. It's the caller's
+responsibility to ensure that this is so.
+.Sp
+They differ in that \f(CW\*(C`sv_vcatpvfn_flags\*(C'\fR has a \f(CW\*(C`flags\*(C'\fR parameter in which you
+can set or clear the \f(CW\*(C`SV_GMAGIC\*(C'\fR and/or SV_SMAGIC flags, to specify which
+magic to handle or not handle; whereas plain \f(CW\*(C`sv_vcatpvfn\*(C'\fR always specifies
+both 'get' and 'set' magic.
+.Sp
+They are usually used via one of the frontends "\f(CW\*(C`sv_vcatpvf\*(C'\fR" and
+"\f(CW\*(C`sv_vcatpvf_mg\*(C'\fR".
+.RS 4
+.Sp
+.Vb 9
+\& void sv_vcatpvfn (SV * const sv, const char * const pat,
+\& const STRLEN patlen, va_list * const args,
+\& SV ** const svargs, const Size_t sv_count,
+\& bool * const maybe_tainted)
+\& void sv_vcatpvfn_flags(SV * const sv, const char * const pat,
+\& const STRLEN patlen, va_list * const args,
+\& SV ** const svargs, const Size_t sv_count,
+\& bool * const maybe_tainted,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvVOK""" 4
+.el .IP \f(CWSvVOK\fR 4
+.IX Xref "SvVOK"
+.IX Item "SvVOK"
+Returns a boolean indicating whether the SV contains a v\-string.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvVOK(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_vsetpvf""" 4
+.el .IP \f(CWsv_vsetpvf\fR 4
+.IX Item "sv_vsetpvf"
+.PD 0
+.ie n .IP """sv_vsetpvf_mg""" 4
+.el .IP \f(CWsv_vsetpvf_mg\fR 4
+.IX Xref "sv_vsetpvf sv_vsetpvf_mg"
+.IX Item "sv_vsetpvf_mg"
+.PD
+These work like \f(CW"sv_vcatpvf"\fR but copy the text into the SV instead of
+appending it.
+.Sp
+They differ only in that \f(CW\*(C`sv_vsetpvf_mg\*(C'\fR performs 'set' magic;
+\&\f(CW\*(C`sv_vsetpvf\*(C'\fR skips all magic.
+.Sp
+They are usually used via their frontends, \f(CW"sv_setpvf"\fR and
+\&\f(CW"sv_setpvf_mg"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& void sv_vsetpvf(SV * const sv, const char * const pat,
+\& va_list * const args)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_vsetpvfn""" 4
+.el .IP \f(CWsv_vsetpvfn\fR 4
+.IX Xref "sv_vsetpvfn"
+.IX Item "sv_vsetpvfn"
+Works like \f(CW\*(C`sv_vcatpvfn\*(C'\fR but copies the text into the SV instead of
+appending it.
+.Sp
+Usually used via one of its frontends "\f(CW\*(C`sv_vsetpvf\*(C'\fR" and
+"\f(CW\*(C`sv_vsetpvf_mg\*(C'\fR".
+.RS 4
+.Sp
+.Vb 4
+\& void sv_vsetpvfn(SV * const sv, const char * const pat,
+\& const STRLEN patlen, va_list * const args,
+\& SV ** const svargs, const Size_t sv_count,
+\& bool * const maybe_tainted)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvVSTRING_mg""" 4
+.el .IP \f(CWSvVSTRING_mg\fR 4
+.IX Xref "SvVSTRING_mg"
+.IX Item "SvVSTRING_mg"
+Returns the vstring magic, or NULL if none
+.RS 4
+.Sp
+.Vb 1
+\& MAGIC* SvVSTRING_mg(SV * sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vnewSVpvf""" 4
+.el .IP \f(CWvnewSVpvf\fR 4
+.IX Xref "vnewSVpvf"
+.IX Item "vnewSVpvf"
+Like \f(CW"newSVpvf"\fR but the arguments are an encapsulated argument list.
+.RS 4
+.Sp
+.Vb 1
+\& SV * vnewSVpvf(const char * const pat, va_list * const args)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Tainting
+.IX Header "Tainting"
+.ie n .IP """SvTAINT""" 4
+.el .IP \f(CWSvTAINT\fR 4
+.IX Xref "SvTAINT"
+.IX Item "SvTAINT"
+Taints an SV if tainting is enabled, and if some input to the current
+expression is tainted\-\-usually a variable, but possibly also implicit
+inputs such as locale settings. \f(CW\*(C`SvTAINT\*(C'\fR propagates that taintedness to
+the outputs of an expression in a pessimistic fashion; i.e., without paying
+attention to precisely which outputs are influenced by which inputs.
+.RS 4
+.Sp
+.Vb 1
+\& void SvTAINT(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvTAINTED""" 4
+.el .IP \f(CWSvTAINTED\fR 4
+.IX Xref "SvTAINTED"
+.IX Item "SvTAINTED"
+Checks to see if an SV is tainted. Returns TRUE if it is, FALSE if
+not.
+.RS 4
+.Sp
+.Vb 1
+\& bool SvTAINTED(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvTAINTED_off""" 4
+.el .IP \f(CWSvTAINTED_off\fR 4
+.IX Xref "SvTAINTED_off"
+.IX Item "SvTAINTED_off"
+Untaints an SV. Be \fIvery\fR careful with this routine, as it short-circuits
+some of Perl's fundamental security features. XS module authors should not
+use this function unless they fully understand all the implications of
+unconditionally untainting the value. Untainting should be done in the
+standard perl fashion, via a carefully crafted regexp, rather than directly
+untainting variables.
+.RS 4
+.Sp
+.Vb 1
+\& void SvTAINTED_off(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SvTAINTED_on""" 4
+.el .IP \f(CWSvTAINTED_on\fR 4
+.IX Xref "SvTAINTED_on"
+.IX Item "SvTAINTED_on"
+Marks an SV as tainted if tainting is enabled.
+.RS 4
+.Sp
+.Vb 1
+\& void SvTAINTED_on(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Time
+.IX Header "Time"
+.ie n .IP """ASCTIME_R_PROTO""" 4
+.el .IP \f(CWASCTIME_R_PROTO\fR 4
+.IX Xref "ASCTIME_R_PROTO"
+.IX Item "ASCTIME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`asctime_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_asctime_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_asctime_r\*(C'\fR
+is defined.
+.ie n .IP """CTIME_R_PROTO""" 4
+.el .IP \f(CWCTIME_R_PROTO\fR 4
+.IX Xref "CTIME_R_PROTO"
+.IX Item "CTIME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`ctime_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_ctime_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_ctime_r\*(C'\fR
+is defined.
+.ie n .IP """GMTIME_MAX""" 4
+.el .IP \f(CWGMTIME_MAX\fR 4
+.IX Xref "GMTIME_MAX"
+.IX Item "GMTIME_MAX"
+This symbol contains the maximum value for the \f(CW\*(C`time_t\*(C'\fR offset that
+the system function gmtime () accepts, and defaults to 0
+.ie n .IP """GMTIME_MIN""" 4
+.el .IP \f(CWGMTIME_MIN\fR 4
+.IX Xref "GMTIME_MIN"
+.IX Item "GMTIME_MIN"
+This symbol contains the minimum value for the \f(CW\*(C`time_t\*(C'\fR offset that
+the system function gmtime () accepts, and defaults to 0
+.ie n .IP """GMTIME_R_PROTO""" 4
+.el .IP \f(CWGMTIME_R_PROTO\fR 4
+.IX Xref "GMTIME_R_PROTO"
+.IX Item "GMTIME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`gmtime_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_gmtime_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_gmtime_r\*(C'\fR
+is defined.
+.ie n .IP """HAS_ASCTIME_R""" 4
+.el .IP \f(CWHAS_ASCTIME_R\fR 4
+.IX Xref "HAS_ASCTIME_R"
+.IX Item "HAS_ASCTIME_R"
+This symbol, if defined, indicates that the \f(CW\*(C`asctime_r\*(C'\fR routine
+is available to asctime re-entrantly.
+.ie n .IP """HAS_ASCTIME64""" 4
+.el .IP \f(CWHAS_ASCTIME64\fR 4
+.IX Xref "HAS_ASCTIME64"
+.IX Item "HAS_ASCTIME64"
+This symbol, if defined, indicates that the \f(CW\*(C`asctime64\*(C'\fR () routine is
+available to do the 64bit variant of asctime ()
+.ie n .IP """HAS_CTIME_R""" 4
+.el .IP \f(CWHAS_CTIME_R\fR 4
+.IX Xref "HAS_CTIME_R"
+.IX Item "HAS_CTIME_R"
+This symbol, if defined, indicates that the \f(CW\*(C`ctime_r\*(C'\fR routine
+is available to ctime re-entrantly.
+.ie n .IP """HAS_CTIME64""" 4
+.el .IP \f(CWHAS_CTIME64\fR 4
+.IX Xref "HAS_CTIME64"
+.IX Item "HAS_CTIME64"
+This symbol, if defined, indicates that the \f(CW\*(C`ctime64\*(C'\fR () routine is
+available to do the 64bit variant of ctime ()
+.ie n .IP """HAS_DIFFTIME""" 4
+.el .IP \f(CWHAS_DIFFTIME\fR 4
+.IX Xref "HAS_DIFFTIME"
+.IX Item "HAS_DIFFTIME"
+This symbol, if defined, indicates that the \f(CW\*(C`difftime\*(C'\fR routine is
+available.
+.ie n .IP """HAS_DIFFTIME64""" 4
+.el .IP \f(CWHAS_DIFFTIME64\fR 4
+.IX Xref "HAS_DIFFTIME64"
+.IX Item "HAS_DIFFTIME64"
+This symbol, if defined, indicates that the \f(CW\*(C`difftime64\*(C'\fR () routine is
+available to do the 64bit variant of difftime ()
+.ie n .IP """HAS_FUTIMES""" 4
+.el .IP \f(CWHAS_FUTIMES\fR 4
+.IX Xref "HAS_FUTIMES"
+.IX Item "HAS_FUTIMES"
+This symbol, if defined, indicates that the \f(CW\*(C`futimes\*(C'\fR routine is
+available to change file descriptor time stamps with \f(CW\*(C`struct timevals\*(C'\fR.
+.ie n .IP """HAS_GETITIMER""" 4
+.el .IP \f(CWHAS_GETITIMER\fR 4
+.IX Xref "HAS_GETITIMER"
+.IX Item "HAS_GETITIMER"
+This symbol, if defined, indicates that the \f(CW\*(C`getitimer\*(C'\fR routine is
+available to return interval timers.
+.ie n .IP """HAS_GETTIMEOFDAY""" 4
+.el .IP \f(CWHAS_GETTIMEOFDAY\fR 4
+.IX Xref "HAS_GETTIMEOFDAY"
+.IX Item "HAS_GETTIMEOFDAY"
+This symbol, if defined, indicates that the \f(CWgettimeofday()\fR system
+call is available for a sub-second accuracy clock. Usually, the file
+\&\fIsys/resource.h\fR needs to be included (see \f(CW"I_SYS_RESOURCE"\fR).
+The type "Timeval" should be used to refer to "\f(CW\*(C`struct timeval\*(C'\fR".
+.ie n .IP """HAS_GMTIME_R""" 4
+.el .IP \f(CWHAS_GMTIME_R\fR 4
+.IX Xref "HAS_GMTIME_R"
+.IX Item "HAS_GMTIME_R"
+This symbol, if defined, indicates that the \f(CW\*(C`gmtime_r\*(C'\fR routine
+is available to gmtime re-entrantly.
+.ie n .IP """HAS_GMTIME64""" 4
+.el .IP \f(CWHAS_GMTIME64\fR 4
+.IX Xref "HAS_GMTIME64"
+.IX Item "HAS_GMTIME64"
+This symbol, if defined, indicates that the \f(CW\*(C`gmtime64\*(C'\fR () routine is
+available to do the 64bit variant of gmtime ()
+.ie n .IP """HAS_LOCALTIME_R""" 4
+.el .IP \f(CWHAS_LOCALTIME_R\fR 4
+.IX Xref "HAS_LOCALTIME_R"
+.IX Item "HAS_LOCALTIME_R"
+This symbol, if defined, indicates that the \f(CW\*(C`localtime_r\*(C'\fR routine
+is available to localtime re-entrantly.
+.ie n .IP """HAS_LOCALTIME64""" 4
+.el .IP \f(CWHAS_LOCALTIME64\fR 4
+.IX Xref "HAS_LOCALTIME64"
+.IX Item "HAS_LOCALTIME64"
+This symbol, if defined, indicates that the \f(CW\*(C`localtime64\*(C'\fR () routine is
+available to do the 64bit variant of localtime ()
+.ie n .IP """HAS_MKTIME""" 4
+.el .IP \f(CWHAS_MKTIME\fR 4
+.IX Xref "HAS_MKTIME"
+.IX Item "HAS_MKTIME"
+This symbol, if defined, indicates that the \f(CW\*(C`mktime\*(C'\fR routine is
+available.
+.ie n .IP """HAS_MKTIME64""" 4
+.el .IP \f(CWHAS_MKTIME64\fR 4
+.IX Xref "HAS_MKTIME64"
+.IX Item "HAS_MKTIME64"
+This symbol, if defined, indicates that the \f(CW\*(C`mktime64\*(C'\fR () routine is
+available to do the 64bit variant of mktime ()
+.ie n .IP """HAS_NANOSLEEP""" 4
+.el .IP \f(CWHAS_NANOSLEEP\fR 4
+.IX Xref "HAS_NANOSLEEP"
+.IX Item "HAS_NANOSLEEP"
+This symbol, if defined, indicates that the \f(CW\*(C`nanosleep\*(C'\fR
+system call is available to sleep with 1E\-9 sec accuracy.
+.ie n .IP """HAS_SETITIMER""" 4
+.el .IP \f(CWHAS_SETITIMER\fR 4
+.IX Xref "HAS_SETITIMER"
+.IX Item "HAS_SETITIMER"
+This symbol, if defined, indicates that the \f(CW\*(C`setitimer\*(C'\fR routine is
+available to set interval timers.
+.ie n .IP """HAS_STRFTIME""" 4
+.el .IP \f(CWHAS_STRFTIME\fR 4
+.IX Xref "HAS_STRFTIME"
+.IX Item "HAS_STRFTIME"
+This symbol, if defined, indicates that the \f(CW\*(C`strftime\*(C'\fR routine is
+available to do time formatting.
+.ie n .IP """HAS_TIME""" 4
+.el .IP \f(CWHAS_TIME\fR 4
+.IX Xref "HAS_TIME"
+.IX Item "HAS_TIME"
+This symbol, if defined, indicates that the \f(CWtime()\fR routine exists.
+.ie n .IP """HAS_TIMEGM""" 4
+.el .IP \f(CWHAS_TIMEGM\fR 4
+.IX Xref "HAS_TIMEGM"
+.IX Item "HAS_TIMEGM"
+This symbol, if defined, indicates that the \f(CW\*(C`timegm\*(C'\fR routine is
+available to do the opposite of gmtime ()
+.ie n .IP """HAS_TIMES""" 4
+.el .IP \f(CWHAS_TIMES\fR 4
+.IX Xref "HAS_TIMES"
+.IX Item "HAS_TIMES"
+This symbol, if defined, indicates that the \f(CWtimes()\fR routine exists.
+Note that this became obsolete on some systems (\f(CW\*(C`SUNOS\*(C'\fR), which now
+use \f(CWgetrusage()\fR. It may be necessary to include \fIsys/times.h\fR.
+.ie n .IP """HAS_TM_TM_GMTOFF""" 4
+.el .IP \f(CWHAS_TM_TM_GMTOFF\fR 4
+.IX Xref "HAS_TM_TM_GMTOFF"
+.IX Item "HAS_TM_TM_GMTOFF"
+This symbol, if defined, indicates to the C program that
+the \f(CW\*(C`struct tm\*(C'\fR has a \f(CW\*(C`tm_gmtoff\*(C'\fR field.
+.ie n .IP """HAS_TM_TM_ZONE""" 4
+.el .IP \f(CWHAS_TM_TM_ZONE\fR 4
+.IX Xref "HAS_TM_TM_ZONE"
+.IX Item "HAS_TM_TM_ZONE"
+This symbol, if defined, indicates to the C program that
+the \f(CW\*(C`struct tm\*(C'\fR has a \f(CW\*(C`tm_zone\*(C'\fR field.
+.ie n .IP """HAS_TZNAME""" 4
+.el .IP \f(CWHAS_TZNAME\fR 4
+.IX Xref "HAS_TZNAME"
+.IX Item "HAS_TZNAME"
+This symbol, if defined, indicates that the \f(CW\*(C`tzname[]\*(C'\fR array is
+available to access timezone names.
+.ie n .IP """HAS_USLEEP""" 4
+.el .IP \f(CWHAS_USLEEP\fR 4
+.IX Xref "HAS_USLEEP"
+.IX Item "HAS_USLEEP"
+This symbol, if defined, indicates that the \f(CW\*(C`usleep\*(C'\fR routine is
+available to let the process sleep on a sub-second accuracy.
+.ie n .IP """HAS_USLEEP_PROTO""" 4
+.el .IP \f(CWHAS_USLEEP_PROTO\fR 4
+.IX Xref "HAS_USLEEP_PROTO"
+.IX Item "HAS_USLEEP_PROTO"
+This symbol, if defined, indicates that the system provides
+a prototype for the \f(CWusleep()\fR function. Otherwise, it is up
+to the program to supply one. A good guess is
+.Sp
+.Vb 1
+\& extern int usleep(useconds_t);
+.Ve
+.ie n .IP """I_TIME""" 4
+.el .IP \f(CWI_TIME\fR 4
+.IX Xref "I_TIME"
+.IX Item "I_TIME"
+This symbol is always defined, and indicates to the C program that
+it should include \fItime.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_TIME
+\& #include <time.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """I_UTIME""" 4
+.el .IP \f(CWI_UTIME\fR 4
+.IX Xref "I_UTIME"
+.IX Item "I_UTIME"
+This symbol, if defined, indicates to the C program that it should
+include \fIutime.h\fR.
+.RS 4
+.Sp
+.Vb 3
+\& #ifdef I_UTIME
+\& #include <utime.h>
+\& #endif
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LOCALTIME_MAX""" 4
+.el .IP \f(CWLOCALTIME_MAX\fR 4
+.IX Xref "LOCALTIME_MAX"
+.IX Item "LOCALTIME_MAX"
+This symbol contains the maximum value for the \f(CW\*(C`time_t\*(C'\fR offset that
+the system function localtime () accepts, and defaults to 0
+.ie n .IP """LOCALTIME_MIN""" 4
+.el .IP \f(CWLOCALTIME_MIN\fR 4
+.IX Xref "LOCALTIME_MIN"
+.IX Item "LOCALTIME_MIN"
+This symbol contains the minimum value for the \f(CW\*(C`time_t\*(C'\fR offset that
+the system function localtime () accepts, and defaults to 0
+.ie n .IP """LOCALTIME_R_NEEDS_TZSET""" 4
+.el .IP \f(CWLOCALTIME_R_NEEDS_TZSET\fR 4
+.IX Xref "LOCALTIME_R_NEEDS_TZSET"
+.IX Item "LOCALTIME_R_NEEDS_TZSET"
+Many libc's \f(CW\*(C`localtime_r\*(C'\fR implementations do not call tzset,
+making them differ from \f(CWlocaltime()\fR, and making timezone
+changes using $\f(CW\*(C`ENV\*(C'\fR{TZ} without explicitly calling tzset
+impossible. This symbol makes us call tzset before \f(CW\*(C`localtime_r\*(C'\fR
+.ie n .IP """LOCALTIME_R_PROTO""" 4
+.el .IP \f(CWLOCALTIME_R_PROTO\fR 4
+.IX Xref "LOCALTIME_R_PROTO"
+.IX Item "LOCALTIME_R_PROTO"
+This symbol encodes the prototype of \f(CW\*(C`localtime_r\*(C'\fR.
+It is zero if \f(CW\*(C`d_localtime_r\*(C'\fR is undef, and one of the
+\&\f(CW\*(C`REENTRANT_PROTO_T_ABC\*(C'\fR macros of \fIreentr.h\fR if \f(CW\*(C`d_localtime_r\*(C'\fR
+is defined.
+.ie n .IP """L_R_TZSET""" 4
+.el .IP \f(CWL_R_TZSET\fR 4
+.IX Xref "L_R_TZSET"
+.IX Item "L_R_TZSET"
+If \f(CWlocaltime_r()\fR needs tzset, it is defined in this define
+.ie n .IP """mini_mktime""" 4
+.el .IP \f(CWmini_mktime\fR 4
+.IX Xref "mini_mktime"
+.IX Item "mini_mktime"
+normalise \f(CW\*(C`struct\ tm\*(C'\fR values without the \fBlocaltime()\fR semantics (and
+overhead) of \fBmktime()\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void mini_mktime(struct tm *ptm)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_strftime""" 4
+.el .IP \f(CWmy_strftime\fR 4
+.IX Xref "my_strftime"
+.IX Item "my_strftime"
+\&\fBstrftime()\fR, but with a different API so that the return value is a pointer
+to the formatted result (which MUST be arranged to be FREED BY THE
+CALLER). This allows this function to increase the buffer size as needed,
+so that the caller doesn't have to worry about that.
+.Sp
+On failure it returns NULL.
+.Sp
+Note that yday and wday effectively are ignored by this function, as
+\&\fBmini_mktime()\fR overwrites them.
+.Sp
+Also note that it is always executed in the underlying \f(CW\*(C`LC_TIME\*(C'\fR locale of
+the program, giving results based on that locale.
+.RS 4
+.Sp
+.Vb 3
+\& char * my_strftime(const char *fmt, int sec, int min, int hour,
+\& int mday, int mon, int year, int wday,
+\& int yday, int isdst)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """switch_to_global_locale""" 4
+.el .IP \f(CWswitch_to_global_locale\fR 4
+.IX Xref "switch_to_global_locale"
+.IX Item "switch_to_global_locale"
+This function copies the locale state of the calling thread into the program's
+global locale, and converts the thread to use that global locale.
+.Sp
+It is intended so that Perl can safely be used with C libraries that access the
+global locale and which can't be converted to not access it. Effectively, this
+means libraries that call \f(CWsetlocale(3)\fR on non-Windows systems. (For
+portability, it is a good idea to use it on Windows as well.)
+.Sp
+A downside of using it is that it disables the services that Perl provides to
+hide locale gotchas from your code. The service you most likely will miss
+regards the radix character (decimal point) in floating point numbers. Code
+executed after this function is called can no longer just assume that this
+character is correct for the current circumstances.
+.Sp
+To return to Perl control, and restart the gotcha prevention services, call
+\&\f(CW"sync_locale"\fR. Behavior is undefined for any pure Perl code that executes
+while the switch is in effect.
+.Sp
+The global locale and the per-thread locales are independent. As long as just
+one thread converts to the global locale, everything works smoothly. But if
+more than one does, they can easily interfere with each other, and races are
+likely. On Windows systems prior to Visual Studio 15 (at which point Microsoft
+fixed a bug), races can occur (even if only one thread has been converted to
+the global locale), but only if you use the following operations:
+.RS 4
+.IP POSIX::localeconv 4
+.IX Item "POSIX::localeconv"
+.PD 0
+.ie n .IP "I18N::Langinfo, items ""CRNCYSTR"" and ""THOUSEP""" 4
+.el .IP "I18N::Langinfo, items \f(CWCRNCYSTR\fR and \f(CWTHOUSEP\fR" 4
+.IX Item "I18N::Langinfo, items CRNCYSTR and THOUSEP"
+.ie n .IP """Perl_langinfo"" in perlapi, items ""CRNCYSTR"" and ""THOUSEP""" 4
+.el .IP """Perl_langinfo"" in perlapi, items \f(CWCRNCYSTR\fR and \f(CWTHOUSEP\fR" 4
+.IX Item """Perl_langinfo"" in perlapi, items CRNCYSTR and THOUSEP"
+.RE
+.RS 4
+.PD
+.Sp
+The first item is not fixable (except by upgrading to a later Visual Studio
+release), but it would be possible to work around the latter two items by
+having Perl change its algorithm for calculating these to use Windows API
+functions (likely \f(CW\*(C`GetNumberFormat\*(C'\fR and \f(CW\*(C`GetCurrencyFormat\*(C'\fR); patches
+welcome.
+.Sp
+XS code should never call plain \f(CW\*(C`setlocale\*(C'\fR, but should instead be converted
+to either call \f(CW\*(C`Perl_setlocale\*(C'\fR (which is a drop-in
+for the system \f(CW\*(C`setlocale\*(C'\fR) or use the methods given in perlcall to call
+\&\f(CW\*(C`POSIX::setlocale\*(C'\fR. Either one will transparently properly
+handle all cases of single\- vs multi-thread, POSIX 2008\-supported or not.
+.Sp
+.Vb 1
+\& void switch_to_global_locale()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sync_locale""" 4
+.el .IP \f(CWsync_locale\fR 4
+.IX Xref "sync_locale"
+.IX Item "sync_locale"
+This function copies the state of the program global locale into the calling
+thread, and converts that thread to using per-thread locales, if it wasn't
+already, and the platform supports them. The LC_NUMERIC locale is toggled into
+the standard state (using the C locale's conventions), if not within the
+lexical scope of \f(CW\*(C`use\ locale\*(C'\fR.
+.Sp
+Perl will now consider itself to have control of the locale.
+.Sp
+Since unthreaded perls have only a global locale, this function is a no-op
+without threads.
+.Sp
+This function is intended for use with C libraries that do locale manipulation.
+It allows Perl to accommodate the use of them. Call this function before
+transferring back to Perl space so that it knows what state the C code has left
+things in.
+.Sp
+XS code should not manipulate the locale on its own. Instead,
+\&\f(CW\*(C`Perl_setlocale\*(C'\fR can be used at any time to query or
+change the locale (though changing the locale is antisocial and dangerous on
+multi-threaded systems that don't have multi-thread safe locale operations.
+(See "Multi-threaded operation" in perllocale).
+.Sp
+Using the libc \f(CWsetlocale(3)\fR function should be avoided. Nevertheless,
+certain non-Perl libraries called from XS, do call it, and their behavior may
+not be able to be changed. This function, along with
+\&\f(CW"switch_to_global_locale"\fR, can be used to get seamless behavior in these
+circumstances, as long as only one thread is involved.
+.Sp
+If the library has an option to turn off its locale manipulation, doing that is
+preferable to using this mechanism. \f(CW\*(C`Gtk\*(C'\fR is such a library.
+.Sp
+The return value is a boolean: TRUE if the global locale at the time of call
+was in effect for the caller; and FALSE if a per-thread locale was in effect.
+.RS 4
+.Sp
+.Vb 1
+\& bool sync_locale()
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Typedef names"
+.IX Header "Typedef names"
+.ie n .IP """DB_Hash_t""" 4
+.el .IP \f(CWDB_Hash_t\fR 4
+.IX Xref "DB_Hash_t"
+.IX Item "DB_Hash_t"
+This symbol contains the type of the prefix structure element
+in the \fIdb.h\fR header file. In older versions of DB, it was
+int, while in newer ones it is \f(CW\*(C`size_t\*(C'\fR.
+.ie n .IP """DB_Prefix_t""" 4
+.el .IP \f(CWDB_Prefix_t\fR 4
+.IX Xref "DB_Prefix_t"
+.IX Item "DB_Prefix_t"
+This symbol contains the type of the prefix structure element
+in the \fIdb.h\fR header file. In older versions of DB, it was
+int, while in newer ones it is \f(CW\*(C`u_int32_t\*(C'\fR.
+.ie n .IP """Direntry_t""" 4
+.el .IP \f(CWDirentry_t\fR 4
+.IX Xref "Direntry_t"
+.IX Item "Direntry_t"
+This symbol is set to '\f(CW\*(C`struct direct\*(C'\fR' or '\f(CW\*(C`struct dirent\*(C'\fR' depending on
+whether dirent is available or not. You should use this pseudo type to
+portably declare your directory entries.
+.ie n .IP """Fpos_t""" 4
+.el .IP \f(CWFpos_t\fR 4
+.IX Xref "Fpos_t"
+.IX Item "Fpos_t"
+This symbol holds the type used to declare file positions in libc.
+It can be \f(CW\*(C`fpos_t\*(C'\fR, long, uint, etc... It may be necessary to include
+\&\fIsys/types.h\fR to get any typedef'ed information.
+.ie n .IP """Free_t""" 4
+.el .IP \f(CWFree_t\fR 4
+.IX Xref "Free_t"
+.IX Item "Free_t"
+This variable contains the return type of \f(CWfree()\fR. It is usually
+void, but occasionally int.
+.ie n .IP """Gid_t""" 4
+.el .IP \f(CWGid_t\fR 4
+.IX Xref "Gid_t"
+.IX Item "Gid_t"
+This symbol holds the return type of \f(CWgetgid()\fR and the type of
+argument to \f(CWsetrgid()\fR and related functions. Typically,
+it is the type of group ids in the kernel. It can be int, ushort,
+\&\f(CW\*(C`gid_t\*(C'\fR, etc... It may be necessary to include \fIsys/types.h\fR to get
+any typedef'ed information.
+.ie n .IP """Gid_t_f""" 4
+.el .IP \f(CWGid_t_f\fR 4
+.IX Xref "Gid_t_f"
+.IX Item "Gid_t_f"
+This symbol defines the format string used for printing a \f(CW\*(C`Gid_t\*(C'\fR.
+.ie n .IP """Gid_t_sign""" 4
+.el .IP \f(CWGid_t_sign\fR 4
+.IX Xref "Gid_t_sign"
+.IX Item "Gid_t_sign"
+This symbol holds the signedness of a \f(CW\*(C`Gid_t\*(C'\fR.
+1 for unsigned, \-1 for signed.
+.ie n .IP """Gid_t_size""" 4
+.el .IP \f(CWGid_t_size\fR 4
+.IX Xref "Gid_t_size"
+.IX Item "Gid_t_size"
+This symbol holds the size of a \f(CW\*(C`Gid_t\*(C'\fR in bytes.
+.ie n .IP """Groups_t""" 4
+.el .IP \f(CWGroups_t\fR 4
+.IX Xref "Groups_t"
+.IX Item "Groups_t"
+This symbol holds the type used for the second argument to
+\&\f(CWgetgroups()\fR and \f(CWsetgroups()\fR. Usually, this is the same as
+gidtype (\f(CW\*(C`gid_t\*(C'\fR) , but sometimes it isn't.
+It can be int, ushort, \f(CW\*(C`gid_t\*(C'\fR, etc...
+It may be necessary to include \fIsys/types.h\fR to get any
+typedef'ed information. This is only required if you have
+\&\f(CWgetgroups()\fR or \f(CWsetgroups()\fR..
+.ie n .IP """Malloc_t""" 4
+.el .IP \f(CWMalloc_t\fR 4
+.IX Xref "Malloc_t"
+.IX Item "Malloc_t"
+This symbol is the type of pointer returned by malloc and realloc.
+.ie n .IP """Mmap_t""" 4
+.el .IP \f(CWMmap_t\fR 4
+.IX Xref "Mmap_t"
+.IX Item "Mmap_t"
+This symbol holds the return type of the \f(CWmmap()\fR system call
+(and simultaneously the type of the first argument).
+Usually set to 'void *' or '\f(CW\*(C`caddr_t\*(C'\fR'.
+.ie n .IP """Mode_t""" 4
+.el .IP \f(CWMode_t\fR 4
+.IX Xref "Mode_t"
+.IX Item "Mode_t"
+This symbol holds the type used to declare file modes
+for systems calls. It is usually \f(CW\*(C`mode_t\*(C'\fR, but may be
+int or unsigned short. It may be necessary to include \fIsys/types.h\fR
+to get any typedef'ed information.
+.ie n .IP """Netdb_hlen_t""" 4
+.el .IP \f(CWNetdb_hlen_t\fR 4
+.IX Xref "Netdb_hlen_t"
+.IX Item "Netdb_hlen_t"
+This symbol holds the type used for the 2nd argument
+to \f(CWgethostbyaddr()\fR.
+.ie n .IP """Netdb_host_t""" 4
+.el .IP \f(CWNetdb_host_t\fR 4
+.IX Xref "Netdb_host_t"
+.IX Item "Netdb_host_t"
+This symbol holds the type used for the 1st argument
+to \f(CWgethostbyaddr()\fR.
+.ie n .IP """Netdb_name_t""" 4
+.el .IP \f(CWNetdb_name_t\fR 4
+.IX Xref "Netdb_name_t"
+.IX Item "Netdb_name_t"
+This symbol holds the type used for the argument to
+\&\f(CWgethostbyname()\fR.
+.ie n .IP """Netdb_net_t""" 4
+.el .IP \f(CWNetdb_net_t\fR 4
+.IX Xref "Netdb_net_t"
+.IX Item "Netdb_net_t"
+This symbol holds the type used for the 1st argument to
+\&\f(CWgetnetbyaddr()\fR.
+.ie n .IP """Off_t""" 4
+.el .IP \f(CWOff_t\fR 4
+.IX Xref "Off_t"
+.IX Item "Off_t"
+This symbol holds the type used to declare offsets in the kernel.
+It can be int, long, \f(CW\*(C`off_t\*(C'\fR, etc... It may be necessary to include
+\&\fIsys/types.h\fR to get any typedef'ed information.
+.ie n .IP """Off_t_size""" 4
+.el .IP \f(CWOff_t_size\fR 4
+.IX Xref "Off_t_size"
+.IX Item "Off_t_size"
+This symbol holds the number of bytes used by the \f(CW\*(C`Off_t\*(C'\fR.
+.ie n .IP """Pid_t""" 4
+.el .IP \f(CWPid_t\fR 4
+.IX Xref "Pid_t"
+.IX Item "Pid_t"
+This symbol holds the type used to declare process ids in the kernel.
+It can be int, uint, \f(CW\*(C`pid_t\*(C'\fR, etc... It may be necessary to include
+\&\fIsys/types.h\fR to get any typedef'ed information.
+.ie n .IP """Rand_seed_t""" 4
+.el .IP \f(CWRand_seed_t\fR 4
+.IX Xref "Rand_seed_t"
+.IX Item "Rand_seed_t"
+This symbol defines the type of the argument of the
+random seed function.
+.ie n .IP """Select_fd_set_t""" 4
+.el .IP \f(CWSelect_fd_set_t\fR 4
+.IX Xref "Select_fd_set_t"
+.IX Item "Select_fd_set_t"
+This symbol holds the type used for the 2nd, 3rd, and 4th
+arguments to select. Usually, this is '\f(CW\*(C`fd_set\*(C'\fR *', if \f(CW\*(C`HAS_FD_SET\*(C'\fR
+is defined, and 'int *' otherwise. This is only useful if you
+have \f(CWselect()\fR, of course.
+.ie n .IP """Shmat_t""" 4
+.el .IP \f(CWShmat_t\fR 4
+.IX Xref "Shmat_t"
+.IX Item "Shmat_t"
+This symbol holds the return type of the \f(CWshmat()\fR system call.
+Usually set to 'void *' or 'char *'.
+.ie n .IP """Signal_t""" 4
+.el .IP \f(CWSignal_t\fR 4
+.IX Xref "Signal_t"
+.IX Item "Signal_t"
+This symbol's value is either "void" or "int", corresponding to the
+appropriate return type of a signal handler. Thus, you can declare
+a signal handler using "\f(CW\*(C`Signal_t\*(C'\fR (*handler)()", and define the
+handler using "\f(CW\*(C`Signal_t\*(C'\fR \f(CWhandler(sig)\fR".
+.ie n .IP """Size_t""" 4
+.el .IP \f(CWSize_t\fR 4
+.IX Xref "Size_t"
+.IX Item "Size_t"
+This symbol holds the type used to declare length parameters
+for string functions. It is usually \f(CW\*(C`size_t\*(C'\fR, but may be
+unsigned long, int, etc. It may be necessary to include
+\&\fIsys/types.h\fR to get any typedef'ed information.
+.ie n .IP """Size_t_size""" 4
+.el .IP \f(CWSize_t_size\fR 4
+.IX Xref "Size_t_size"
+.IX Item "Size_t_size"
+This symbol holds the size of a \f(CW\*(C`Size_t\*(C'\fR in bytes.
+.ie n .IP """Sock_size_t""" 4
+.el .IP \f(CWSock_size_t\fR 4
+.IX Xref "Sock_size_t"
+.IX Item "Sock_size_t"
+This symbol holds the type used for the size argument of
+various socket calls (just the base type, not the pointer-to).
+.ie n .IP """SSize_t""" 4
+.el .IP \f(CWSSize_t\fR 4
+.IX Xref "SSize_t"
+.IX Item "SSize_t"
+This symbol holds the type used by functions that return
+a count of bytes or an error condition. It must be a signed type.
+It is usually \f(CW\*(C`ssize_t\*(C'\fR, but may be long or int, etc.
+It may be necessary to include \fIsys/types.h\fR or \fIunistd.h\fR
+to get any typedef'ed information.
+We will pick a type such that \f(CWsizeof(SSize_t)\fR == \f(CWsizeof(Size_t)\fR.
+.ie n .IP """Time_t""" 4
+.el .IP \f(CWTime_t\fR 4
+.IX Xref "Time_t"
+.IX Item "Time_t"
+This symbol holds the type returned by \f(CWtime()\fR. It can be long,
+or \f(CW\*(C`time_t\*(C'\fR on \f(CW\*(C`BSD\*(C'\fR sites (in which case \fIsys/types.h\fR should be
+included).
+.ie n .IP """Uid_t""" 4
+.el .IP \f(CWUid_t\fR 4
+.IX Xref "Uid_t"
+.IX Item "Uid_t"
+This symbol holds the type used to declare user ids in the kernel.
+It can be int, ushort, \f(CW\*(C`uid_t\*(C'\fR, etc... It may be necessary to include
+\&\fIsys/types.h\fR to get any typedef'ed information.
+.ie n .IP """Uid_t_f""" 4
+.el .IP \f(CWUid_t_f\fR 4
+.IX Xref "Uid_t_f"
+.IX Item "Uid_t_f"
+This symbol defines the format string used for printing a \f(CW\*(C`Uid_t\*(C'\fR.
+.ie n .IP """Uid_t_sign""" 4
+.el .IP \f(CWUid_t_sign\fR 4
+.IX Xref "Uid_t_sign"
+.IX Item "Uid_t_sign"
+This symbol holds the signedness of a \f(CW\*(C`Uid_t\*(C'\fR.
+1 for unsigned, \-1 for signed.
+.ie n .IP """Uid_t_size""" 4
+.el .IP \f(CWUid_t_size\fR 4
+.IX Xref "Uid_t_size"
+.IX Item "Uid_t_size"
+This symbol holds the size of a \f(CW\*(C`Uid_t\*(C'\fR in bytes.
+.SH "Unicode Support"
+.IX Xref "UNICODE_DISALLOW_ABOVE_31_BIT UNICODE_DISALLOW_ILLEGAL_C9_INTERCHANGE UNICODE_DISALLOW_ILLEGAL_INTERCHANGE UNICODE_DISALLOW_NONCHAR UNICODE_DISALLOW_PERL_EXTENDED UNICODE_DISALLOW_SUPER UNICODE_DISALLOW_SURROGATE UNICODE_WARN_ABOVE_31_BIT UNICODE_WARN_ILLEGAL_C9_INTERCHANGE UNICODE_WARN_ILLEGAL_INTERCHANGE UNICODE_WARN_NONCHAR UNICODE_WARN_PERL_EXTENDED UNICODE_WARN_SUPER UNICODE_WARN_SURROGATE UNI_DISPLAY_BACKSLASH UNI_DISPLAY_BACKSPACE UNI_DISPLAY_ISPRINT UNI_DISPLAY_QQ UNI_DISPLAY_REGEX UTF8_CHECK_ONLY UTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE UTF8_DISALLOW_ILLEGAL_INTERCHANGE UTF8_DISALLOW_NONCHAR UTF8_DISALLOW_PERL_EXTENDED UTF8_DISALLOW_SUPER UTF8_DISALLOW_SURROGATE UTF8_GOT_CONTINUATION UTF8_GOT_EMPTY UTF8_GOT_LONG UTF8_GOT_NONCHAR UTF8_GOT_NON_CONTINUATION UTF8_GOT_OVERFLOW UTF8_GOT_PERL_EXTENDED UTF8_GOT_SHORT UTF8_GOT_SUPER UTF8_GOT_SURROGATE UTF8_WARN_ILLEGAL_C9_INTERCHANGE UTF8_WARN_ILLEGAL_INTERCHANGE UTF8_WARN_NONCHAR UTF8_WARN_PERL_EXTENDED UTF8_WARN_SUPER UTF8_WARN_SURROGATE"
+.IX Header "Unicode Support"
+"Unicode Support" in perlguts has an introduction to this API.
+.PP
+See also \f(CW"Character classification"\fR,
+\&\f(CW"Character case changing"\fR,
+and \f(CW"String Handling"\fR.
+Various functions outside this section also work specially with
+Unicode. Search for the string "utf8" in this document.
+.ie n .IP """BOM_UTF8""" 4
+.el .IP \f(CWBOM_UTF8\fR 4
+.IX Xref "BOM_UTF8"
+.IX Item "BOM_UTF8"
+This is a macro that evaluates to a string constant of the UTF\-8 bytes that
+define the Unicode BYTE ORDER MARK (U+FEFF) for the platform that perl
+is compiled on. This allows code to use a mnemonic for this character that
+works on both ASCII and EBCDIC platforms.
+\&\f(CW\*(C`sizeof(BOM_UTF8)\ \-\ 1\*(C'\fR can be used to get its length in
+bytes.
+.ie n .IP """bytes_cmp_utf8""" 4
+.el .IP \f(CWbytes_cmp_utf8\fR 4
+.IX Xref "bytes_cmp_utf8"
+.IX Item "bytes_cmp_utf8"
+Compares the sequence of characters (stored as octets) in \f(CW\*(C`b\*(C'\fR, \f(CW\*(C`blen\*(C'\fR with the
+sequence of characters (stored as UTF\-8)
+in \f(CW\*(C`u\*(C'\fR, \f(CW\*(C`ulen\*(C'\fR. Returns 0 if they are
+equal, \-1 or \-2 if the first string is less than the second string, +1 or +2
+if the first string is greater than the second string.
+.Sp
+\&\-1 or +1 is returned if the shorter string was identical to the start of the
+longer string. \-2 or +2 is returned if
+there was a difference between characters
+within the strings.
+.RS 4
+.Sp
+.Vb 2
+\& int bytes_cmp_utf8(const U8 *b, STRLEN blen, const U8 *u,
+\& STRLEN ulen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """bytes_from_utf8""" 4
+.el .IP \f(CWbytes_from_utf8\fR 4
+.IX Xref "bytes_from_utf8"
+.IX Item "bytes_from_utf8"
+NOTE: \f(CW\*(C`bytes_from_utf8\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Converts a potentially UTF\-8 encoded string \f(CW\*(C`s\*(C'\fR of length \f(CW*lenp\fR into native
+byte encoding. On input, the boolean \f(CW*is_utf8p\fR gives whether or not \f(CW\*(C`s\*(C'\fR is
+actually encoded in UTF\-8.
+.Sp
+Unlike "utf8_to_bytes" but like "bytes_to_utf8", this is non-destructive of
+the input string.
+.Sp
+Do nothing if \f(CW*is_utf8p\fR is 0, or if there are code points in the string
+not expressible in native byte encoding. In these cases, \f(CW*is_utf8p\fR and
+\&\f(CW*lenp\fR are unchanged, and the return value is the original \f(CW\*(C`s\*(C'\fR.
+.Sp
+Otherwise, \f(CW*is_utf8p\fR is set to 0, and the return value is a pointer to a
+newly created string containing a downgraded copy of \f(CW\*(C`s\*(C'\fR, and whose length is
+returned in \f(CW*lenp\fR, updated. The new string is \f(CW\*(C`NUL\*(C'\fR\-terminated. The
+caller is responsible for arranging for the memory used by this string to get
+freed.
+.Sp
+Upon successful return, the number of variants in the string can be computed by
+having saved the value of \f(CW*lenp\fR before the call, and subtracting the
+after-call value of \f(CW*lenp\fR from it.
+.RS 4
+.Sp
+.Vb 1
+\& U8 * bytes_from_utf8(const U8 *s, STRLEN *lenp, bool *is_utf8p)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """bytes_to_utf8""" 4
+.el .IP \f(CWbytes_to_utf8\fR 4
+.IX Xref "bytes_to_utf8"
+.IX Item "bytes_to_utf8"
+NOTE: \f(CW\*(C`bytes_to_utf8\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Converts a string \f(CW\*(C`s\*(C'\fR of length \f(CW*lenp\fR bytes from the native encoding into
+UTF\-8.
+Returns a pointer to the newly-created string, and sets \f(CW*lenp\fR to
+reflect the new length in bytes. The caller is responsible for arranging for
+the memory used by this string to get freed.
+.Sp
+Upon successful return, the number of variants in the string can be computed by
+having saved the value of \f(CW*lenp\fR before the call, and subtracting it from the
+after-call value of \f(CW*lenp\fR.
+.Sp
+A \f(CW\*(C`NUL\*(C'\fR character will be written after the end of the string.
+.Sp
+If you want to convert to UTF\-8 from encodings other than
+the native (Latin1 or EBCDIC),
+see "sv_recode_to_utf8"().
+.RS 4
+.Sp
+.Vb 1
+\& U8 * bytes_to_utf8(const U8 *s, STRLEN *lenp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """DO_UTF8""" 4
+.el .IP \f(CWDO_UTF8\fR 4
+.IX Xref "DO_UTF8"
+.IX Item "DO_UTF8"
+Returns a bool giving whether or not the PV in \f(CW\*(C`sv\*(C'\fR is to be treated as being
+encoded in UTF\-8.
+.Sp
+You should use this \fIafter\fR a call to \f(CWSvPV()\fR or one of its variants, in
+case any call to string overloading updates the internal UTF\-8 encoding flag.
+.RS 4
+.Sp
+.Vb 1
+\& bool DO_UTF8(SV* sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """foldEQ_utf8""" 4
+.el .IP \f(CWfoldEQ_utf8\fR 4
+.IX Xref "foldEQ_utf8"
+.IX Item "foldEQ_utf8"
+Returns true if the leading portions of the strings \f(CW\*(C`s1\*(C'\fR and \f(CW\*(C`s2\*(C'\fR (either or
+both of which may be in UTF\-8) are the same case-insensitively; false
+otherwise. How far into the strings to compare is determined by other input
+parameters.
+.Sp
+If \f(CW\*(C`u1\*(C'\fR is true, the string \f(CW\*(C`s1\*(C'\fR is assumed to be in UTF\-8\-encoded Unicode;
+otherwise it is assumed to be in native 8\-bit encoding. Correspondingly for
+\&\f(CW\*(C`u2\*(C'\fR with respect to \f(CW\*(C`s2\*(C'\fR.
+.Sp
+If the byte length \f(CW\*(C`l1\*(C'\fR is non-zero, it says how far into \f(CW\*(C`s1\*(C'\fR to check for
+fold equality. In other words, \f(CW\*(C`s1\*(C'\fR+\f(CW\*(C`l1\*(C'\fR will be used as a goal to reach.
+The scan will not be considered to be a match unless the goal is reached, and
+scanning won't continue past that goal. Correspondingly for \f(CW\*(C`l2\*(C'\fR with respect
+to \f(CW\*(C`s2\*(C'\fR.
+.Sp
+If \f(CW\*(C`pe1\*(C'\fR is non\-\f(CW\*(C`NULL\*(C'\fR and the pointer it points to is not \f(CW\*(C`NULL\*(C'\fR, that
+pointer is considered an end pointer to the position 1 byte past the maximum
+point in \f(CW\*(C`s1\*(C'\fR beyond which scanning will not continue under any circumstances.
+(This routine assumes that UTF\-8 encoded input strings are not malformed;
+malformed input can cause it to read past \f(CW\*(C`pe1\*(C'\fR). This means that if both
+\&\f(CW\*(C`l1\*(C'\fR and \f(CW\*(C`pe1\*(C'\fR are specified, and \f(CW\*(C`pe1\*(C'\fR is less than \f(CW\*(C`s1\*(C'\fR+\f(CW\*(C`l1\*(C'\fR, the match
+will never be successful because it can never
+get as far as its goal (and in fact is asserted against). Correspondingly for
+\&\f(CW\*(C`pe2\*(C'\fR with respect to \f(CW\*(C`s2\*(C'\fR.
+.Sp
+At least one of \f(CW\*(C`s1\*(C'\fR and \f(CW\*(C`s2\*(C'\fR must have a goal (at least one of \f(CW\*(C`l1\*(C'\fR and
+\&\f(CW\*(C`l2\*(C'\fR must be non-zero), and if both do, both have to be
+reached for a successful match. Also, if the fold of a character is multiple
+characters, all of them must be matched (see tr21 reference below for
+\&'folding').
+.Sp
+Upon a successful match, if \f(CW\*(C`pe1\*(C'\fR is non\-\f(CW\*(C`NULL\*(C'\fR,
+it will be set to point to the beginning of the \fInext\fR character of \f(CW\*(C`s1\*(C'\fR
+beyond what was matched. Correspondingly for \f(CW\*(C`pe2\*(C'\fR and \f(CW\*(C`s2\*(C'\fR.
+.Sp
+For case-insensitiveness, the "casefolding" of Unicode is used
+instead of upper/lowercasing both the characters, see
+<https://www.unicode.org/reports/tr21/> (Case Mappings).
+.RS 4
+.Sp
+.Vb 2
+\& I32 foldEQ_utf8(const char *s1, char **pe1, UV l1, bool u1,
+\& const char *s2, char **pe2, UV l2, bool u2)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_ascii_string""" 4
+.el .IP \f(CWis_ascii_string\fR 4
+.IX Xref "is_ascii_string"
+.IX Item "is_ascii_string"
+This is a misleadingly-named synonym for "is_utf8_invariant_string".
+On ASCII-ish platforms, the name isn't misleading: the ASCII-range characters
+are exactly the UTF\-8 invariants. But EBCDIC machines have more invariants
+than just the ASCII characters, so \f(CW\*(C`is_utf8_invariant_string\*(C'\fR is preferred.
+.RS 4
+.Sp
+.Vb 1
+\& bool is_ascii_string(const U8 * const s, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isC9_STRICT_UTF8_CHAR""" 4
+.el .IP \f(CWisC9_STRICT_UTF8_CHAR\fR 4
+.IX Xref "isC9_STRICT_UTF8_CHAR"
+.IX Item "isC9_STRICT_UTF8_CHAR"
+Evaluates to non-zero if the first few bytes of the string starting at \f(CW\*(C`s\*(C'\fR and
+looking no further than \f(CW\*(C`e\ \-\ 1\*(C'\fR are well-formed UTF\-8 that represents some
+Unicode non-surrogate code point; otherwise it evaluates to 0. If non-zero,
+the value gives how many bytes starting at \f(CW\*(C`s\*(C'\fR comprise the code point's
+representation. Any bytes remaining before \f(CW\*(C`e\*(C'\fR, but beyond the ones needed to
+form the first code point in \f(CW\*(C`s\*(C'\fR, are not examined.
+.Sp
+The largest acceptable code point is the Unicode maximum 0x10FFFF. This
+differs from \f(CW"isSTRICT_UTF8_CHAR"\fR only in that it accepts non-character
+code points. This corresponds to
+Unicode Corrigendum #9 <http://www.unicode.org/versions/corrigendum9.html>.
+which said that non-character code points are merely discouraged rather than
+completely forbidden in open interchange. See
+"Noncharacter code points" in perlunicode.
+.Sp
+Use \f(CW"isUTF8_CHAR"\fR to check for Perl's extended UTF\-8; and
+\&\f(CW"isUTF8_CHAR_flags"\fR for a more customized definition.
+.Sp
+Use \f(CW"is_c9strict_utf8_string"\fR, \f(CW"is_c9strict_utf8_string_loc"\fR, and
+\&\f(CW"is_c9strict_utf8_string_loclen"\fR to check entire strings.
+.RS 4
+.Sp
+.Vb 2
+\& Size_t isC9_STRICT_UTF8_CHAR(const U8 * const s0,
+\& const U8 * const e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_c9strict_utf8_string""" 4
+.el .IP \f(CWis_c9strict_utf8_string\fR 4
+.IX Xref "is_c9strict_utf8_string"
+.IX Item "is_c9strict_utf8_string"
+Returns TRUE if the first \f(CW\*(C`len\*(C'\fR bytes of string \f(CW\*(C`s\*(C'\fR form a valid
+UTF\-8\-encoded string that conforms to
+Unicode Corrigendum #9 <http://www.unicode.org/versions/corrigendum9.html>;
+otherwise it returns FALSE. If \f(CW\*(C`len\*(C'\fR is 0, it will be calculated using
+\&\f(CWstrlen(s)\fR (which means if you use this option, that \f(CW\*(C`s\*(C'\fR can't have embedded
+\&\f(CW\*(C`NUL\*(C'\fR characters and has to have a terminating \f(CW\*(C`NUL\*(C'\fR byte). Note that all
+characters being ASCII constitute 'a valid UTF\-8 string'.
+.Sp
+This function returns FALSE for strings containing any code points above the
+Unicode max of 0x10FFFF or surrogate code points, but accepts non-character
+code points per
+Corrigendum #9 <http://www.unicode.org/versions/corrigendum9.html>.
+.Sp
+See also
+\&\f(CW"is_utf8_invariant_string"\fR,
+\&\f(CW"is_utf8_invariant_string_loc"\fR,
+\&\f(CW"is_utf8_string"\fR,
+\&\f(CW"is_utf8_string_flags"\fR,
+\&\f(CW"is_utf8_string_loc"\fR,
+\&\f(CW"is_utf8_string_loc_flags"\fR,
+\&\f(CW"is_utf8_string_loclen"\fR,
+\&\f(CW"is_utf8_string_loclen_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loc_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loclen_flags"\fR,
+\&\f(CW"is_strict_utf8_string"\fR,
+\&\f(CW"is_strict_utf8_string_loc"\fR,
+\&\f(CW"is_strict_utf8_string_loclen"\fR,
+\&\f(CW"is_c9strict_utf8_string_loc"\fR,
+and
+\&\f(CW"is_c9strict_utf8_string_loclen"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool is_c9strict_utf8_string(const U8 *s, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_c9strict_utf8_string_loc""" 4
+.el .IP \f(CWis_c9strict_utf8_string_loc\fR 4
+.IX Xref "is_c9strict_utf8_string_loc"
+.IX Item "is_c9strict_utf8_string_loc"
+Like \f(CW"is_c9strict_utf8_string"\fR but stores the location of the failure (in
+the case of "utf8ness failure") or the location \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR (in the case of
+"utf8ness success") in the \f(CW\*(C`ep\*(C'\fR pointer.
+.Sp
+See also \f(CW"is_c9strict_utf8_string_loclen"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_c9strict_utf8_string_loc(const U8 *s, STRLEN len,
+\& const U8 **ep)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_c9strict_utf8_string_loclen""" 4
+.el .IP \f(CWis_c9strict_utf8_string_loclen\fR 4
+.IX Xref "is_c9strict_utf8_string_loclen"
+.IX Item "is_c9strict_utf8_string_loclen"
+Like \f(CW"is_c9strict_utf8_string"\fR but stores the location of the failure (in
+the case of "utf8ness failure") or the location \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR (in the case of
+"utf8ness success") in the \f(CW\*(C`ep\*(C'\fR pointer, and the number of UTF\-8 encoded
+characters in the \f(CW\*(C`el\*(C'\fR pointer.
+.Sp
+See also \f(CW"is_c9strict_utf8_string_loc"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_c9strict_utf8_string_loclen(const U8 *s, STRLEN len,
+\& const U8 **ep, STRLEN *el)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_invariant_string""" 4
+.el .IP \f(CWis_invariant_string\fR 4
+.IX Xref "is_invariant_string"
+.IX Item "is_invariant_string"
+This is a somewhat misleadingly-named synonym for "is_utf8_invariant_string".
+\&\f(CW\*(C`is_utf8_invariant_string\*(C'\fR is preferred, as it indicates under what conditions
+the string is invariant.
+.RS 4
+.Sp
+.Vb 1
+\& bool is_invariant_string(const U8 * const s, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isSTRICT_UTF8_CHAR""" 4
+.el .IP \f(CWisSTRICT_UTF8_CHAR\fR 4
+.IX Xref "isSTRICT_UTF8_CHAR"
+.IX Item "isSTRICT_UTF8_CHAR"
+Evaluates to non-zero if the first few bytes of the string starting at \f(CW\*(C`s\*(C'\fR and
+looking no further than \f(CW\*(C`e\ \-\ 1\*(C'\fR are well-formed UTF\-8 that represents some
+Unicode code point completely acceptable for open interchange between all
+applications; otherwise it evaluates to 0. If non-zero, the value gives how
+many bytes starting at \f(CW\*(C`s\*(C'\fR comprise the code point's representation. Any
+bytes remaining before \f(CW\*(C`e\*(C'\fR, but beyond the ones needed to form the first code
+point in \f(CW\*(C`s\*(C'\fR, are not examined.
+.Sp
+The largest acceptable code point is the Unicode maximum 0x10FFFF, and must not
+be a surrogate nor a non-character code point. Thus this excludes any code
+point from Perl's extended UTF\-8.
+.Sp
+This is used to efficiently decide if the next few bytes in \f(CW\*(C`s\*(C'\fR is
+legal Unicode-acceptable UTF\-8 for a single character.
+.Sp
+Use \f(CW"isC9_STRICT_UTF8_CHAR"\fR to use the Unicode Corrigendum
+#9 <http://www.unicode.org/versions/corrigendum9.html> definition of allowable
+code points; \f(CW"isUTF8_CHAR"\fR to check for Perl's extended UTF\-8;
+and \f(CW"isUTF8_CHAR_flags"\fR for a more customized definition.
+.Sp
+Use \f(CW"is_strict_utf8_string"\fR, \f(CW"is_strict_utf8_string_loc"\fR, and
+\&\f(CW"is_strict_utf8_string_loclen"\fR to check entire strings.
+.RS 4
+.Sp
+.Vb 2
+\& Size_t isSTRICT_UTF8_CHAR(const U8 * const s0,
+\& const U8 * const e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_strict_utf8_string""" 4
+.el .IP \f(CWis_strict_utf8_string\fR 4
+.IX Xref "is_strict_utf8_string"
+.IX Item "is_strict_utf8_string"
+Returns TRUE if the first \f(CW\*(C`len\*(C'\fR bytes of string \f(CW\*(C`s\*(C'\fR form a valid
+UTF\-8\-encoded string that is fully interchangeable by any application using
+Unicode rules; otherwise it returns FALSE. If \f(CW\*(C`len\*(C'\fR is 0, it will be
+calculated using \f(CWstrlen(s)\fR (which means if you use this option, that \f(CW\*(C`s\*(C'\fR
+can't have embedded \f(CW\*(C`NUL\*(C'\fR characters and has to have a terminating \f(CW\*(C`NUL\*(C'\fR
+byte). Note that all characters being ASCII constitute 'a valid UTF\-8 string'.
+.Sp
+This function returns FALSE for strings containing any
+code points above the Unicode max of 0x10FFFF, surrogate code points, or
+non-character code points.
+.Sp
+See also
+\&\f(CW"is_utf8_invariant_string"\fR,
+\&\f(CW"is_utf8_invariant_string_loc"\fR,
+\&\f(CW"is_utf8_string"\fR,
+\&\f(CW"is_utf8_string_flags"\fR,
+\&\f(CW"is_utf8_string_loc"\fR,
+\&\f(CW"is_utf8_string_loc_flags"\fR,
+\&\f(CW"is_utf8_string_loclen"\fR,
+\&\f(CW"is_utf8_string_loclen_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loc_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loclen_flags"\fR,
+\&\f(CW"is_strict_utf8_string_loc"\fR,
+\&\f(CW"is_strict_utf8_string_loclen"\fR,
+\&\f(CW"is_c9strict_utf8_string"\fR,
+\&\f(CW"is_c9strict_utf8_string_loc"\fR,
+and
+\&\f(CW"is_c9strict_utf8_string_loclen"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool is_strict_utf8_string(const U8 *s, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_strict_utf8_string_loc""" 4
+.el .IP \f(CWis_strict_utf8_string_loc\fR 4
+.IX Xref "is_strict_utf8_string_loc"
+.IX Item "is_strict_utf8_string_loc"
+Like \f(CW"is_strict_utf8_string"\fR but stores the location of the failure (in the
+case of "utf8ness failure") or the location \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR (in the case of
+"utf8ness success") in the \f(CW\*(C`ep\*(C'\fR pointer.
+.Sp
+See also \f(CW"is_strict_utf8_string_loclen"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_strict_utf8_string_loc(const U8 *s, STRLEN len,
+\& const U8 **ep)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_strict_utf8_string_loclen""" 4
+.el .IP \f(CWis_strict_utf8_string_loclen\fR 4
+.IX Xref "is_strict_utf8_string_loclen"
+.IX Item "is_strict_utf8_string_loclen"
+Like \f(CW"is_strict_utf8_string"\fR but stores the location of the failure (in the
+case of "utf8ness failure") or the location \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR (in the case of
+"utf8ness success") in the \f(CW\*(C`ep\*(C'\fR pointer, and the number of UTF\-8
+encoded characters in the \f(CW\*(C`el\*(C'\fR pointer.
+.Sp
+See also \f(CW"is_strict_utf8_string_loc"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_strict_utf8_string_loclen(const U8 *s, STRLEN len,
+\& const U8 **ep, STRLEN *el)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isUTF8_CHAR""" 4
+.el .IP \f(CWisUTF8_CHAR\fR 4
+.IX Xref "isUTF8_CHAR"
+.IX Item "isUTF8_CHAR"
+Evaluates to non-zero if the first few bytes of the string starting at \f(CW\*(C`s\*(C'\fR and
+looking no further than \f(CW\*(C`e\ \-\ 1\*(C'\fR are well-formed UTF\-8, as extended by Perl,
+that represents some code point; otherwise it evaluates to 0. If non-zero, the
+value gives how many bytes starting at \f(CW\*(C`s\*(C'\fR comprise the code point's
+representation. Any bytes remaining before \f(CW\*(C`e\*(C'\fR, but beyond the ones needed to
+form the first code point in \f(CW\*(C`s\*(C'\fR, are not examined.
+.Sp
+The code point can be any that will fit in an IV on this machine, using Perl's
+extension to official UTF\-8 to represent those higher than the Unicode maximum
+of 0x10FFFF. That means that this macro is used to efficiently decide if the
+next few bytes in \f(CW\*(C`s\*(C'\fR is legal UTF\-8 for a single character.
+.Sp
+Use \f(CW"isSTRICT_UTF8_CHAR"\fR to restrict the acceptable code points to those
+defined by Unicode to be fully interchangeable across applications;
+\&\f(CW"isC9_STRICT_UTF8_CHAR"\fR to use the Unicode Corrigendum
+#9 <http://www.unicode.org/versions/corrigendum9.html> definition of allowable
+code points; and \f(CW"isUTF8_CHAR_flags"\fR for a more customized definition.
+.Sp
+Use \f(CW"is_utf8_string"\fR, \f(CW"is_utf8_string_loc"\fR, and
+\&\f(CW"is_utf8_string_loclen"\fR to check entire strings.
+.Sp
+Note also that a UTF\-8 "invariant" character (i.e. ASCII on non-EBCDIC
+machines) is a valid UTF\-8 character.
+.RS 4
+.Sp
+.Vb 1
+\& Size_t isUTF8_CHAR(const U8 * const s0, const U8 * const e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_char_buf""" 4
+.el .IP \f(CWis_utf8_char_buf\fR 4
+.IX Xref "is_utf8_char_buf"
+.IX Item "is_utf8_char_buf"
+This is identical to the macro "isUTF8_CHAR" in perlapi.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN is_utf8_char_buf(const U8 *buf, const U8 *buf_end)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """isUTF8_CHAR_flags""" 4
+.el .IP \f(CWisUTF8_CHAR_flags\fR 4
+.IX Xref "isUTF8_CHAR_flags"
+.IX Item "isUTF8_CHAR_flags"
+Evaluates to non-zero if the first few bytes of the string starting at \f(CW\*(C`s\*(C'\fR and
+looking no further than \f(CW\*(C`e\ \-\ 1\*(C'\fR are well-formed UTF\-8, as extended by Perl,
+that represents some code point, subject to the restrictions given by \f(CW\*(C`flags\*(C'\fR;
+otherwise it evaluates to 0. If non-zero, the value gives how many bytes
+starting at \f(CW\*(C`s\*(C'\fR comprise the code point's representation. Any bytes remaining
+before \f(CW\*(C`e\*(C'\fR, but beyond the ones needed to form the first code point in \f(CW\*(C`s\*(C'\fR,
+are not examined.
+.Sp
+If \f(CW\*(C`flags\*(C'\fR is 0, this gives the same results as \f(CW"isUTF8_CHAR"\fR;
+if \f(CW\*(C`flags\*(C'\fR is \f(CW\*(C`UTF8_DISALLOW_ILLEGAL_INTERCHANGE\*(C'\fR, this gives the same results
+as \f(CW"isSTRICT_UTF8_CHAR"\fR;
+and if \f(CW\*(C`flags\*(C'\fR is \f(CW\*(C`UTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE\*(C'\fR, this gives
+the same results as \f(CW"isC9_STRICT_UTF8_CHAR"\fR.
+Otherwise \f(CW\*(C`flags\*(C'\fR may be any combination of the \f(CW\*(C`UTF8_DISALLOW_\fR\f(CIfoo\fR\f(CW\*(C'\fR flags
+understood by \f(CW"utf8n_to_uvchr"\fR, with the same meanings.
+.Sp
+The three alternative macros are for the most commonly needed validations; they
+are likely to run somewhat faster than this more general one, as they can be
+inlined into your code.
+.Sp
+Use "is_utf8_string_flags", "is_utf8_string_loc_flags", and
+"is_utf8_string_loclen_flags" to check entire strings.
+.RS 4
+.Sp
+.Vb 2
+\& Size_t isUTF8_CHAR_flags(const U8 * const s0, const U8 * const e,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_fixed_width_buf_flags""" 4
+.el .IP \f(CWis_utf8_fixed_width_buf_flags\fR 4
+.IX Xref "is_utf8_fixed_width_buf_flags"
+.IX Item "is_utf8_fixed_width_buf_flags"
+Returns TRUE if the fixed-width buffer starting at \f(CW\*(C`s\*(C'\fR with length \f(CW\*(C`len\*(C'\fR
+is entirely valid UTF\-8, subject to the restrictions given by \f(CW\*(C`flags\*(C'\fR;
+otherwise it returns FALSE.
+.Sp
+If \f(CW\*(C`flags\*(C'\fR is 0, any well-formed UTF\-8, as extended by Perl, is accepted
+without restriction. If the final few bytes of the buffer do not form a
+complete code point, this will return TRUE anyway, provided that
+\&\f(CW"is_utf8_valid_partial_char_flags"\fR returns TRUE for them.
+.Sp
+If \f(CW\*(C`flags\*(C'\fR in non-zero, it can be any combination of the
+\&\f(CW\*(C`UTF8_DISALLOW_\fR\f(CIfoo\fR\f(CW\*(C'\fR flags accepted by \f(CW"utf8n_to_uvchr"\fR, and with the
+same meanings.
+.Sp
+This function differs from \f(CW"is_utf8_string_flags"\fR only in that the latter
+returns FALSE if the final few bytes of the string don't form a complete code
+point.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_utf8_fixed_width_buf_flags(const U8 * const s,
+\& STRLEN len, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_fixed_width_buf_loc_flags""" 4
+.el .IP \f(CWis_utf8_fixed_width_buf_loc_flags\fR 4
+.IX Xref "is_utf8_fixed_width_buf_loc_flags"
+.IX Item "is_utf8_fixed_width_buf_loc_flags"
+Like \f(CW"is_utf8_fixed_width_buf_flags"\fR but stores the location of the
+failure in the \f(CW\*(C`ep\*(C'\fR pointer. If the function returns TRUE, \f(CW*ep\fR will point
+to the beginning of any partial character at the end of the buffer; if there is
+no partial character \f(CW*ep\fR will contain \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR.
+.Sp
+See also \f(CW"is_utf8_fixed_width_buf_loclen_flags"\fR.
+.RS 4
+.Sp
+.Vb 3
+\& bool is_utf8_fixed_width_buf_loc_flags(const U8 * const s,
+\& STRLEN len, const U8 **ep,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_fixed_width_buf_loclen_flags""" 4
+.el .IP \f(CWis_utf8_fixed_width_buf_loclen_flags\fR 4
+.IX Xref "is_utf8_fixed_width_buf_loclen_flags"
+.IX Item "is_utf8_fixed_width_buf_loclen_flags"
+Like \f(CW"is_utf8_fixed_width_buf_loc_flags"\fR but stores the number of
+complete, valid characters found in the \f(CW\*(C`el\*(C'\fR pointer.
+.RS 4
+.Sp
+.Vb 5
+\& bool is_utf8_fixed_width_buf_loclen_flags(const U8 * const s,
+\& STRLEN len,
+\& const U8 **ep,
+\& STRLEN *el,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_invariant_string""" 4
+.el .IP \f(CWis_utf8_invariant_string\fR 4
+.IX Xref "is_utf8_invariant_string"
+.IX Item "is_utf8_invariant_string"
+Returns TRUE if the first \f(CW\*(C`len\*(C'\fR bytes of the string \f(CW\*(C`s\*(C'\fR are the same
+regardless of the UTF\-8 encoding of the string (or UTF-EBCDIC encoding on
+EBCDIC machines); otherwise it returns FALSE. That is, it returns TRUE if they
+are UTF\-8 invariant. On ASCII-ish machines, all the ASCII characters and only
+the ASCII characters fit this definition. On EBCDIC machines, the ASCII-range
+characters are invariant, but so also are the C1 controls.
+.Sp
+If \f(CW\*(C`len\*(C'\fR is 0, it will be calculated using \f(CWstrlen(s)\fR, (which means if you
+use this option, that \f(CW\*(C`s\*(C'\fR can't have embedded \f(CW\*(C`NUL\*(C'\fR characters and has to
+have a terminating \f(CW\*(C`NUL\*(C'\fR byte).
+.Sp
+See also
+\&\f(CW"is_utf8_string"\fR,
+\&\f(CW"is_utf8_string_flags"\fR,
+\&\f(CW"is_utf8_string_loc"\fR,
+\&\f(CW"is_utf8_string_loc_flags"\fR,
+\&\f(CW"is_utf8_string_loclen"\fR,
+\&\f(CW"is_utf8_string_loclen_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loc_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loclen_flags"\fR,
+\&\f(CW"is_strict_utf8_string"\fR,
+\&\f(CW"is_strict_utf8_string_loc"\fR,
+\&\f(CW"is_strict_utf8_string_loclen"\fR,
+\&\f(CW"is_c9strict_utf8_string"\fR,
+\&\f(CW"is_c9strict_utf8_string_loc"\fR,
+and
+\&\f(CW"is_c9strict_utf8_string_loclen"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& bool is_utf8_invariant_string(const U8 * const s, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_invariant_string_loc""" 4
+.el .IP \f(CWis_utf8_invariant_string_loc\fR 4
+.IX Xref "is_utf8_invariant_string_loc"
+.IX Item "is_utf8_invariant_string_loc"
+Like \f(CW"is_utf8_invariant_string"\fR but upon failure, stores the location of
+the first UTF\-8 variant character in the \f(CW\*(C`ep\*(C'\fR pointer; if all characters are
+UTF\-8 invariant, this function does not change the contents of \f(CW*ep\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_utf8_invariant_string_loc(const U8 * const s, STRLEN len,
+\& const U8 **ep)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_string""" 4
+.el .IP \f(CWis_utf8_string\fR 4
+.IX Xref "is_utf8_string"
+.IX Item "is_utf8_string"
+Returns TRUE if the first \f(CW\*(C`len\*(C'\fR bytes of string \f(CW\*(C`s\*(C'\fR form a valid
+Perl\-extended\-UTF\-8 string; returns FALSE otherwise. If \f(CW\*(C`len\*(C'\fR is 0, it will
+be calculated using \f(CWstrlen(s)\fR (which means if you use this option, that \f(CW\*(C`s\*(C'\fR
+can't have embedded \f(CW\*(C`NUL\*(C'\fR characters and has to have a terminating \f(CW\*(C`NUL\*(C'\fR
+byte). Note that all characters being ASCII constitute 'a valid UTF\-8 string'.
+.Sp
+This function considers Perl's extended UTF\-8 to be valid. That means that
+code points above Unicode, surrogates, and non-character code points are
+considered valid by this function. Use \f(CW"is_strict_utf8_string"\fR,
+\&\f(CW"is_c9strict_utf8_string"\fR, or \f(CW"is_utf8_string_flags"\fR to restrict what
+code points are considered valid.
+.Sp
+See also
+\&\f(CW"is_utf8_invariant_string"\fR,
+\&\f(CW"is_utf8_invariant_string_loc"\fR,
+\&\f(CW"is_utf8_string_loc"\fR,
+\&\f(CW"is_utf8_string_loclen"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loc_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loclen_flags"\fR,
+.RS 4
+.Sp
+.Vb 1
+\& bool is_utf8_string(const U8 *s, STRLEN len)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_string_flags""" 4
+.el .IP \f(CWis_utf8_string_flags\fR 4
+.IX Xref "is_utf8_string_flags"
+.IX Item "is_utf8_string_flags"
+Returns TRUE if the first \f(CW\*(C`len\*(C'\fR bytes of string \f(CW\*(C`s\*(C'\fR form a valid
+UTF\-8 string, subject to the restrictions imposed by \f(CW\*(C`flags\*(C'\fR;
+returns FALSE otherwise. If \f(CW\*(C`len\*(C'\fR is 0, it will be calculated
+using \f(CWstrlen(s)\fR (which means if you use this option, that \f(CW\*(C`s\*(C'\fR can't have
+embedded \f(CW\*(C`NUL\*(C'\fR characters and has to have a terminating \f(CW\*(C`NUL\*(C'\fR byte). Note
+that all characters being ASCII constitute 'a valid UTF\-8 string'.
+.Sp
+If \f(CW\*(C`flags\*(C'\fR is 0, this gives the same results as \f(CW"is_utf8_string"\fR; if
+\&\f(CW\*(C`flags\*(C'\fR is \f(CW\*(C`UTF8_DISALLOW_ILLEGAL_INTERCHANGE\*(C'\fR, this gives the same results
+as \f(CW"is_strict_utf8_string"\fR; and if \f(CW\*(C`flags\*(C'\fR is
+\&\f(CW\*(C`UTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE\*(C'\fR, this gives the same results as
+\&\f(CW"is_c9strict_utf8_string"\fR. Otherwise \f(CW\*(C`flags\*(C'\fR may be any
+combination of the \f(CW\*(C`UTF8_DISALLOW_\fR\f(CIfoo\fR\f(CW\*(C'\fR flags understood by
+\&\f(CW"utf8n_to_uvchr"\fR, with the same meanings.
+.Sp
+See also
+\&\f(CW"is_utf8_invariant_string"\fR,
+\&\f(CW"is_utf8_invariant_string_loc"\fR,
+\&\f(CW"is_utf8_string"\fR,
+\&\f(CW"is_utf8_string_loc"\fR,
+\&\f(CW"is_utf8_string_loc_flags"\fR,
+\&\f(CW"is_utf8_string_loclen"\fR,
+\&\f(CW"is_utf8_string_loclen_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loc_flags"\fR,
+\&\f(CW"is_utf8_fixed_width_buf_loclen_flags"\fR,
+\&\f(CW"is_strict_utf8_string"\fR,
+\&\f(CW"is_strict_utf8_string_loc"\fR,
+\&\f(CW"is_strict_utf8_string_loclen"\fR,
+\&\f(CW"is_c9strict_utf8_string"\fR,
+\&\f(CW"is_c9strict_utf8_string_loc"\fR,
+and
+\&\f(CW"is_c9strict_utf8_string_loclen"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_utf8_string_flags(const U8 *s, STRLEN len,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_string_loc""" 4
+.el .IP \f(CWis_utf8_string_loc\fR 4
+.IX Xref "is_utf8_string_loc"
+.IX Item "is_utf8_string_loc"
+Like \f(CW"is_utf8_string"\fR but stores the location of the failure (in the
+case of "utf8ness failure") or the location \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR (in the case of
+"utf8ness success") in the \f(CW\*(C`ep\*(C'\fR pointer.
+.Sp
+See also \f(CW"is_utf8_string_loclen"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_utf8_string_loc(const U8 *s, const STRLEN len,
+\& const U8 **ep)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_string_loc_flags""" 4
+.el .IP \f(CWis_utf8_string_loc_flags\fR 4
+.IX Xref "is_utf8_string_loc_flags"
+.IX Item "is_utf8_string_loc_flags"
+Like \f(CW"is_utf8_string_flags"\fR but stores the location of the failure (in the
+case of "utf8ness failure") or the location \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR (in the case of
+"utf8ness success") in the \f(CW\*(C`ep\*(C'\fR pointer.
+.Sp
+See also \f(CW"is_utf8_string_loclen_flags"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_utf8_string_loc_flags(const U8 *s, STRLEN len,
+\& const U8 **ep, const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_string_loclen""" 4
+.el .IP \f(CWis_utf8_string_loclen\fR 4
+.IX Xref "is_utf8_string_loclen"
+.IX Item "is_utf8_string_loclen"
+Like \f(CW"is_utf8_string"\fR but stores the location of the failure (in the
+case of "utf8ness failure") or the location \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR (in the case of
+"utf8ness success") in the \f(CW\*(C`ep\*(C'\fR pointer, and the number of UTF\-8
+encoded characters in the \f(CW\*(C`el\*(C'\fR pointer.
+.Sp
+See also \f(CW"is_utf8_string_loc"\fR.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_utf8_string_loclen(const U8 *s, STRLEN len,
+\& const U8 **ep, STRLEN *el)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_string_loclen_flags""" 4
+.el .IP \f(CWis_utf8_string_loclen_flags\fR 4
+.IX Xref "is_utf8_string_loclen_flags"
+.IX Item "is_utf8_string_loclen_flags"
+Like \f(CW"is_utf8_string_flags"\fR but stores the location of the failure (in the
+case of "utf8ness failure") or the location \f(CW\*(C`s\*(C'\fR+\f(CW\*(C`len\*(C'\fR (in the case of
+"utf8ness success") in the \f(CW\*(C`ep\*(C'\fR pointer, and the number of UTF\-8
+encoded characters in the \f(CW\*(C`el\*(C'\fR pointer.
+.Sp
+See also \f(CW"is_utf8_string_loc_flags"\fR.
+.RS 4
+.Sp
+.Vb 3
+\& bool is_utf8_string_loclen_flags(const U8 *s, STRLEN len,
+\& const U8 **ep, STRLEN *el,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_valid_partial_char""" 4
+.el .IP \f(CWis_utf8_valid_partial_char\fR 4
+.IX Xref "is_utf8_valid_partial_char"
+.IX Item "is_utf8_valid_partial_char"
+Returns 0 if the sequence of bytes starting at \f(CW\*(C`s\*(C'\fR and looking no further than
+\&\f(CW\*(C`e\ \-\ 1\*(C'\fR is the UTF\-8 encoding, as extended by Perl, for one or more code
+points. Otherwise, it returns 1 if there exists at least one non-empty
+sequence of bytes that when appended to sequence \f(CW\*(C`s\*(C'\fR, starting at position
+\&\f(CW\*(C`e\*(C'\fR causes the entire sequence to be the well-formed UTF\-8 of some code point;
+otherwise returns 0.
+.Sp
+In other words this returns TRUE if \f(CW\*(C`s\*(C'\fR points to a partial UTF\-8\-encoded code
+point.
+.Sp
+This is useful when a fixed-length buffer is being tested for being well-formed
+UTF\-8, but the final few bytes in it don't comprise a full character; that is,
+it is split somewhere in the middle of the final code point's UTF\-8
+representation. (Presumably when the buffer is refreshed with the next chunk
+of data, the new first bytes will complete the partial code point.) This
+function is used to verify that the final bytes in the current buffer are in
+fact the legal beginning of some code point, so that if they aren't, the
+failure can be signalled without having to wait for the next read.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_utf8_valid_partial_char(const U8 * const s0,
+\& const U8 * const e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_utf8_valid_partial_char_flags""" 4
+.el .IP \f(CWis_utf8_valid_partial_char_flags\fR 4
+.IX Xref "is_utf8_valid_partial_char_flags"
+.IX Item "is_utf8_valid_partial_char_flags"
+Like \f(CW"is_utf8_valid_partial_char"\fR, it returns a boolean giving whether
+or not the input is a valid UTF\-8 encoded partial character, but it takes an
+extra parameter, \f(CW\*(C`flags\*(C'\fR, which can further restrict which code points are
+considered valid.
+.Sp
+If \f(CW\*(C`flags\*(C'\fR is 0, this behaves identically to
+\&\f(CW"is_utf8_valid_partial_char"\fR. Otherwise \f(CW\*(C`flags\*(C'\fR can be any combination
+of the \f(CW\*(C`UTF8_DISALLOW_\fR\f(CIfoo\fR\f(CW\*(C'\fR flags accepted by \f(CW"utf8n_to_uvchr"\fR. If
+there is any sequence of bytes that can complete the input partial character in
+such a way that a non-prohibited character is formed, the function returns
+TRUE; otherwise FALSE. Non character code points cannot be determined based on
+partial character input. But many of the other possible excluded types can be
+determined from just the first one or two bytes.
+.RS 4
+.Sp
+.Vb 3
+\& bool is_utf8_valid_partial_char_flags(const U8 * const s0,
+\& const U8 * const e,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """LATIN1_TO_NATIVE""" 4
+.el .IP \f(CWLATIN1_TO_NATIVE\fR 4
+.IX Xref "LATIN1_TO_NATIVE"
+.IX Item "LATIN1_TO_NATIVE"
+Returns the native equivalent of the input Latin\-1 code point (including ASCII
+and control characters) given by \f(CW\*(C`ch\*(C'\fR. Thus, \f(CWLATIN1_TO_NATIVE(66)\fR on
+EBCDIC platforms returns 194. These each represent the character \f(CW"B"\fR on
+their respective platforms. On ASCII platforms no conversion is needed, so
+this macro expands to just its input, adding no time nor space requirements to
+the implementation.
+.Sp
+For conversion of code points potentially larger than will fit in a character,
+use "UNI_TO_NATIVE".
+.RS 4
+.Sp
+.Vb 1
+\& U8 LATIN1_TO_NATIVE(U8 ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """NATIVE_TO_LATIN1""" 4
+.el .IP \f(CWNATIVE_TO_LATIN1\fR 4
+.IX Xref "NATIVE_TO_LATIN1"
+.IX Item "NATIVE_TO_LATIN1"
+Returns the Latin\-1 (including ASCII and control characters) equivalent of the
+input native code point given by \f(CW\*(C`ch\*(C'\fR. Thus, \f(CWNATIVE_TO_LATIN1(193)\fR on
+EBCDIC platforms returns 65. These each represent the character \f(CW"A"\fR on
+their respective platforms. On ASCII platforms no conversion is needed, so
+this macro expands to just its input, adding no time nor space requirements to
+the implementation.
+.Sp
+For conversion of code points potentially larger than will fit in a character,
+use "NATIVE_TO_UNI".
+.RS 4
+.Sp
+.Vb 1
+\& U8 NATIVE_TO_LATIN1(U8 ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """NATIVE_TO_UNI""" 4
+.el .IP \f(CWNATIVE_TO_UNI\fR 4
+.IX Xref "NATIVE_TO_UNI"
+.IX Item "NATIVE_TO_UNI"
+Returns the Unicode equivalent of the input native code point given by \f(CW\*(C`ch\*(C'\fR.
+Thus, \f(CWNATIVE_TO_UNI(195)\fR on EBCDIC platforms returns 67. These each
+represent the character \f(CW"C"\fR on their respective platforms. On ASCII
+platforms no conversion is needed, so this macro expands to just its input,
+adding no time nor space requirements to the implementation.
+.RS 4
+.Sp
+.Vb 1
+\& UV NATIVE_TO_UNI(UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """pv_uni_display""" 4
+.el .IP \f(CWpv_uni_display\fR 4
+.IX Xref "pv_uni_display"
+.IX Item "pv_uni_display"
+Build to the scalar \f(CW\*(C`dsv\*(C'\fR a displayable version of the UTF\-8 encoded string
+\&\f(CW\*(C`spv\*(C'\fR, length \f(CW\*(C`len\*(C'\fR, the displayable version being at most \f(CW\*(C`pvlim\*(C'\fR bytes
+long (if longer, the rest is truncated and \f(CW"..."\fR will be appended).
+.Sp
+The \f(CW\*(C`flags\*(C'\fR argument can have \f(CW\*(C`UNI_DISPLAY_ISPRINT\*(C'\fR set to display
+\&\f(CWisPRINT()\fRable characters as themselves, \f(CW\*(C`UNI_DISPLAY_BACKSLASH\*(C'\fR
+to display the \f(CW\*(C`\e\e[nrfta\e\e]\*(C'\fR as the backslashed versions (like \f(CW"\en"\fR)
+(\f(CW\*(C`UNI_DISPLAY_BACKSLASH\*(C'\fR is preferred over \f(CW\*(C`UNI_DISPLAY_ISPRINT\*(C'\fR for \f(CW"\e\e"\fR).
+\&\f(CW\*(C`UNI_DISPLAY_QQ\*(C'\fR (and its alias \f(CW\*(C`UNI_DISPLAY_REGEX\*(C'\fR) have both
+\&\f(CW\*(C`UNI_DISPLAY_BACKSLASH\*(C'\fR and \f(CW\*(C`UNI_DISPLAY_ISPRINT\*(C'\fR turned on.
+.Sp
+Additionally, there is now \f(CW\*(C`UNI_DISPLAY_BACKSPACE\*(C'\fR which allows \f(CW\*(C`\eb\*(C'\fR for a
+backspace, but only when \f(CW\*(C`UNI_DISPLAY_BACKSLASH\*(C'\fR also is set.
+.Sp
+The pointer to the PV of the \f(CW\*(C`dsv\*(C'\fR is returned.
+.Sp
+See also "sv_uni_display".
+.RS 4
+.Sp
+.Vb 2
+\& char * pv_uni_display(SV *dsv, const U8 *spv, STRLEN len,
+\& STRLEN pvlim, UV flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """REPLACEMENT_CHARACTER_UTF8""" 4
+.el .IP \f(CWREPLACEMENT_CHARACTER_UTF8\fR 4
+.IX Xref "REPLACEMENT_CHARACTER_UTF8"
+.IX Item "REPLACEMENT_CHARACTER_UTF8"
+This is a macro that evaluates to a string constant of the UTF\-8 bytes that
+define the Unicode REPLACEMENT CHARACTER (U+FFFD) for the platform that perl
+is compiled on. This allows code to use a mnemonic for this character that
+works on both ASCII and EBCDIC platforms.
+\&\f(CW\*(C`sizeof(REPLACEMENT_CHARACTER_UTF8)\ \-\ 1\*(C'\fR can be used to get its length in
+bytes.
+.ie n .IP """sv_cat_decode""" 4
+.el .IP \f(CWsv_cat_decode\fR 4
+.IX Xref "sv_cat_decode"
+.IX Item "sv_cat_decode"
+\&\f(CW\*(C`encoding\*(C'\fR is assumed to be an \f(CW\*(C`Encode\*(C'\fR object, the PV of \f(CW\*(C`ssv\*(C'\fR is
+assumed to be octets in that encoding and decoding the input starts
+from the position which \f(CW\*(C`(PV\ +\ *offset)\*(C'\fR pointed to. \f(CW\*(C`dsv\*(C'\fR will be
+concatenated with the decoded UTF\-8 string from \f(CW\*(C`ssv\*(C'\fR. Decoding will terminate
+when the string \f(CW\*(C`tstr\*(C'\fR appears in decoding output or the input ends on
+the PV of \f(CW\*(C`ssv\*(C'\fR. The value which \f(CW\*(C`offset\*(C'\fR points will be modified
+to the last input position on \f(CW\*(C`ssv\*(C'\fR.
+.Sp
+Returns TRUE if the terminator was found, else returns FALSE.
+.RS 4
+.Sp
+.Vb 2
+\& bool sv_cat_decode(SV *dsv, SV *encoding, SV *ssv, int *offset,
+\& char *tstr, int tlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_recode_to_utf8""" 4
+.el .IP \f(CWsv_recode_to_utf8\fR 4
+.IX Xref "sv_recode_to_utf8"
+.IX Item "sv_recode_to_utf8"
+\&\f(CW\*(C`encoding\*(C'\fR is assumed to be an \f(CW\*(C`Encode\*(C'\fR object, on entry the PV
+of \f(CW\*(C`sv\*(C'\fR is assumed to be octets in that encoding, and \f(CW\*(C`sv\*(C'\fR
+will be converted into Unicode (and UTF\-8).
+.Sp
+If \f(CW\*(C`sv\*(C'\fR already is UTF\-8 (or if it is not \f(CW\*(C`POK\*(C'\fR), or if \f(CW\*(C`encoding\*(C'\fR
+is not a reference, nothing is done to \f(CW\*(C`sv\*(C'\fR. If \f(CW\*(C`encoding\*(C'\fR is not
+an \f(CW\*(C`Encode::XS\*(C'\fR Encoding object, bad things will happen.
+(See encoding and Encode.)
+.Sp
+The PV of \f(CW\*(C`sv\*(C'\fR is returned.
+.RS 4
+.Sp
+.Vb 1
+\& char * sv_recode_to_utf8(SV *sv, SV *encoding)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_uni_display""" 4
+.el .IP \f(CWsv_uni_display\fR 4
+.IX Xref "sv_uni_display"
+.IX Item "sv_uni_display"
+Build to the scalar \f(CW\*(C`dsv\*(C'\fR a displayable version of the scalar \f(CW\*(C`sv\*(C'\fR,
+the displayable version being at most \f(CW\*(C`pvlim\*(C'\fR bytes long
+(if longer, the rest is truncated and "..." will be appended).
+.Sp
+The \f(CW\*(C`flags\*(C'\fR argument is as in "pv_uni_display"().
+.Sp
+The pointer to the PV of the \f(CW\*(C`dsv\*(C'\fR is returned.
+.RS 4
+.Sp
+.Vb 1
+\& char * sv_uni_display(SV *dsv, SV *ssv, STRLEN pvlim, UV flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UNICODE_IS_NONCHAR""" 4
+.el .IP \f(CWUNICODE_IS_NONCHAR\fR 4
+.IX Xref "UNICODE_IS_NONCHAR"
+.IX Item "UNICODE_IS_NONCHAR"
+Returns a boolean as to whether or not \f(CW\*(C`uv\*(C'\fR is one of the Unicode
+non-character code points
+.RS 4
+.Sp
+.Vb 1
+\& bool UNICODE_IS_NONCHAR(const UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UNICODE_IS_REPLACEMENT""" 4
+.el .IP \f(CWUNICODE_IS_REPLACEMENT\fR 4
+.IX Xref "UNICODE_IS_REPLACEMENT"
+.IX Item "UNICODE_IS_REPLACEMENT"
+Returns a boolean as to whether or not \f(CW\*(C`uv\*(C'\fR is the Unicode REPLACEMENT
+CHARACTER
+.RS 4
+.Sp
+.Vb 1
+\& bool UNICODE_IS_REPLACEMENT(const UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UNICODE_IS_SUPER""" 4
+.el .IP \f(CWUNICODE_IS_SUPER\fR 4
+.IX Xref "UNICODE_IS_SUPER"
+.IX Item "UNICODE_IS_SUPER"
+Returns a boolean as to whether or not \f(CW\*(C`uv\*(C'\fR is above the maximum legal Unicode
+code point of U+10FFFF.
+.RS 4
+.Sp
+.Vb 1
+\& bool UNICODE_IS_SUPER(const UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UNICODE_IS_SURROGATE""" 4
+.el .IP \f(CWUNICODE_IS_SURROGATE\fR 4
+.IX Xref "UNICODE_IS_SURROGATE"
+.IX Item "UNICODE_IS_SURROGATE"
+Returns a boolean as to whether or not \f(CW\*(C`uv\*(C'\fR is one of the Unicode surrogate
+code points
+.RS 4
+.Sp
+.Vb 1
+\& bool UNICODE_IS_SURROGATE(const UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UNICODE_REPLACEMENT""" 4
+.el .IP \f(CWUNICODE_REPLACEMENT\fR 4
+.IX Xref "UNICODE_REPLACEMENT"
+.IX Item "UNICODE_REPLACEMENT"
+Evaluates to 0xFFFD, the code point of the Unicode REPLACEMENT CHARACTER
+.ie n .IP """UNI_TO_NATIVE""" 4
+.el .IP \f(CWUNI_TO_NATIVE\fR 4
+.IX Xref "UNI_TO_NATIVE"
+.IX Item "UNI_TO_NATIVE"
+Returns the native equivalent of the input Unicode code point given by \f(CW\*(C`ch\*(C'\fR.
+Thus, \f(CWUNI_TO_NATIVE(68)\fR on EBCDIC platforms returns 196. These each
+represent the character \f(CW"D"\fR on their respective platforms. On ASCII
+platforms no conversion is needed, so this macro expands to just its input,
+adding no time nor space requirements to the implementation.
+.RS 4
+.Sp
+.Vb 1
+\& UV UNI_TO_NATIVE(UV ch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_CHK_SKIP""" 4
+.el .IP \f(CWUTF8_CHK_SKIP\fR 4
+.IX Xref "UTF8_CHK_SKIP"
+.IX Item "UTF8_CHK_SKIP"
+This is a safer version of \f(CW"UTF8SKIP"\fR, but still not as safe as
+\&\f(CW"UTF8_SAFE_SKIP"\fR. This version doesn't blindly assume that the input
+string pointed to by \f(CW\*(C`s\*(C'\fR is well-formed, but verifies that there isn't a NUL
+terminating character before the expected end of the next character in \f(CW\*(C`s\*(C'\fR.
+The length \f(CW\*(C`UTF8_CHK_SKIP\*(C'\fR returns stops just before any such NUL.
+.Sp
+Perl tends to add NULs, as an insurance policy, after the end of strings in
+SV's, so it is likely that using this macro will prevent inadvertent reading
+beyond the end of the input buffer, even if it is malformed UTF\-8.
+.Sp
+This macro is intended to be used by XS modules where the inputs could be
+malformed, and it isn't feasible to restructure to use the safer
+\&\f(CW"UTF8_SAFE_SKIP"\fR, for example when interfacing with a C library.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN UTF8_CHK_SKIP(char* s)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_distance""" 4
+.el .IP \f(CWutf8_distance\fR 4
+.IX Xref "utf8_distance"
+.IX Item "utf8_distance"
+Returns the number of UTF\-8 characters between the UTF\-8 pointers \f(CW\*(C`a\*(C'\fR
+and \f(CW\*(C`b\*(C'\fR.
+.Sp
+WARNING: use only if you *know* that the pointers point inside the
+same UTF\-8 buffer.
+.RS 4
+.Sp
+.Vb 1
+\& IV utf8_distance(const U8 *a, const U8 *b)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_hop""" 4
+.el .IP \f(CWutf8_hop\fR 4
+.IX Xref "utf8_hop"
+.IX Item "utf8_hop"
+Return the UTF\-8 pointer \f(CW\*(C`s\*(C'\fR displaced by \f(CW\*(C`off\*(C'\fR characters, either
+forward (if \f(CW\*(C`off\*(C'\fR is positive) or backward (if negative). \f(CW\*(C`s\*(C'\fR does not need
+to be pointing to the starting byte of a character. If it isn't, one count of
+\&\f(CW\*(C`off\*(C'\fR will be used up to get to the start of the next character for forward
+hops, and to the start of the current character for negative ones.
+.Sp
+WARNING: Prefer "utf8_hop_safe" to this one.
+.Sp
+Do NOT use this function unless you \fBknow\fR \f(CW\*(C`off\*(C'\fR is within
+the UTF\-8 data pointed to by \f(CW\*(C`s\*(C'\fR \fBand\fR that on entry \f(CW\*(C`s\*(C'\fR is aligned
+on the first byte of a character or just after the last byte of a character.
+.RS 4
+.Sp
+.Vb 1
+\& U8 * utf8_hop(const U8 *s, SSize_t off)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_hop_back""" 4
+.el .IP \f(CWutf8_hop_back\fR 4
+.IX Xref "utf8_hop_back"
+.IX Item "utf8_hop_back"
+Return the UTF\-8 pointer \f(CW\*(C`s\*(C'\fR displaced by up to \f(CW\*(C`off\*(C'\fR characters,
+backward. \f(CW\*(C`s\*(C'\fR does not need to be pointing to the starting byte of a
+character. If it isn't, one count of \f(CW\*(C`off\*(C'\fR will be used up to get to that
+start.
+.Sp
+\&\f(CW\*(C`off\*(C'\fR must be non-positive.
+.Sp
+\&\f(CW\*(C`s\*(C'\fR must be after or equal to \f(CW\*(C`start\*(C'\fR.
+.Sp
+When moving backward it will not move before \f(CW\*(C`start\*(C'\fR.
+.Sp
+Will not exceed this limit even if the string is not valid "UTF\-8".
+.RS 4
+.Sp
+.Vb 1
+\& U8 * utf8_hop_back(const U8 *s, SSize_t off, const U8 *start)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_hop_forward""" 4
+.el .IP \f(CWutf8_hop_forward\fR 4
+.IX Xref "utf8_hop_forward"
+.IX Item "utf8_hop_forward"
+Return the UTF\-8 pointer \f(CW\*(C`s\*(C'\fR displaced by up to \f(CW\*(C`off\*(C'\fR characters,
+forward. \f(CW\*(C`s\*(C'\fR does not need to be pointing to the starting byte of a
+character. If it isn't, one count of \f(CW\*(C`off\*(C'\fR will be used up to get to the
+start of the next character.
+.Sp
+\&\f(CW\*(C`off\*(C'\fR must be non-negative.
+.Sp
+\&\f(CW\*(C`s\*(C'\fR must be before or equal to \f(CW\*(C`end\*(C'\fR.
+.Sp
+When moving forward it will not move beyond \f(CW\*(C`end\*(C'\fR.
+.Sp
+Will not exceed this limit even if the string is not valid "UTF\-8".
+.RS 4
+.Sp
+.Vb 1
+\& U8 * utf8_hop_forward(const U8 *s, SSize_t off, const U8 *end)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_hop_safe""" 4
+.el .IP \f(CWutf8_hop_safe\fR 4
+.IX Xref "utf8_hop_safe"
+.IX Item "utf8_hop_safe"
+Return the UTF\-8 pointer \f(CW\*(C`s\*(C'\fR displaced by up to \f(CW\*(C`off\*(C'\fR characters,
+either forward or backward. \f(CW\*(C`s\*(C'\fR does not need to be pointing to the starting
+byte of a character. If it isn't, one count of \f(CW\*(C`off\*(C'\fR will be used up to get
+to the start of the next character for forward hops, and to the start of the
+current character for negative ones.
+.Sp
+When moving backward it will not move before \f(CW\*(C`start\*(C'\fR.
+.Sp
+When moving forward it will not move beyond \f(CW\*(C`end\*(C'\fR.
+.Sp
+Will not exceed those limits even if the string is not valid "UTF\-8".
+.RS 4
+.Sp
+.Vb 2
+\& U8 * utf8_hop_safe(const U8 *s, SSize_t off, const U8 *start,
+\& const U8 *end)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_IS_INVARIANT""" 4
+.el .IP \f(CWUTF8_IS_INVARIANT\fR 4
+.IX Xref "UTF8_IS_INVARIANT"
+.IX Item "UTF8_IS_INVARIANT"
+Evaluates to 1 if the byte \f(CW\*(C`c\*(C'\fR represents the same character when encoded in
+UTF\-8 as when not; otherwise evaluates to 0. UTF\-8 invariant characters can be
+copied as-is when converting to/from UTF\-8, saving time.
+.Sp
+In spite of the name, this macro gives the correct result if the input string
+from which \f(CW\*(C`c\*(C'\fR comes is not encoded in UTF\-8.
+.Sp
+See \f(CW"UVCHR_IS_INVARIANT"\fR for checking if a UV is invariant.
+.RS 4
+.Sp
+.Vb 1
+\& bool UTF8_IS_INVARIANT(char c)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_IS_NONCHAR""" 4
+.el .IP \f(CWUTF8_IS_NONCHAR\fR 4
+.IX Xref "UTF8_IS_NONCHAR"
+.IX Item "UTF8_IS_NONCHAR"
+Evaluates to non-zero if the first few bytes of the string starting at \f(CW\*(C`s\*(C'\fR and
+looking no further than \f(CW\*(C`e\ \-\ 1\*(C'\fR are well-formed UTF\-8 that represents one
+of the Unicode non-character code points; otherwise it evaluates to 0. If
+non-zero, the value gives how many bytes starting at \f(CW\*(C`s\*(C'\fR comprise the code
+point's representation.
+.RS 4
+.Sp
+.Vb 1
+\& bool UTF8_IS_NONCHAR(const U8 *s, const U8 *e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_IS_REPLACEMENT""" 4
+.el .IP \f(CWUTF8_IS_REPLACEMENT\fR 4
+.IX Xref "UTF8_IS_REPLACEMENT"
+.IX Item "UTF8_IS_REPLACEMENT"
+Evaluates to non-zero if the first few bytes of the string starting at \f(CW\*(C`s\*(C'\fR and
+looking no further than \f(CW\*(C`e\ \-\ 1\*(C'\fR are well-formed UTF\-8 that represents the
+Unicode REPLACEMENT CHARACTER; otherwise it evaluates to 0. If non-zero, the
+value gives how many bytes starting at \f(CW\*(C`s\*(C'\fR comprise the code point's
+representation.
+.RS 4
+.Sp
+.Vb 1
+\& bool UTF8_IS_REPLACEMENT(const U8 *s, const U8 *e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_IS_SUPER""" 4
+.el .IP \f(CWUTF8_IS_SUPER\fR 4
+.IX Xref "UTF8_IS_SUPER"
+.IX Item "UTF8_IS_SUPER"
+Recall that Perl recognizes an extension to UTF\-8 that can encode code
+points larger than the ones defined by Unicode, which are 0..0x10FFFF.
+.Sp
+This macro evaluates to non-zero if the first few bytes of the string starting
+at \f(CW\*(C`s\*(C'\fR and looking no further than \f(CW\*(C`e\ \-\ 1\*(C'\fR are from this UTF\-8 extension;
+otherwise it evaluates to 0. If non-zero, the return is how many bytes
+starting at \f(CW\*(C`s\*(C'\fR comprise the code point's representation.
+.Sp
+0 is returned if the bytes are not well-formed extended UTF\-8, or if they
+represent a code point that cannot fit in a UV on the current platform. Hence
+this macro can give different results when run on a 64\-bit word machine than on
+one with a 32\-bit word size.
+.Sp
+Note that it is illegal in Perl to have code points that are larger than what can
+fit in an IV on the current machine; and illegal in Unicode to have any that
+this macro matches
+.RS 4
+.Sp
+.Vb 1
+\& bool UTF8_IS_SUPER(const U8 *s, const U8 *e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_IS_SURROGATE""" 4
+.el .IP \f(CWUTF8_IS_SURROGATE\fR 4
+.IX Xref "UTF8_IS_SURROGATE"
+.IX Item "UTF8_IS_SURROGATE"
+Evaluates to non-zero if the first few bytes of the string starting at \f(CW\*(C`s\*(C'\fR and
+looking no further than \f(CW\*(C`e\ \-\ 1\*(C'\fR are well-formed UTF\-8 that represents one
+of the Unicode surrogate code points; otherwise it evaluates to 0. If
+non-zero, the value gives how many bytes starting at \f(CW\*(C`s\*(C'\fR comprise the code
+point's representation.
+.RS 4
+.Sp
+.Vb 1
+\& bool UTF8_IS_SURROGATE(const U8 *s, const U8 *e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_length""" 4
+.el .IP \f(CWutf8_length\fR 4
+.IX Xref "utf8_length"
+.IX Item "utf8_length"
+Returns the number of characters in the sequence of UTF\-8\-encoded bytes starting
+at \f(CW\*(C`s\*(C'\fR and ending at the byte just before \f(CW\*(C`e\*(C'\fR. If <s> and <e> point to the
+same place, it returns 0 with no warning raised.
+.Sp
+If \f(CW\*(C`e < s\*(C'\fR or if the scan would end up past \f(CW\*(C`e\*(C'\fR, it raises a UTF8 warning
+and returns the number of valid characters.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN utf8_length(const U8 *s0, const U8 *e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_MAXBYTES""" 4
+.el .IP \f(CWUTF8_MAXBYTES\fR 4
+.IX Xref "UTF8_MAXBYTES"
+.IX Item "UTF8_MAXBYTES"
+The maximum width of a single UTF\-8 encoded character, in bytes.
+.Sp
+NOTE: Strictly speaking Perl's UTF\-8 should not be called UTF\-8 since UTF\-8
+is an encoding of Unicode, and Unicode's upper limit, 0x10FFFF, can be
+expressed with 4 bytes. However, Perl thinks of UTF\-8 as a way to encode
+non-negative integers in a binary format, even those above Unicode.
+.ie n .IP """UTF8_MAXBYTES_CASE""" 4
+.el .IP \f(CWUTF8_MAXBYTES_CASE\fR 4
+.IX Xref "UTF8_MAXBYTES_CASE"
+.IX Item "UTF8_MAXBYTES_CASE"
+The maximum number of UTF\-8 bytes a single Unicode character can
+uppercase/lowercase/titlecase/fold into.
+.ie n .IP """utf8ness_t""" 4
+.el .IP \f(CWutf8ness_t\fR 4
+.IX Xref "utf8ness_t"
+.IX Item "utf8ness_t"
+This typedef is used by several core functions that return PV strings, to
+indicate the UTF\-8ness of those strings.
+.Sp
+(If you write a new function, you probably should instead return the PV in an
+SV with the UTF\-8 flag of the SV properly set, rather than use this mechanism.)
+.Sp
+The possible values this can be are:
+.RS 4
+.ie n .IP """UTF8NESS_YES""" 4
+.el .IP \f(CWUTF8NESS_YES\fR 4
+.IX Item "UTF8NESS_YES"
+This means the string definitely should be treated as a sequence of
+UTF\-8\-encoded characters.
+.Sp
+Most code that needs to handle this typedef should be of the form:
+.Sp
+.Vb 3
+\& if (utf8ness_flag == UTF8NESS_YES) {
+\& treat as utf8; // like turning on an SV UTF\-8 flag
+\& }
+.Ve
+.ie n .IP """UTF8NESS_NO""" 4
+.el .IP \f(CWUTF8NESS_NO\fR 4
+.IX Item "UTF8NESS_NO"
+This means the string definitely should be treated as a sequence of bytes, not
+encoded as UTF\-8.
+.ie n .IP """UTF8NESS_IMMATERIAL""" 4
+.el .IP \f(CWUTF8NESS_IMMATERIAL\fR 4
+.IX Item "UTF8NESS_IMMATERIAL"
+This means it is equally valid to treat the string as bytes, or as UTF\-8
+characters; use whichever way you want. This happens when the string consists
+entirely of characters which have the same representation whether encoded in
+UTF\-8 or not.
+.ie n .IP """UTF8NESS_UNKNOWN""" 4
+.el .IP \f(CWUTF8NESS_UNKNOWN\fR 4
+.IX Item "UTF8NESS_UNKNOWN"
+This means it is unknown how the string should be treated. No core function
+will ever return this value to a non-core caller. Instead, it is used by the
+caller to initialize a variable to a non-legal value. A typical call will look like:
+.Sp
+.Vb 5
+\& utf8ness_t string_is_utf8 = UTF8NESS_UNKNOWN
+\& const char * string = foo(arg1, arg2, ..., &string_is_utf8);
+\& if (string_is_utf8 == UTF8NESS_YES) {
+\& do something for UTF\-8;
+\& }
+.Ve
+.RE
+.RS 4
+.Sp
+The following relationships hold between the enum values:
+.ie n .IP """0\ <=\ \fIenum\ value\fR\ <=\ UTF8NESS_IMMATERIAL""" 4
+.el .IP "\f(CW0\ <=\ \fR\f(CIenum\ value\fR\f(CW\ <=\ UTF8NESS_IMMATERIAL\fR" 4
+.IX Item "0 <= enum value <= UTF8NESS_IMMATERIAL"
+the string may be treated in code as non\-UTF8
+.ie n .IP """UTF8NESS_IMMATERIAL\ <=\ <\fIenum\ value\fR""" 4
+.el .IP "\f(CWUTF8NESS_IMMATERIAL\ <=\ <\fR\f(CIenum\ value\fR\f(CW\fR" 4
+.IX Item "UTF8NESS_IMMATERIAL <= <enum value"
+the string may be treated in code as encoded in UTF\-8
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8n_to_uvchr""" 4
+.el .IP \f(CWutf8n_to_uvchr\fR 4
+.IX Xref "utf8n_to_uvchr"
+.IX Item "utf8n_to_uvchr"
+THIS FUNCTION SHOULD BE USED IN ONLY VERY SPECIALIZED CIRCUMSTANCES.
+Most code should use "utf8_to_uvchr_buf"() rather than call this
+directly.
+.Sp
+Bottom level UTF\-8 decode routine.
+Returns the native code point value of the first character in the string \f(CW\*(C`s\*(C'\fR,
+which is assumed to be in UTF\-8 (or UTF-EBCDIC) encoding, and no longer than
+\&\f(CW\*(C`curlen\*(C'\fR bytes; \f(CW*retlen\fR (if \f(CW\*(C`retlen\*(C'\fR isn't NULL) will be set to
+the length, in bytes, of that character.
+.Sp
+The value of \f(CW\*(C`flags\*(C'\fR determines the behavior when \f(CW\*(C`s\*(C'\fR does not point to a
+well-formed UTF\-8 character. If \f(CW\*(C`flags\*(C'\fR is 0, encountering a malformation
+causes zero to be returned and \f(CW*retlen\fR is set so that (\f(CW\*(C`s\*(C'\fR\ +\ \f(CW*retlen\fR)
+is the next possible position in \f(CW\*(C`s\*(C'\fR that could begin a non-malformed
+character. Also, if UTF\-8 warnings haven't been lexically disabled, a warning
+is raised. Some UTF\-8 input sequences may contain multiple malformations.
+This function tries to find every possible one in each call, so multiple
+warnings can be raised for the same sequence.
+.Sp
+Various ALLOW flags can be set in \f(CW\*(C`flags\*(C'\fR to allow (and not warn on)
+individual types of malformations, such as the sequence being overlong (that
+is, when there is a shorter sequence that can express the same code point;
+overlong sequences are expressly forbidden in the UTF\-8 standard due to
+potential security issues). Another malformation example is the first byte of
+a character not being a legal first byte. See \fIutf8.h\fR for the list of such
+flags. Even if allowed, this function generally returns the Unicode
+REPLACEMENT CHARACTER when it encounters a malformation. There are flags in
+\&\fIutf8.h\fR to override this behavior for the overlong malformations, but don't
+do that except for very specialized purposes.
+.Sp
+The \f(CW\*(C`UTF8_CHECK_ONLY\*(C'\fR flag overrides the behavior when a non-allowed (by other
+flags) malformation is found. If this flag is set, the routine assumes that
+the caller will raise a warning, and this function will silently just set
+\&\f(CW\*(C`retlen\*(C'\fR to \f(CW\-1\fR (cast to \f(CW\*(C`STRLEN\*(C'\fR) and return zero.
+.Sp
+Note that this API requires disambiguation between successful decoding a \f(CW\*(C`NUL\*(C'\fR
+character, and an error return (unless the \f(CW\*(C`UTF8_CHECK_ONLY\*(C'\fR flag is set), as
+in both cases, 0 is returned, and, depending on the malformation, \f(CW\*(C`retlen\*(C'\fR may
+be set to 1. To disambiguate, upon a zero return, see if the first byte of
+\&\f(CW\*(C`s\*(C'\fR is 0 as well. If so, the input was a \f(CW\*(C`NUL\*(C'\fR; if not, the input had an
+error. Or you can use \f(CW"utf8n_to_uvchr_error"\fR.
+.Sp
+Certain code points are considered problematic. These are Unicode surrogates,
+Unicode non-characters, and code points above the Unicode maximum of 0x10FFFF.
+By default these are considered regular code points, but certain situations
+warrant special handling for them, which can be specified using the \f(CW\*(C`flags\*(C'\fR
+parameter. If \f(CW\*(C`flags\*(C'\fR contains \f(CW\*(C`UTF8_DISALLOW_ILLEGAL_INTERCHANGE\*(C'\fR, all
+three classes are treated as malformations and handled as such. The flags
+\&\f(CW\*(C`UTF8_DISALLOW_SURROGATE\*(C'\fR, \f(CW\*(C`UTF8_DISALLOW_NONCHAR\*(C'\fR, and
+\&\f(CW\*(C`UTF8_DISALLOW_SUPER\*(C'\fR (meaning above the legal Unicode maximum) can be set to
+disallow these categories individually. \f(CW\*(C`UTF8_DISALLOW_ILLEGAL_INTERCHANGE\*(C'\fR
+restricts the allowed inputs to the strict UTF\-8 traditionally defined by
+Unicode. Use \f(CW\*(C`UTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE\*(C'\fR to use the strictness
+definition given by
+Unicode Corrigendum #9 <https://www.unicode.org/versions/corrigendum9.html>.
+The difference between traditional strictness and C9 strictness is that the
+latter does not forbid non-character code points. (They are still discouraged,
+however.) For more discussion see "Noncharacter code points" in perlunicode.
+.Sp
+The flags \f(CW\*(C`UTF8_WARN_ILLEGAL_INTERCHANGE\*(C'\fR,
+\&\f(CW\*(C`UTF8_WARN_ILLEGAL_C9_INTERCHANGE\*(C'\fR, \f(CW\*(C`UTF8_WARN_SURROGATE\*(C'\fR,
+\&\f(CW\*(C`UTF8_WARN_NONCHAR\*(C'\fR, and \f(CW\*(C`UTF8_WARN_SUPER\*(C'\fR will cause warning messages to be
+raised for their respective categories, but otherwise the code points are
+considered valid (not malformations). To get a category to both be treated as
+a malformation and raise a warning, specify both the WARN and DISALLOW flags.
+(But note that warnings are not raised if lexically disabled nor if
+\&\f(CW\*(C`UTF8_CHECK_ONLY\*(C'\fR is also specified.)
+.Sp
+Extremely high code points were never specified in any standard, and require an
+extension to UTF\-8 to express, which Perl does. It is likely that programs
+written in something other than Perl would not be able to read files that
+contain these; nor would Perl understand files written by something that uses a
+different extension. For these reasons, there is a separate set of flags that
+can warn and/or disallow these extremely high code points, even if other
+above-Unicode ones are accepted. They are the \f(CW\*(C`UTF8_WARN_PERL_EXTENDED\*(C'\fR and
+\&\f(CW\*(C`UTF8_DISALLOW_PERL_EXTENDED\*(C'\fR flags. For more information see
+\&\f(CW"UTF8_GOT_PERL_EXTENDED"\fR. Of course \f(CW\*(C`UTF8_DISALLOW_SUPER\*(C'\fR will treat all
+above-Unicode code points, including these, as malformations.
+(Note that the Unicode standard considers anything above 0x10FFFF to be
+illegal, but there are standards predating it that allow up to 0x7FFF_FFFF
+(2**31 \-1))
+.Sp
+A somewhat misleadingly named synonym for \f(CW\*(C`UTF8_WARN_PERL_EXTENDED\*(C'\fR is
+retained for backward compatibility: \f(CW\*(C`UTF8_WARN_ABOVE_31_BIT\*(C'\fR. Similarly,
+\&\f(CW\*(C`UTF8_DISALLOW_ABOVE_31_BIT\*(C'\fR is usable instead of the more accurately named
+\&\f(CW\*(C`UTF8_DISALLOW_PERL_EXTENDED\*(C'\fR. The names are misleading because these flags
+can apply to code points that actually do fit in 31 bits. This happens on
+EBCDIC platforms, and sometimes when the overlong
+malformation is also present. The new names accurately
+describe the situation in all cases.
+.Sp
+All other code points corresponding to Unicode characters, including private
+use and those yet to be assigned, are never considered malformed and never
+warn.
+.RS 4
+.Sp
+.Vb 2
+\& UV utf8n_to_uvchr(const U8 *s, STRLEN curlen, STRLEN *retlen,
+\& const U32 flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8n_to_uvchr_error""" 4
+.el .IP \f(CWutf8n_to_uvchr_error\fR 4
+.IX Xref "utf8n_to_uvchr_error"
+.IX Item "utf8n_to_uvchr_error"
+THIS FUNCTION SHOULD BE USED IN ONLY VERY SPECIALIZED CIRCUMSTANCES.
+Most code should use "utf8_to_uvchr_buf"() rather than call this
+directly.
+.Sp
+This function is for code that needs to know what the precise malformation(s)
+are when an error is found. If you also need to know the generated warning
+messages, use "utf8n_to_uvchr_msgs"() instead.
+.Sp
+It is like \f(CW"utf8n_to_uvchr"\fR but it takes an extra parameter placed after
+all the others, \f(CW\*(C`errors\*(C'\fR. If this parameter is 0, this function behaves
+identically to \f(CW"utf8n_to_uvchr"\fR. Otherwise, \f(CW\*(C`errors\*(C'\fR should be a pointer
+to a \f(CW\*(C`U32\*(C'\fR variable, which this function sets to indicate any errors found.
+Upon return, if \f(CW*errors\fR is 0, there were no errors found. Otherwise,
+\&\f(CW*errors\fR is the bit-wise \f(CW\*(C`OR\*(C'\fR of the bits described in the list below. Some
+of these bits will be set if a malformation is found, even if the input
+\&\f(CW\*(C`flags\*(C'\fR parameter indicates that the given malformation is allowed; those
+exceptions are noted:
+.RS 4
+.ie n .IP """UTF8_GOT_PERL_EXTENDED""" 4
+.el .IP \f(CWUTF8_GOT_PERL_EXTENDED\fR 4
+.IX Item "UTF8_GOT_PERL_EXTENDED"
+The input sequence is not standard UTF\-8, but a Perl extension. This bit is
+set only if the input \f(CW\*(C`flags\*(C'\fR parameter contains either the
+\&\f(CW\*(C`UTF8_DISALLOW_PERL_EXTENDED\*(C'\fR or the \f(CW\*(C`UTF8_WARN_PERL_EXTENDED\*(C'\fR flags.
+.Sp
+Code points above 0x7FFF_FFFF (2**31 \- 1) were never specified in any standard,
+and so some extension must be used to express them. Perl uses a natural
+extension to UTF\-8 to represent the ones up to 2**36\-1, and invented a further
+extension to represent even higher ones, so that any code point that fits in a
+64\-bit word can be represented. Text using these extensions is not likely to
+be portable to non-Perl code. We lump both of these extensions together and
+refer to them as Perl extended UTF\-8. There exist other extensions that people
+have invented, incompatible with Perl's.
+.Sp
+On EBCDIC platforms starting in Perl v5.24, the Perl extension for representing
+extremely high code points kicks in at 0x3FFF_FFFF (2**30 \-1), which is lower
+than on ASCII. Prior to that, code points 2**31 and higher were simply
+unrepresentable, and a different, incompatible method was used to represent
+code points between 2**30 and 2**31 \- 1.
+.Sp
+On both platforms, ASCII and EBCDIC, \f(CW\*(C`UTF8_GOT_PERL_EXTENDED\*(C'\fR is set if
+Perl extended UTF\-8 is used.
+.Sp
+In earlier Perls, this bit was named \f(CW\*(C`UTF8_GOT_ABOVE_31_BIT\*(C'\fR, which you still
+may use for backward compatibility. That name is misleading, as this flag may
+be set when the code point actually does fit in 31 bits. This happens on
+EBCDIC platforms, and sometimes when the overlong
+malformation is also present. The new name accurately
+describes the situation in all cases.
+.ie n .IP """UTF8_GOT_CONTINUATION""" 4
+.el .IP \f(CWUTF8_GOT_CONTINUATION\fR 4
+.IX Item "UTF8_GOT_CONTINUATION"
+The input sequence was malformed in that the first byte was a UTF\-8
+continuation byte.
+.ie n .IP """UTF8_GOT_EMPTY""" 4
+.el .IP \f(CWUTF8_GOT_EMPTY\fR 4
+.IX Item "UTF8_GOT_EMPTY"
+The input \f(CW\*(C`curlen\*(C'\fR parameter was 0.
+.ie n .IP """UTF8_GOT_LONG""" 4
+.el .IP \f(CWUTF8_GOT_LONG\fR 4
+.IX Item "UTF8_GOT_LONG"
+The input sequence was malformed in that there is some other sequence that
+evaluates to the same code point, but that sequence is shorter than this one.
+.Sp
+Until Unicode 3.1, it was legal for programs to accept this malformation, but
+it was discovered that this created security issues.
+.ie n .IP """UTF8_GOT_NONCHAR""" 4
+.el .IP \f(CWUTF8_GOT_NONCHAR\fR 4
+.IX Item "UTF8_GOT_NONCHAR"
+The code point represented by the input UTF\-8 sequence is for a Unicode
+non-character code point.
+This bit is set only if the input \f(CW\*(C`flags\*(C'\fR parameter contains either the
+\&\f(CW\*(C`UTF8_DISALLOW_NONCHAR\*(C'\fR or the \f(CW\*(C`UTF8_WARN_NONCHAR\*(C'\fR flags.
+.ie n .IP """UTF8_GOT_NON_CONTINUATION""" 4
+.el .IP \f(CWUTF8_GOT_NON_CONTINUATION\fR 4
+.IX Item "UTF8_GOT_NON_CONTINUATION"
+The input sequence was malformed in that a non-continuation type byte was found
+in a position where only a continuation type one should be. See also
+\&\f(CW"UTF8_GOT_SHORT"\fR.
+.ie n .IP """UTF8_GOT_OVERFLOW""" 4
+.el .IP \f(CWUTF8_GOT_OVERFLOW\fR 4
+.IX Item "UTF8_GOT_OVERFLOW"
+The input sequence was malformed in that it is for a code point that is not
+representable in the number of bits available in an IV on the current platform.
+.ie n .IP """UTF8_GOT_SHORT""" 4
+.el .IP \f(CWUTF8_GOT_SHORT\fR 4
+.IX Item "UTF8_GOT_SHORT"
+The input sequence was malformed in that \f(CW\*(C`curlen\*(C'\fR is smaller than required for
+a complete sequence. In other words, the input is for a partial character
+sequence.
+.Sp
+\&\f(CW\*(C`UTF8_GOT_SHORT\*(C'\fR and \f(CW\*(C`UTF8_GOT_NON_CONTINUATION\*(C'\fR both indicate a too short
+sequence. The difference is that \f(CW\*(C`UTF8_GOT_NON_CONTINUATION\*(C'\fR indicates always
+that there is an error, while \f(CW\*(C`UTF8_GOT_SHORT\*(C'\fR means that an incomplete
+sequence was looked at. If no other flags are present, it means that the
+sequence was valid as far as it went. Depending on the application, this could
+mean one of three things:
+.RS 4
+.IP \(bu 4
+The \f(CW\*(C`curlen\*(C'\fR length parameter passed in was too small, and the function was
+prevented from examining all the necessary bytes.
+.IP \(bu 4
+The buffer being looked at is based on reading data, and the data received so
+far stopped in the middle of a character, so that the next read will
+read the remainder of this character. (It is up to the caller to deal with the
+split bytes somehow.)
+.IP \(bu 4
+This is a real error, and the partial sequence is all we're going to get.
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_GOT_SUPER""" 4
+.el .IP \f(CWUTF8_GOT_SUPER\fR 4
+.IX Item "UTF8_GOT_SUPER"
+The input sequence was malformed in that it is for a non-Unicode code point;
+that is, one above the legal Unicode maximum.
+This bit is set only if the input \f(CW\*(C`flags\*(C'\fR parameter contains either the
+\&\f(CW\*(C`UTF8_DISALLOW_SUPER\*(C'\fR or the \f(CW\*(C`UTF8_WARN_SUPER\*(C'\fR flags.
+.ie n .IP """UTF8_GOT_SURROGATE""" 4
+.el .IP \f(CWUTF8_GOT_SURROGATE\fR 4
+.IX Item "UTF8_GOT_SURROGATE"
+The input sequence was malformed in that it is for a \-Unicode UTF\-16 surrogate
+code point.
+This bit is set only if the input \f(CW\*(C`flags\*(C'\fR parameter contains either the
+\&\f(CW\*(C`UTF8_DISALLOW_SURROGATE\*(C'\fR or the \f(CW\*(C`UTF8_WARN_SURROGATE\*(C'\fR flags.
+.RE
+.RS 4
+.Sp
+To do your own error handling, call this function with the \f(CW\*(C`UTF8_CHECK_ONLY\*(C'\fR
+flag to suppress any warnings, and then examine the \f(CW*errors\fR return.
+.Sp
+.Vb 3
+\& UV utf8n_to_uvchr_error(const U8 *s, STRLEN curlen,
+\& STRLEN *retlen, const U32 flags,
+\& U32 *errors)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8n_to_uvchr_msgs""" 4
+.el .IP \f(CWutf8n_to_uvchr_msgs\fR 4
+.IX Xref "utf8n_to_uvchr_msgs"
+.IX Item "utf8n_to_uvchr_msgs"
+THIS FUNCTION SHOULD BE USED IN ONLY VERY SPECIALIZED CIRCUMSTANCES.
+Most code should use "utf8_to_uvchr_buf"() rather than call this
+directly.
+.Sp
+This function is for code that needs to know what the precise malformation(s)
+are when an error is found, and wants the corresponding warning and/or error
+messages to be returned to the caller rather than be displayed. All messages
+that would have been displayed if all lexical warnings are enabled will be
+returned.
+.Sp
+It is just like \f(CW"utf8n_to_uvchr_error"\fR but it takes an extra parameter
+placed after all the others, \f(CW\*(C`msgs\*(C'\fR. If this parameter is 0, this function
+behaves identically to \f(CW"utf8n_to_uvchr_error"\fR. Otherwise, \f(CW\*(C`msgs\*(C'\fR should
+be a pointer to an \f(CW\*(C`AV *\*(C'\fR variable, in which this function creates a new AV to
+contain any appropriate messages. The elements of the array are ordered so
+that the first message that would have been displayed is in the 0th element,
+and so on. Each element is a hash with three key-value pairs, as follows:
+.RS 4
+.ie n .IP """text""" 4
+.el .IP \f(CWtext\fR 4
+.IX Item "text"
+The text of the message as a \f(CW\*(C`SVpv\*(C'\fR.
+.ie n .IP """warn_categories""" 4
+.el .IP \f(CWwarn_categories\fR 4
+.IX Item "warn_categories"
+The warning category (or categories) packed into a \f(CW\*(C`SVuv\*(C'\fR.
+.ie n .IP """flag""" 4
+.el .IP \f(CWflag\fR 4
+.IX Item "flag"
+A single flag bit associated with this message, in a \f(CW\*(C`SVuv\*(C'\fR.
+The bit corresponds to some bit in the \f(CW*errors\fR return value,
+such as \f(CW\*(C`UTF8_GOT_LONG\*(C'\fR.
+.RE
+.RS 4
+.Sp
+It's important to note that specifying this parameter as non-null will cause
+any warnings this function would otherwise generate to be suppressed, and
+instead be placed in \f(CW*msgs\fR. The caller can check the lexical warnings state
+(or not) when choosing what to do with the returned messages.
+.Sp
+If the flag \f(CW\*(C`UTF8_CHECK_ONLY\*(C'\fR is passed, no warnings are generated, and hence
+no AV is created.
+.Sp
+The caller, of course, is responsible for freeing any returned AV.
+.Sp
+.Vb 3
+\& UV utf8n_to_uvchr_msgs(const U8 *s, STRLEN curlen,
+\& STRLEN *retlen, const U32 flags,
+\& U32 *errors, AV **msgs)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_SAFE_SKIP""" 4
+.el .IP \f(CWUTF8_SAFE_SKIP\fR 4
+.IX Xref "UTF8_SAFE_SKIP"
+.IX Item "UTF8_SAFE_SKIP"
+returns 0 if \f(CW\*(C`s\ >=\ e\*(C'\fR; otherwise returns the number of bytes in the
+UTF\-8 encoded character whose first byte is pointed to by \f(CW\*(C`s\*(C'\fR. But it never
+returns beyond \f(CW\*(C`e\*(C'\fR. On DEBUGGING builds, it asserts that \f(CW\*(C`s\ <=\ e\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN UTF8_SAFE_SKIP(char* s, char* e)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8SKIP""" 4
+.el .IP \f(CWUTF8SKIP\fR 4
+.IX Xref "UTF8SKIP"
+.IX Item "UTF8SKIP"
+returns the number of bytes a non-malformed UTF\-8 encoded character whose first
+(perhaps only) byte is pointed to by \f(CW\*(C`s\*(C'\fR.
+.Sp
+If there is a possibility of malformed input, use instead:
+.RS 4
+.ie n .IP """UTF8_SAFE_SKIP"" if you know the maximum ending pointer in the buffer pointed to by ""s""; or" 4
+.el .IP "\f(CW""UTF8_SAFE_SKIP""\fR if you know the maximum ending pointer in the buffer pointed to by \f(CWs\fR; or" 4
+.IX Item """UTF8_SAFE_SKIP"" if you know the maximum ending pointer in the buffer pointed to by s; or"
+.PD 0
+.ie n .IP """UTF8_CHK_SKIP"" if you don't know it." 4
+.el .IP "\f(CW""UTF8_CHK_SKIP""\fR if you don't know it." 4
+.IX Item """UTF8_CHK_SKIP"" if you don't know it."
+.RE
+.RS 4
+.PD
+.Sp
+It is better to restructure your code so the end pointer is passed down so that
+you know what it actually is at the point of this call, but if that isn't
+possible, \f(CW"UTF8_CHK_SKIP"\fR can minimize the chance of accessing beyond the end
+of the input buffer.
+.Sp
+.Vb 1
+\& STRLEN UTF8SKIP(char* s)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UTF8_SKIP""" 4
+.el .IP \f(CWUTF8_SKIP\fR 4
+.IX Xref "UTF8_SKIP"
+.IX Item "UTF8_SKIP"
+This is a synonym for \f(CW"UTF8SKIP"\fR
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN UTF8_SKIP(char* s)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_to_bytes""" 4
+.el .IP \f(CWutf8_to_bytes\fR 4
+.IX Xref "utf8_to_bytes"
+.IX Item "utf8_to_bytes"
+NOTE: \f(CW\*(C`utf8_to_bytes\*(C'\fR is \fBexperimental\fR and may change or be
+removed without notice.
+.Sp
+Converts a string \f(CW"s"\fR of length \f(CW*lenp\fR from UTF\-8 into native byte encoding.
+Unlike "bytes_to_utf8", this over-writes the original string, and
+updates \f(CW*lenp\fR to contain the new length.
+Returns zero on failure (leaving \f(CW"s"\fR unchanged) setting \f(CW*lenp\fR to \-1.
+.Sp
+Upon successful return, the number of variants in the string can be computed by
+having saved the value of \f(CW*lenp\fR before the call, and subtracting the
+after-call value of \f(CW*lenp\fR from it.
+.Sp
+If you need a copy of the string, see "bytes_from_utf8".
+.RS 4
+.Sp
+.Vb 1
+\& U8 * utf8_to_bytes(U8 *s, STRLEN *lenp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_to_uvchr""" 4
+.el .IP \f(CWutf8_to_uvchr\fR 4
+.IX Xref "utf8_to_uvchr"
+.IX Item "utf8_to_uvchr"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`utf8_to_uvchr\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+Returns the native code point of the first character in the string \f(CW\*(C`s\*(C'\fR
+which is assumed to be in UTF\-8 encoding; \f(CW\*(C`retlen\*(C'\fR will be set to the
+length, in bytes, of that character.
+.Sp
+Some, but not all, UTF\-8 malformations are detected, and in fact, some
+malformed input could cause reading beyond the end of the input buffer, which
+is why this function is deprecated. Use "utf8_to_uvchr_buf" instead.
+.Sp
+If \f(CW\*(C`s\*(C'\fR points to one of the detected malformations, and UTF8 warnings are
+enabled, zero is returned and \f(CW*retlen\fR is set (if \f(CW\*(C`retlen\*(C'\fR isn't
+\&\f(CW\*(C`NULL\*(C'\fR) to \-1. If those warnings are off, the computed value if well-defined (or
+the Unicode REPLACEMENT CHARACTER, if not) is silently returned, and \f(CW*retlen\fR
+is set (if \f(CW\*(C`retlen\*(C'\fR isn't NULL) so that (\f(CW\*(C`s\*(C'\fR\ +\ \f(CW*retlen\fR) is the
+next possible position in \f(CW\*(C`s\*(C'\fR that could begin a non-malformed character.
+See "utf8n_to_uvchr" for details on when the REPLACEMENT CHARACTER is returned.
+.RS 4
+.Sp
+.Vb 1
+\& UV utf8_to_uvchr(const U8 *s, STRLEN *retlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """utf8_to_uvchr_buf""" 4
+.el .IP \f(CWutf8_to_uvchr_buf\fR 4
+.IX Xref "utf8_to_uvchr_buf"
+.IX Item "utf8_to_uvchr_buf"
+Returns the native code point of the first character in the string \f(CW\*(C`s\*(C'\fR which
+is assumed to be in UTF\-8 encoding; \f(CW\*(C`send\*(C'\fR points to 1 beyond the end of \f(CW\*(C`s\*(C'\fR.
+\&\f(CW*retlen\fR will be set to the length, in bytes, of that character.
+.Sp
+If \f(CW\*(C`s\*(C'\fR does not point to a well-formed UTF\-8 character and UTF8 warnings are
+enabled, zero is returned and \f(CW*retlen\fR is set (if \f(CW\*(C`retlen\*(C'\fR isn't
+\&\f(CW\*(C`NULL\*(C'\fR) to \-1. If those warnings are off, the computed value, if well-defined
+(or the Unicode REPLACEMENT CHARACTER if not), is silently returned, and
+\&\f(CW*retlen\fR is set (if \f(CW\*(C`retlen\*(C'\fR isn't \f(CW\*(C`NULL\*(C'\fR) so that (\f(CW\*(C`s\*(C'\fR\ +\ \f(CW*retlen\fR) is
+the next possible position in \f(CW\*(C`s\*(C'\fR that could begin a non-malformed character.
+See "utf8n_to_uvchr" for details on when the REPLACEMENT CHARACTER is
+returned.
+.RS 4
+.Sp
+.Vb 1
+\& UV utf8_to_uvchr_buf(const U8 *s, const U8 *send, STRLEN *retlen)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UVCHR_IS_INVARIANT""" 4
+.el .IP \f(CWUVCHR_IS_INVARIANT\fR 4
+.IX Xref "UVCHR_IS_INVARIANT"
+.IX Item "UVCHR_IS_INVARIANT"
+Evaluates to 1 if the representation of code point \f(CW\*(C`cp\*(C'\fR is the same whether or
+not it is encoded in UTF\-8; otherwise evaluates to 0. UTF\-8 invariant
+characters can be copied as-is when converting to/from UTF\-8, saving time.
+\&\f(CW\*(C`cp\*(C'\fR is Unicode if above 255; otherwise is platform-native.
+.RS 4
+.Sp
+.Vb 1
+\& bool UVCHR_IS_INVARIANT(UV cp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UVCHR_SKIP""" 4
+.el .IP \f(CWUVCHR_SKIP\fR 4
+.IX Xref "UVCHR_SKIP"
+.IX Item "UVCHR_SKIP"
+returns the number of bytes required to represent the code point \f(CW\*(C`cp\*(C'\fR when
+encoded as UTF\-8. \f(CW\*(C`cp\*(C'\fR is a native (ASCII or EBCDIC) code point if less than
+255; a Unicode code point otherwise.
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN UVCHR_SKIP(UV cp)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """uvchr_to_utf8_flags""" 4
+.el .IP \f(CWuvchr_to_utf8_flags\fR 4
+.IX Xref "uvchr_to_utf8_flags"
+.IX Item "uvchr_to_utf8_flags"
+Adds the UTF\-8 representation of the native code point \f(CW\*(C`uv\*(C'\fR to the end
+of the string \f(CW\*(C`d\*(C'\fR; \f(CW\*(C`d\*(C'\fR should have at least \f(CW\*(C`UVCHR_SKIP(uv)+1\*(C'\fR (up to
+\&\f(CW\*(C`UTF8_MAXBYTES+1\*(C'\fR) free bytes available. The return value is the pointer to
+the byte after the end of the new character. In other words,
+.Sp
+.Vb 1
+\& d = uvchr_to_utf8_flags(d, uv, flags);
+.Ve
+.Sp
+or, in most cases,
+.Sp
+.Vb 1
+\& d = uvchr_to_utf8_flags(d, uv, 0);
+.Ve
+.Sp
+This is the Unicode-aware way of saying
+.Sp
+.Vb 1
+\& *(d++) = uv;
+.Ve
+.Sp
+If \f(CW\*(C`flags\*(C'\fR is 0, this function accepts any code point from 0..\f(CW\*(C`IV_MAX\*(C'\fR as
+input. \f(CW\*(C`IV_MAX\*(C'\fR is typically 0x7FFF_FFFF in a 32\-bit word.
+.Sp
+Specifying \f(CW\*(C`flags\*(C'\fR can further restrict what is allowed and not warned on, as
+follows:
+.Sp
+If \f(CW\*(C`uv\*(C'\fR is a Unicode surrogate code point and \f(CW\*(C`UNICODE_WARN_SURROGATE\*(C'\fR is set,
+the function will raise a warning, provided UTF8 warnings are enabled. If
+instead \f(CW\*(C`UNICODE_DISALLOW_SURROGATE\*(C'\fR is set, the function will fail and return
+NULL. If both flags are set, the function will both warn and return NULL.
+.Sp
+Similarly, the \f(CW\*(C`UNICODE_WARN_NONCHAR\*(C'\fR and \f(CW\*(C`UNICODE_DISALLOW_NONCHAR\*(C'\fR flags
+affect how the function handles a Unicode non-character.
+.Sp
+And likewise, the \f(CW\*(C`UNICODE_WARN_SUPER\*(C'\fR and \f(CW\*(C`UNICODE_DISALLOW_SUPER\*(C'\fR flags
+affect the handling of code points that are above the Unicode maximum of
+0x10FFFF. Languages other than Perl may not be able to accept files that
+contain these.
+.Sp
+The flag \f(CW\*(C`UNICODE_WARN_ILLEGAL_INTERCHANGE\*(C'\fR selects all three of
+the above WARN flags; and \f(CW\*(C`UNICODE_DISALLOW_ILLEGAL_INTERCHANGE\*(C'\fR selects all
+three DISALLOW flags. \f(CW\*(C`UNICODE_DISALLOW_ILLEGAL_INTERCHANGE\*(C'\fR restricts the
+allowed inputs to the strict UTF\-8 traditionally defined by Unicode.
+Similarly, \f(CW\*(C`UNICODE_WARN_ILLEGAL_C9_INTERCHANGE\*(C'\fR and
+\&\f(CW\*(C`UNICODE_DISALLOW_ILLEGAL_C9_INTERCHANGE\*(C'\fR are shortcuts to select the
+above-Unicode and surrogate flags, but not the non-character ones, as
+defined in
+Unicode Corrigendum #9 <https://www.unicode.org/versions/corrigendum9.html>.
+See "Noncharacter code points" in perlunicode.
+.Sp
+Extremely high code points were never specified in any standard, and require an
+extension to UTF\-8 to express, which Perl does. It is likely that programs
+written in something other than Perl would not be able to read files that
+contain these; nor would Perl understand files written by something that uses a
+different extension. For these reasons, there is a separate set of flags that
+can warn and/or disallow these extremely high code points, even if other
+above-Unicode ones are accepted. They are the \f(CW\*(C`UNICODE_WARN_PERL_EXTENDED\*(C'\fR
+and \f(CW\*(C`UNICODE_DISALLOW_PERL_EXTENDED\*(C'\fR flags. For more information see
+\&\f(CW"UTF8_GOT_PERL_EXTENDED"\fR. Of course \f(CW\*(C`UNICODE_DISALLOW_SUPER\*(C'\fR will
+treat all above-Unicode code points, including these, as malformations. (Note
+that the Unicode standard considers anything above 0x10FFFF to be illegal, but
+there are standards predating it that allow up to 0x7FFF_FFFF (2**31 \-1))
+.Sp
+A somewhat misleadingly named synonym for \f(CW\*(C`UNICODE_WARN_PERL_EXTENDED\*(C'\fR is
+retained for backward compatibility: \f(CW\*(C`UNICODE_WARN_ABOVE_31_BIT\*(C'\fR. Similarly,
+\&\f(CW\*(C`UNICODE_DISALLOW_ABOVE_31_BIT\*(C'\fR is usable instead of the more accurately named
+\&\f(CW\*(C`UNICODE_DISALLOW_PERL_EXTENDED\*(C'\fR. The names are misleading because on EBCDIC
+platforms,these flags can apply to code points that actually do fit in 31 bits.
+The new names accurately describe the situation in all cases.
+.RS 4
+.Sp
+.Vb 1
+\& U8 * uvchr_to_utf8_flags(U8 *d, UV uv, UV flags)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """uvchr_to_utf8_flags_msgs""" 4
+.el .IP \f(CWuvchr_to_utf8_flags_msgs\fR 4
+.IX Xref "uvchr_to_utf8_flags_msgs"
+.IX Item "uvchr_to_utf8_flags_msgs"
+THIS FUNCTION SHOULD BE USED IN ONLY VERY SPECIALIZED CIRCUMSTANCES.
+.Sp
+Most code should use \f(CW\*(C`"uvchr_to_utf8_flags"()\*(C'\fR rather than call this directly.
+.Sp
+This function is for code that wants any warning and/or error messages to be
+returned to the caller rather than be displayed. All messages that would have
+been displayed if all lexical warnings are enabled will be returned.
+.Sp
+It is just like \f(CW"uvchr_to_utf8_flags"\fR but it takes an extra parameter
+placed after all the others, \f(CW\*(C`msgs\*(C'\fR. If this parameter is 0, this function
+behaves identically to \f(CW"uvchr_to_utf8_flags"\fR. Otherwise, \f(CW\*(C`msgs\*(C'\fR should
+be a pointer to an \f(CW\*(C`HV *\*(C'\fR variable, in which this function creates a new HV to
+contain any appropriate messages. The hash has three key-value pairs, as
+follows:
+.RS 4
+.ie n .IP """text""" 4
+.el .IP \f(CWtext\fR 4
+.IX Item "text"
+The text of the message as a \f(CW\*(C`SVpv\*(C'\fR.
+.ie n .IP """warn_categories""" 4
+.el .IP \f(CWwarn_categories\fR 4
+.IX Item "warn_categories"
+The warning category (or categories) packed into a \f(CW\*(C`SVuv\*(C'\fR.
+.ie n .IP """flag""" 4
+.el .IP \f(CWflag\fR 4
+.IX Item "flag"
+A single flag bit associated with this message, in a \f(CW\*(C`SVuv\*(C'\fR.
+The bit corresponds to some bit in the \f(CW*errors\fR return value,
+such as \f(CW\*(C`UNICODE_GOT_SURROGATE\*(C'\fR.
+.RE
+.RS 4
+.Sp
+It's important to note that specifying this parameter as non-null will cause
+any warnings this function would otherwise generate to be suppressed, and
+instead be placed in \f(CW*msgs\fR. The caller can check the lexical warnings state
+(or not) when choosing what to do with the returned messages.
+.Sp
+The caller, of course, is responsible for freeing any returned HV.
+.Sp
+.Vb 1
+\& U8 * uvchr_to_utf8_flags_msgs(U8 *d, UV uv, UV flags, HV **msgs)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """uvchr_to_utf8""" 4
+.el .IP \f(CWuvchr_to_utf8\fR 4
+.IX Xref "uvchr_to_utf8"
+.IX Item "uvchr_to_utf8"
+Adds the UTF\-8 representation of the native code point \f(CW\*(C`uv\*(C'\fR to the end
+of the string \f(CW\*(C`d\*(C'\fR; \f(CW\*(C`d\*(C'\fR should have at least \f(CW\*(C`UVCHR_SKIP(uv)+1\*(C'\fR (up to
+\&\f(CW\*(C`UTF8_MAXBYTES+1\*(C'\fR) free bytes available. The return value is the pointer to
+the byte after the end of the new character. In other words,
+.Sp
+.Vb 1
+\& d = uvchr_to_utf8(d, uv);
+.Ve
+.Sp
+is the recommended wide native character-aware way of saying
+.Sp
+.Vb 1
+\& *(d++) = uv;
+.Ve
+.Sp
+This function accepts any code point from 0..\f(CW\*(C`IV_MAX\*(C'\fR as input.
+\&\f(CW\*(C`IV_MAX\*(C'\fR is typically 0x7FFF_FFFF in a 32\-bit word.
+.Sp
+It is possible to forbid or warn on non-Unicode code points, or those that may
+be problematic by using "uvchr_to_utf8_flags".
+.RS 4
+.Sp
+.Vb 1
+\& U8 * uvchr_to_utf8(U8 *d, UV uv)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Utility Functions"
+.IX Header "Utility Functions"
+.ie n .IP """C_ARRAY_END""" 4
+.el .IP \f(CWC_ARRAY_END\fR 4
+.IX Xref "C_ARRAY_END"
+.IX Item "C_ARRAY_END"
+Returns a pointer to one element past the final element of the input C array.
+.RS 4
+.Sp
+.Vb 1
+\& void * C_ARRAY_END(void *a)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """C_ARRAY_LENGTH""" 4
+.el .IP \f(CWC_ARRAY_LENGTH\fR 4
+.IX Xref "C_ARRAY_LENGTH"
+.IX Item "C_ARRAY_LENGTH"
+Returns the number of elements in the input C array (so you want your
+zero-based indices to be less than but not equal to).
+.RS 4
+.Sp
+.Vb 1
+\& STRLEN C_ARRAY_LENGTH(void *a)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """getcwd_sv""" 4
+.el .IP \f(CWgetcwd_sv\fR 4
+.IX Xref "getcwd_sv"
+.IX Item "getcwd_sv"
+Fill \f(CW\*(C`sv\*(C'\fR with current working directory
+.RS 4
+.Sp
+.Vb 1
+\& int getcwd_sv(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IN_PERL_COMPILETIME""" 4
+.el .IP \f(CWIN_PERL_COMPILETIME\fR 4
+.IX Xref "IN_PERL_COMPILETIME"
+.IX Item "IN_PERL_COMPILETIME"
+Returns 1 if this macro is being called during the compilation phase of the
+program; otherwise 0;
+.RS 4
+.Sp
+.Vb 1
+\& bool IN_PERL_COMPILETIME
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IN_PERL_RUNTIME""" 4
+.el .IP \f(CWIN_PERL_RUNTIME\fR 4
+.IX Xref "IN_PERL_RUNTIME"
+.IX Item "IN_PERL_RUNTIME"
+Returns 1 if this macro is being called during the execution phase of the
+program; otherwise 0;
+.RS 4
+.Sp
+.Vb 1
+\& bool IN_PERL_RUNTIME
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """IS_SAFE_SYSCALL""" 4
+.el .IP \f(CWIS_SAFE_SYSCALL\fR 4
+.IX Xref "IS_SAFE_SYSCALL"
+.IX Item "IS_SAFE_SYSCALL"
+Same as "is_safe_syscall".
+.RS 4
+.Sp
+.Vb 2
+\& bool IS_SAFE_SYSCALL(NN const char *pv, STRLEN len,
+\& NN const char *what, NN const char *op_name)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """is_safe_syscall""" 4
+.el .IP \f(CWis_safe_syscall\fR 4
+.IX Xref "is_safe_syscall"
+.IX Item "is_safe_syscall"
+Test that the given \f(CW\*(C`pv\*(C'\fR (with length \f(CW\*(C`len\*(C'\fR) doesn't contain any internal
+\&\f(CW\*(C`NUL\*(C'\fR characters.
+If it does, set \f(CW\*(C`errno\*(C'\fR to \f(CW\*(C`ENOENT\*(C'\fR, optionally warn using the \f(CW\*(C`syscalls\*(C'\fR
+category, and return FALSE.
+.Sp
+Return TRUE if the name is safe.
+.Sp
+\&\f(CW\*(C`what\*(C'\fR and \f(CW\*(C`op_name\*(C'\fR are used in any warning.
+.Sp
+Used by the \f(CWIS_SAFE_SYSCALL()\fR macro.
+.RS 4
+.Sp
+.Vb 2
+\& bool is_safe_syscall(const char *pv, STRLEN len,
+\& const char *what, const char *op_name)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """my_setenv""" 4
+.el .IP \f(CWmy_setenv\fR 4
+.IX Xref "my_setenv"
+.IX Item "my_setenv"
+A wrapper for the C library \fBsetenv\fR\|(3). Don't use the latter, as the perl
+version has desirable safeguards
+.RS 4
+.Sp
+.Vb 1
+\& void my_setenv(const char *nam, const char *val)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """newPADxVOP""" 4
+.el .IP \f(CWnewPADxVOP\fR 4
+.IX Xref "newPADxVOP"
+.IX Item "newPADxVOP"
+Constructs, checks and returns an op containing a pad offset. \f(CW\*(C`type\*(C'\fR is
+the opcode, which should be one of \f(CW\*(C`OP_PADSV\*(C'\fR, \f(CW\*(C`OP_PADAV\*(C'\fR, \f(CW\*(C`OP_PADHV\*(C'\fR
+or \f(CW\*(C`OP_PADCV\*(C'\fR. The returned op will have the \f(CW\*(C`op_targ\*(C'\fR field set by
+the \f(CW\*(C`padix\*(C'\fR argument.
+.Sp
+This is convenient when constructing a large optree in nested function
+calls, as it avoids needing to store the pad op directly to set the
+\&\f(CW\*(C`op_targ\*(C'\fR field as a side-effect. For example
+.Sp
+.Vb 2
+\& o = op_append_elem(OP_LINESEQ, o,
+\& newPADxVOP(OP_PADSV, 0, padix));
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& OP * newPADxVOP(I32 type, I32 flags, PADOFFSET padix)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """phase_name""" 4
+.el .IP \f(CWphase_name\fR 4
+.IX Xref "phase_name"
+.IX Item "phase_name"
+Returns the given phase's name as a NUL-terminated string.
+.Sp
+For example, to print a stack trace that includes the current
+interpreter phase you might do:
+.Sp
+.Vb 2
+\& const char* phase_name = phase_name(PL_phase);
+\& mess("This is weird. (Perl phase: %s)", phase_name);
+.Ve
+.RS 4
+.Sp
+.Vb 1
+\& const char * const phase_name(enum perl_phase)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """Poison""" 4
+.el .IP \f(CWPoison\fR 4
+.IX Xref "Poison"
+.IX Item "Poison"
+PoisonWith(0xEF) for catching access to freed memory.
+.RS 4
+.Sp
+.Vb 1
+\& void Poison(void* dest, int nitems, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PoisonFree""" 4
+.el .IP \f(CWPoisonFree\fR 4
+.IX Xref "PoisonFree"
+.IX Item "PoisonFree"
+PoisonWith(0xEF) for catching access to freed memory.
+.RS 4
+.Sp
+.Vb 1
+\& void PoisonFree(void* dest, int nitems, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PoisonNew""" 4
+.el .IP \f(CWPoisonNew\fR 4
+.IX Xref "PoisonNew"
+.IX Item "PoisonNew"
+PoisonWith(0xAB) for catching access to allocated but uninitialized memory.
+.RS 4
+.Sp
+.Vb 1
+\& void PoisonNew(void* dest, int nitems, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PoisonWith""" 4
+.el .IP \f(CWPoisonWith\fR 4
+.IX Xref "PoisonWith"
+.IX Item "PoisonWith"
+Fill up memory with a byte pattern (a byte repeated over and over
+again) that hopefully catches attempts to access uninitialized memory.
+.RS 4
+.Sp
+.Vb 1
+\& void PoisonWith(void* dest, int nitems, type, U8 byte)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """StructCopy""" 4
+.el .IP \f(CWStructCopy\fR 4
+.IX Xref "StructCopy"
+.IX Item "StructCopy"
+This is an architecture-independent macro to copy one structure to another.
+.RS 4
+.Sp
+.Vb 1
+\& void StructCopy(type *src, type *dest, type)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_destroyable""" 4
+.el .IP \f(CWsv_destroyable\fR 4
+.IX Xref "sv_destroyable"
+.IX Item "sv_destroyable"
+Dummy routine which reports that object can be destroyed when there is no
+sharing module present. It ignores its single SV argument, and returns
+\&'true'. Exists to avoid test for a \f(CW\*(C`NULL\*(C'\fR function pointer and because it
+could potentially warn under some level of strict-ness.
+.RS 4
+.Sp
+.Vb 1
+\& bool sv_destroyable(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """sv_nosharing""" 4
+.el .IP \f(CWsv_nosharing\fR 4
+.IX Xref "sv_nosharing"
+.IX Item "sv_nosharing"
+Dummy routine which "shares" an SV when there is no sharing module present.
+Or "locks" it. Or "unlocks" it. In other
+words, ignores its single SV argument.
+Exists to avoid test for a \f(CW\*(C`NULL\*(C'\fR function pointer and because it could
+potentially warn under some level of strict-ness.
+.RS 4
+.Sp
+.Vb 1
+\& void sv_nosharing(SV *sv)
+.Ve
+.RE
+.RS 4
+.RE
+.SH Versioning
+.IX Header "Versioning"
+.ie n .IP """new_version""" 4
+.el .IP \f(CWnew_version\fR 4
+.IX Xref "new_version"
+.IX Item "new_version"
+Returns a new version object based on the passed in SV:
+.Sp
+.Vb 1
+\& SV *sv = new_version(SV *ver);
+.Ve
+.Sp
+Does not alter the passed in ver SV. See "upg_version" if you
+want to upgrade the SV.
+.RS 4
+.Sp
+.Vb 1
+\& SV * new_version(SV *ver)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """PERL_REVISION""" 4
+.el .IP \f(CWPERL_REVISION\fR 4
+.IX Xref "PERL_REVISION"
+.IX Item "PERL_REVISION"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`PERL_REVISION\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+The major number component of the perl interpreter currently being compiled or
+executing. This has been \f(CW5\fR from 1993 into 2020.
+.Sp
+Instead use one of the version comparison macros. See \f(CW"PERL_VERSION_EQ"\fR.
+.ie n .IP """PERL_SUBVERSION""" 4
+.el .IP \f(CWPERL_SUBVERSION\fR 4
+.IX Xref "PERL_SUBVERSION"
+.IX Item "PERL_SUBVERSION"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`PERL_SUBVERSION\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+The micro number component of the perl interpreter currently being compiled or
+executing. In stable releases this gives the dot release number for
+maintenance updates. In development releases this gives a tag for a snapshot
+of the status at various points in the development cycle.
+.Sp
+Instead use one of the version comparison macros. See \f(CW"PERL_VERSION_EQ"\fR.
+.ie n .IP """PERL_VERSION""" 4
+.el .IP \f(CWPERL_VERSION\fR 4
+.IX Xref "PERL_VERSION"
+.IX Item "PERL_VERSION"
+\&\f(CW\*(C`\fR\f(CBDEPRECATED!\fR\f(CW\*(C'\fR It is planned to remove \f(CW\*(C`PERL_VERSION\*(C'\fR
+from a future release of Perl. Do not use it for
+new code; remove it from existing code.
+.Sp
+The minor number component of the perl interpreter currently being compiled or
+executing. Between 1993 into 2020, this has ranged from 0 to 33.
+.Sp
+Instead use one of the version comparison macros. See \f(CW"PERL_VERSION_EQ"\fR.
+.ie n .IP """PERL_VERSION_EQ""" 4
+.el .IP \f(CWPERL_VERSION_EQ\fR 4
+.IX Item "PERL_VERSION_EQ"
+.PD 0
+.ie n .IP """PERL_VERSION_GE""" 4
+.el .IP \f(CWPERL_VERSION_GE\fR 4
+.IX Item "PERL_VERSION_GE"
+.ie n .IP """PERL_VERSION_GT""" 4
+.el .IP \f(CWPERL_VERSION_GT\fR 4
+.IX Item "PERL_VERSION_GT"
+.ie n .IP """PERL_VERSION_LE""" 4
+.el .IP \f(CWPERL_VERSION_LE\fR 4
+.IX Item "PERL_VERSION_LE"
+.ie n .IP """PERL_VERSION_LT""" 4
+.el .IP \f(CWPERL_VERSION_LT\fR 4
+.IX Item "PERL_VERSION_LT"
+.ie n .IP """PERL_VERSION_NE""" 4
+.el .IP \f(CWPERL_VERSION_NE\fR 4
+.IX Xref "PERL_VERSION_EQ PERL_VERSION_GE PERL_VERSION_GT PERL_VERSION_LE PERL_VERSION_LT PERL_VERSION_NE"
+.IX Item "PERL_VERSION_NE"
+.PD
+Returns whether or not the perl currently being compiled has the specified
+relationship to the perl given by the parameters. For example,
+.Sp
+.Vb 5
+\& #if PERL_VERSION_GT(5,24,2)
+\& code that will only be compiled on perls after v5.24.2
+\& #else
+\& fallback code
+\& #endif
+.Ve
+.Sp
+Note that this is usable in making compile-time decisions
+.Sp
+You may use the special value '*' for the final number to mean ALL possible
+values for it. Thus,
+.Sp
+.Vb 1
+\& #if PERL_VERSION_EQ(5,31,\*(Aq*\*(Aq)
+.Ve
+.Sp
+means all perls in the 5.31 series. And
+.Sp
+.Vb 1
+\& #if PERL_VERSION_NE(5,24,\*(Aq*\*(Aq)
+.Ve
+.Sp
+means all perls EXCEPT 5.24 ones. And
+.Sp
+.Vb 1
+\& #if PERL_VERSION_LE(5,9,\*(Aq*\*(Aq)
+.Ve
+.Sp
+is effectively
+.Sp
+.Vb 1
+\& #if PERL_VERSION_LT(5,10,0)
+.Ve
+.Sp
+This means you don't have to think so much when converting from the existing
+deprecated \f(CW\*(C`PERL_VERSION\*(C'\fR to using this macro:
+.Sp
+.Vb 1
+\& #if PERL_VERSION <= 9
+.Ve
+.Sp
+becomes
+.Sp
+.Vb 1
+\& #if PERL_VERSION_LE(5,9,\*(Aq*\*(Aq)
+.Ve
+.RS 4
+.Sp
+.Vb 2
+\& bool PERL_VERSION_EQ(const U8 major, const U8 minor,
+\& const U8 patch)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """prescan_version""" 4
+.el .IP \f(CWprescan_version\fR 4
+.IX Xref "prescan_version"
+.IX Item "prescan_version"
+Validate that a given string can be parsed as a version object, but doesn't
+actually perform the parsing. Can use either strict or lax validation rules.
+Can optionally set a number of hint variables to save the parsing code
+some time when tokenizing.
+.RS 4
+.Sp
+.Vb 4
+\& const char * prescan_version(const char *s, bool strict,
+\& const char **errstr, bool *sqv,
+\& int *ssaw_decimal, int *swidth,
+\& bool *salpha)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """scan_version""" 4
+.el .IP \f(CWscan_version\fR 4
+.IX Xref "scan_version"
+.IX Item "scan_version"
+Returns a pointer to the next character after the parsed
+version string, as well as upgrading the passed in SV to
+an RV.
+.Sp
+Function must be called with an already existing SV like
+.Sp
+.Vb 2
+\& sv = newSV(0);
+\& s = scan_version(s, SV *sv, bool qv);
+.Ve
+.Sp
+Performs some preprocessing to the string to ensure that
+it has the correct characteristics of a version. Flags the
+object if it contains an underscore (which denotes this
+is an alpha version). The boolean qv denotes that the version
+should be interpreted as if it had multiple decimals, even if
+it doesn't.
+.RS 4
+.Sp
+.Vb 1
+\& const char * scan_version(const char *s, SV *rv, bool qv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """upg_version""" 4
+.el .IP \f(CWupg_version\fR 4
+.IX Xref "upg_version"
+.IX Item "upg_version"
+In-place upgrade of the supplied SV to a version object.
+.Sp
+.Vb 1
+\& SV *sv = upg_version(SV *sv, bool qv);
+.Ve
+.Sp
+Returns a pointer to the upgraded SV. Set the boolean qv if you want
+to force this SV to be interpreted as an "extended" version.
+.RS 4
+.Sp
+.Vb 1
+\& SV * upg_version(SV *ver, bool qv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vcmp""" 4
+.el .IP \f(CWvcmp\fR 4
+.IX Xref "vcmp"
+.IX Item "vcmp"
+Version object aware cmp. Both operands must already have been
+converted into version objects.
+.RS 4
+.Sp
+.Vb 1
+\& int vcmp(SV *lhv, SV *rhv)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vnormal""" 4
+.el .IP \f(CWvnormal\fR 4
+.IX Xref "vnormal"
+.IX Item "vnormal"
+Accepts a version object and returns the normalized string
+representation. Call like:
+.Sp
+.Vb 1
+\& sv = vnormal(rv);
+.Ve
+.Sp
+NOTE: you can pass either the object directly or the SV
+contained within the RV.
+.Sp
+The SV returned has a refcount of 1.
+.RS 4
+.Sp
+.Vb 1
+\& SV * vnormal(SV *vs)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vnumify""" 4
+.el .IP \f(CWvnumify\fR 4
+.IX Xref "vnumify"
+.IX Item "vnumify"
+Accepts a version object and returns the normalized floating
+point representation. Call like:
+.Sp
+.Vb 1
+\& sv = vnumify(rv);
+.Ve
+.Sp
+NOTE: you can pass either the object directly or the SV
+contained within the RV.
+.Sp
+The SV returned has a refcount of 1.
+.RS 4
+.Sp
+.Vb 1
+\& SV * vnumify(SV *vs)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vstringify""" 4
+.el .IP \f(CWvstringify\fR 4
+.IX Xref "vstringify"
+.IX Item "vstringify"
+In order to maintain maximum compatibility with earlier versions
+of Perl, this function will return either the floating point
+notation or the multiple dotted notation, depending on whether
+the original version contained 1 or more dots, respectively.
+.Sp
+The SV returned has a refcount of 1.
+.RS 4
+.Sp
+.Vb 1
+\& SV * vstringify(SV *vs)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vverify""" 4
+.el .IP \f(CWvverify\fR 4
+.IX Xref "vverify"
+.IX Item "vverify"
+Validates that the SV contains valid internal structure for a version object.
+It may be passed either the version object (RV) or the hash itself (HV). If
+the structure is valid, it returns the HV. If the structure is invalid,
+it returns NULL.
+.Sp
+.Vb 1
+\& SV *hv = vverify(sv);
+.Ve
+.Sp
+Note that it only confirms the bare minimum structure (so as not to get
+confused by derived classes which may contain additional hash entries):
+.RS 4
+.IP \(bu 4
+The SV is an HV or a reference to an HV
+.IP \(bu 4
+The hash contains a "version" key
+.IP \(bu 4
+The "version" key has a reference to an AV as its value
+.RE
+.RS 4
+.Sp
+.Vb 1
+\& SV * vverify(SV *vs)
+.Ve
+.RE
+.RS 4
+.RE
+.SH "Warning and Dieing"
+.IX Xref "WARN_ALL WARN_AMBIGUOUS WARN_BAREWORD WARN_CLOSED WARN_CLOSURE WARN_DEBUGGING WARN_DEPRECATED WARN_DEPRECATED__APOSTROPHE_AS_PACKAGE_SEPARATOR WARN_DEPRECATED__DELIMITER_WILL_BE_PAIRED WARN_DEPRECATED__DOT_IN_INC WARN_DEPRECATED__GOTO_CONSTRUCT WARN_DEPRECATED__SMARTMATCH WARN_DEPRECATED__UNICODE_PROPERTY_NAME WARN_DEPRECATED__VERSION_DOWNGRADE WARN_DIGIT WARN_EXEC WARN_EXITING WARN_EXPERIMENTAL WARN_EXPERIMENTAL__ARGS_ARRAY_WITH_SIGNATURES WARN_EXPERIMENTAL__BUILTIN WARN_EXPERIMENTAL__CLASS WARN_EXPERIMENTAL__CONST_ATTR WARN_EXPERIMENTAL__DECLARED_REFS WARN_EXPERIMENTAL__DEFER WARN_EXPERIMENTAL__EXTRA_PAIRED_DELIMITERS WARN_EXPERIMENTAL__FOR_LIST WARN_EXPERIMENTAL__PRIVATE_USE WARN_EXPERIMENTAL__REFALIASING WARN_EXPERIMENTAL__REGEX_SETS WARN_EXPERIMENTAL__RE_STRICT WARN_EXPERIMENTAL__TRY WARN_EXPERIMENTAL__UNIPROP_WILDCARDS WARN_EXPERIMENTAL__VLB WARN_GLOB WARN_ILLEGALPROTO WARN_IMPRECISION WARN_INPLACE WARN_INTERNAL WARN_IO WARN_LAYER WARN_LOCALE WARN_MALLOC WARN_MISC WARN_MISSING WARN_NEWLINE WARN_NONCHAR WARN_NON_UNICODE 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_REDUNDANT WARN_REGEXP WARN_RESERVED WARN_SCALAR WARN_SEMICOLON WARN_SEVERE WARN_SHADOW WARN_SIGNAL WARN_SUBSTR WARN_SURROGATE WARN_SYNTAX WARN_SYSCALLS WARN_TAINT WARN_THREADS WARN_UNINITIALIZED WARN_UNOPENED WARN_UNPACK WARN_UNTIE WARN_UTF8 WARN_VOID"
+.IX Header "Warning and Dieing"
+In all these calls, the \f(CW\*(C`U32 w\fR\f(CIn\fR\f(CW\*(C'\fR parameters are warning category
+constants. You can see the ones currently available in
+"Category Hierarchy" in warnings, just capitalize all letters in the names
+and prefix them by \f(CW\*(C`WARN_\*(C'\fR. So, for example, the category \f(CW\*(C`void\*(C'\fR used in a
+perl program becomes \f(CW\*(C`WARN_VOID\*(C'\fR when used in XS code and passed to one of
+the calls below.
+.ie n .IP """ckWARN""" 4
+.el .IP \f(CWckWARN\fR 4
+.IX Item "ckWARN"
+.PD 0
+.ie n .IP """ckWARN2""" 4
+.el .IP \f(CWckWARN2\fR 4
+.IX Item "ckWARN2"
+.ie n .IP """ckWARN3""" 4
+.el .IP \f(CWckWARN3\fR 4
+.IX Item "ckWARN3"
+.ie n .IP """ckWARN4""" 4
+.el .IP \f(CWckWARN4\fR 4
+.IX Xref "ckWARN ckWARN2 ckWARN3 ckWARN4"
+.IX Item "ckWARN4"
+.PD
+These return a boolean as to whether or not warnings are enabled for any of
+the warning category(ies) parameters: \f(CW\*(C`w\*(C'\fR, \f(CW\*(C`w1\*(C'\fR, ....
+.Sp
+Should any of the categories by default be enabled even if not within the
+scope of \f(CW\*(C`use\ warnings\*(C'\fR, instead use the \f(CW"ckWARN_d"\fR macros.
+.Sp
+The categories must be completely independent, one may not be subclassed from
+the other.
+.RS 4
+.Sp
+.Vb 4
+\& bool ckWARN (U32 w)
+\& bool ckWARN2(U32 w1, U32 w2)
+\& bool ckWARN3(U32 w1, U32 w2, U32 w3)
+\& bool ckWARN4(U32 w1, U32 w2, U32 w3, U32 w4)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ckWARN_d""" 4
+.el .IP \f(CWckWARN_d\fR 4
+.IX Item "ckWARN_d"
+.PD 0
+.ie n .IP """ckWARN2_d""" 4
+.el .IP \f(CWckWARN2_d\fR 4
+.IX Item "ckWARN2_d"
+.ie n .IP """ckWARN3_d""" 4
+.el .IP \f(CWckWARN3_d\fR 4
+.IX Item "ckWARN3_d"
+.ie n .IP """ckWARN4_d""" 4
+.el .IP \f(CWckWARN4_d\fR 4
+.IX Xref "ckWARN_d ckWARN2_d ckWARN3_d ckWARN4_d"
+.IX Item "ckWARN4_d"
+.PD
+Like \f(CW"ckWARN"\fR, but for use if and only if the warning category(ies) is by
+default enabled even if not within the scope of \f(CW\*(C`use\ warnings\*(C'\fR.
+.RS 4
+.Sp
+.Vb 4
+\& bool ckWARN_d (U32 w)
+\& bool ckWARN2_d(U32 w1, U32 w2)
+\& bool ckWARN3_d(U32 w1, U32 w2, U32 w3)
+\& bool ckWARN4_d(U32 w1, U32 w2, U32 w3, U32 w4)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ck_warner""" 4
+.el .IP \f(CWck_warner\fR 4
+.IX Item "ck_warner"
+.PD 0
+.ie n .IP """ck_warner_d""" 4
+.el .IP \f(CWck_warner_d\fR 4
+.IX Xref "ck_warner ck_warner_d"
+.IX Item "ck_warner_d"
+.PD
+If none of the warning categories given by \f(CW\*(C`err\*(C'\fR are enabled, do nothing;
+otherwise call \f(CW"warner"\fR or \f(CW"warner_nocontext"\fR with the passed-in
+parameters;.
+.Sp
+\&\f(CW\*(C`err\*(C'\fR must be one of the \f(CW"packWARN"\fR, \f(CW\*(C`packWARN2\*(C'\fR, \f(CW\*(C`packWARN3\*(C'\fR,
+\&\f(CW\*(C`packWARN4\*(C'\fR macros populated with the appropriate number of warning
+categories.
+.Sp
+The two forms differ only in that \f(CW\*(C`ck_warner_d\*(C'\fR should be used if warnings for
+any of the categories are by default enabled.
+.Sp
+NOTE: \f(CW\*(C`ck_warner\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_ck_warner\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.Sp
+NOTE: \f(CW\*(C`ck_warner_d\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_ck_warner_d\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 1
+\& void Perl_ck_warner(pTHX_ U32 err, const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CLEAR_ERRSV""" 4
+.el .IP \f(CWCLEAR_ERRSV\fR 4
+.IX Xref "CLEAR_ERRSV"
+.IX Item "CLEAR_ERRSV"
+Clear the contents of \f(CW$@\fR, setting it to the empty string.
+.Sp
+This replaces any read-only SV with a fresh SV and removes any magic.
+.RS 4
+.Sp
+.Vb 1
+\& void CLEAR_ERRSV()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """croak""" 4
+.el .IP \f(CWcroak\fR 4
+.IX Item "croak"
+.PD 0
+.ie n .IP """croak_nocontext""" 4
+.el .IP \f(CWcroak_nocontext\fR 4
+.IX Xref "croak croak_nocontext"
+.IX Item "croak_nocontext"
+.PD
+These are XS interfaces to Perl's \f(CW\*(C`die\*(C'\fR function.
+.Sp
+They take a sprintf-style format pattern and argument list, which are used to
+generate a string message. If the message does not end with a newline, then it
+will be extended with some indication of the current location in the code, as
+described for \f(CW"mess_sv"\fR.
+.Sp
+The error message will be used as an exception, by default
+returning control to the nearest enclosing \f(CW\*(C`eval\*(C'\fR, but subject to
+modification by a \f(CW$SIG{_\|_DIE_\|_}\fR handler. In any case, these croak
+functions never return normally.
+.Sp
+For historical reasons, if \f(CW\*(C`pat\*(C'\fR is null then the contents of \f(CW\*(C`ERRSV\*(C'\fR
+(\f(CW$@\fR) will be used as an error message or object instead of building an
+error message from arguments. If you want to throw a non-string object,
+or build an error message in an SV yourself, it is preferable to use
+the \f(CW"croak_sv"\fR function, which does not involve clobbering \f(CW\*(C`ERRSV\*(C'\fR.
+.Sp
+The two forms differ only in that \f(CW\*(C`croak_nocontext\*(C'\fR does not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter. It is usually preferred as it takes up fewer
+bytes of code than plain \f(CW\*(C`Perl_croak\*(C'\fR, and time is rarely a critical resource
+when you are about to throw an exception.
+.Sp
+NOTE: \f(CW\*(C`croak\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_croak\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& void Perl_croak (pTHX_ const char *pat, ...)
+\& void croak_nocontext(const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """croak_no_modify""" 4
+.el .IP \f(CWcroak_no_modify\fR 4
+.IX Xref "croak_no_modify"
+.IX Item "croak_no_modify"
+This encapsulates a common reason for dying, generating terser object code than
+using the generic \f(CW\*(C`Perl_croak\*(C'\fR. It is exactly equivalent to
+\&\f(CW\*(C`Perl_croak(aTHX_ "%s", PL_no_modify)\*(C'\fR (which expands to something like
+"Modification of a read-only value attempted").
+.Sp
+Less code used on exception code paths reduces CPU cache pressure.
+.RS 4
+.Sp
+.Vb 1
+\& void croak_no_modify()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """croak_sv""" 4
+.el .IP \f(CWcroak_sv\fR 4
+.IX Xref "croak_sv"
+.IX Item "croak_sv"
+This is an XS interface to Perl's \f(CW\*(C`die\*(C'\fR function.
+.Sp
+\&\f(CW\*(C`baseex\*(C'\fR is the error message or object. If it is a reference, it
+will be used as-is. Otherwise it is used as a string, and if it does
+not end with a newline then it will be extended with some indication of
+the current location in the code, as described for "mess_sv".
+.Sp
+The error message or object will be used as an exception, by default
+returning control to the nearest enclosing \f(CW\*(C`eval\*(C'\fR, but subject to
+modification by a \f(CW$SIG{_\|_DIE_\|_}\fR handler. In any case, the \f(CW\*(C`croak_sv\*(C'\fR
+function never returns normally.
+.Sp
+To die with a simple string message, the "croak" function may be
+more convenient.
+.RS 4
+.Sp
+.Vb 1
+\& void croak_sv(SV *baseex)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """die""" 4
+.el .IP \f(CWdie\fR 4
+.IX Item "die"
+.PD 0
+.ie n .IP """die_nocontext""" 4
+.el .IP \f(CWdie_nocontext\fR 4
+.IX Xref "die die_nocontext"
+.IX Item "die_nocontext"
+.PD
+These behave the same as "croak", except for the return type.
+They should be used only where the \f(CW\*(C`OP *\*(C'\fR return type is required.
+They never actually return.
+.Sp
+The two forms differ only in that \f(CW\*(C`die_nocontext\*(C'\fR does not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter, so is used in situations where the caller doesn't
+already have the thread context.
+.Sp
+NOTE: \f(CW\*(C`die\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_die\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& OP * Perl_die (pTHX_ const char *pat, ...)
+\& OP * die_nocontext(const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """die_sv""" 4
+.el .IP \f(CWdie_sv\fR 4
+.IX Xref "die_sv"
+.IX Item "die_sv"
+This behaves the same as "croak_sv", except for the return type.
+It should be used only where the \f(CW\*(C`OP *\*(C'\fR return type is required.
+The function never actually returns.
+.RS 4
+.Sp
+.Vb 1
+\& OP * die_sv(SV *baseex)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ERRSV""" 4
+.el .IP \f(CWERRSV\fR 4
+.IX Xref "ERRSV"
+.IX Item "ERRSV"
+Returns the SV for \f(CW$@\fR, creating it if needed.
+.RS 4
+.Sp
+.Vb 1
+\& SV * ERRSV
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """packWARN""" 4
+.el .IP \f(CWpackWARN\fR 4
+.IX Item "packWARN"
+.PD 0
+.ie n .IP """packWARN2""" 4
+.el .IP \f(CWpackWARN2\fR 4
+.IX Item "packWARN2"
+.ie n .IP """packWARN3""" 4
+.el .IP \f(CWpackWARN3\fR 4
+.IX Item "packWARN3"
+.ie n .IP """packWARN4""" 4
+.el .IP \f(CWpackWARN4\fR 4
+.IX Xref "packWARN packWARN2 packWARN3 packWARN4"
+.IX Item "packWARN4"
+.PD
+These macros are used to pack warning categories into a single U32 to pass to
+macros and functions that take a warning category parameter. The number of
+categories to pack is given by the name, with a corresponding number of
+category parameters passed.
+.RS 4
+.Sp
+.Vb 4
+\& U32 packWARN (U32 w1)
+\& U32 packWARN2(U32 w1, U32 w2)
+\& U32 packWARN3(U32 w1, U32 w2, U32 w3)
+\& U32 packWARN4(U32 w1, U32 w2, U32 w3, U32 w4)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """SANE_ERRSV""" 4
+.el .IP \f(CWSANE_ERRSV\fR 4
+.IX Xref "SANE_ERRSV"
+.IX Item "SANE_ERRSV"
+Clean up ERRSV so we can safely set it.
+.Sp
+This replaces any read-only SV with a fresh writable copy and removes
+any magic.
+.RS 4
+.Sp
+.Vb 1
+\& void SANE_ERRSV()
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vcroak""" 4
+.el .IP \f(CWvcroak\fR 4
+.IX Xref "vcroak"
+.IX Item "vcroak"
+This is an XS interface to Perl's \f(CW\*(C`die\*(C'\fR function.
+.Sp
+\&\f(CW\*(C`pat\*(C'\fR and \f(CW\*(C`args\*(C'\fR are a sprintf-style format pattern and encapsulated
+argument list. These are used to generate a string message. If the
+message does not end with a newline, then it will be extended with
+some indication of the current location in the code, as described for
+"mess_sv".
+.Sp
+The error message will be used as an exception, by default
+returning control to the nearest enclosing \f(CW\*(C`eval\*(C'\fR, but subject to
+modification by a \f(CW$SIG{_\|_DIE_\|_}\fR handler. In any case, the \f(CW\*(C`croak\*(C'\fR
+function never returns normally.
+.Sp
+For historical reasons, if \f(CW\*(C`pat\*(C'\fR is null then the contents of \f(CW\*(C`ERRSV\*(C'\fR
+(\f(CW$@\fR) will be used as an error message or object instead of building an
+error message from arguments. If you want to throw a non-string object,
+or build an error message in an SV yourself, it is preferable to use
+the "croak_sv" function, which does not involve clobbering \f(CW\*(C`ERRSV\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& void vcroak(const char *pat, va_list *args)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vwarn""" 4
+.el .IP \f(CWvwarn\fR 4
+.IX Xref "vwarn"
+.IX Item "vwarn"
+This is an XS interface to Perl's \f(CW\*(C`warn\*(C'\fR function.
+.Sp
+This is like \f(CW"warn"\fR, but \f(CW\*(C`args\*(C'\fR are an encapsulated
+argument list.
+.Sp
+Unlike with "vcroak", \f(CW\*(C`pat\*(C'\fR is not permitted to be null.
+.RS 4
+.Sp
+.Vb 1
+\& void vwarn(const char *pat, va_list *args)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """vwarner""" 4
+.el .IP \f(CWvwarner\fR 4
+.IX Xref "vwarner"
+.IX Item "vwarner"
+This is like \f(CW"warner"\fR, but \f(CW\*(C`args\*(C'\fR are an encapsulated argument list.
+.RS 4
+.Sp
+.Vb 1
+\& void vwarner(U32 err, const char *pat, va_list *args)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """warn""" 4
+.el .IP \f(CWwarn\fR 4
+.IX Item "warn"
+.PD 0
+.ie n .IP """warn_nocontext""" 4
+.el .IP \f(CWwarn_nocontext\fR 4
+.IX Xref "warn warn_nocontext"
+.IX Item "warn_nocontext"
+.PD
+These are XS interfaces to Perl's \f(CW\*(C`warn\*(C'\fR function.
+.Sp
+They take a sprintf-style format pattern and argument list, which are used to
+generate a string message. If the message does not end with a newline, then it
+will be extended with some indication of the current location in the code, as
+described for \f(CW"mess_sv"\fR.
+.Sp
+The error message or object will by default be written to standard error,
+but this is subject to modification by a \f(CW$SIG{_\|_WARN_\|_}\fR handler.
+.Sp
+Unlike with \f(CW"croak"\fR, \f(CW\*(C`pat\*(C'\fR is not permitted to be null.
+.Sp
+The two forms differ only in that \f(CW\*(C`warn_nocontext\*(C'\fR does not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter, so is used in situations where the caller doesn't
+already have the thread context.
+.Sp
+NOTE: \f(CW\*(C`warn\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_warn\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& void Perl_warn (pTHX_ const char *pat, ...)
+\& void warn_nocontext(const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """warner""" 4
+.el .IP \f(CWwarner\fR 4
+.IX Item "warner"
+.PD 0
+.ie n .IP """warner_nocontext""" 4
+.el .IP \f(CWwarner_nocontext\fR 4
+.IX Xref "warner warner_nocontext"
+.IX Item "warner_nocontext"
+.PD
+These output a warning of the specified category (or categories) given by
+\&\f(CW\*(C`err\*(C'\fR, using the sprintf-style format pattern \f(CW\*(C`pat\*(C'\fR, and argument list.
+.Sp
+\&\f(CW\*(C`err\*(C'\fR must be one of the \f(CW"packWARN"\fR, \f(CW\*(C`packWARN2\*(C'\fR, \f(CW\*(C`packWARN3\*(C'\fR,
+\&\f(CW\*(C`packWARN4\*(C'\fR macros populated with the appropriate number of warning
+categories. If any of the warning categories they specify is fatal, a fatal
+exception is thrown.
+.Sp
+In any event a message is generated by the pattern and arguments. If the
+message does not end with a newline, then it will be extended with some
+indication of the current location in the code, as described for "mess_sv".
+.Sp
+The error message or object will by default be written to standard error,
+but this is subject to modification by a \f(CW$SIG{_\|_WARN_\|_}\fR handler.
+.Sp
+\&\f(CW\*(C`pat\*(C'\fR is not permitted to be null.
+.Sp
+The two forms differ only in that \f(CW\*(C`warner_nocontext\*(C'\fR does not take a thread
+context (\f(CW\*(C`aTHX\*(C'\fR) parameter, so is used in situations where the caller doesn't
+already have the thread context.
+.Sp
+These functions differ from the similarly named \f(CW"warn"\fR functions, in that
+the latter are for XS code to unconditionally display a warning, whereas these
+are for code that may be compiling a perl program, and does extra checking to
+see if the warning should be fatal.
+.Sp
+NOTE: \f(CW\*(C`warner\*(C'\fR must be explicitly called as
+\&\f(CW\*(C`Perl_warner\*(C'\fR
+with an \f(CW\*(C`aTHX_\*(C'\fR parameter.
+.RS 4
+.Sp
+.Vb 2
+\& void Perl_warner (pTHX_ U32 err, const char *pat, ...)
+\& void warner_nocontext(U32 err, const char *pat, ...)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """warn_sv""" 4
+.el .IP \f(CWwarn_sv\fR 4
+.IX Xref "warn_sv"
+.IX Item "warn_sv"
+This is an XS interface to Perl's \f(CW\*(C`warn\*(C'\fR function.
+.Sp
+\&\f(CW\*(C`baseex\*(C'\fR is the error message or object. If it is a reference, it
+will be used as-is. Otherwise it is used as a string, and if it does
+not end with a newline then it will be extended with some indication of
+the current location in the code, as described for "mess_sv".
+.Sp
+The error message or object will by default be written to standard error,
+but this is subject to modification by a \f(CW$SIG{_\|_WARN_\|_}\fR handler.
+.Sp
+To warn with a simple string message, the "warn" function may be
+more convenient.
+.RS 4
+.Sp
+.Vb 1
+\& void warn_sv(SV *baseex)
+.Ve
+.RE
+.RS 4
+.RE
+.SH XS
+.IX Header "XS"
+\&\fIxsubpp\fR compiles XS code into C. See "xsubpp" in perlutil.
+.ie n .IP """aMY_CXT""" 4
+.el .IP \f(CWaMY_CXT\fR 4
+.IX Item "aMY_CXT"
+Described in perlxs.
+.ie n .IP """_aMY_CXT""" 4
+.el .IP \f(CW_aMY_CXT\fR 4
+.IX Item "_aMY_CXT"
+Described in perlxs.
+.ie n .IP """aMY_CXT_""" 4
+.el .IP \f(CWaMY_CXT_\fR 4
+.IX Item "aMY_CXT_"
+Described in perlxs.
+.ie n .IP """ax""" 4
+.el .IP \f(CWax\fR 4
+.IX Xref "ax"
+.IX Item "ax"
+Variable which is setup by \f(CW\*(C`xsubpp\*(C'\fR to indicate the stack base offset,
+used by the \f(CW\*(C`ST\*(C'\fR, \f(CW\*(C`XSprePUSH\*(C'\fR and \f(CW\*(C`XSRETURN\*(C'\fR macros. The \f(CW\*(C`dMARK\*(C'\fR macro
+must be called prior to setup the \f(CW\*(C`MARK\*(C'\fR variable.
+.RS 4
+.Sp
+.Vb 1
+\& I32 ax
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """CLASS""" 4
+.el .IP \f(CWCLASS\fR 4
+.IX Xref "CLASS"
+.IX Item "CLASS"
+Variable which is setup by \f(CW\*(C`xsubpp\*(C'\fR to indicate the
+class name for a C++ XS constructor. This is always a \f(CW\*(C`char*\*(C'\fR. See
+\&\f(CW"THIS"\fR.
+.RS 4
+.Sp
+.Vb 1
+\& char* CLASS
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dAX""" 4
+.el .IP \f(CWdAX\fR 4
+.IX Xref "dAX"
+.IX Item "dAX"
+Sets up the \f(CW\*(C`ax\*(C'\fR variable.
+This is usually handled automatically by \f(CW\*(C`xsubpp\*(C'\fR by calling \f(CW\*(C`dXSARGS\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& dAX;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dAXMARK""" 4
+.el .IP \f(CWdAXMARK\fR 4
+.IX Xref "dAXMARK"
+.IX Item "dAXMARK"
+Sets up the \f(CW\*(C`ax\*(C'\fR variable and stack marker variable \f(CW\*(C`mark\*(C'\fR.
+This is usually handled automatically by \f(CW\*(C`xsubpp\*(C'\fR by calling \f(CW\*(C`dXSARGS\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& dAXMARK;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dITEMS""" 4
+.el .IP \f(CWdITEMS\fR 4
+.IX Xref "dITEMS"
+.IX Item "dITEMS"
+Sets up the \f(CW\*(C`items\*(C'\fR variable.
+This is usually handled automatically by \f(CW\*(C`xsubpp\*(C'\fR by calling \f(CW\*(C`dXSARGS\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& dITEMS;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dMY_CXT""" 4
+.el .IP \f(CWdMY_CXT\fR 4
+.IX Item "dMY_CXT"
+Described in perlxs.
+.ie n .IP """dMY_CXT_SV""" 4
+.el .IP \f(CWdMY_CXT_SV\fR 4
+.IX Xref "dMY_CXT_SV"
+.IX Item "dMY_CXT_SV"
+Now a placeholder that declares nothing
+.RS 4
+.Sp
+.Vb 1
+\& dMY_CXT_SV;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dUNDERBAR""" 4
+.el .IP \f(CWdUNDERBAR\fR 4
+.IX Xref "dUNDERBAR"
+.IX Item "dUNDERBAR"
+Sets up any variable needed by the \f(CW\*(C`UNDERBAR\*(C'\fR macro. It used to define
+\&\f(CW\*(C`padoff_du\*(C'\fR, but it is currently a noop. However, it is strongly advised
+to still use it for ensuring past and future compatibility.
+.RS 4
+.Sp
+.Vb 1
+\& dUNDERBAR;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dXSARGS""" 4
+.el .IP \f(CWdXSARGS\fR 4
+.IX Xref "dXSARGS"
+.IX Item "dXSARGS"
+Sets up stack and mark pointers for an XSUB, calling \f(CW\*(C`dSP\*(C'\fR and \f(CW\*(C`dMARK\*(C'\fR.
+Sets up the \f(CW\*(C`ax\*(C'\fR and \f(CW\*(C`items\*(C'\fR variables by calling \f(CW\*(C`dAX\*(C'\fR and \f(CW\*(C`dITEMS\*(C'\fR.
+This is usually handled automatically by \f(CW\*(C`xsubpp\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& dXSARGS;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """dXSI32""" 4
+.el .IP \f(CWdXSI32\fR 4
+.IX Xref "dXSI32"
+.IX Item "dXSI32"
+Sets up the \f(CW\*(C`ix\*(C'\fR variable for an XSUB which has aliases. This is usually
+handled automatically by \f(CW\*(C`xsubpp\*(C'\fR.
+.RS 4
+.Sp
+.Vb 1
+\& dXSI32;
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """items""" 4
+.el .IP \f(CWitems\fR 4
+.IX Xref "items"
+.IX Item "items"
+Variable which is setup by \f(CW\*(C`xsubpp\*(C'\fR to indicate the number of
+items on the stack. See "Variable-length Parameter Lists" in perlxs.
+.RS 4
+.Sp
+.Vb 1
+\& I32 items
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ix""" 4
+.el .IP \f(CWix\fR 4
+.IX Xref "ix"
+.IX Item "ix"
+Variable which is setup by \f(CW\*(C`xsubpp\*(C'\fR to indicate which of an
+XSUB's aliases was used to invoke it. See "The ALIAS: Keyword" in perlxs.
+.RS 4
+.Sp
+.Vb 1
+\& I32 ix
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """MY_CXT""" 4
+.el .IP \f(CWMY_CXT\fR 4
+.IX Item "MY_CXT"
+Described in perlxs.
+.ie n .IP """MY_CXT_CLONE""" 4
+.el .IP \f(CWMY_CXT_CLONE\fR 4
+.IX Item "MY_CXT_CLONE"
+Described in perlxs.
+.ie n .IP """MY_CXT_INIT""" 4
+.el .IP \f(CWMY_CXT_INIT\fR 4
+.IX Item "MY_CXT_INIT"
+Described in perlxs.
+.ie n .IP """pMY_CXT""" 4
+.el .IP \f(CWpMY_CXT\fR 4
+.IX Item "pMY_CXT"
+Described in perlxs.
+.ie n .IP """_pMY_CXT""" 4
+.el .IP \f(CW_pMY_CXT\fR 4
+.IX Item "_pMY_CXT"
+Described in perlxs.
+.ie n .IP """pMY_CXT_""" 4
+.el .IP \f(CWpMY_CXT_\fR 4
+.IX Item "pMY_CXT_"
+Described in perlxs.
+.ie n .IP """RETVAL""" 4
+.el .IP \f(CWRETVAL\fR 4
+.IX Xref "RETVAL"
+.IX Item "RETVAL"
+Variable which is setup by \f(CW\*(C`xsubpp\*(C'\fR to hold the return value for an
+XSUB. This is always the proper type for the XSUB. See
+"The RETVAL Variable" in perlxs.
+.RS 4
+.Sp
+.Vb 1
+\& type RETVAL
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """ST""" 4
+.el .IP \f(CWST\fR 4
+.IX Xref "ST"
+.IX Item "ST"
+Used to access elements on the XSUB's stack.
+.RS 4
+.Sp
+.Vb 1
+\& SV* ST(int ix)
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """START_MY_CXT""" 4
+.el .IP \f(CWSTART_MY_CXT\fR 4
+.IX Item "START_MY_CXT"
+Described in perlxs.
+.ie n .IP """THIS""" 4
+.el .IP \f(CWTHIS\fR 4
+.IX Xref "THIS"
+.IX Item "THIS"
+Variable which is setup by \f(CW\*(C`xsubpp\*(C'\fR to designate the object in a C++
+XSUB. This is always the proper type for the C++ object. See \f(CW"CLASS"\fR and
+"Using XS With C++" in perlxs.
+.RS 4
+.Sp
+.Vb 1
+\& type THIS
+.Ve
+.RE
+.RS 4
+.RE
+.ie n .IP """UNDERBAR""" 4
+.el .IP \f(CWUNDERBAR\fR 4
+.IX Xref "UNDERBAR"
+.IX Item "UNDERBAR"
+The SV* corresponding to the \f(CW$_\fR variable. Works even if there
+is a lexical \f(CW$_\fR in scope.
+.ie n .IP """XS""" 4
+.el .IP \f(CWXS\fR 4
+.IX Xref "XS"
+.IX Item "XS"
+Macro to declare an XSUB and its C parameter list. This is handled by
+\&\f(CW\*(C`xsubpp\*(C'\fR. It is the same as using the more explicit \f(CW\*(C`XS_EXTERNAL\*(C'\fR macro; the
+latter is preferred.
+.ie n .IP """XS_EXTERNAL""" 4
+.el .IP \f(CWXS_EXTERNAL\fR 4
+.IX Xref "XS_EXTERNAL"
+.IX Item "XS_EXTERNAL"
+Macro to declare an XSUB and its C parameter list explicitly exporting the symbols.
+.ie n .IP """XS_INTERNAL""" 4
+.el .IP \f(CWXS_INTERNAL\fR 4
+.IX Xref "XS_INTERNAL"
+.IX Item "XS_INTERNAL"
+Macro to declare an XSUB and its C parameter list without exporting the symbols.
+This is handled by \f(CW\*(C`xsubpp\*(C'\fR and generally preferable over exporting the XSUB
+symbols unnecessarily.
+.ie n .IP """XSPROTO""" 4
+.el .IP \f(CWXSPROTO\fR 4
+.IX Xref "XSPROTO"
+.IX Item "XSPROTO"
+Macro used by \f(CW"XS_INTERNAL"\fR and \f(CW"XS_EXTERNAL"\fR to declare a function
+prototype. You probably shouldn't be using this directly yourself.
+.SH "Undocumented elements"
+.IX Header "Undocumented elements"
+The following functions have been flagged as part of the public
+API, but are currently undocumented. Use them at your own risk,
+as the interfaces are subject to change. Functions that are not
+listed in this document are not intended for public use, and
+should NOT be used under any circumstances.
+.PP
+If you feel you need to use one of these functions, first send
+email to perl5\-porters@perl.org <mailto:perl5-porters@perl.org>.
+It may be that there is a good reason for the function not being
+documented, and it should be removed from this list; or it may
+just be that no one has gotten around to documenting it. In the
+latter case, you will be asked to submit a patch to document the
+function. Once your patch is accepted, it will indicate that the
+interface is stable (unless it is explicitly marked otherwise) and
+usable by you.
+.PP
+
+.IX Xref "clone_params_del clone_params_new do_open do_openn newANONATTRSUB newANONHASH newANONLIST newANONSUB newAVREF newCVREF newGVREF newHVREF newSVREF resume_compcv sv_dup sv_dup_inc"
+.PP
+.Vb 4
+\& clone_params_del newANONATTRSUB newAVREF newSVREF
+\& clone_params_new newANONHASH newCVREF resume_compcv
+\& do_open newANONLIST newGVREF sv_dup
+\& do_openn newANONSUB newHVREF sv_dup_inc
+.Ve
+.PP
+Next are the API-flagged elements that are considered experimental. Using one
+of these is even more risky than plain undocumented ones. They are listed
+here because they should be listed somewhere (so their existence doesn't get
+lost) and this is the best place for them.
+.PP
+
+.IX Xref "apply_attrs_string gv_fetchmethod_pv_flags gv_fetchmethod_pvn_flags gv_fetchmethod_sv_flags hv_store_flags leave_adjust_stacks newXS_flags savetmps thread_locale_init thread_locale_term"
+.PP
+.Vb 4
+\& apply_attrs_string hv_store_flags thread_locale_init
+\& gv_fetchmethod_pv_flags leave_adjust_stacks thread_locale_term
+\& gv_fetchmethod_pvn_flags newXS_flags
+\& gv_fetchmethod_sv_flags savetmps
+.Ve
+.PP
+Finally are deprecated undocumented API elements.
+Do not use any for new code; remove all occurrences of all of these from
+existing code.
+.PP
+There are currently no items of this type
+.SH AUTHORS
+.IX Header "AUTHORS"
+Until May 1997, this document was maintained by Jeff Okamoto
+<okamoto@corp.hp.com>. It is now maintained as part of Perl itself.
+.PP
+With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
+Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
+Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
+Stephen McCamant, and Gurusamy Sarathy.
+.PP
+API Listing originally by Dean Roehrich <roehrich@cray.com>.
+.PP
+Updated to be autogenerated from comments in the source by Benjamin Stuhl.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIconfig.h\fR, perlapio, perlcall, perlclib, perlembed, perlfilter, perlguts, perlhacktips, perlintern, perlinterp, perliol, perlmroapi, perlreapi, perlreguts, perlxs