内容

名称

perlapi - perl 公共 API 的自动生成文档

描述

此文件包含 perl 公共 API 的大部分文档,由 embed.pl 生成。具体来说,它列出了扩展编写者可以使用的一些函数、宏、标志和变量。除了 perlinternconfig.h 之外,这里还列出了一些实际上在其他 pod 中有文档记录的项目。

最后 是一个尚未记录的函数列表。欢迎提供补丁!这些接口可能会在未经通知的情况下更改。

这里记录的一些函数已合并,以便单个条目可用于多个函数,这些函数基本上执行相同的操作,但有一些细微的差异。例如,一种形式可能会处理魔法,而另一种则不会。每种变体的名称都列在单个条目的顶部。但是,如果所有形式都具有相同的签名(参数和返回类型)除了它们的名称之外,则仅显示基本形式的用法。如果任何一种形式具有不同的签名(例如返回 const 或不返回),则会显式显示每个函数的签名。

这里或其他提到的 pod 中没有列出的任何内容都不属于公共 API,扩展编写者不应该使用。出于这些原因,在编写扩展时应避免盲目使用 proto.h 中列出的函数。

在 Perl 中,与 C 不同,字符串通常可以包含嵌入的 NUL 字符。有时在文档中,Perl 字符串被称为“缓冲区”,以将其与 C 字符串区分开来,但有时它们都被称为字符串。

请注意,所有 Perl API 全局变量都必须使用 PL_ 前缀引用。同样,这里没有列出的那些不应该被扩展编写者使用,并且可能会在未经通知的情况下更改或删除;宏也是如此。提供了一些宏以与旧的、未修饰的名称兼容,但这种支持可能会在将来的版本中被禁用。

Perl 最初是为处理 US-ASCII 编写(即字符的序数在 0 - 127 范围内)。文档和注释可能仍然使用术语 ASCII,而实际上有时是指 0 - 255 的整个范围。

小于 256 的非 ASCII 字符可以有不同的含义,具体取决于各种因素。(最值得注意的是,请参阅 perllocale。)但通常整个范围可以称为 ISO-8859-1。通常,术语“Latin-1”(或“Latin1”)被用作 ISO-8859-1 的等效项。但有些人将“Latin1”视为仅指 128 到 255 范围内的字符,有时是指 160 到 255 范围内的字符。本文档使用“Latin1”和“Latin-1”来指代所有 256 个字符。

请注意,Perl 可以编译并在 ASCII 或 EBCDIC 下运行(请参阅 perlebcdic)。大多数文档(甚至代码中的注释)都忽略了 EBCDIC 的可能性。对于几乎所有目的而言,差异都是透明的。例如,在 EBCDIC 下,使用 UTF-EBCDIC 而不是 UTF-8 来编码 Unicode 字符串,因此,无论何时本文档提到 utf8(以及该名称的变体,包括函数名称),它也(基本上是透明地)意味着 UTF-EBCDIC。但是字符的序数在 ASCII、EBCDIC 和 UTF 编码之间有所不同,并且以 UTF-EBCDIC 编码的字符串可能占用与 UTF-8 中不同的字节数。

本文档的组织结构是暂定的,可能会发生变化。欢迎您提出建议和补丁 [email protected]

本文档中的部分目前包括:

"AV 处理"
"回调函数"
"强制转换"
"字符大小写转换"
"字符分类"
"编译器和预处理器信息"
"编译器指令"
"编译时作用域钩子"
"并发"
"COP 和提示哈希"
"自定义运算符"
"CV 处理"
"调试"
"显示函数"
"嵌入、线程和解释器克隆"
"Errno"
"异常处理(简单)宏"
"文件系统配置值"
"浮点数"
"通用配置"
"全局变量"
"GV 处理和存储"
"钩子操作"
"HV 处理"
"输入/输出"
"整数"
"I/O 格式"
"词法分析器接口"
"区域设置"
"魔数"
"内存管理"
"MRO"
"多重调用函数"
"数值函数"
"优化树"
"打包和解包"
"填充数据结构"
"密码和组访问"
"系统命令路径"
"原型信息"
"正则表达式函数"
"报告和格式"
"信号"
"站点配置"
"套接字配置值"
"源过滤器"
"堆栈操作宏"
"字符串处理"
"SV 标志"
"SV 处理"
"污染"
"时间"
"类型定义名称"
"Unicode 支持"
"实用函数"
"版本控制"
"警告和退出"
"XS"
"未记录的元素"

以下列表按字母顺序排列,不区分大小写。

AV 处理

AV

perlguts 中描述。

AvALLOC

perlguts 中描述。

    AvALLOC(AV* av)
AvARRAY

返回指向 AV 内部 SV* 数组的指针。

这对于对数组进行指针运算很有用。如果你只需要查找数组元素,那么更倾向于使用 av_fetch

    SV**  AvARRAY(AV* av)
av_clear

释放数组的所有元素,使其为空。相当于 XS 中的 @array = ()。另请参见 "av_undef"

请注意,直接或间接调用析构函数来释放数组元素可能会导致数组本身的引用计数减少(例如,通过删除符号表中的条目)。因此,除非你持有对它的引用,否则 AV 可能会在返回时被释放(甚至重新分配)。

    void  av_clear(AV *av)
av_count

返回数组 av 中的元素数量。这是数组的真实长度,包括任何未定义的元素。它始终与 av_top_index(av) + 1 相同。

    Size_t  av_count(AV *av)
av_create_and_push

将一个 SV 推入数组末尾,如果需要则创建数组。一个小的内部辅助函数,用于移除常见的重复代码。

注意:av_create_and_push 必须显式地调用为 Perl_av_create_and_push,并带有一个 aTHX_ 参数。

    void  Perl_av_create_and_push(pTHX_ AV ** const avp,
                                  SV * const val)
av_create_and_unshift_one

将一个 SV 推入数组开头,如果需要则创建数组。一个小的内部辅助函数,用于移除常见的重复代码。

注意:av_create_and_unshift_one 必须显式地调用为 Perl_av_create_and_unshift_one,并带有一个 aTHX_ 参数。

    SV **  Perl_av_create_and_unshift_one(pTHX_ AV ** const avp,
                                          SV * const val)
av_delete

删除数组中由 key 索引的元素,使该元素成为临时的,并返回它。如果 flags 等于 G_DISCARD,则释放该元素并返回 NULL。如果 key 超出范围,也会返回 NULL。

Perl 等价物:splice(@myarray, $key, 1, undef)(如果存在 G_DISCARD,则 splice 在空上下文)。

    SV *  av_delete(AV *av, SSize_t key, I32 flags)
av_exists

如果由 key 索引的元素已初始化,则返回 true。

这依赖于未初始化的数组元素被设置为 NULL 的事实。

Perl 等价物:exists($myarray[$key])

    bool  av_exists(AV *av, SSize_t key)
av_extend

预先扩展数组,使其能够存储索引为0..key的值。因此,av_extend(av,99)保证数组可以存储100个元素,即在普通数组上,av_store(av, 0, sv)av_store(av, 99, sv)将无需任何进一步的内存分配即可正常工作。

如果 av 参数是一个绑定数组,则将调用 EXTEND 绑定数组方法,并传递参数 (key+1)

    void  av_extend(AV *av, SSize_t key)
av_fetch

返回数组中指定索引处的 SV。key 是索引。如果 lval 为真,则保证返回一个真实的 SV(如果之前不是真实的),然后可以修改它。在将返回值解引用为 SV* 之前,请检查返回值是否为非 NULL。

有关如何在绑定数组上使用此函数的更多信息,请参见 "perlguts 中的理解绑定哈希和数组的魔力"

Perl 中的粗略等效代码为 $myarray[$key]

    SV **  av_fetch(AV *av, SSize_t key, I32 lval)
AvFILL

"av_top_index""av_tindex" 相同。

    SSize_t  AvFILL(AV* av)
av_fill

将数组中最高索引设置为给定数字,等效于 Perl 中的 $#array = $fill;

av_fill() 返回后,数组中的元素数量将为 fill + 1。如果数组之前较短,则附加的额外元素将设置为 NULL。如果数组较长,则将释放多余的元素。 av_fill(av, -1)av_clear(av) 相同。

    void  av_fill(AV *av, SSize_t fill)
av_len

"av_top_index" 相同。请注意,与名称暗示的相反,它返回数组中的最大索引。这与 "sv_len" 不同,后者返回您期望的值。

要获取数组中元素的真实数量,请使用 "av_count".

    SSize_t  av_len(AV *av)
av_make

创建一个新的 AV,并使用 SV 列表(**strp,长度为 size)填充它。每个 SV 都将被复制,因此它们的引用计数不会改变。新的 AV 将具有 1 的引用计数。

Perl 中的等效代码为:my @new_array = ($scalar1, $scalar2, $scalar3...);

    AV *  av_make(SSize_t size, SV **strp)
av_pop

从数组末尾删除一个 SV,将其大小减 1,并将 SV(传递一个引用计数的控制权)返回给调用者。如果数组为空,则返回 &PL_sv_undef

Perl 等效代码:pop(@myarray);

    SV *  av_pop(AV *av)
av_push

将一个 SV(转移一个引用计数的控制权)压入数组的末尾。数组将自动增长以容纳添加的元素。

Perl 等效代码:push @myarray, $val;

    void  av_push(AV *av, SV *val)
av_push_simple

这是一个简化版的 av_push,它假设数组非常简单 - 没有魔法,不可读,并且是 AvREAL - 并且 key 不小于 -1。此函数在任何这些假设可能不成立的情况下都不得使用。

将一个 SV(转移一个引用计数的控制权)压入数组的末尾。数组将自动增长以容纳添加的元素。

Perl 等效代码:push @myarray, $val;

    void  av_push_simple(AV *av, SV *val)
av_shift

从数组的开头移除一个 SV,将其大小减少一个,并将 SV(转移一个引用计数的控制权)返回给调用者。如果数组为空,则返回 &PL_sv_undef

Perl 等效代码:shift(@myarray);

    SV *  av_shift(AV *av)
av_store

将一个 SV 存储在数组中。数组索引由 key 指定。如果操作失败或值不需要实际存储在数组中(如绑定数组的情况),则返回值将为 NULL。否则,它可以被解引用以获取存储在那里的 SV*(= val)。

请注意,调用者负责在调用之前适当地增加 val 的引用计数,并在函数返回 NULL 时减少它。

近似的 Perl 等效代码:splice(@myarray, $key, 1, $val)

有关如何在绑定数组上使用此函数的更多信息,请参见 "perlguts 中的理解绑定哈希和数组的魔力"

    SV **  av_store(AV *av, SSize_t key, SV *val)
av_tindex
av_top_index

这些函数的行为相同。如果数组 av 为空,则这些函数返回 -1;否则,它们将返回当前在 av 中定义的所有数组元素的索引的最大值。

它们处理“获取”魔法。

这些函数的 Perl 等效代码是 $#av

使用 "av_count" 获取数组中的元素数量。

    SSize_t  av_tindex(AV *av)
av_undef

取消定义数组。undef(@array) 的 XS 等效代码。

除了释放数组的所有元素(如 av_clear())之外,它还释放 av 用于存储其标量列表的内存。

有关数组在返回时可能无效的说明,请参阅 "av_clear"

    void  av_undef(AV *av)
av_unshift

将给定数量的 undef 值移到数组的开头。数组将自动增长以容纳添加的元素。

Perl 等效代码:unshift @myarray, ((undef) x $num);

    void  av_unshift(AV *av, SSize_t num)
get_av

返回指定 Perl 全局或包数组的 AV,该数组具有给定的名称(因此它不适用于词法变量)。flags 传递给 gv_fetchpv。如果设置了 GV_ADD 并且 Perl 变量不存在,则会创建该变量。如果 flags 为零(忽略 SVf_UTF8)并且变量不存在,则返回 NULL

Perl 等效项:@{"$name"}

注意:perl_get_av() 形式已弃用

    AV *  get_av(const char *name, I32 flags)
newAV
newAV_alloc_x
newAV_alloc_xz

这些都创建了一个新的 AV,并将引用计数设置为 1。如果您还知道数组的初始元素,请参见 "av_make"

作为背景,数组包含三个部分

  1. 一个包含有关整个数组的信息的数据结构,例如其大小和引用计数。

  2. 一个指向各个元素的指针的 C 语言数组。这些被视为指向 SV 的指针,因此所有指针都必须可以转换为 SV*。

  3. 各个元素本身。这些可以是,例如,SV 和/或 AV 和/或 HV 等。

空数组只需要第一个数据结构,所有这些函数都会创建它。它们在其他方面有所不同,如下所示

newAV 形式

除了创建整个数组数据结构之外,它什么也不做。Perl 等效项大约是 my @array;

当数组的最小大小可能为零时(可能存在完全跳过使用它的代码路径),这很有用。

如果使用数组,则需要在此时分配指针数据结构。这最终将由 "av_extend"> 完成,无论是显式地

av_extend(av, len);

还是在存储第一个元素时隐式地

(void)av_store(av, 0, sv);

未使用的数组元素通常由 av_extend 初始化。

newAV_alloc_x 形式

这实际上执行了 newAV,然后还为指针数组分配(未初始化的)空间。当您提前知道数组的最小可能大小时,这很有用。这样做比执行一个简单的 newAV 然后执行 av_extend 更有效。

当然,如果需要,数组可以在以后扩展。

size 必须至少为 1。

newAV_alloc_xz 表单

这是 newAV_alloc_x,但将其中的每个指针初始化为 NULL。这提供了额外的安全性,以防止在设置之前读取它们。

size 必须至少为 1。

以下示例都将导致一个可以容纳四个元素(索引 0 .. 3)的数组

AV *av = newAV();
av_extend(av, 3);

AV *av = newAV_alloc_x(4);

AV *av = newAV_alloc_xz(4);

相反,以下示例分配的数组仅保证在不扩展的情况下可以容纳一个元素

AV *av = newAV_alloc_x(1);
AV *av = newAV_alloc_xz(1);
    AV *  newAV         ()
    AV *  newAV_alloc_x (SSize_t size)
    AV *  newAV_alloc_xz(SSize_t size)
newAVav

创建一个新的 AV 并使用从现有 AV 复制的值填充它。新 AV 的引用计数为 1,并将包含从原始 SV 复制的全新创建的 SV。原始源将保持不变。

Perl 等效项:my @new_array = @existing_array;

    AV *  newAVav(AV *oav)
newAVhv

创建一个新的 AV 并使用从现有 HV 复制的键和值填充它。新 AV 的引用计数为 1,并将包含从原始 HV 复制的全新创建的 SV。原始源将保持不变。

Perl 等效项:my @new_array = %existing_hash;

    AV *  newAVhv(HV *ohv)
Nullav

已弃用! 计划从 Perl 的未来版本中删除 Nullav。不要在新代码中使用它;从现有代码中删除它。

空 AV 指针。

(已弃用 - 改用 (AV *)NULL

回调函数

call_argv

对指定的命名和包范围的 Perl 子例程执行回调,使用 argv(一个以 NULL 结尾的字符串数组)作为参数。参见 perlcall

近似 Perl 等效项:&{"$sub_name"}(@$argv)

注意:perl_call_argv() 形式已弃用

    I32  call_argv(const char *sub_name, I32 flags, char **argv)
call_method

对指定的 Perl 方法执行回调。祝福的对象必须在堆栈上。参见 perlcall

注意:perl_call_method() 形式已弃用

    I32  call_method(const char *methname, I32 flags)
call_pv

对指定的 Perl 子例程执行回调。参见 perlcall

注意:perl_call_pv() 形式已弃用

    I32  call_pv(const char *sub_name, I32 flags)
call_sv

对由 SV 指定的 Perl 子例程执行回调。

如果未提供G_METHODG_METHOD_NAMED 标志,则 SV 可以是 CV、GV、对 CV 的引用、对 GV 的引用,或者SvPV(sv) 将用作要调用的子例程的名称。

如果提供了G_METHOD 标志,则 SV 可以是对 CV 的引用,或者SvPV(sv) 将用作要调用的方法的名称。

如果提供了G_METHOD_NAMED 标志,则SvPV(sv) 将用作要调用的方法的名称。

某些其他值在内部使用时会得到特殊处理,不应依赖于它们。

参见 perlcall

注意:perl_call_sv() 形式已弃用

    I32  call_sv(SV *sv, volatile I32 flags)
DESTRUCTORFUNC_NOCONTEXT_t

perlguts 中描述。

DESTRUCTORFUNC_t

perlguts 中描述。

ENTER

回调的左括号。参见 "LEAVE"perlcall

    ENTER;
ENTER_with_name

"ENTER" 相同,但在启用调试时,它还会将给定的文字字符串与新作用域关联。

    ENTER_with_name("name");
eval_pv

告诉 Perl 以标量上下文eval 给定的字符串,并返回一个 SV* 结果。

注意:perl_eval_pv() 形式已弃用

    SV *  eval_pv(const char *p, I32 croak_on_error)
eval_sv

告诉 Perl eval SV 中的字符串。它支持与 call_sv 相同的标志,但明显地除外 G_EVAL。参见 perlcall

如果只需要 eval_sv() 执行由字符串指定的代码,但不捕获任何错误,则可以使用 G_RETHROW 标志。

注意:perl_eval_sv() 形式已弃用

    I32  eval_sv(SV *sv, I32 flags)
FREETMPS

回调中临时变量的右括号。参见 "SAVETMPS"perlcall

    FREETMPS;
G_DISCARD

perlcall 中描述。

G_EVAL

perlcall 中描述。

GIMME

已弃用! 计划从 Perl 的未来版本中删除 GIMME。不要在新代码中使用它;从现有代码中删除它。

GIMME_V 的向后兼容版本,它只能返回 G_SCALARG_LIST;在空上下文环境中,它返回 G_SCALAR。已弃用。请使用 GIMME_V 代替。

    U32  GIMME
GIMME_V

XSUB 编写者等效于 Perl 的 wantarray。分别返回 G_VOIDG_SCALARG_LIST,表示空、标量或列表上下文。有关使用示例,请参阅 perlcall

    U32  GIMME_V
G_KEEPERR

perlcall 中描述。

G_LIST

perlcall 中描述。

G_NOARGS

perlcall 中描述。

G_SCALAR

perlcall 中描述。

G_VOID

perlcall 中描述。

is_lvalue_sub

如果调用此函数的子程序在左值上下文中被调用,则返回非零值。否则返回 0。

    I32  is_lvalue_sub()
LEAVE

回调的结束括号。请参阅 "ENTER"perlcall

    LEAVE;
LEAVE_with_name

"LEAVE" 相同,但在启用调试时,它首先检查范围是否具有给定名称。name 必须是文字字符串。

    LEAVE_with_name("name");
MORTALDESTRUCTOR_SV

perlguts 中描述。

    MORTALDESTRUCTOR_SV(SV *coderef, SV *args)
mortal_destructor_sv

此函数安排在**当前语句结束时**调用 Perl 代码引用或 C 函数引用。

coderef 参数确定将调用的函数类型。如果它是 SvROK(),则假定它是对 CV 的引用,并将安排调用 coderef。如果它不是 SvROK(),则假定它是 SvIV(),它是一个 SvIOK(),其值为使用 PTR2INT() 创建的类型为 DESTRUCTORFUNC_t 的 C 函数的指针。无论哪种方式,args 参数都将作为参数提供给回调,尽管 Perl 和 C 模式之间的执行规则有所不同。通常,此函数仅直接用于 Perl 案例,而包装器 mortal_destructor_x() 用于 C 函数案例。

在 Perl 回调模式下运行时,args 参数可以为 NULL,在这种情况下,代码引用将不带任何参数调用,否则,如果它是 AV(SvTYPE(args) == SVt_PVAV),则 AV 的内容将用作代码引用的参数,如果它是任何其他类型,则 args SV 将作为单个参数提供给代码引用。

在 C 回调模式下运行时,args 参数将直接作为 void * 指针传递给 C 函数。不会对参数进行任何额外的处理,并且调用者有责任在必要时释放 args 参数。

请注意,当前语句结束当前伪块结束之间存在显著的时间差异。如果您正在寻找在当前伪块结束时触发函数的机制,您应该查看SAVEDESTRUCTORX()而不是此函数。

    void  mortal_destructor_sv(SV *coderef, SV *args)
MORTALDESTRUCTOR_X

perlguts 中描述。

    MORTALDESTRUCTOR_X(DESTRUCTORFUNC_t f, SV *sv)
PL_errgv

perlcall 中描述。

save_aelem
save_aelem_flags

这些都安排在封闭的伪块结束时恢复数组元素av[idx]的值。

save_aelem中,C**sptr>处的SV将被一个新的undef标量替换。该标量将继承来自原始**sptr的任何魔法,并且任何“set”魔法都将被处理。

save_aelem_flags中,SAVEf_KEEPOLDELEMflags中被设置会导致函数放弃所有这些:**sptr处的标量保持不变。如果SAVEf_KEEPOLDELEM未设置,则C**sptr>处的SV将被一个新的undef标量替换。该标量将继承来自原始**sptr的任何魔法。仅当SAVEf_SETMAGICflags中设置时,才会处理任何“set”魔法。

    void  save_aelem      (AV *av, SSize_t idx, SV **sptr)
    void  save_aelem_flags(AV *av, SSize_t idx, SV **sptr,
                           const U32 flags)
save_aptr

perlguts 中描述。

    void  save_aptr(AV **aptr)
save_ary

perlguts 中描述。

    AV *  save_ary(GV *gv)
SAVEBOOL

perlguts 中描述。

    SAVEBOOL(bool i)
SAVEDELETE

perlguts 中描述。

    SAVEDELETE(HV * hv, char * key, I32 length)
SAVEDESTRUCTOR

perlguts 中描述。

    SAVEDESTRUCTOR(DESTRUCTORFUNC_NOCONTEXT_t f, void *p)
SAVEDESTRUCTOR_X

perlguts 中描述。

    SAVEDESTRUCTOR_X(DESTRUCTORFUNC_t f, void *p)
SAVEFREEOP

perlguts 中描述。

    SAVEFREEOP(OP *op)
SAVEFREEPV

perlguts 中描述。

    SAVEFREEPV(char *pv)
SAVEFREERCPV

perlguts 中描述。

    SAVEFREERCPV(char *pv)
SAVEFREESV

perlguts 中描述。

    SAVEFREESV(SV* sv)
SAVEGENERICSV

perlguts 中描述。

    SAVEGENERICSV(char **psv)
save_hash

perlguts 中描述。

    HV *  save_hash(GV *gv)
save_helem
save_helem_flags

这些都安排在封闭的伪块结束时恢复哈希元素(以 Perl 术语)$hv{key}]的值。

save_helem中,C**sptr>处的SV将被一个新的undef标量替换。该标量将继承来自原始**sptr的任何魔法,并且任何“set”魔法都将被处理。

save_helem_flags 中,如果 flags 中设置了 SAVEf_KEEPOLDELEM,则该函数将放弃所有操作:**sptr 处的标量将保持不变。如果未设置 SAVEf_KEEPOLDELEM,则 C**sptr> 处的 SV 将被一个新的 undef 标量替换。该标量将继承来自原始 **sptr 的任何魔法。仅当 flags 中设置了 SAVEf_SETMAGIC 时,才会处理任何“设置”魔法。

    void  save_helem      (HV *hv, SV *key, SV **sptr)
    void  save_helem_flags(HV *hv, SV *key, SV **sptr,
                           const U32 flags)
save_hptr

perlguts 中描述。

    void  save_hptr(HV **hptr)
SAVEINT

perlguts 中描述。

    SAVEINT(int i)
save_item

perlguts 中描述。

    void  save_item(SV *item)
SAVEIV

perlguts 中描述。

    SAVEIV(IV i)
SAVEI8

perlguts 中描述。

    SAVEI8(I8 i)
SAVEI16

perlguts 中描述。

    SAVEI16(I16 i)
SAVEI32

perlguts 中描述。

    SAVEI32(I32 i)
SAVELONG

perlguts 中描述。

    SAVELONG(long i)
SAVEMORTALIZESV

perlguts 中描述。

    SAVEMORTALIZESV(SV* sv)
SAVEPPTR

perlguts 中描述。

    SAVEPPTR(char * p)
SAVERCPV

perlguts 中描述。

    SAVERCPV(char *pv)
save_scalar

perlguts 中描述。

    SV *  save_scalar(GV *gv)
SAVESPTR

perlguts 中描述。

    SAVESPTR(SV * s)
SAVESTACK_POS

perlguts 中描述。

    SAVESTACK_POS()
SAVESTRLEN

perlguts 中描述。

    SAVESTRLEN(STRLEN i)
save_svref

perlguts 中描述。

    SV *  save_svref(SV **sptr)
SAVETMPS

回调上的临时变量的左括号。参见 "FREETMPS"perlcall

    SAVETMPS;

强制转换

Atof

这是 "my_atof" 的同义词。

    NV  Atof(NN const char * const s)
cBOOL

强制转换为布尔值。当 Perl 能够在 pre-C99 编译器上编译时,(bool) 强制转换不一定能正确执行,因此创建了这个宏(并使其变得有些复杂以解决旧编译器中的错误)。现在,许多年过去了,C99 被使用,这不再需要,但为了向后兼容而保留。

    bool  cBOOL(bool expr)
INT2PTR

perlguts 中描述。

    type  INT2PTR(type, int value)
I_V

将 NV 强制转换为 IV,同时避免未定义的 C 行为

    IV  I_V(NV what)
I_32

将 NV 强制转换为 I32,同时避免未定义的 C 行为

    I32  I_32(NV what)
PTR2IV

perlguts 中描述。

    IV  PTR2IV(void * ptr)
PTR2nat

perlguts 中描述。

    IV  PTR2nat(void *)
PTR2NV

perlguts 中描述。

    NV  PTR2NV(void * ptr)
PTR2ul

perlguts 中描述。

    unsigned long  PTR2ul(void *)
PTR2UV

perlguts 中描述。

    UV  PTR2UV(void * ptr)
PTRV

perlguts 中描述。

U_V

将 NV 转换为 UV,同时避免 C 语言中的未定义行为

    UV  U_V(NV what)
U_32

将 NV 转换为 U32,同时避免 C 语言中的未定义行为

    U32  U_32(NV what)

字符大小写转换

Perl 使用“完整”的 Unicode 大小写映射。这意味着将单个字符转换为另一种大小写可能会导致生成多个字符的序列。例如,ß(拉丁小写字母锐音 S)的大写形式是两个字符的序列 SS。这带来了一些复杂性。0..255 范围内所有字符的小写形式都是单个字符,因此提供了 "toLOWER_L1"。但是,toUPPER_L1 不存在,因为它无法为所有合法输入返回有效结果。相反,"toUPPER_uvchr" 的 API 允许返回所有可能的合法结果。同样,这里没有实现其他受限于无法为所有可能的输入提供正确结果的功能。

toFOLD
toFOLD_A
toFOLD_utf8
toFOLD_utf8_safe
toFOLD_uvchr

这些函数都返回字符的折叠大小写。“折叠大小写”是 /i 模式匹配的内部大小写。如果字符 A 的折叠大小写与字符 B 的折叠大小写相同,则它们在不区分大小写的情况下匹配;否则它们不匹配。

这些形式的区别在于它们的操作域,以及输入是作为代码点(具有 cp 参数的那些形式)还是作为 UTF-8 字符串(其他形式)指定。在后一种情况下,要使用的代码点是 UTF-8 编码代码点缓冲区中的第一个代码点,由参数 p .. e - 1 分隔。

toFOLDtoFOLD_A 是彼此的同义词。它们返回任何 ASCII 范围代码点的折叠大小写。在这个范围内,折叠大小写与小写相同。所有其他输入都将保持不变。由于这些是宏,因此输入类型可以是任何整型类型,输出将占用与输入相同数量的位。

没有 toFOLD_L1toFOLD_LATIN1,因为 0..255 范围内某些代码点的折叠大小写超出了该范围或包含多个字符。请改用 toFOLD_uvchr

toFOLD_uvchr 返回任何 Unicode 代码点的折叠大小写。对于 ASCII 范围内的输入代码点,返回值与 toFOLD_A 的返回值相同。绝大多数 Unicode 代码点的折叠大小写与其本身相同。对于这些代码点以及超过合法 Unicode 最大值的代码点,此函数将返回未更改的输入代码点。它还会将结果的 UTF-8 存储到从 s 开始的缓冲区中,并将它的字节长度存储到 *lenp 中。调用者必须使 s 足够大,以容纳至少 UTF8_MAXBYTES_CASE+1 个字节,以避免可能的溢出。

注意:一个代码点的折叠大小写可能包含多个代码点。此函数的返回值仅为这些代码点中的第一个。整个折叠大小写将在s中返回。要确定结果是否超过单个代码点,您可以执行以下操作

uc = toFOLD_uvchr(cp, s, &len);
if (len > UTF8SKIP(s)) { is multiple code points }
else { is a single code point }

toFOLD_utf8toFOLD_utf8_safe是彼此的同义词。它们与toFOLD_uvchr唯一的区别在于,它们的源代码以 UTF-8 编码,而不是代码点。它作为从p开始的缓冲区传递,e指向其末尾之外的一个字节。p缓冲区可能包含多个代码点;但仅检查第一个代码点(直到e - 1)。如果输入字符的 UTF-8 编码以某种方式格式错误,程序可能会崩溃,或者函数可能会返回替换字符,具体取决于实现,并且可能会在将来的版本中发生变化。

    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)
toLOWER
toLOWER_A
toLOWER_LATIN1
toLOWER_LC
toLOWER_L1
toLOWER_utf8
toLOWER_utf8_safe
toLOWER_uvchr

这些函数都返回字符的小写形式。它们的区别在于它们的操作域,以及输入是作为代码点指定(带有cp参数的那些形式)还是作为 UTF-8 字符串(其他形式)。在后一种情况下,要使用的代码点是 UTF-8 编码代码点缓冲区中的第一个代码点,由参数p .. e - 1界定。

toLOWERtoLOWER_A是彼此的同义词。它们返回任何大写 ASCII 范围代码点的小写形式。所有其他输入都将保持不变。由于这些是宏,输入类型可以是任何整数类型,输出将占用与输入相同数量的位。

toLOWER_L1toLOWER_LATIN1 是彼此的同义词。它们在 ASCII 范围内的输入行为与 toLOWER 相同。但此外,它们将返回整个 0..255 范围内任何大写代码点的 lowercase,假设使用 Latin-1 编码(或在这些平台上使用 EBCDIC 等效编码)。

toLOWER_LC 根据当前 POSIX 本地化的规则返回输入代码点的 lowercase。输入代码点超出范围 0..255 将保持不变。

toLOWER_uvchr 返回任何 Unicode 代码点的 lowercase。返回值与输入代码点在 0..255 范围内的 toLOWER_L1 相同。绝大多数 Unicode 代码点的 lowercase 与代码点本身相同。对于这些代码点以及超过合法 Unicode 最大值的代码点,此函数将返回输入代码点不变。它还将结果的 UTF-8 存储到以 s 开头的缓冲区中,并将它的字节长度存储到 *lenp 中。调用者必须使 s 足够大,以容纳至少 UTF8_MAXBYTES_CASE+1 个字节,以避免可能的溢出。

注意:代码点的 lowercase 可能不止一个代码点。此函数的返回值仅是这些代码点中的第一个。整个 lowercase 将返回到 s 中。要确定结果是否超过一个代码点,您可以执行以下操作

uc = toLOWER_uvchr(cp, s, &len);
if (len > UTF8SKIP(s)) { is multiple code points }
else { is a single code point }

toLOWER_utf8toLOWER_utf8_safe 是彼此的同义词。它们与 toLOWER_uvchr 的唯一区别在于,它们的源代码以 UTF-8 编码,而不是代码点。它作为以 p 开头的缓冲区传递,e 指向其末尾之外的一个字节。p 缓冲区当然可能包含多个代码点;但只检查第一个代码点(直到 e - 1)。如果输入字符的 UTF-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)
toTITLE
toTITLE_A
toTITLE_utf8
toTITLE_utf8_safe
toTITLE_uvchr

这些函数都返回字符的首字母大写形式。它们的区别在于它们的操作域以及输入是作为码点(带有 cp 参数的那些形式)还是作为 UTF-8 字符串(其他形式)指定。在后一种情况下,要使用的码点是 UTF-8 编码码点缓冲区中的第一个码点,由参数 p .. e - 1 分隔。

toTITLEtoTITLE_A 是彼此的同义词。它们返回任何小写 ASCII 范围码点的首字母大写形式。在这个范围内,首字母大写形式与大写形式相同。所有其他输入都保持不变。由于这些是宏,输入类型可以是任何整数类型,输出将占用与输入相同的位数。

没有 toTITLE_L1toTITLE_LATIN1,因为 0..255 范围内某些码点的首字母大写形式超出了该范围或包含多个字符。请改用 toTITLE_uvchr

toTITLE_uvchr 返回任何 Unicode 码点的首字母大写形式。对于 ASCII 范围内的输入码点,返回值与 toTITLE_A 的返回值相同。绝大多数 Unicode 码点的首字母大写形式与其自身相同。对于这些码点以及超过合法 Unicode 最大值的码点,此函数将返回未更改的输入码点。它还会将结果的 UTF-8 存储到以 s 开头的缓冲区中,并将它的字节长度存储到 *lenp 中。调用者必须使 s 足够大,以容纳至少 UTF8_MAXBYTES_CASE+1 个字节,以避免可能的溢出。

注意:码点的首字母大写形式可能包含多个码点。此函数的返回值仅是这些码点中的第一个。整个首字母大写形式在 s 中返回。要确定结果是否包含多个码点,您可以执行以下操作

uc = toTITLE_uvchr(cp, s, &len);
if (len > UTF8SKIP(s)) { is multiple code points }
else { is a single code point }

toTITLE_utf8toTITLE_utf8_safe 是彼此的同义词。这些函数与 toTITLE_uvchr 之间的唯一区别是,这些函数的源代码以 UTF-8 编码,而不是码点。它作为以 p 开头的缓冲区传递,e 指向其末尾之外的一个字节。p 缓冲区可能包含多个码点;但只检查第一个码点(直到 e - 1)。如果输入字符的 UTF-8 编码以某种方式格式错误,程序可能会崩溃,或者函数可能会返回替换字符,具体取决于实现,并且可能会在将来的版本中发生更改。

    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)
toUPPER
toUPPER_A
toUPPER_utf8
toUPPER_utf8_safe
toUPPER_uvchr

这些函数都返回字符的大写形式。它们的区别在于它们的操作域,以及输入是作为码点(带有 cp 参数的那些形式)还是作为 UTF-8 字符串(其他形式)指定。在后一种情况下,要使用的码点是 UTF-8 编码码点缓冲区中的第一个码点,由参数 p .. e - 1 分隔。

toUPPERtoUPPER_A 是彼此的同义词。它们返回任何小写 ASCII 范围码点的大写形式。所有其他输入都保持不变。由于这些是宏,因此输入类型可以是任何整数类型,输出将占用与输入相同数量的位。

没有 toUPPER_L1toUPPER_LATIN1,因为 0..255 范围内某些码点的大写形式超出了该范围或包含多个字符。请改用 toUPPER_uvchr

toUPPER_uvchr 返回任何 Unicode 码点的大写形式。对于 ASCII 范围内的输入码点,返回值与 toUPPER_A 的返回值相同。绝大多数 Unicode 码点的大写形式与其自身相同。对于这些码点以及超过合法 Unicode 最大值的码点,此函数将返回未更改的输入码点。此外,它还会将结果的 UTF-8 存储到从 s 开始的缓冲区中,并将它的字节长度存储到 *lenp 中。调用者必须使 s 足够大,以容纳至少 UTF8_MAXBYTES_CASE+1 个字节,以避免可能的溢出。

注意:码点的大写形式可能包含多个码点。此函数的返回值仅是这些码点中的第一个。整个大写形式将返回到 s 中。要确定结果是否包含多个码点,您可以执行以下操作

uc = toUPPER_uvchr(cp, s, &len);
if (len > UTF8SKIP(s)) { is multiple code points }
else { is a single code point }

toUPPER_utf8toUPPER_utf8_safe 是彼此的同义词。它们与 toUPPER_uvchr 的唯一区别在于它们的源代码是 UTF-8 编码的,而不是码点。它作为从 p 开始的缓冲区传递,e 指向其末尾之外的一个字节。p 缓冲区当然可能包含多个码点;但只检查第一个码点(直到 e - 1)。如果输入字符的 UTF-8 编码以某种方式格式错误,程序可能会崩溃,或者函数可能会返回替换字符,具体取决于实现,并且可能会在将来的版本中发生更改。

    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)

字符分类

本节介绍用于将字符分类为不同类型的函数(实际上是宏),例如标点符号与字母等。大多数函数类似于正则表达式字符类。(参见 "perlrecharclass 中的 POSIX 字符类"。)每个类都有几种变体。(并非所有宏都具有所有变体;下面列出了每个项目中有效的变体。)use bytes 不会影响任何变体,只有名称中包含 LC 的变体才会受当前区域设置的影响。

基本函数(例如 isALPHA())接受任何有符号或无符号值,将其视为代码点,并返回一个布尔值,表示该值所代表的字符是否为(或在非 ASCII 平台上,是否对应于)平台、Unicode 和 Perl 规则定义的命名类中的 ASCII 字符。如果输入是超出八位字节范围的数字,则返回 FALSE。

变体 isFOO_A(例如 isALPHA_A())与没有后缀 "_A" 的基本函数相同。此变体通过其名称强调只有 ASCII 范围内的字符才能返回 TRUE。

变体 isFOO_L1 将 Latin-1(或 EBCDIC 等效字符集)字符集强加于平台。也就是说,ASCII 代码点不受影响,因为 ASCII 是 Latin-1 的子集。但非 ASCII 代码点将被视为 Latin-1 字符。例如,isWORDCHAR_L1() 在调用时使用代码点 0xDF 将返回 true,因为 0xDF 在 ASCII 和 EBCDIC 中都是一个单词字符(尽管它们在每个字符集中代表不同的字符)。如果输入是超出八位字节范围的数字,则返回 FALSE。(Perl 的文档使用 Latin-1 的口语定义,包括所有低于 256 的代码点。)

变体 isFOO_uvchrisFOO_L1 变体完全相同,适用于低于 256 的输入,但如果代码点大于 255,则使用 Unicode 规则来确定它是否属于该字符类。例如,isWORDCHAR_uvchr(0x100) 返回 TRUE,因为 0x100 在 Unicode 中是 LATIN CAPITAL LETTER A WITH MACRON,并且是一个单词字符。

变体 isFOO_utf8isFOO_utf8_safeisFOO_uvchr 相似,但用于 UTF-8 编码的字符串。这两种形式是同一事物的不同名称。对其中任何一个的每次调用都会对从 p 开始的字符串的第一个字符进行分类。第二个参数 e 指向字符串中第一个字符之后的任何位置,直到整个字符串结束后的一个字节。尽管两种变体相同,但其中一个名称中的后缀 _safe 强调它不会尝试读取超出 e - 1 的范围,前提是约束 s < e 为真(这在 -DDEBUGGING 构建中得到断言)。如果输入字符的 UTF-8 格式在某种程度上存在错误,程序可能会崩溃,或者函数可能会返回 FALSE,这取决于实现的决定,并且可能会在将来的版本中发生变化。

变体 isFOO_LCisFOO_AisFOO_L1 变体类似,但结果基于当前区域设置,名称中的 LC 代表区域设置。如果 Perl 可以确定当前区域设置是 UTF-8 区域设置,它将使用已发布的 Unicode 规则;否则,它将使用提供命名分类的 C 库函数。例如,当不在 UTF-8 区域设置中时,isDIGIT_LC() 返回调用 isdigit() 的结果。如果输入不能放入一个字节中,则始终返回 FALSE。在某些 C 库函数已知有缺陷的平台上,Perl 会更改其结果以遵循 POSIX 标准的规则。

变体 isFOO_LC_uvchr 对小于 256 的输入的行为与 isFOO_LC 完全相同,但对于更大的输入,它返回代码点的 Unicode 分类。

变体 isFOO_LC_utf8isFOO_LC_utf8_safeisFOO_LC_uvchr 类似,但用于 UTF-8 编码的字符串。这两种形式是同一事物的不同名称。对其中任何一个的每次调用都会对从 p 开始的字符串的第一个字符进行分类。第二个参数 e 指向字符串中第一个字符之后的任何位置,直到整个字符串末尾的下一个字节。尽管这两种变体相同,但名称中的 _safe 后缀强调它不会尝试读取超出 e - 1 的范围,前提是约束 s < e 为真(这在 -DDEBUGGING 构建中得到断言)。如果输入字符的 UTF-8 以某种方式格式错误,程序可能会崩溃,或者函数可能会返回 FALSE,这取决于实现的决定,并且可能会在将来的版本中发生变化。

isALNUM
isALNUM_A
isALNUM_LC
isALNUM_LC_uvchr

这些都是它们各自命名的 "isWORDCHAR" 变体的同义词。

它们是为了向后兼容而提供的,即使单词字符包含比标准 C 语言中字母数字的含义更多的内容。要获得 C 语言定义,请使用相应的 "isALPHANUMERIC" 变体。

    bool  isALNUM(UV ch)
isALNUMC
isALNUMC_A
isALNUMC_LC
isALNUMC_LC_uvchr
isALNUMC_L1

这些是 "isALPHANUMERIC" 的不推荐使用的向后兼容宏。也就是说,每个宏都返回一个布尔值,指示指定的字符是否为 [A-Za-z0-9] 中的一个,类似于 m/[[:alnum:]]/

名称中的 C 后缀表示它们对应于 C 语言的 isalnum(3)

    bool  isALNUMC(UV ch)
isALPHA
isALPHA_A
isALPHA_LC
isALPHA_LC_utf8_safe
isALPHA_LC_uvchr
isALPHA_L1
isALPHA_utf8
isALPHA_utf8_safe
isALPHA_uvchr

返回一个布尔值,指示指定的输入是否为 [A-Za-z] 中的一个,类似于 m/[[:alpha:]]/。有关变体的说明,请参见 本节顶部

    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)
isALPHANUMERIC
isALPHANUMERIC_A
isALPHANUMERIC_LC
isALPHANUMERIC_LC_utf8_safe
isALPHANUMERIC_LC_uvchr
isALPHANUMERIC_L1
isALPHANUMERIC_utf8
isALPHANUMERIC_utf8_safe
isALPHANUMERIC_uvchr

返回一个布尔值,指示指定的字符是否为 [A-Za-z0-9] 中的一个,类似于 m/[[:alnum:]]/。有关变体的说明,请参见 本节顶部

    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)
isASCII
isASCII_A
isASCII_LC
isASCII_LC_utf8_safe
isASCII_LC_uvchr
isASCII_L1
isASCII_utf8
isASCII_utf8_safe
isASCII_uvchr

返回一个布尔值,指示指定字符是否为 ASCII 字符集中的 128 个字符之一,类似于 m/[[:ascii:]]/。在非 ASCII 平台上,当此字符对应于 ASCII 字符时,它返回 TRUE。变体 isASCII_A()isASCII_L1()isASCII() 相同。有关变体的说明,请参见 本节顶部。但是,请注意,某些平台没有 C 库例程 isascii()。在这些情况下,名称包含 LC 的变体与不包含 LC 的相应变体相同。

另外请注意,由于所有 ASCII 字符都是 UTF-8 不变的(意味着它们无论是在 UTF-8 中编码还是未编码,都具有完全相同的表示形式(始终为单个字节)),因此 isASCII 在使用任何字符串中的任何字节(在 UTF-8 中编码或未编码)调用时将给出正确的结果。类似地,isASCII_utf8isASCII_utf8_safe 将在任何字符串(在 UTF-8 中编码或未编码)上正常工作。

    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)
isBLANK
isBLANK_A
isBLANK_LC
isBLANK_LC_utf8_safe
isBLANK_LC_uvchr
isBLANK_L1
isBLANK_utf8
isBLANK_utf8_safe
isBLANK_uvchr

返回一个布尔值,指示指定字符是否为被认为是空格的字符,类似于 m/[[:blank:]]/。有关变体的说明,请参见 本节顶部。但是,请注意,某些平台没有 C 库例程 isblank()。在这些情况下,名称包含 LC 的变体与不包含 LC 的相应变体相同。

    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)
isCNTRL
isCNTRL_A
isCNTRL_LC
isCNTRL_LC_utf8_safe
isCNTRL_LC_uvchr
isCNTRL_L1
isCNTRL_utf8
isCNTRL_utf8_safe
isCNTRL_uvchr

返回一个布尔值,指示指定字符是否为控制字符,类似于 m/[[:cntrl:]]/。有关变体的说明,请参见 本节顶部。在 EBCDIC 平台上,您几乎总是希望使用 isCNTRL_L1 变体。

    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)
isDIGIT
isDIGIT_A
isDIGIT_LC
isDIGIT_LC_utf8_safe
isDIGIT_LC_uvchr
isDIGIT_L1
isDIGIT_utf8
isDIGIT_utf8_safe
isDIGIT_uvchr

返回一个布尔值,指示指定字符是否为数字,类似于 m/[[:digit:]]/。变体 isDIGIT_AisDIGIT_L1isDIGIT 相同。有关变体的解释,请参见 本节顶部

    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)
isGRAPH
isGRAPH_A
isGRAPH_LC
isGRAPH_LC_utf8_safe
isGRAPH_LC_uvchr
isGRAPH_L1
isGRAPH_utf8
isGRAPH_utf8_safe
isGRAPH_uvchr

返回一个布尔值,指示指定字符是否为图形字符,类似于 m/[[:graph:]]/。有关变体的解释,请参见 本节顶部

    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)
isIDCONT
isIDCONT_A
isIDCONT_LC
isIDCONT_LC_utf8_safe
isIDCONT_LC_uvchr
isIDCONT_L1
isIDCONT_utf8
isIDCONT_utf8_safe
isIDCONT_uvchr

返回一个布尔值,指示指定字符是否可以作为标识符的第二个或后续字符。这与官方 Unicode 属性 XID_Continue 非常接近,但并不完全相同。区别在于,只有当输入字符也匹配 "isWORDCHAR" 时,此函数才会返回 true。有关变体的解释,请参见 本节顶部

    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)
isIDFIRST
isIDFIRST_A
isIDFIRST_LC
isIDFIRST_LC_utf8_safe
isIDFIRST_LC_uvchr
isIDFIRST_L1
isIDFIRST_utf8
isIDFIRST_utf8_safe
isIDFIRST_uvchr

返回一个布尔值,指示指定字符是否可以作为标识符的第一个字符。这与官方 Unicode 属性 XID_Start 非常接近,但并不完全相同。区别在于,只有当输入字符也匹配 "isWORDCHAR" 时,此函数才会返回 true。有关变体的解释,请参见 本节顶部

    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)
isLOWER
isLOWER_A
isLOWER_LC
isLOWER_LC_utf8_safe
isLOWER_LC_uvchr
isLOWER_L1
isLOWER_utf8
isLOWER_utf8_safe
isLOWER_uvchr

返回一个布尔值,指示指定字符是否为小写字符,类似于 m/[[:lower:]]/。有关变体的解释,请参见 本节顶部

    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)
isOCTAL
isOCTAL_A
isOCTAL_L1

返回一个布尔值,指示指定字符是否为八进制数字,[0-7]。只有两个变体 isOCTAL_AisOCTAL_L1;每个都与 isOCTAL 相同。

    bool  isOCTAL(UV ch)
isPRINT
isPRINT_A
isPRINT_LC
isPRINT_LC_utf8_safe
isPRINT_LC_uvchr
isPRINT_L1
isPRINT_utf8
isPRINT_utf8_safe
isPRINT_uvchr

返回一个布尔值,指示指定字符是否为可打印字符,类似于 m/[[:print:]]/。有关变体的解释,请参见 本节顶部

    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)
isPSXSPC
isPSXSPC_A
isPSXSPC_LC
isPSXSPC_LC_utf8_safe
isPSXSPC_LC_uvchr
isPSXSPC_L1
isPSXSPC_utf8
isPSXSPC_utf8_safe
isPSXSPC_uvchr

(Posix Space 的简写) 从 5.18 版本开始,此宏的所有形式都与其对应的 isSPACE() 宏相同。此宏的区域设置形式在其所有 Perl 版本中与其对应的 isSPACE() 形式相同。在 5.18 之前的版本中,非区域设置形式与其 isSPACE() 形式的不同之处仅在于 isSPACE() 形式不匹配垂直制表符,而 isPSXSPC() 形式匹配。否则它们是相同的。因此,此宏类似于正则表达式中 m/[[:space:]]/ 的匹配结果。有关变体的解释,请参见 本节顶部

    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)
isPUNCT
isPUNCT_A
isPUNCT_LC
isPUNCT_LC_utf8_safe
isPUNCT_LC_uvchr
isPUNCT_L1
isPUNCT_utf8
isPUNCT_utf8_safe
isPUNCT_uvchr

返回一个布尔值,指示指定字符是否为标点符号字符,类似于 m/[[:punct:]]/。请注意,标点符号的定义并不像人们期望的那样简单。有关详细信息,请参见 "perlrecharclass 中的 POSIX 字符类"。有关变体的解释,请参见 本节顶部

    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)
isSPACE
isSPACE_A
isSPACE_LC
isSPACE_LC_utf8_safe
isSPACE_LC_uvchr
isSPACE_L1
isSPACE_utf8
isSPACE_utf8_safe
isSPACE_uvchr

返回一个布尔值,指示指定字符是否为空格字符。这类似于正则表达式中m/\s/匹配的内容。从 Perl 5.18 开始,它也匹配m/[[:space:]]/匹配的内容。在 5.18 之前,只有此宏的区域设置形式(名称中包含LC 的形式)与m/[[:space:]]/完全匹配。在这些版本中,唯一区别在于非区域设置变体中,isSPACE()不匹配垂直制表符。(有关在所有版本中匹配垂直制表符的宏,请参见"isPSXSPC"。)有关变体的说明,请参见本节顶部

    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)
isUPPER
isUPPER_A
isUPPER_LC
isUPPER_LC_utf8_safe
isUPPER_LC_uvchr
isUPPER_L1
isUPPER_utf8
isUPPER_utf8_safe
isUPPER_uvchr

返回一个布尔值,指示指定字符是否为大写字符,类似于m/[[:upper:]]/。有关变体的说明,请参见本节顶部

    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)
isWORDCHAR
isWORDCHAR_A
isWORDCHAR_LC
isWORDCHAR_LC_utf8_safe
isWORDCHAR_LC_uvchr
isWORDCHAR_L1
isWORDCHAR_utf8
isWORDCHAR_utf8_safe
isWORDCHAR_uvchr

返回一个布尔值,指示指定字符是否为单词字符,类似于正则表达式中m/\w/m/[[:word:]]/匹配的内容。单词字符是字母字符、十进制数字、连接标点符号(如下划线)或附加到其中一个的“标记”字符(如某种重音)。

有关变体的说明,请参见本节顶部

isWORDCHAR_AisWORDCHAR_L1isWORDCHAR_uvchrisWORDCHAR_LCisWORDCHAR_LC_uvchrisWORDCHAR_LC_utf8isWORDCHAR_LC_utf8_safe 也如那里所述,但此外还包括平台的本机下划线。

    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)
isXDIGIT
isXDIGIT_A
isXDIGIT_LC
isXDIGIT_LC_utf8_safe
isXDIGIT_LC_uvchr
isXDIGIT_L1
isXDIGIT_utf8
isXDIGIT_utf8_safe
isXDIGIT_uvchr

返回一个布尔值,指示指定字符是否为十六进制数字。在 ASCII 范围内,这些是 [0-9A-Fa-f]。变体 isXDIGIT_A()isXDIGIT_L1()isXDIGIT() 相同。有关变体的说明,请参见本节顶部

    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)

编译器和预处理器信息

CPPLAST

此符号旨在与 CPPRUN 一起使用,方式与符号 CPPMINUSCPPSTDIN 一起使用的方式相同。它包含 "-" 或 ""。

CPPMINUS

此符号包含将对标准输入调用 C 预处理器并生成到标准输出的字符串的第二部分。如果 CPPSTDIN 需要减号来指定标准输入,则此符号的值将为 "-",否则值为 ""。

CPPRUN

此符号包含将对标准输入调用 C 预处理器并生成到标准输出的字符串。它需要以 CPPLAST 结尾,在所有其他预处理器标志都已指定之后。与 CPPSTDIN 的主要区别在于,此程序永远不会是指向 shell 包装器的指针,即如果用户没有直接使用预处理器,它将为空。请注意,它可能与用于编译 C 程序的预处理器不同。

CPPSTDIN

此符号包含将调用标准输入上的 C 预处理器并生成到标准输出的字符串的第一部分。典型的值为“cc -E”或“/lib/cpp”,但它也可以调用包装器。参见 "CPPRUN"

HASATTRIBUTE_ALWAYS_INLINE

我们是否可以处理 GCC 属性,用于始终内联的函数。

HASATTRIBUTE_DEPRECATED

我们是否可以处理 GCC 属性,用于标记已弃用的 API

HASATTRIBUTE_FORMAT

我们是否可以处理 GCC 属性,用于检查 printf 风格的格式

HASATTRIBUTE_NONNULL

我们是否可以处理 GCC 属性,用于非空函数参数。

HASATTRIBUTE_NORETURN

我们是否可以处理 GCC 属性,用于不返回的函数

HASATTRIBUTE_PURE

我们是否可以处理 GCC 属性,用于纯函数

HASATTRIBUTE_UNUSED

我们是否可以处理 GCC 属性,用于未使用的变量和参数

HASATTRIBUTE_VISIBILITY

我们是否可以处理 GCC 属性,用于应该具有不同可见性的函数。

HASATTRIBUTE_WARN_UNUSED_RESULT

我们是否可以处理 GCC 属性,用于警告未使用的结果

HAS_BUILTIN_ADD_OVERFLOW

如果定义了此符号,则表示编译器支持 __builtin_add_overflow 用于添加带有溢出检查的整数。

HAS_BUILTIN_CHOOSE_EXPR

我们是否可以处理 GCC 内置函数,用于编译时三元运算符式表达式

HAS_BUILTIN_EXPECT

我们是否可以处理 GCC 内置函数,用于告知某些值更有可能

HAS_BUILTIN_MUL_OVERFLOW

如果定义了此符号,则表示编译器支持 __builtin_mul_overflow 用于将整数相乘并进行溢出检查。

HAS_BUILTIN_SUB_OVERFLOW

如果定义了此符号,则表示编译器支持 __builtin_sub_overflow 用于将整数相减并进行溢出检查。

HAS_C99_VARIADIC_MACROS

如果定义,编译器支持 C99 可变参数宏。

HAS_STATIC_INLINE

如果定义了此符号,则表示 C 编译器支持 C99 风格的静态内联。也就是说,该函数不能从另一个翻译单元调用。

MEM_ALIGNBYTES

此符号包含对齐双精度浮点数或长双精度浮点数(如果适用)所需的字节数。常见值为 2、4 和 8。默认值为 8,以确保安全。对于交叉编译或多架构支持,Configure 将设置最小值为 8。

PERL_STATIC_INLINE

此符号提供了对静态内联函数使用最佳猜测的咒语。如果定义了 HAS_STATIC_INLINE,它将给出 C99 风格的内联。如果未定义 HAS_STATIC_INLINE,它将给出普通的 'static'。它将始终定义为提供静态链接的内容。可能性包括

static inline       (c99)
static __inline__   (gcc -ansi)
static __inline     (MSVC)
static _inline      (older MSVC)
static              (c89 compilers)
PERL_THREAD_LOCAL

如果定义了此符号,它将给出线程局部存储的链接规范。例如,对于 C11 编译器,这将是 _Thread_local。注意,一些编译器对它们被告知解析的 C 语言标准很敏感。例如,suncc 默认使用 C11,因此我们的探测将报告可以使用 _Thread_local。但是,如果稍后将 -std=c99 添加到编译器标志中,则 _Thread_local 将成为语法错误。因此,在探测和使用之间保持这些标志一致非常重要。

U32_ALIGNMENT_REQUIRED

如果定义了此符号,则表示您必须通过与 U32 对齐的指针访问字符数据。

编译器指令

__ASSERT_

这是一个辅助宏,用于避免预处理器问题,除非在 DEBUGGING 下,否则它将被替换为空,它将扩展为其参数的断言,后跟一个逗号(因此是逗号运算符)。如果我们只是使用一个直接的 assert(),那么在不使用 DEBUGGING 时,我们将得到一个逗号,前面什么也没有。

    __ASSERT_(bool expr)
ASSUME

ASSUME 类似于 assert(),但在发布版本中具有优势。它向编译器提供有关函数调用自由表达式中事实陈述的提示,从而允许编译器生成更好的机器代码。在调试版本中,ASSUME(x) 等同于 assert(x)ASSUME(0) 表示控制路径不可达。在 for 循环中,ASSUME 可用于提示循环至少运行 X 次。ASSUME 基于 MSVC 的 __assume 内在函数,有关更多详细信息,请参阅其文档。

    ASSUME(bool expr)
dNOOP

不声明任何内容;通常用作占位符,以替换以前声明某些内容的内容。适用于需要在任何代码之前进行声明的编译器。

    dNOOP;
END_EXTERN_C

在不使用 C++ 编译时,扩展为空。否则,它将结束由 "START_EXTERN_C" 开始的代码部分。

    END_EXTERN_C
EXTERN_C

在不使用 C++ 编译时,扩展为空。否则,它用于函数声明中,以指示函数应具有外部 C 链接。对于几乎所有编译到 perl 的具有外部链接的函数,都需要这样做。通常,您可以使用 "START_EXTERN_C" ... "END_EXTERN_C" 块包围所有需要此链接的代码。

示例用法

EXTERN_C int flock(int fd, int op);
LIKELY

返回未更改的输入,但同时它向编译器提供分支预测提示,表明此条件很可能为真。

    LIKELY(bool expr)
NOOP

不执行任何操作;通常用作占位符,以替换以前执行某些操作的内容。

    NOOP;
PERL_UNUSED_ARG

这用于抑制编译器警告,即函数的参数未被使用。例如,当参数在某些配置条件下需要,而在其他条件下不需要时,就会出现这种情况,因此 C 预处理器条件编译会导致它仅在某些情况下被使用。

    PERL_UNUSED_ARG(void x);
PERL_UNUSED_CONTEXT

这用于抑制编译器警告,即函数的线程上下文参数未被使用。例如,当 C 预处理器条件编译导致它仅在某些情况下被使用时,就会出现这种情况。

    PERL_UNUSED_CONTEXT;
PERL_UNUSED_DECL

告诉编译器,它之前的函数原型中的参数不一定会在函数中使用。并非所有编译器都理解这一点,因此只有在无法方便地使用"PERL_UNUSED_ARG"的情况下才应使用它。

示例用法

    Signal_t
    Perl_perly_sighandler(int sig, Siginfo_t *sip PERL_UNUSED_DECL,
                          void *uap PERL_UNUSED_DECL, bool safe)
PERL_UNUSED_RESULT

此宏指示丢弃其内部函数调用的返回值,例如:

PERL_UNUSED_RESULT(foo(a, b))

这样做的主要原因是gcc -Wunused-result-Wall的一部分)和__attribute__((warn_unused_result))的组合无法通过强制转换为void来消除。当系统头文件使用该属性时,会导致问题。

谨慎使用PERL_UNUSED_RESULT,因为通常警告是有原因的:您可能会丢失成功/失败信息,或泄漏资源,或资源发生变化。

但有时您只想忽略返回值,例如,在即将结束的代码路径上,或在“尽力而为”的尝试中,或在没有好的方法来处理失败的情况中。

有时PERL_UNUSED_RESULT可能不是最自然的方式:另一种可能性是您可以捕获返回值并对它使用"PERL_UNUSED_VAR"

    PERL_UNUSED_RESULT(void x)
PERL_UNUSED_VAR

这用于抑制编译器关于变量x未使用的警告。例如,当 C 预处理器条件编译导致它仅在某些情况下使用时,就会出现这种情况。

    PERL_UNUSED_VAR(void x);
START_EXTERN_C

在不使用 C++ 编译时,扩展为空。否则,开始一段代码,其中每个函数将有效地应用"EXTERN_C",即具有外部 C 链接。该部分以"END_EXTERN_C"结束。

    START_EXTERN_C
STATIC

perlguts 中描述。

STMT_END
STMT_START

这些允许宏中的一系列语句用作单个语句,例如

if (x) STMT_START { ... } STMT_END else ...

请注意,您无法从该结构中返回值,也无法将其用作逗号运算符的操作数。这些限制了它的实用性。

但是,可以通过构建 API 来返回一个值,以便传递一个指针,宏取消引用该指针以设置返回值。如果该值可以是各种类型中的任何一个,具体取决于上下文,则可以通过添加返回值的类型作为额外的伴随参数来处理某些情况下的这种情况

#define foo(param, type)  STMT_START {
                             type * param; *param = do_calc; ...
                          } STMT_END

这可能很麻烦,因此请考虑改用 C 语言的static inline函数。

如果您确实使用了这种结构,很容易忘记它是一个宏而不是一个函数,因此会陷入陷阱,这些陷阱可能直到某天有人编写了包含与您在此处选择的名称冲突的名称的代码,或者用一个参数调用它,该参数是一个具有副作用的表达式,而您没有考虑这些副作用的后果。有关如何避免这些问题的说明,请参阅"perlhacktips 中的编写更安全的宏"

UNLIKELY

返回未更改的输入,但同时向编译器提供一个分支预测提示,表明此条件可能为假。

    UNLIKELY(bool expr)

编译时作用域钩子

BhkDISABLE

注意:BhkDISABLE 是 **实验性的**,可能会在未经通知的情况下更改或删除。

通过清除相应的标志,临时禁用此 BHK 结构中的条目。which 是一个预处理器标记,指示要禁用的条目。

    void  BhkDISABLE(BHK *hk, token which)
BhkENABLE

注意:BhkENABLE 是 **实验性的**,可能会在未经通知的情况下更改或删除。

通过设置相应的标志,重新启用此 BHK 结构中的条目。which 是一个预处理器标记,指示要启用的条目。如果条目不包含有效指针,这将断言(在 -DDEBUGGING 下)。

    void  BhkENABLE(BHK *hk, token which)
BhkENTRY_set

注意:BhkENTRY_set 是 **实验性的**,可能会在未经通知的情况下更改或删除。

在 BHK 结构中设置一个条目,并设置标志以指示它有效。which 是一个预处理标记,指示要设置的条目。ptr 的类型取决于条目。

    void  BhkENTRY_set(BHK *hk, token which, void *ptr)
blockhook_register

注意:blockhook_register 是 **实验性的**,可能会在未经通知的情况下更改或删除。

注册一组钩子,以便在 Perl 词法作用域在编译时发生变化时调用。请参阅 "perlguts 中的编译时作用域钩子"

注意:blockhook_register 必须显式地调用为 Perl_blockhook_register,并带有 aTHX_ 参数。

    void  Perl_blockhook_register(pTHX_ BHK *hk)

并发

aTHX

perlguts 中描述。

aTHX_

perlguts 中描述。

CPERLscope

已弃用! 计划从 Perl 的未来版本中删除 CPERLscope。不要在新的代码中使用它;从现有代码中删除它。

现在是一个空操作。

    void  CPERLscope(void x)
dTHR

perlguts 中描述。

dTHX

perlguts 中描述。

dTHXa

在带线程的 Perl 中,将 pTHX 设置为 a;在不带线程的 Perl 中,什么也不做。

dTHXoa

现在是 "dTHXa" 的同义词。

dVAR

现在是 dNOOP 的同义词:声明为空

GETENV_PRESERVES_OTHER_THREAD

如果定义了此符号,则表示 getenv 系统调用不会清除其他线程中 getenv() 的静态缓冲区。典型的 getenv() 实现将返回指向 **environ** 中适当位置的指针。但有些可能会将它们复制到 getenv() 中的静态缓冲区。如果该缓冲区存在每个线程的实例,或者返回值指向 **environ**,那么多个读取器/1 个写入器互斥锁将起作用;否则需要一个独占锁定互斥锁来防止竞争。

HAS_PTHREAD_ATFORK

如果定义了此符号,则表示 pthread_atfork 例程可用于设置 fork 处理程序。

HAS_PTHREAD_ATTR_SETSCOPE

如果定义了此符号,则表示 pthread_attr_setscope 系统调用可用于设置线程属性对象的竞争范围属性。

HAS_PTHREAD_YIELD

如果定义了此符号,则表示 pthread_yield 例程可用于让出当前线程的执行。sched_yieldpthread_yield 更可取。

HAS_SCHED_YIELD

如果定义了此符号,则表示 sched_yield 例程可用于让出当前线程的执行。sched_yieldpthread_yield 更可取。

I_MACH_CTHREADS

如果定义了此符号,则表示 C 程序应包含 mach/cthreads.h

    #ifdef I_MACH_CTHREADS
        #include <mach_cthreads.h>
    #endif
I_PTHREAD

如果定义了此符号,则表示 C 程序应包含 pthread.h

    #ifdef I_PTHREAD
        #include <pthread.h>
    #endif
MULTIPLICITY

如果定义了此符号,则表示 Perl 应构建为使用多重性。

OLD_PTHREAD_CREATE_JOINABLE

如果定义了此符号,则表示如何以可连接(也称为未分离)状态创建 pthread。注意:如果 pthread.h 已经定义了 PTHREAD_CREATE_JOINABLE(常量的最新版本),则不会定义。如果定义了,则已知值为 PTHREAD_CREATE_UNDETACHED__UNDETACHED

OLD_PTHREADS_API

如果定义了此符号,则表示 Perl 应构建为使用旧的草案 POSIX 线程 API

PERL_IMPLICIT_CONTEXT

perlguts 中描述。

PERL_NO_GET_CONTEXT

perlguts 中描述。

pTHX

perlguts 中描述。

pTHX_

perlguts 中描述。

SCHED_YIELD

此符号定义了让当前线程执行让步的方式。已知的方式包括 sched_yieldpthread_yield 以及带有 NULLpthread_yield

COP 和提示哈希

cop_fetch_label

注意:cop_fetch_label实验性的,可能会在不通知的情况下更改或删除。

返回附加到 cop 的标签,并将它的长度(以字节为单位)存储到 *len 中。返回后,*flags 将被设置为 SVf_UTF8 或 0。

或者,使用宏 "CopLABEL_len_flags";或者,如果您不需要知道标签是否为 UTF-8,则使用宏 "CopLABEL_len";或者,如果您另外不需要知道长度,则使用 "CopLABEL"

    const char *  cop_fetch_label(COP * const cop, STRLEN *len,
                                  U32 *flags)
CopFILE

返回与 COP c 关联的文件名。

    const char *  CopFILE(const COP * c)
CopFILEAV

返回与 COP c 关联的 AV,如果不存在则创建它。

    AV *  CopFILEAV(const COP * c)
CopFILEAVn

返回与 COP c 关联的 AV,如果不存在则返回 NULL。

    AV *  CopFILEAVn(const COP * c)
CopFILE_copy

有效地将 cop 文件名从一个 COP 复制到另一个 COP。封装了在线程下或非线程下执行引用计数复制所需的逻辑。

    void  CopFILE_copy(COP * dst, COP * src)
CopFILE_free

释放 cop 中的文件数据。在幕后,这是一个引用计数操作。

    void  CopFILE_free(COP * c)
CopFILEGV

返回与 COP c 关联的 GV。

    GV *  CopFILEGV(const COP * c)
CopFILEGV_set

仅在非线程化的 Perl 上可用。使 pv 成为与 COP c 关联的文件名。

    void  CopFILEGV_set(COP *c, GV *gv)
CopFILE_LEN

返回与 COP c 关联的文件的长度。

    const char *  CopFILE_LEN(const COP * c)
CopFILE_set

使 pv 成为与 COP c 关联的文件名。

    void  CopFILE_set(COP * c, const char * pv)
CopFILE_setn

使 pv 成为与 COP c 关联的文件名。

    void  CopFILE_setn(COP * c, const char * pv, STRLEN len)
CopFILESV

返回与 COP c 关联的 SV。

    SV *  CopFILESV(const COP * c)
cophh_copy

注意:cophh_copy 处于实验阶段,可能会在未经通知的情况下更改或删除。

创建并返回 cop 提示哈希 cophh 的完整副本。

    COPHH *  cophh_copy(COPHH *cophh)
cophh_delete_pv
cophh_delete_pvn
cophh_delete_pvs
cophh_delete_sv

注意:所有这些形式都处于实验阶段,可能会在未经通知的情况下更改或删除。

这些函数从 cop 提示哈希 cophh 中删除一个键及其关联的值,并返回修改后的哈希。返回的哈希指针通常与传入的哈希指针不同。输入哈希被函数消耗,并且不能随后使用指向它的指针。如果您需要两个哈希,请使用 "cophh_copy"

这些形式在指定键的方式上有所不同。在所有形式中,键都由 key 指向。在普通的 pv 形式中,键是 C 语言的以 NUL 结尾的字符串。在 pvs 形式中,键是 C 语言的字符串字面量。在 pvn 形式中,一个额外的参数 keylen 指定字符串的长度,因此它可能包含嵌入的 NUL 字符。在 sv 形式中,*key 是一个 SV,键是从该 SV 中提取的 PV,使用 "SvPV_const"

hash 是键字符串的预计算哈希值,如果它没有被预计算,则为零。此参数从 pvs 形式中省略,因为它在编译时自动计算。

flags 参数中当前仅使用一个标志 COPHH_KEY_UTF8。在 sv 形式中设置此标志是非法的。在 pv* 形式中,它指定键字节是否被解释为 UTF-8(如果设置)或 Latin-1(如果清除)。sv 形式使用底层 SV 来确定字节的 UTF-8 性质。

    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)
cophh_exists_pvn

注意:cophh_exists_pvn 处于实验阶段,可能会在未经通知的情况下更改或删除。

这些函数在 cop cop 中查找具有由 key(以及 pvn 形式中的 keylen)指定的键的提示条目,如果存在值则返回 true,否则返回 false。

这些形式在指定键的方式上有所不同。在普通的 pv 形式中,键是一个 C 语言的以 NUL 结尾的字符串。在 pvs 形式中,键是一个 C 语言的字符串字面量。在 pvn 形式中,一个额外的参数 keylen 指定了字符串的长度,因此它可能包含嵌入的 NUL 字符。在 sv 形式中,*key 是一个 SV,键是从该 SV 中提取的 PV,使用 "SvPV_const"

hash 是键字符串的预计算哈希值,如果它没有被预计算,则为零。此参数从 pvs 形式中省略,因为它在编译时自动计算。

flags 参数中当前仅使用一个标志 COPHH_KEY_UTF8。在 sv 形式中设置此标志是非法的。在 pv* 形式中,它指定键字节是否被解释为 UTF-8(如果设置)或 Latin-1(如果清除)。sv 形式使用底层 SV 来确定字节的 UTF-8 性质。

    bool  cophh_exists_pvn(const COPHH *cophh, const char *key,
                           STRLEN keylen, U32 hash, U32 flags)
cophh_fetch_pv
cophh_fetch_pvn
cophh_fetch_pvs
cophh_fetch_sv

注意:所有这些形式都处于实验阶段,可能会在未经通知的情况下更改或删除。

这些函数在 cop 提示哈希 cophh 中查找由 key(以及 pvn 形式中的 keylen)指定的键对应的条目,并返回该值作为可变的标量副本,如果与该键没有关联的值,则返回 &PL_sv_placeholder

这些形式在指定键的方式上有所不同。在普通的 pv 形式中,键是一个 C 语言的以 NUL 结尾的字符串。在 pvs 形式中,键是一个 C 语言的字符串字面量。在 pvn 形式中,一个额外的参数 keylen 指定了字符串的长度,因此它可能包含嵌入的 NUL 字符。在 sv 形式中,*key 是一个 SV,键是从该 SV 中提取的 PV,使用 "SvPV_const"

hash 是键字符串的预计算哈希值,如果它没有被预计算,则为零。此参数从 pvs 形式中省略,因为它在编译时自动计算。

flags 参数中当前仅使用一个标志 COPHH_KEY_UTF8。在 sv 形式中设置此标志是非法的。在 pv* 形式中,它指定键字节是否被解释为 UTF-8(如果设置)或 Latin-1(如果清除)。sv 形式使用底层 SV 来确定字节的 UTF-8 性质。

    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)
cophh_free

注意:cophh_free实验性的,可能会在不通知的情况下更改或删除。

丢弃 cop 提示哈希 cophh,释放与之关联的所有资源。

    void  cophh_free(COPHH *cophh)
cophh_2hv

注意:cophh_2hv实验性的,可能会在不通知的情况下更改或删除。

生成并返回一个标准的 Perl 哈希,表示 cop 提示哈希 cophh 中的全部键值对。flags 目前未被使用,必须为零。

    HV *  cophh_2hv(const COPHH *cophh, U32 flags)
cophh_new_empty

注意:cophh_new_empty实验性的,可能会在不通知的情况下更改或删除。

生成并返回一个不包含任何条目的新的 cop 提示哈希。

    COPHH *  cophh_new_empty()
cophh_store_pv
cophh_store_pvn
cophh_store_pvs
cophh_store_sv

注意:所有这些形式都处于实验阶段,可能会在未经通知的情况下更改或删除。

这些函数将与键关联的值存储在 cop 提示哈希 cophh 中,并返回修改后的哈希。返回的哈希指针通常与传入的哈希指针不同。输入哈希被函数消耗,并且不能随后使用指向它的指针。如果您需要两个哈希,请使用 "cophh_copy"

value 是要为此键存储的标量值。value 被这些函数复制,因此它们不会获取对它的任何引用的所有权,因此对标量的后续更改不会反映在 cop 提示哈希中可见的值中。标量的复杂类型不会以引用完整性存储,而是会被强制转换为字符串。

这些形式在指定键的方式上有所不同。在所有形式中,键都由 key 指向。在普通的 pv 形式中,键是 C 语言的以 NUL 结尾的字符串。在 pvs 形式中,键是 C 语言的字符串字面量。在 pvn 形式中,一个额外的参数 keylen 指定字符串的长度,因此它可能包含嵌入的 NUL 字符。在 sv 形式中,*key 是一个 SV,键是从该 SV 中提取的 PV,使用 "SvPV_const"

hash 是键字符串的预计算哈希值,如果它没有被预计算,则为零。此参数从 pvs 形式中省略,因为它在编译时自动计算。

flags 参数中当前仅使用一个标志 COPHH_KEY_UTF8。在 sv 形式中设置此标志是非法的。在 pv* 形式中,它指定键字节是否被解释为 UTF-8(如果设置)或 Latin-1(如果清除)。sv 形式使用底层 SV 来确定字节的 UTF-8 性质。

    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)
cop_hints_exists_pv
cop_hints_exists_pvn
cop_hints_exists_pvs
cop_hints_exists_sv

这些函数在 cop cop 中查找具有由 key(以及 pvn 形式中的 keylen)指定的键的提示条目,如果存在值则返回 true,否则返回 false。

这些形式在指定键的方式上有所不同。在所有形式中,键都由 key 指向。在普通的 pv 形式中,键是 C 语言的以 NUL 结尾的字符串。在 pvs 形式中,键是 C 语言的字符串字面量。在 pvn 形式中,一个额外的参数 keylen 指定字符串的长度,因此它可能包含嵌入的 NUL 字符。在 sv 形式中,*key 是一个 SV,键是从该 SV 中提取的 PV,使用 "SvPV_const"

hash 是键字符串的预计算哈希值,如果它没有被预计算,则为零。此参数从 pvs 形式中省略,因为它在编译时自动计算。

flags 参数中当前仅使用一个标志 COPHH_KEY_UTF8。在 sv 形式中设置此标志是非法的。在 pv* 形式中,它指定键字节是否被解释为 UTF-8(如果设置)或 Latin-1(如果清除)。sv 形式使用底层 SV 来确定字节的 UTF-8 性质。

    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)
cop_hints_fetch_pv
cop_hints_fetch_pvn
cop_hints_fetch_pvs
cop_hints_fetch_sv

这些函数在 cop cop 中查找由 key(以及 pvn 形式中的 keylen)指定的键的提示条目,将该值作为可变标量副本返回,或者如果与该键没有关联的值,则返回 &PL_sv_placeholder

这些形式在指定键的方式上有所不同。在普通的 pv 形式中,键是一个 C 语言的以 NUL 结尾的字符串。在 pvs 形式中,键是一个 C 语言的字符串字面量。在 pvn 形式中,一个额外的参数 keylen 指定了字符串的长度,因此它可能包含嵌入的 NUL 字符。在 sv 形式中,*key 是一个 SV,键是从该 SV 中提取的 PV,使用 "SvPV_const"

hash 是键字符串的预计算哈希值,如果它没有被预计算,则为零。此参数从 pvs 形式中省略,因为它在编译时自动计算。

flags 参数中当前仅使用一个标志 COPHH_KEY_UTF8。在 sv 形式中设置此标志是非法的。在 pv* 形式中,它指定键字节是否被解释为 UTF-8(如果设置)或 Latin-1(如果清除)。sv 形式使用底层 SV 来确定字节的 UTF-8 性质。

    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)
cop_hints_2hv

生成并返回一个标准 Perl 哈希,表示 cop cop 中的完整提示条目集。flags 当前未使用,必须为零。

    HV *  cop_hints_2hv(const COP *cop, U32 flags)
CopLABEL
CopLABEL_len
CopLABEL_len_flags

这些函数返回附加到 cop 的标签。

CopLABEL_lenCopLABEL_len_flags 还会将组成返回标签的字节数存储到 *len 中。

CopLABEL_len_flags 还会通过将 *flags 设置为 0 或 SVf_UTF8 来返回返回标签的 UTF-8 性质。

    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)
CopLINE

返回与 COP c 关联的源代码中的行号。

    line_t  CopLINE(const COP * c)
CopSTASH

返回与 c 关联的 stash。

    HV *  CopSTASH(const COP * c)
CopSTASH_eq

返回一个布尔值,表示 hv 是否是与 c 关联的 stash。

    bool  CopSTASH_eq(const COP * c, const HV * hv)
CopSTASHPV

返回与 c 关联的 stash 的包名,如果不存在关联的 stash,则返回 NULL

    char *  CopSTASHPV(const COP * c)
CopSTASHPV_set

将与 c 关联的 stash 的包名设置为以 NUL 结尾的 C 字符串 p,如果需要,则创建该包。

    void  CopSTASHPV_set(COP * c, const char * pv)
CopSTASH_set

将与 c 关联的 stash 设置为 hv

    bool  CopSTASH_set(COP * c, HV * hv)
cop_store_label

注意:cop_store_label 处于实验阶段,可能会在不通知的情况下更改或删除。

将标签保存到 cop_hints_hash 中。您需要将标志设置为 SVf_UTF8 以表示 UTF-8 标签。任何其他标志都会被忽略。

    void  cop_store_label(COP * const cop, const char *label,
                          STRLEN len, U32 flags)
PERL_SI

使用此 typedef 声明要保存 struct stackinfo 的变量。

PL_curcop

当前活动的 COP(控制操作),大致代表源代码中的当前语句。

在多线程 Perl 中,每个线程都有此变量的独立副本;每个副本在创建时都使用创建线程副本的当前值进行初始化。

    COP*  PL_curcop
RCPV_LEN

返回使用 rcpv_new() 创建的 pv 的长度。请注意,这反映了调用者视角的字符串长度,不包括始终在字符串末尾由 rcpv_new() 插入的强制性空字符。不会执行任何检查以确保 pv 实际上是使用 rcpv_new() 分配的,调用者有责任确保这一点。

    RCPV *  RCPV_LEN(char *pv)
RCPV_REFCNT_dec

减少使用 rcpv_new() 调用创建的 char * 指针的引用计数。与调用 rcpv_free() 相同。不会执行任何检查以确保 pv 实际上是使用 rcpv_new() 分配的,调用者有责任确保这一点。

    RCPV *  RCPV_REFCNT_dec(char *pv)
RCPV_REFCNT_inc

增加使用 rcpv_new() 调用创建的 char * 指针的引用计数。与调用 rcpv_copy() 相同。不会执行任何检查以确保 pv 实际上是使用 rcpv_new() 分配的,调用者有责任确保这一点。

    RCPV *  RCPV_REFCNT_inc(char *pv)
RCPV_REFCOUNT

返回使用 rcpv_new() 创建的 pv 的引用计数。不会执行任何检查以确保 pv 实际上是使用 rcpv_new() 分配的,调用者有责任确保这一点。

    RCPV *  RCPV_REFCOUNT(char *pv)
RCPVx

返回使用 rcpv_new() 创建的引用计数字符串 pv 的 RCPV 结构(struct rcpv)。不会执行任何检查以确保 pv 实际上是使用 rcpv_new() 分配的,确保这一点是调用者的责任。

    RCPV *  RCPVx(char *pv)

自定义运算符

custom_op_register

注册自定义运算符。请参阅 "perlguts 中的自定义运算符"

注意:custom_op_register 必须显式调用为 Perl_custom_op_register,并带有 aTHX_ 参数。

    void  Perl_custom_op_register(pTHX_ Perl_ppaddr_t ppaddr,
                                  const XOP *xop)
Perl_custom_op_xop

返回给定自定义运算符的 XOP 结构。此宏应被视为 OP_NAME 和其他访问宏的内部宏:请使用它们。此宏确实调用了一个函数。在 5.19.6 之前,这是作为函数实现的。

    const XOP *  Perl_custom_op_xop(pTHX_ const OP *o)
XopDISABLE

通过清除相应的标志,暂时禁用 XOP 的成员。

    void  XopDISABLE(XOP *xop, token which)
XopENABLE

重新启用已禁用的 XOP 成员。

    void  XopENABLE(XOP *xop, token which)
XopENTRY

返回 XOP 结构的成员。which 是一个 cpp 标记,指示要返回的条目。如果成员未设置,则将返回默认值。返回类型取决于 which。此宏多次评估其参数。如果您正在使用 Perl_custom_op_xopOP * 中检索 XOP *,请使用更高效的 "XopENTRYCUSTOM"

    XopENTRY(XOP *xop, token which)
XopENTRYCUSTOM

XopENTRY(XopENTRY(Perl_custom_op_xop(aTHX_ o), which) 完全相同,但更高效。which 参数与 "XopENTRY" 相同。

    XopENTRYCUSTOM(const OP *o, token which)
XopENTRY_set

设置 XOP 结构的成员。which 是一个 cpp 标记,指示要设置的条目。有关可用成员及其使用方式的详细信息,请参阅 "perlguts 中的自定义运算符"。此宏多次评估其参数。

    void  XopENTRY_set(XOP *xop, token which, value)
XopFLAGS

返回 XOP 的标志。

    U32  XopFLAGS(XOP *xop)

CV 处理

本节介绍用于操作 CV 的函数,CV 是代码值,即子例程。有关更多信息,请参阅 perlguts

caller_cx

这是 XSUB 编写者版本的 caller()。返回的 PERL_CONTEXT 结构可以被用来查询所有由 caller 返回给 Perl 的信息。请注意,XSUB 没有堆栈帧,因此 caller_cx(0, NULL) 将返回紧邻的 Perl 代码的信息。

此函数会跳过调试器代表调试器对 &DB::sub 的自动调用。如果请求的堆栈帧是由 DB::sub 调用的子程序,则返回值将是调用 DB::sub 的帧,因为该帧具有调用位置的正确行号等信息。如果 dbcxpNULL,则它将被设置为指向子程序调用本身的帧的指针。

    const PERL_CONTEXT *  caller_cx(I32 level,
                                    const PERL_CONTEXT **dbcxp)
CvDEPTH

返回 CV sv 的递归级别。因此 >= 2 表示我们处于递归调用中。

    I32 *  CvDEPTH(const CV * const sv)
CvGV

返回与 CV sv 关联的 GV,必要时进行具体化。

    GV *  CvGV(CV *sv)
CvSTASH

返回 CV 的 stash。stash 是符号表哈希,包含定义子程序的包中的包级变量。有关更多信息,请参阅 perlguts

它在 XS AUTOLOAD 子程序中也有特殊用途。请参阅 "perlguts 中的“使用 XSUB 进行自动加载”"

    HV*  CvSTASH(CV* cv)
find_runcv

找到与当前正在执行的子程序或 eval 相对应的 CV。如果 db_seqp 非空,则跳过 DB 包中的 CV,并将 *db_seqp 填充为进入 DB:: 代码时的 cop 序列号。(这允许调试器在断点范围内进行 eval,而不是在调试器本身的范围内进行 eval。)

    CV *  find_runcv(U32 *db_seqp)
get_cv
get_cvn_flags
get_cvs

这些函数返回指定 Perl 子程序的 CV。flags 传递给 gv_fetchpvn_flags。如果设置了 GV_ADD 并且 Perl 子程序不存在,则它将被声明(这与说 sub name; 的效果相同)。如果未设置 GV_ADD 并且子程序不存在,则返回 NULL。

这些形式仅在指定子程序的方式上有所不同。使用 get_cvs,名称是一个字面 C 字符串,用双引号括起来。使用 get_cv,名称由 name 参数给出,该参数必须是 NUL 结尾的 C 字符串。使用 get_cvn_flags,名称也由 name 参数给出,但它是一个 Perl 字符串(可能包含嵌入的 NUL 字节),其字节长度包含在 len 参数中。

注意:perl_get_cv() 形式已弃用

注意:perl_get_cvn_flags() 形式已弃用

注意:perl_get_cvs() 形式已弃用

    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)
Nullcv

已弃用! 计划从 Perl 的未来版本中删除 Nullcv。不要在新的代码中使用它;从现有代码中删除它。

空 CV 指针。

(已弃用 - 改用 (CV *)NULL)

调试

av_dump

将 AV 的内容转储到 STDERR 文件句柄中,类似于对数组引用使用 Devel::Peek,但不需要 RV 包装器。将内容转储到 3 级深度。

    void  av_dump(AV *av)
deb
deb_nocontext

当 perl 使用 -DDEBUGGING 编译时,这会将参数给出的信息打印到 STDERR,并在信息前面加上包含导致调用的脚本的文件名以及该文件中的行号。

如果启用了 v(详细)调试选项,还会打印进程 ID。

这两种形式的区别仅在于 deb_nocontext 不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

注意:deb 必须使用 aTHX_ 参数显式调用为 Perl_deb

    void  Perl_deb     (pTHX_ const char *pat, ...)
    void  deb_nocontext(const char *pat, ...)
debstack

转储当前堆栈

    I32  debstack()
dump_all

将当前程序的整个 optree 从 PL_main_root 转储到 STDERR。还会转储 PL_defstash 中所有可见子例程的 optree。

    void  dump_all()
dump_c_backtrace

将 C 回溯转储到给定的 fp

如果可以检索到回溯,则返回 true,否则返回 false。

    bool  dump_c_backtrace(PerlIO *fp, int max_depth, int skip)
dump_eval

perlguts 中描述。

    void  dump_eval()
dump_form

将 GV gv 中包含的格式的内容转储到 STDERR,或者转储一条消息,表明格式不存在。

    void  dump_form(const GV *gv)
dump_packsubs

转储 stash 中所有可见子例程的 optree。

    void  dump_packsubs(const HV *stash)
dump_sub

perlguts 中描述。

    void  dump_sub(const GV *gv)
get_c_backtrace_dump

返回一个 SV,其中包含调用堆栈 depth 帧的转储,跳过最里面的 skip 帧。depth 为 20 通常就足够了。

附加的输出看起来像

...
1   10e004812:0082   Perl_croak   util.c:1716    /usr/bin/perl
2   10df8d6d2:1d72   perl_parse   perl.c:3975    /usr/bin/perl
...

字段以制表符分隔。第一列是深度(0 表示最里面的非跳过帧)。在 hex:offset 中,hex 是程序计数器在 S_parse_body 中的位置,而 :offset(可能缺失)表示程序计数器在 S_parse_body 中的位置。

util.c:1716 是源代码文件和行号。

/usr/bin/perl 很明显(希望如此)。

未知项为 "-"。未知项不幸的是很容易发生:如果平台不支持检索信息;如果二进制文件缺少调试信息;如果优化器通过例如内联的方式转换了代码。

    SV *  get_c_backtrace_dump(int max_depth, int skip)
gv_dump

将 GV gv 的名称以及(如果不同)有效名称转储到 STDERR

    void  gv_dump(GV *gv)
HAS_BACKTRACE

如果定义了此符号,则表示 backtrace() 例程可用以获取堆栈跟踪。必须包含 execinfo.h 头文件才能使用此例程。

hv_dump

将 HV 的内容转储到 STDERR 文件句柄。类似于对 hashref 使用 Devel::Peek,但不期望 RV 包装器。将内容转储到 3 级深度。

    void  hv_dump(HV *hv)
magic_dump

将 MAGIC mg 的内容转储到 STDERR

    void  magic_dump(const MAGIC *mg)
op_class

给定一个操作符,确定它已分配为哪种类型的结构。返回一个 OPclass 枚举,例如 OPclass_LISTOP。

    OPclass  op_class(const OP *o)
op_dump

将从操作符 o 开始的 optree 转储到 STDERR

    void  op_dump(const OP *o)
PL_op

perlhacktips 中描述。

PL_runops

perlguts 中描述。

PL_sv_serial

perlhacktips 中描述。

pmop_dump

转储与模式匹配相关的操作符,例如 s/foo/bar/;这些需要特殊处理。

    void  pmop_dump(PMOP *pm)
sv_dump

将 SV 的内容转储到 STDERR 文件句柄。

有关其输出示例,请参阅 Devel::Peek。如果该项是 SvROK,它将转储深度为 4 的项,否则它将仅转储顶层项,这意味着它不会转储 AV * 或 HV * 的内容。为此,请使用 av_dump()hv_dump()

    void  sv_dump(SV *sv)
sv_dump_depth

将 SV 的内容转储到 STDERR 文件句柄,转储深度由请求决定。此函数可用于任何具有适当强制转换的 SV 派生类型(GV、HV、AV)。这是一个比 sv_dump() 更灵活的变体。例如

HV *hv = ...;
sv_dump_depth((SV*)hv, 2);

将转储 hv、它的键和值,但不会递归到任何 RV 值。

    void  sv_dump_depth(SV *sv, I32 depth)
vdeb

这类似于 "deb",但 args 是一个封装的参数列表。

    void  vdeb(const char *pat, va_list *args)

显示函数

form
form_nocontext

这些函数接受一个 sprintf 样式的格式模式和常规(非 SV)参数,并返回格式化的字符串。

(char *) Perl_form(pTHX_ const char* pat, ...)

可以在任何需要字符串(char *)的地方使用

char * s = Perl_form("%d.%d",major,minor);

它们使用一个单一的(每个线程)私有缓冲区,因此如果您想格式化多个字符串,则必须显式地将之前的字符串复制出来(并在完成后释放副本)。

这两种形式的区别仅在于 form_nocontext 不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

注意:form 必须显式地调用为 Perl_form,并带有 aTHX_ 参数。

    char *  Perl_form     (pTHX_ const char *pat, ...)
    char *  form_nocontext(const char *pat, ...)
mess
mess_nocontext

这些函数接受一个 sprintf 样式的格式模式和参数列表,用于生成字符串消息。如果消息没有以换行符结尾,则会扩展一些代码中当前位置的指示,如 "mess_sv" 所述。

通常,生成的邮件将保存在一个新的 mortal SV 中。但在全局销毁期间,单个 SV 可以在此函数的多次使用之间共享。

这两种形式的区别仅在于 mess_nocontext 不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

注意:mess 必须显式地调用为 Perl_mess,并带有 aTHX_ 参数。

    SV *  Perl_mess     (pTHX_ const char *pat, ...)
    SV *  mess_nocontext(const char *pat, ...)
mess_sv

扩展消息,供用户使用,包括代码中当前位置的指示,如果消息看起来不完整。

basemsg 是初始消息或对象。如果它是一个引用,它将按原样使用,并将成为此函数的结果。否则,它将用作字符串,如果它已经以换行符结尾,则它被认为是完整的,此函数的结果将是相同的字符串。如果消息没有以换行符结尾,则会附加一个类似于 at foo.pl line 37 的段,以及可能指示当前执行状态的其他子句。结果消息将以句点和换行符结尾。

通常,结果消息将返回到一个新的 mortal SV 中。在全局销毁期间,单个 SV 可以在此函数的多个使用之间共享。如果 consume 为真,则允许(但不要求)函数修改并返回 basemsg 而不是分配新的 SV。

    SV *  mess_sv(SV *basemsg, bool consume)
pv_display

类似于

pv_escape(dsv,pv,cur,pvlim,PERL_PV_ESCAPE_QUOTE);

除了当 len > cur 且 pv[cur] 为 "\0" 时,将在字符串末尾追加一个额外的 "\0"。

请注意,最终字符串可能比 pvlim 长最多 7 个字符。

    char *  pv_display(SV *dsv, const char *pv, STRLEN cur,
                       STRLEN len, STRLEN pvlim)
pv_escape

转义 pv 的前 count 个字符(最多),并将结果放入 dsv 中,这样转义字符串的大小不会超过 max 个字符,并且不会包含任何不完整的转义序列。如果 STRLEN *escaped 参数不为空,则转义的字节数将返回到该参数中。当 dsv 参数为空时,实际上不会发生转义,但将计算如果它不为空将转义的字节数。

如果 flags 包含 PERL_PV_ESCAPE_QUOTE,则字符串中的任何双引号也将被转义。

通常,在准备转义字符串之前,SV 将被清除,但是当设置 PERL_PV_ESCAPE_NOCLEAR 时,这将不会发生。

如果设置了 PERL_PV_ESCAPE_UNI,则输入字符串将被视为 UTF-8。如果设置了 PERL_PV_ESCAPE_UNI_DETECT,则将使用 is_utf8_string() 扫描输入字符串以确定它是否为 UTF-8。

如果设置了 PERL_PV_ESCAPE_ALL,则所有输入字符都将使用 \x01F1 样式转义输出,否则,如果设置了 PERL_PV_ESCAPE_NONASCII,则只有非 ASCII 字符将使用此样式转义;否则,只有大于 255 的字符将被如此转义;其他不可打印字符将使用八进制或常见的转义模式,例如 \n。否则,如果设置了 PERL_PV_ESCAPE_NOBACKSLASH,则所有小于 255 的字符将被视为可打印字符,并将作为文字输出。PERL_PV_ESCAPE_NON_WC 修改了之前的规则,导致单词字符(Unicode 或其他)作为文字输出,请注意,这使用 *Unicode* 规则来决定单词字符。

如果设置了 PERL_PV_ESCAPE_FIRSTCHAR,则只有字符串的第一个字符将被转义,而不管 max 的值。如果输出将以十六进制形式,则它将作为纯十六进制序列返回。因此,输出将是单个字符、八进制转义序列、特殊转义(如 \n)或十六进制值。

如果设置了 PERL_PV_ESCAPE_RE,则使用的转义字符将是 "%" 而不是 "\\"。这是因为正则表达式经常包含反斜杠序列,而 "%" 在模式中并不是一个特别常见的字符。

返回指向由 dsv 持有的转义文本的指针。

    char *  pv_escape(SV *dsv, char const * const str,
                      const STRLEN count, STRLEN max,
                      STRLEN * const escaped, U32 flags)
pv_pretty

将字符串转换为可呈现的格式,通过 pv_escape() 处理转义,并支持引号和省略号。

如果设置了 PERL_PV_PRETTY_QUOTE 标志,则结果将用双引号括起来,字符串中的所有双引号都将被转义。否则,如果设置了 PERL_PV_PRETTY_LTGT 标志,则结果将用尖括号括起来。

如果设置了 PERL_PV_PRETTY_ELLIPSES 标志,并且字符串中并非所有字符都已输出,则省略号 ... 将被附加到字符串末尾。请注意,这发生在字符串被引号括起来之后。

如果 start_color 非空,则它将在开始引号(如果有)之后但转义文本之前插入。如果 end_color 非空,则它将在转义文本之后但在任何引号或省略号之前插入。

返回指向由 dsv 持有的美化文本的指针。

    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)
vform

类似于 "form",但参数是一个封装的参数列表。

    char *  vform(const char *pat, va_list *args)
vmess

patargs 分别是 sprintf 样式的格式模式和封装的参数列表。它们用于生成字符串消息。如果消息没有以换行符结尾,则它将被扩展为包含代码中当前位置的指示,如 "mess_sv" 中所述。

通常,生成的 message 会保存在一个新的 mortal SV 中。在全局销毁期间,单个 SV 可以在此函数的多个使用之间共享。

    SV *  vmess(const char *pat, va_list *args)

嵌入、线程和解释器克隆

call_atexit

将函数 fn 添加到全局销毁时要调用的函数列表中。ptr 将作为参数传递给 fn;它可以指向一个 struct,以便您可以传递任何您想要的东西。

请注意,在多线程环境下,fn 可能运行多次。这是因为每次当前线程或任何子线程终止时都会执行该列表。

    void  call_atexit(ATEXIT_t fn, void *ptr)
cv_clone

克隆一个 CV,创建一个词法闭包。proto 提供函数的原型:其代码、填充结构和其他属性。原型与对外部词法的捕获相结合,代码引用这些词法,这些词法取自当前执行的紧邻代码实例。

    CV *  cv_clone(CV *proto)
cv_name

返回一个包含 CV 名称的 SV,主要用于错误报告。CV 实际上可能是一个 GV,在这种情况下,返回的 SV 包含 GV 的名称。除了 GV 或 CV 之外的任何内容都被视为一个已经包含子名称的字符串,但这在将来可能会改变。

可以将 SV 作为第二个参数传递。如果是这样,名称将被分配给它,并且它将被返回。否则,返回的 SV 将是一个新的 mortal。

如果 flags 设置了 CV_NAME_NOTQUAL 位,则不会包含包名。如果第一个参数既不是 CV 也不是 GV,则忽略此标志(可能会更改)。

    SV *  cv_name(CV *cv, SV *sv, U32 flags)
cv_undef

清除 CV 的所有活动组件。这可以通过显式 undef &foo 或引用计数变为零来实现。在前一种情况下,我们保留 CvOUTSIDE 指针,以便任何匿名子级仍然可以遵循完整的词法作用域链。

    void  cv_undef(CV *cv)
find_rundefsv

返回全局变量 $_

    SV *  find_rundefsv()
get_op_descs

已弃用! 计划从 Perl 的未来版本中删除 get_op_descs。不要在新的代码中使用它;从现有代码中删除它。

返回指向所有各种 OP 描述的数组的指针。给定来自 opcodes.h 中枚举的 opcode,PL_op_desc[opcode] 返回指向 C 语言字符串的指针,该字符串给出其描述。

    char **  get_op_descs()
get_op_names

已弃用! 计划从 Perl 的未来版本中删除 get_op_names。不要在新的代码中使用它;从现有代码中删除它。

返回指向所有各种 OP 名称的数组的指针。给定来自 opcodes.h 中枚举的 opcode,PL_op_name[opcode] 返回指向 C 语言字符串的指针,该字符串给出其名称。

    char **  get_op_names()
HAS_SKIP_LOCALE_INIT

perlembed 中描述。

intro_my

my 变量“引入”到可见状态。这在解析期间在每个语句结束时被调用,以使词法变量对后续语句可见。

    U32  intro_my()
load_module
load_module_nocontext

这些加载模块,其名称由 name 的字符串部分指向。请注意,应给出实际的模块名称,而不是其文件名。例如,"Foo::Bar" 而不是 "Foo/Bar.pm"。ver(如果指定且不为 NULL)提供类似于 use Foo::Bar VERSION 的版本语义。可选的尾随参数可用于指定模块的 import() 方法的参数,类似于 use Foo::Bar VERSION LIST;它们的精确处理取决于标志。flags 参数是 PERL_LOADMOD_DENYPERL_LOADMOD_NOIMPORTPERL_LOADMOD_IMPORT_OPS(或 0 表示无标志)的按位或组合。

如果设置了PERL_LOADMOD_NOIMPORT,则模块将像使用空导入列表一样加载,就像在use Foo::Bar ()中一样;这是唯一可以完全省略尾部可选参数的情况。否则,如果设置了PERL_LOADMOD_IMPORT_OPS,则尾部参数必须包含一个OP*,其中包含生成相关导入参数的运算符树。否则,尾部参数必须全部是SV*值,这些值将用作导入参数;并且列表必须以(SV*) NULL结尾。如果既没有设置PERL_LOADMOD_NOIMPORT也没有设置PERL_LOADMOD_IMPORT_OPS,即使不需要导入参数,也需要尾部的NULL指针。每个指定的SV*参数的引用计数都会递减。此外,name参数也会被修改。

如果设置了PERL_LOADMOD_DENY,则模块将像使用no而不是use一样加载。

load_moduleload_module_nocontext具有相同的表观签名,但前者隐藏了它正在访问线程上下文参数的事实。因此,当您遇到关于pTHX的编译错误时,请使用后者。

    void  load_module          (U32 flags, SV *name, SV *ver, ...)
    void  load_module_nocontext(U32 flags, SV *name, SV *ver, ...)
my_exit

C 库 exit(3) 的包装器,遵守 "perlapi 中的 PL_exit_flags" 的说明。

    void  my_exit(U32 status)
my_failure_exit

以错误退出正在运行的 Perl 进程。

在非 VMS 平台上,这与 "my_exit" 本质上等效,使用errno,但如果errno为 0,则强制使用错误代码 255。

在 VMS 上,它会注意在退出状态中设置适当的严重性位。

    void  my_failure_exit()
my_strlcat

如果可用,则为 C 库strlcat,或其 Perl 实现。这在 C NUL 终止的字符串上运行。

my_strlcat() 将字符串src 附加到dst 的末尾。它最多会附加 size - strlen(dst) - 1 个字符。然后它将NUL 终止,除非size 为 0 或原始dst 字符串长于size(实际上,这应该不会发生,因为这意味着size 不正确或dst 不是正确的NUL 终止字符串)。

请注意,size 是目标缓冲区的完整大小,并且如果存在空间,则结果保证为NUL 终止。请注意,size 中应包含NUL 的空间。

返回值是如果 size 足够大,dst 的总长度。因此它等于 dst 的初始长度加上 src 的长度。如果 size 小于返回值,则不会追加多余的部分。

    Size_t  my_strlcat(char *dst, const char *src, Size_t size)
my_strlcpy

如果可用,则为 C 库 strlcpy,否则为它的 Perl 实现。它操作 C 的 NUL 终止字符串。

my_strlcpy() 从字符串 src 复制最多 size - 1 个字符到 dst,如果 size 不为 0,则在结果中添加 NUL 终止符。

返回值是如果复制完全成功,src 的总长度。如果它大于 size,则不会复制多余的部分。

    Size_t  my_strlcpy(char *dst, const char *src, Size_t size)
newPADNAMELIST

注意:newPADNAMELIST 处于实验阶段,可能会在不通知的情况下更改或删除。

创建一个新的垫子名称列表。max 是分配空间的最高索引。

    PADNAMELIST *  newPADNAMELIST(size_t max)
newPADNAMEouter

注意:newPADNAMEouter 处于实验阶段,可能会在不通知的情况下更改或删除。

构造并返回一个新的垫子名称。仅对引用外部词法变量的名称使用此函数。(另请参见 "newPADNAMEpvn"。)outer 是此垫子名称所镜像的外部垫子名称。返回的垫子名称已设置 PADNAMEf_OUTER 标志。

    PADNAME *  newPADNAMEouter(PADNAME *outer)
newPADNAMEpvn

注意:newPADNAMEpvn 处于实验阶段,可能会在不通知的情况下更改或删除。

构造并返回一个新的垫子名称。s 必须是 UTF-8 字符串。不要将其用于指向外部词法变量的垫子名称。请参见 "newPADNAMEouter"

    PADNAME *  newPADNAMEpvn(const char *s, STRLEN len)
nothreadhook

当没有线程时,提供用于 perl_destruct 的线程钩子的存根。

    int  nothreadhook()
pad_add_anon

在当前正在编译的垫子中(通过 "pad_alloc")为一个在当前正在编译的函数中词法作用域内的匿名函数分配一个位置。函数 func 被链接到垫子中,它对外部作用域的 CvOUTSIDE 链接被弱化以避免引用循环。

一个引用计数被窃取,因此您可能需要执行 SvREFCNT_inc(func)

optype 应该是一个操作码,指示垫子条目要支持的操作类型。这不会影响操作语义,但用于调试。

    PADOFFSET  pad_add_anon(CV *func, I32 optype)
pad_add_name_pv

"pad_add_name_pvn" 完全相同,但接受以空字符结尾的字符串而不是字符串/长度对。

    PADOFFSET  pad_add_name_pv(const char *name, const U32 flags,
                               HV *typestash, HV *ourstash)
pad_add_name_pvn

在当前正在编译的 pad 中分配一个用于命名词法变量的位置。将名称和其他元数据存储在 pad 的名称部分,并准备管理变量的词法作用域。返回分配的 pad 槽的偏移量。

namepv/namelen 指定变量的名称,包括前导符号。如果 typestash 非空,则该名称用于类型化的词法变量,并标识该类型。如果 ourstash 非空,则它是一个对包变量的词法引用,并标识该包。以下标志可以按位或运算组合在一起

padadd_OUR          redundantly specifies if it's 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
    PADOFFSET  pad_add_name_pvn(const char *namepv, STRLEN namelen,
                                U32 flags, HV *typestash,
                                HV *ourstash)
pad_add_name_sv

"pad_add_name_pvn" 完全相同,但接受以 SV 形式的名称字符串而不是字符串/长度对。

    PADOFFSET  pad_add_name_sv(SV *name, U32 flags, HV *typestash,
                               HV *ourstash)
pad_alloc

注意:pad_alloc 是 **实验性的**,可能会在未经通知的情况下更改或删除。

在当前正在编译的 pad 中分配一个位置,返回分配的 pad 槽的偏移量。最初没有名称附加到 pad 槽。tmptype 是一组标志,指示所需的 pad 条目类型,这些标志将在分配的 pad 条目的值 SV 中设置

SVs_PADMY    named lexical variable ("my", "our", "state")
SVs_PADTMP   unnamed temporary store
SVf_READONLY constant shared between recursion levels

SVf_READONLY 仅从 Perl 5.20 开始支持。要与更早的版本一起使用,请使用 SVf_READONLY|SVs_PADTMPSVf_READONLY 不会导致 pad 槽中的 SV 被标记为只读,而只是告诉 pad_alloc 它将被标记为只读(由调用者),或者至少应该被视为只读。

optype 应该是一个操作码,指示垫子条目要支持的操作类型。这不会影响操作语义,但用于调试。

    PADOFFSET  pad_alloc(I32 optype, U32 tmptype)
pad_findmy_pv

"pad_findmy_pvn" 完全相同,但接受以空字符结尾的字符串而不是字符串/长度对。

    PADOFFSET  pad_findmy_pv(const char *name, U32 flags)
pad_findmy_pvn

给定词法变量的名称,找到它在当前正在编译的 pad 中的位置。namepv/namelen 指定变量的名称,包括前导符号。flags 保留,必须为零。如果它不在当前 pad 中,但出现在任何词法封闭作用域的 pad 中,则会在当前 pad 中为它添加一个伪条目。返回当前 pad 中的偏移量,如果不存在此类词法变量,则返回 NOT_IN_PAD

    PADOFFSET  pad_findmy_pvn(const char *namepv, STRLEN namelen,
                              U32 flags)
pad_findmy_sv

"pad_findmy_pvn" 完全相同,但接受以 SV 形式的名称字符串而不是字符串/长度对。

    PADOFFSET  pad_findmy_sv(SV *name, U32 flags)
padnamelist_fetch

注意:padnamelist_fetch 是 **实验性的**,可能会在未经通知的情况下更改或删除。

从给定索引中获取 pad 名称。

    PADNAME *  padnamelist_fetch(PADNAMELIST *pnl, SSize_t key)
padnamelist_store

注意:padnamelist_store 处于**实验阶段**,可能会在未经通知的情况下更改或删除。

在给定索引处存储衬垫名称(可能为空),释放该插槽中任何现有的衬垫名称。

    PADNAME **  padnamelist_store(PADNAMELIST *pnl, SSize_t key,
                                  PADNAME *val)
pad_tidy

注意:pad_tidy 处于**实验阶段**,可能会在未经通知的情况下更改或删除。

在编译代码(衬垫所属的代码)结束时整理衬垫。在此执行的任务包括:从匿名子例程原型衬垫中删除大多数内容;赋予它一个@_;将临时变量标记为临时变量。type 指示子例程的类型。

padtidy_SUB        ordinary subroutine
padtidy_SUBCLONE   prototype for lexical closure
padtidy_FORMAT     format
    void  pad_tidy(padtidy_type type)
perl_alloc

分配一个新的 Perl 解释器。请参阅 perlembed

    PerlInterpreter *  perl_alloc()
PERL_ASYNC_CHECK

perlinterp 中描述。

    void  PERL_ASYNC_CHECK()
perl_clone

通过克隆当前解释器来创建并返回一个新的解释器。

perl_clone 将这些标志作为参数。

CLONEf_COPY_STACKS - 用于复制堆栈,没有它,我们只克隆数据并清零堆栈,有了它,我们复制堆栈,新的 Perl 解释器就可以在与之前相同的点运行。伪 fork 代码使用COPY_STACKS,而线程->create 则不使用。

CLONEf_KEEP_PTR_TABLE - perl_clone 保持一个 ptr_table,其中旧变量的指针作为键,新变量作为值,这允许它检查是否已克隆某个变量,并且不再克隆它,而是直接使用该值并增加引用计数。如果未设置KEEP_PTR_TABLE,则perl_clone 将使用函数 ptr_table_free(PL_ptr_table); PL_ptr_table = NULL; 来销毁 ptr_table。保留它的原因是,如果您想复制一些不在 Perl 扫描的图中的自定义变量。

CLONEf_CLONE_HOST - 这是一个 win32 东西,在 unix 上会被忽略,它告诉 Perl 的 win32host 代码(它是 c++)克隆自身,这在 win32 上是必需的,如果您想同时运行两个线程,如果您只想在单独的 Perl 解释器中执行一些操作,然后丢弃它并返回到原始解释器,则无需执行任何操作。

    PerlInterpreter *  perl_clone(PerlInterpreter *proto_perl,
                                  UV flags)
perl_construct

初始化一个新的 Perl 解释器。参见 perlembed

    void  perl_construct(PerlInterpreter *my_perl)
perl_destruct

关闭一个 Perl 解释器。参见 perlembed 获取教程。

my_perl 指向 Perl 解释器。它必须之前通过使用 "perl_alloc""perl_construct" 创建。它可能已经通过 "perl_parse" 初始化,并且可能已经通过 "perl_run" 和其他方式使用。对于任何使用 "perl_construct" 创建的 Perl 解释器,即使后续操作失败,例如 "perl_parse" 返回非零值,也应该调用此函数。

如果解释器的 PL_exit_flags 字包含 PERL_EXIT_DESTRUCT_END 标志,则此函数将在执行其余销毁操作之前执行 END 块中的代码。如果希望在 "perl_parse""perl_destruct" 之间使用解释器,除了调用 "perl_run" 之外,则应该尽早设置此标志。如果不会调用 "perl_run",或者除了调用 "perl_run" 之外还会执行其他操作,则这一点很重要。

返回一个适合传递给 C 库函数 exit(或从 main 返回)的值,作为指示解释器终止方式的退出代码。这将考虑 "perl_parse" 的任何失败以及 "perl_run" 的任何早期退出。退出代码是主机操作系统所需的类型,因此由于不同的退出代码约定,将特定数值解释为具有特定含义不可移植。

    int  perl_destruct(PerlInterpreter *my_perl)
perl_free

释放一个 Perl 解释器。参见 perlembed

    void  perl_free(PerlInterpreter *my_perl)
PERL_GET_CONTEXT

perlguts 中描述。

PerlInterpreter

perlembed 中描述。

perl_parse

告诉一个 Perl 解释器解析一个 Perl 脚本。这将执行 Perl 解释器的大部分初始化。参见 perlembed 获取教程。

my_perl 指向要解析脚本的 Perl 解释器。它必须之前通过使用 "perl_alloc""perl_construct" 创建。xsinit 指向一个回调函数,该函数将被调用以设置此 Perl 解释器加载 XS 扩展的能力,或者可以为 null 以不执行此类设置。

argcargv 为 Perl 解释器提供一组命令行参数,就像通常传递给 C 程序的 main 函数一样。argv[argc] 必须为 null。这些参数是指定要解析的脚本的位置,可以通过命名脚本文件或在 -e 选项中提供脚本。如果 $0 将在 Perl 解释器中写入,则参数字符串必须位于可写内存中,因此不能只是字符串常量。

env 指定此 Perl 解释器将使用的一组环境变量。如果非 null,它必须指向一个以 null 结尾的环境字符串数组。如果为 null,Perl 解释器将使用 environ 全局变量提供的环境。

此函数初始化解释器,并解析和编译命令行参数指定的脚本。这包括执行BEGINUNITCHECKCHECK块中的代码。它不执行INIT块或主程序。

返回一个整数,其解释略微棘手。返回值的正确用法是作为真值,指示初始化过程中是否发生错误。如果返回零,则表示初始化成功,可以安全地继续调用"perl_run"并进行其他使用。如果返回非零值,则表示存在一些问题,这意味着解释器希望终止。解释器不应该在发生此类错误时被直接放弃;调用者应该继续使用"perl_destruct"干净地关闭解释器,并使用"perl_free"释放它。

出于历史原因,非零返回值还尝试成为一个适合传递给 C 库函数exit(或从main返回)的值,用作指示初始化终止方式的退出代码。但是,由于不同的退出代码约定,这不可移植。它尝试返回主机操作系统所需的类型的退出代码,但由于它被限制为非零,因此不一定能够指示每种类型的退出。它只在 Unix 上可靠,在 Unix 上,零退出代码可以添加一个将被忽略的设置位。无论如何,此函数不是获取退出代码的正确位置:应该从"perl_destruct"获取退出代码。

    int  perl_parse(PerlInterpreter *my_perl, XSINIT_t xsinit,
                    int argc, char **argv, char **env)
perl_run

告诉 Perl 解释器运行其主程序。有关教程,请参阅perlembed

my_perl指向 Perl 解释器。它必须之前通过使用"perl_alloc""perl_construct"创建,并通过"perl_parse"初始化。如果"perl_parse"返回非零值,则不应调用此函数,这表示初始化或编译失败。

此函数执行INIT块中的代码,然后执行主程序。要执行的代码是由之前对"perl_parse"的调用建立的。如果解释器的PL_exit_flags字没有设置PERL_EXIT_DESTRUCT_END标志,则此函数还将在END块中执行代码。如果希望在调用此函数后继续使用解释器,则应通过设置该标志将END块推迟到"perl_destruct"时间。

返回一个整数,其解释略微棘手。返回值的正确使用方法是作为真值,指示程序是否非本地终止。如果返回零,则表示程序已运行完成,并且可以安全地使用解释器(前提是已如上所述设置了PERL_EXIT_DESTRUCT_END标志)。如果返回非零值,则表示解释器希望提前终止。不应该仅仅因为这种终止意愿而放弃解释器;调用者应该继续使用"perl_destruct"干净地关闭解释器,并使用"perl_free"释放它。

出于历史原因,非零返回值也尝试成为一个适合传递给 C 库函数exit(或从main返回)的值,用作退出代码,指示程序终止方式的性质。但是,这不可移植,因为退出代码约定不同。尝试返回主机操作系统所需的类型的退出代码,但由于它被限制为非零,因此不一定能够指示每种类型的退出。它只在 Unix 上可靠,在 Unix 上,零退出代码可以使用将被忽略的设置位进行扩展。无论如何,此函数不是获取退出代码的正确位置:应该从"perl_destruct"获取退出代码。

    int  perl_run(PerlInterpreter *my_perl)
PERL_SET_CONTEXT

perlguts 中描述。

    void  PERL_SET_CONTEXT(PerlInterpreter* i)
PERL_SYS_INIT
PERL_SYS_INIT3

这些提供运行 Perl 解释器所需的 C 运行时环境的系统特定调整。只应使用一个,并且只应在创建任何 Perl 解释器之前调用一次。

它们的不同之处在于PERL_SYS_INIT3还会初始化env

    void  PERL_SYS_INIT (int *argc, char*** argv)
    void  PERL_SYS_INIT3(int *argc, char*** argv, char*** env)
PERL_SYS_TERM

在运行 Perl 解释器后,提供 C 运行时环境的系统特定清理。这应该只调用一次,在释放任何剩余的 Perl 解释器之后。

    void  PERL_SYS_TERM()
PL_exit_flags

包含控制 perl 在 exit() 时行为的标志

  • PERL_EXIT_DESTRUCT_END

    如果设置,则在销毁解释器时执行 END 块。这通常由 perl 本身在解释器构造后设置。

  • PERL_EXIT_ABORT

    在退出时调用 abort()。 这在 Perl 内部使用,如果在处理退出时调用退出,则会中止。

  • PERL_EXIT_WARN

    在退出时发出警告。

  • PERL_EXIT_EXPECTED

    "perlfunc 中的 exit" 运算符设置。

    U8  PL_exit_flags
PL_origalen

perlembed 中描述。

PL_perl_destruct_level

在嵌入时可以设置此值以进行完全清理。

可能的值

  • 0 - 无

  • 1 - 全部

  • 2 或更大 - 全部,并进行检查。

如果 $ENV{PERL_DESTRUCT_LEVEL} 设置为大于 PL_perl_destruct_level 值的整数,则使用其值。

在多线程 Perl 中,每个线程都有此变量的独立副本;每个副本在创建时都使用创建线程副本的当前值进行初始化。

    signed char  PL_perl_destruct_level
ptr_table_fetch

在指针映射表 tbl 中查找 sv,返回其值,如果未找到则返回 NULL。

    void *  ptr_table_fetch(PTR_TBL_t * const tbl,
                            const void * const sv)
ptr_table_free

清除并释放指针表

    void  ptr_table_free(PTR_TBL_t * const tbl)
ptr_table_new

创建一个新的指针映射表

    PTR_TBL_t *  ptr_table_new()
ptr_table_split

将现有指针表的哈希桶大小加倍

    void  ptr_table_split(PTR_TBL_t * const tbl)
ptr_table_store

向指针映射表 tbl 添加一个新条目。 在哈希术语中,oldsv 是键;Cnewsv> 是值。

"old" 和 "new" 这些名称是针对内核在线程克隆中使用 ptr_tables 的典型用法。

    void  ptr_table_store(PTR_TBL_t * const tbl,
                          const void * const oldsv,
                          void * const newsv)
require_pv

告诉 Perl require 由字符串参数命名的文件。 它类似于 Perl 代码 eval "require '$file'"。 它甚至以这种方式实现;考虑使用 load_module 代替。

注意:perl_require_pv() 形式已弃用

    void  require_pv(const char *pv)
vload_module

类似于 "load_module",但参数是封装的参数列表。

    void  vload_module(U32 flags, SV *name, SV *ver, va_list *args)

Errno

sv_string_from_errnum

生成描述操作系统错误的消息字符串,并将其作为 SV 返回。 errnum 必须是 errno 可以取的值,标识错误类型。

如果 tgtsv 非空,则字符串将写入该 SV(覆盖现有内容)并返回。 如果 tgtsv 是空指针,则字符串将写入一个新的 mortal SV,该 SV 将被返回。

消息将来自 $! 将使用的任何区域设置,并将以 $! 将使用的任何方式在 SV 中编码。 此过程的详细信息可能会在将来发生变化。 当前,消息默认情况下来自 C 区域设置(通常生成英文消息),并在 use locale 编译指令的范围内从当前选择的区域设置获取。 将尝试使用启发式方法从区域设置的字符编码解码消息,但它只会解码为 UTF-8 或 ISO-8859-1。 它始终在 UTF-8 区域设置中正确解码,通常在 ISO-8859-1 区域设置中正确解码,而在任何其他区域设置中都不会正确解码。

SV 始终返回包含实际字符串的值,并且没有其他 OK 位被设置。与 $! 不同,即使对于 errnum 为零(表示成功)也会产生消息,如果没有任何有用的消息可用,则会返回一个无用的字符串(目前为空)。

    SV *  sv_string_from_errnum(int errnum, SV *tgtsv)

异常处理(简单)宏

dXCPT

为异常处理设置必要的局部变量。参见 "perlguts 中的异常处理"

    dXCPT;
JMPENV_JUMP

perlinterp 中描述。

    void  JMPENV_JUMP(int v)
JMPENV_PUSH

perlinterp 中描述。

    void  JMPENV_PUSH(int v)
PL_restartop

perlinterp 中描述。

XCPT_CATCH

引入一个捕获块。参见 "perlguts 中的异常处理"

XCPT_RETHROW

重新抛出先前捕获的异常。参见 "perlguts 中的异常处理"

    XCPT_RETHROW;
XCPT_TRY_END

结束一个 try 块。参见 "perlguts 中的异常处理"

XCPT_TRY_START

开始一个 try 块。参见 "perlguts 中的异常处理"

文件系统配置值

另请参见 "功能 HAS_foo 符号列表"

DIRNAMLEN

如果定义了此符号,则表示 C 程序可以通过 d_namlen 字段获取目录条目名称的长度。否则,您需要对 d_name 字段执行 strlen() 操作。

DOSUID

如果定义了此符号,则表示 C 程序应该检查它正在执行的脚本的 setuid/setgid 位,并在系统禁用 setuid #! 脚本(因为内核无法安全地执行此操作)的情况下尝试模拟 setuid/setgid。由软件包设计者确保此模拟是安全执行的。除其他事项外,它应该对刚刚打开的脚本执行 fstat 操作,以确保它确实是一个 setuid/setgid 脚本,它应该确保传递的参数与 #! 行上的参数完全一致,并且它不应该信任任何必须传递文件名而不是脚本文件描述符的子进程以供执行。

EOF_NONBLOCK

如果定义了此符号,则表示在非阻塞文件描述符上进行read()操作时,如果遇到EOF,将返回0,而不是RD_NODATA(通常为-1)中保存的值!

FCNTL_CAN_LOCK

如果定义了此符号,则表示可以使用fcntl()进行文件锁定。通常在 Unix 系统上定义此符号。它可能在VMS上未定义。

FFLUSH_ALL

如果定义了此符号,则表示要刷新所有挂起的 stdio 输出,必须循环遍历存储在数组中的所有 stdio 文件句柄并对其进行fflush操作。请注意,如果定义了fflushNULL,则不会探测fflushall,并且它将保持未定义状态。

FFLUSH_NULL

如果定义了此符号,则表示fflush(NULL)可以正确刷新所有挂起的 stdio 输出,而不会产生副作用。特别是在某些平台上,调用fflush(NULL)*仍然*会破坏STDIN(如果它是管道)。

FILE_base

此宏用于访问其参数指向的FILE结构的_base字段(或等效字段)。如果定义了USE_STDIO_BASE,则此宏将始终定义。

    void *  FILE_base(FILE * f)
FILE_bufsiz

此宏用于确定其参数指向的FILE结构的_base字段(或等效字段)指向的 I/O 缓冲区中的字节数。如果定义了USE_STDIO_BASE,则此宏将始终定义。

    Size_t  FILE_bufsiz(FILE *f)
FILE_cnt

此宏用于访问其参数指向的FILE结构的_cnt字段(或等效字段)。如果定义了USE_STDIO_PTR,则此宏将始终定义。

    Size_t  FILE_cnt(FILE * f)
FILE_ptr

此宏用于访问其参数指向的FILE结构的_ptr字段(或等效字段)。如果定义了USE_STDIO_PTR,则此宏将始终定义。

    void *  FILE_ptr(FILE * f)
FLEXFILENAMES

如果定义了此符号,则表示系统支持长度超过 14 个字符的文件名。

HAS_DIR_DD_FD

如果定义了此符号,则表示DIR* dirstream 结构包含一个名为dd_fd的成员变量。

HAS_DUP2

如果定义了此符号,则表示dup2例程可用于复制文件描述符。

HAS_DUP3

如果定义了此符号,则表示dup3例程可用于复制文件描述符。

HAS_FAST_STDIO

如果定义了此符号,则表示“快速 stdio”可用,可以直接操作 stdio 缓冲区。

HAS_FCHDIR

如果定义了此符号,则表示fchdir例程可用,可以使用文件描述符更改目录。

HAS_FCNTL

如果定义了此符号,则表示 C 程序中存在fcntl()函数。

HAS_FDCLOSE

如果定义了此符号,则表示fdclose例程可用,可以释放FILE结构,而不会关闭底层文件描述符。此函数出现在FreeBSD 10.2 中。

HAS_FPATHCONF

如果定义了此符号,则表示pathconf()可用,用于确定与给定打开文件描述符关联的文件系统相关限制和选项。

HAS_FPOS64_T

如果 C 编译器支持fpos64_t,则将定义此符号。

HAS_FSTATFS

如果定义了此符号,则表示fstatfs例程可用,可以通过文件描述符统计文件系统。

HAS_FSTATVFS

如果定义了此符号,则表示fstatvfs例程可用,可以通过文件描述符统计文件系统。

HAS_GETFSSTAT

如果定义了此符号,则表示getfsstat例程可用,可以批量统计文件系统。

HAS_GETMNT

如果定义了此符号,则表示getmnt例程可用,可以通过文件名获取文件系统挂载信息。

HAS_GETMNTENT

如果定义了此符号,则表示getmntent例程可用,可以遍历已挂载的文件系统以获取其信息。

HAS_HASMNTOPT

如果定义了此符号,则表示hasmntopt例程可用,用于查询文件系统的挂载选项。

HAS_LSEEK_PROTO

如果定义了此符号,则表示系统提供了lseek()函数的原型。否则,程序需要自行提供。一个好的猜测是

extern off_t lseek(int, off_t, int);
HAS_MKDIR

如果定义了此符号,则表示mkdir例程可用于创建目录。否则,您应该派生一个新进程来执行/bin/mkdir

HAS_OFF64_T

如果 C 编译器支持off64_t,则将定义此符号。

HAS_OPENAT

如果openat()例程可用,则定义此符号。

HAS_OPEN3

此清单常量让 C 程序知道open(2)的三参数形式可用。

HAS_POLL

如果定义了此符号,则表示poll例程可用于poll活动文件描述符。请检查I_POLLI_SYS_POLL以了解应包含哪个头文件。

HAS_READDIR

如果定义了此符号,则表示readdir例程可用于读取目录条目。您可能需要包含dirent.h。请参阅"I_DIRENT"

HAS_READDIR64_R

如果定义了此符号,则表示readdir64_r例程可用于以可重入方式读取目录。

HAS_REWINDDIR

如果定义了此符号,则表示rewinddir例程可用。您可能需要包含dirent.h。请参阅"I_DIRENT"

HAS_RMDIR

如果定义了此符号,则表示rmdir例程可用于删除目录。否则,您应该派生一个新进程来执行/bin/rmdir

HAS_SEEKDIR

如果定义了此符号,则表示seekdir例程可用。您可能需要包含dirent.h。请参阅"I_DIRENT"

HAS_SELECT

如果定义了此符号,则表示select例程可用于select活动文件描述符。如果使用超时字段,则可能需要包含sys/time.h

HAS_SETVBUF

如果定义了此符号,则表示setvbuf例程可用于更改打开的 stdio 流的缓冲区,使其进入行缓冲模式。

HAS_STDIO_STREAM_ARRAY

如果定义了此符号,则表示存在一个数组来保存 stdio 流。

HAS_STRUCT_FS_DATA

如果定义了此符号,则表示支持用于执行statfs()struct fs_data

HAS_STRUCT_STATFS

如果定义了此符号,则表示支持用于执行statfs()struct statfs

HAS_STRUCT_STATFS_F_FLAGS

如果定义了此符号,则表示struct statfs具有f_flags成员,该成员包含包含该文件的文件系统的挂载标志。这种类型的struct statfs来自sys/mount.hBSD 4.3),而不是来自sys/statfs.hSYSV)。较旧的BSD(如 Ultrix)没有statfs()struct statfs,它们有ustat()getmnt(),以及struct ustatstruct fs_data

HAS_TELLDIR

如果定义了此符号,则表示telldir例程可用。您可能需要包含dirent.h。请参阅"I_DIRENT"

HAS_USTAT

如果定义了此符号,则表示ustat系统调用可用,可以通过dev_t查询文件系统统计信息。

I_FCNTL

此清单常量告诉 C 程序包含fcntl.h

    #ifdef I_FCNTL
        #include <fcntl.h>
    #endif
I_SYS_DIR

如果定义了此符号,则表示 C 程序应包含sys/dir.h

    #ifdef I_SYS_DIR
        #include <sys_dir.h>
    #endif
I_SYS_FILE

如果定义了此符号,则表示 C 程序应包含sys/file.h以获取R_OK及其同类的定义。

    #ifdef I_SYS_FILE
        #include <sys_file.h>
    #endif
I_SYS_NDIR

如果定义了此符号,则表示 C 程序应包含sys/ndir.h

    #ifdef I_SYS_NDIR
        #include <sys_ndir.h>
    #endif
I_SYS_STATFS

如果定义了此符号,则表示sys/statfs.h存在。

    #ifdef I_SYS_STATFS
        #include <sys_statfs.h>
    #endif
LSEEKSIZE

此符号保存Off_t使用的字节数。

RD_NODATA

此符号保存当非阻塞文件描述符上没有数据时read()的返回值。注意!如果未定义EOF_NONBLOCK,则无法通过发出read()来区分无数据和EOF。您将不得不找到其他方法来确定!

READDIR64_R_PROTO

此符号对readdir64_r的原型进行编码。如果d_readdir64_r未定义,则为零;如果d_readdir64_r已定义,则为reentr.hREENTRANT_PROTO_T_ABC宏之一。

STDCHAR

此符号定义为stdio.h中使用的char类型。它具有“unsigned char”或“char”的值。

STDIO_CNT_LVALUE

如果FILE_cnt宏可以用作左值,则定义此符号。

STDIO_PTR_LVAL_NOCHANGE_CNT

如果将FILE_ptr宏用作左值以将指针增加n,则File_cnt(fp)保持不变,则定义此符号。

STDIO_PTR_LVAL_SETS_CNT

如果将FILE_ptr宏用作左值以将指针增加n,则会产生将File_cnt(fp)的值减少n的副作用,则定义此符号。

STDIO_PTR_LVALUE

如果FILE_ptr宏可以用作左值,则定义此符号。

STDIO_STREAM_ARRAY

此符号告诉保存stdio流的数组的名称。常见值包括_iob__iob__sF

ST_INO_SIGN

此符号保存struct statst_ino的符号。1表示无符号,-1表示有符号。

ST_INO_SIZE

此变量包含struct statst_ino的大小(以字节为单位)。

VAL_EAGAIN

此符号保存当非阻塞文件描述符上没有数据时read()设置的errno错误代码。

VAL_O_NONBLOCK

此符号在open()fcntl(F_SETFL)期间使用,以打开文件描述符的非阻塞I/O。请注意,没有回头路,即您无法通过这种方式将其再次设置为阻塞。如果您希望在阻塞和非阻塞之间切换,请使用ioctl(FIOSNBIO)调用,但并非所有设备都支持该调用。

VOID_CLOSEDIR

如果定义了此符号,则表示closedir()例程不返回值。

浮点数

此外,"List of capability HAS_foo symbols" 列出了本节中未包含的功能。例如,HAS_ASINH,用于双曲正弦函数。

CASTFLAGS

此符号包含标志,用于说明编译器在将奇数浮点值转换为无符号长整型时遇到的困难。

0 = ok
1 = couldn't cast < 0
2 = couldn't cast >= 0x80000000
4 = couldn't cast in argument expression list
CASTNEGFLOAT

如果 C 编译器可以将负数转换为无符号长整型、整型和短整型,则定义此符号。

DOUBLE_HAS_INF

如果定义了此符号,则表示双精度浮点数具有无穷大。

DOUBLE_HAS_NAN

如果定义了此符号,则表示双精度浮点数具有非数字。

DOUBLE_HAS_NEGATIVE_ZERO

如果定义了此符号,则表示双精度浮点数具有负零

DOUBLE_HAS_SUBNORMALS

如果定义了此符号,则表示双精度浮点数具有次正规数(非规格化数)。

DOUBLEINFBYTES

如果定义了此符号,则它是一个逗号分隔的十六进制字节列表,用于表示双精度无穷大。

DOUBLEKIND

DOUBLEKIND 将是以下之一:DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE DOUBLE_IS_VAX_F_FLOAT DOUBLE_IS_VAX_D_FLOAT DOUBLE_IS_VAX_G_FLOAT DOUBLE_IS_IBM_SINGLE_32_BIT DOUBLE_IS_IBM_DOUBLE_64_BIT DOUBLE_IS_CRAY_SINGLE_64_BIT DOUBLE_IS_UNKNOWN_FORMAT

DOUBLEMANTBITS

如果定义了此符号,则它表示双精度浮点数格式中尾数位的数量。请注意,这通常是DBL_MANT_DIG 减 1,因为在标准IEEE 754 格式中,DBL_MANT_DIG 包含隐式位,而隐式位实际上并不存在。

DOUBLENANBYTES

如果定义了此符号,则它是一个逗号分隔的十六进制字节列表(0xHH),用于表示双精度非数字。

DOUBLESIZE

此符号包含双精度浮点数的大小,以便 C 预处理器可以根据它做出决策。

DOUBLE_STYLE_CRAY

如果定义了此符号,则表示双精度浮点数为 64 位 CRAY 大型机格式。

DOUBLE_STYLE_IBM

如果定义了此符号,则表示双精度浮点数为 64 位 IBM 大型机格式。

DOUBLE_STYLE_IEEE

如果定义了此符号,则表示双精度浮点数为 64 位 IEEE 754。

DOUBLE_STYLE_VAX

如果定义了此符号,则表示双精度浮点数为 64 位 VAX 格式 D 或 G。

HAS_ATOLF

如果定义了此符号,则表示 atolf 例程可用,可将字符串转换为长双精度浮点数。

HAS_CLASS

如果定义了此符号,则表示 class 例程可用,可对双精度浮点数进行分类。例如,在 AIX 中可用。返回的值在 float.h 中定义,分别是

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)
HAS_FINITE

如果定义了此符号,则表示 finite 例程可用,可检查双精度浮点数是否为 finite(非无穷大非 NaN)。

HAS_FINITEL

如果定义了此符号,则表示 finitel 例程可用,可检查长双精度浮点数是否为 finite(非无穷大非 NaN)。

HAS_FPCLASS

如果定义了此符号,则表示 fpclass 例程可用,可对双精度浮点数进行分类。例如,在 Solaris/SVR4 中可用。返回的值在 ieeefp.h 中定义,分别是

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
HAS_FP_CLASS

如果定义了此符号,则表示 fp_class 例程可用,可对双精度浮点数进行分类。例如,在 Digital UNIX 中可用。返回的值在 math.h 中定义,分别是

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)
HAS_FPCLASSIFY

如果定义了此符号,则表示 fpclassify 例程可用,可对双精度浮点数进行分类。例如,在 HP-UX 中可用。返回的值在 math.h 中定义,分别是

FP_NORMAL     Normalized
FP_ZERO       Zero
FP_INFINITE   Infinity
FP_SUBNORMAL  Denormalized
FP_NAN        NaN
HAS_FP_CLASSIFY

如果定义了此符号,则表示 fp_classify 例程可用,可对双精度浮点数进行分类。这些值在 math.h 中定义。

FP_NORMAL     Normalized
FP_ZERO       Zero
FP_INFINITE   Infinity
FP_SUBNORMAL  Denormalized
FP_NAN        NaN
HAS_FPCLASSL

如果定义了此符号,则表示 fpclassl 例程可用,可对长双精度浮点数进行分类。例如,在 IRIX 中可用。返回的值在 ieeefp.h 中定义,分别是

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
HAS_FP_CLASSL

如果定义了此符号,则表示fp_classl例程可用于对长双精度浮点数进行分类。例如,在 Digital UNIX 中可用。有关可能的值,请参见HAS_FP_CLASS

HAS_FPGETROUND

如果定义了此符号,则表示fpgetround例程可用于获取浮点舍入模式。

HAS_FREXPL

如果定义了此符号,则表示frexpl例程可用于将长双精度浮点数分解为归一化分数和 2 的整数幂。

HAS_ILOGB

如果定义了此符号,则表示ilogb例程可用于获取浮点值的整数指数。

HAS_ISFINITE

如果定义了此符号,则表示isfinite例程可用于检查双精度浮点数是否为有限数(非无穷大非 NaN)。

HAS_ISFINITEL

如果定义了此符号,则表示isfinitel例程可用于检查长双精度浮点数是否为有限数(非无穷大非 NaN)。

HAS_ISINF

如果定义了此符号,则表示isinf例程可用于检查双精度浮点数是否为无穷大。

HAS_ISINFL

如果定义了此符号,则表示isinfl例程可用于检查长双精度浮点数是否为无穷大。

HAS_ISNAN

如果定义了此符号,则表示isnan例程可用于检查双精度浮点数是否为 NaN。

HAS_ISNANL

如果定义了此符号,则表示isnanl例程可用于检查长双精度浮点数是否为 NaN。

HAS_ISNORMAL

如果定义了此符号,则表示isnormal例程可用于检查双精度浮点数是否为正常数(非零归一化)。

HAS_J0L

如果定义了此符号,则表示 C 程序可以使用j0l()函数来计算长双精度浮点数的零阶第一类贝塞尔函数。

HAS_J0

如果定义了此符号,则表示 C 程序可以使用j0()函数来计算双精度浮点数的零阶第一类贝塞尔函数。

HAS_LDBL_DIG

如果定义了此符号,则表示该系统的float.hlimits.h定义了符号LDBL_DIG,它表示长双精度浮点数的有效数字位数。与DBL_DIG不同,如果未定义LDBL_DIG,则无法对其进行合理的猜测。

HAS_LDEXPL

如果定义了此符号,则表示 ldexpl 例程可用,用于将长双精度浮点数按 2 的整数次幂进行移位。

HAS_LLRINT

如果定义了此符号,则表示 llrint 例程可用,用于返回最接近双精度数的长长整数值(根据当前舍入模式)。

HAS_LLRINTL

如果定义了此符号,则表示 llrintl 例程可用,用于返回最接近长双精度数的长长整数值(根据当前舍入模式)。

HAS_LLROUNDL

如果定义了此符号,则表示 llroundl 例程可用,用于返回长双精度参数值远离零的最近长长整数值。

HAS_LONG_DOUBLE

如果 C 编译器支持长双精度数,则将定义此符号。

HAS_LRINT

如果定义了此符号,则表示 lrint 例程可用,用于返回最接近双精度数的整数值(根据当前舍入模式)。

HAS_LRINTL

如果定义了此符号,则表示 lrintl 例程可用,用于返回最接近长双精度数的整数值(根据当前舍入模式)。

HAS_LROUNDL

如果定义了此符号,则表示 lroundl 例程可用,用于返回长双精度参数值远离零的最近整数值。

HAS_MODFL

如果定义了此符号,则表示 modfl 例程可用,用于将长双精度数 x 分解为小数部分 f 和整数部分 i,使得 |f| < 1.0 且 (f + i) = x。

HAS_NAN

如果定义了此符号,则表示 nan 例程可用,用于生成 NaN。

HAS_NEXTTOWARD

如果定义了此符号,则表示 nexttoward 例程可用,用于返回 x 在 y 方向上的下一个机器可表示的长双精度数。

HAS_REMAINDER

如果定义了此符号,则表示remainder例程可用以返回浮点remainder

HAS_SCALBN

如果定义了此符号,则表示scalbn例程可用以将浮点数乘以基数的整数次幂。

HAS_SIGNBIT

如果定义了此符号,则表示signbit例程可用以检查给定数字的符号位是否已设置。这应包括对 -0.0 的正确测试。仅当signbit()例程在 perl 内部使用的 NV 类型中安全使用时才会设置此标志。用户应调用Perl_signbit(),如果定义了此符号,它将被 #defined 为系统signbit()函数或宏。

HAS_SQRTL

如果定义了此符号,则表示sqrtl例程可用以进行长双精度平方根运算。

HAS_STRTOD_L

如果定义了此符号,则表示strtod_l例程可用以将字符串转换为长双精度数。

HAS_STRTOLD

如果定义了此符号,则表示strtold例程可用以将字符串转换为长双精度数。

HAS_STRTOLD_L

如果定义了此符号,则表示strtold_l例程可用以将字符串转换为长双精度数。

HAS_TRUNC

如果定义了此符号,则表示trunc例程可用以将双精度数向零舍入。

HAS_UNORDERED

如果定义了此符号,则表示unordered例程可用以检查两个双精度数是否unordered(实际上:它们是否都是 NaN)。

I_FENV

如果定义了此符号,则表示 C 程序应包含fenv.h以获取浮点环境定义。

    #ifdef I_FENV
        #include <fenv.h>
    #endif
I_QUADMATH

如果定义了此符号,则表示quadmath.h存在,应包含它。

    #ifdef I_QUADMATH
        #include <quadmath.h>
    #endif
LONGDBLINFBYTES

如果定义了此符号,它将是长双精度无穷大的十六进制字节的逗号分隔列表。

LONGDBLMANTBITS

如果定义了此符号,它将说明长双精度浮点格式中存在多少个尾数位。请注意,这可能是LDBL_MANT_DIG减去一,因为LDBL_MANT_DIG可能包含IEEE 754 隐式位。常见的 x86 风格 80 位长双精度数没有隐式位。

LONGDBLNANBYTES

如果定义了此符号,它将是长双精度非数字的十六进制字节 (0xHH) 的逗号分隔列表。

LONG_DOUBLEKIND

LONG_DOUBLEKIND将是以下之一:LONG_DOUBLE_IS_DOUBLE LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN LONG_DOUBLE_IS_VAX_H_FLOAT LONG_DOUBLE_IS_UNKNOWN_FORMAT 它仅在系统支持长双精度数时定义。

LONG_DOUBLESIZE

此符号包含 long double 的大小,以便 C 预处理器可以根据它做出决策。它仅在系统支持 long double 时定义。请注意,这是 sizeof(long double),它可能包含未使用的字节。

LONG_DOUBLE_STYLE_IEEE

如果定义了此符号,则表示 long double 是任何 IEEE 754 风格的 long double:LONG_DOUBLE_STYLE_IEEE_STDLONG_DOUBLE_STYLE_IEEE_EXTENDEDLONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE

LONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE

如果定义了此符号,则表示 long double 是 128 位双双精度。

LONG_DOUBLE_STYLE_IEEE_EXTENDED

如果定义了此符号,则表示 long double 是 80 位 IEEE 754。请注意,尽管是“扩展”,但它小于“std”,因为这是对双精度的一种扩展。

LONG_DOUBLE_STYLE_IEEE_STD

如果定义了此符号,则表示 long double 是 128 位 IEEE 754。

LONG_DOUBLE_STYLE_VAX

如果定义了此符号,则表示 long double 是 128 位 VAX 格式 H。

NV

perlguts 中描述。

NVMANTBITS

如果定义了此符号,则表示 Perl NV 中有多少个尾数位(不包括隐式位)。这取决于选择了哪种浮点类型。

NV_OVERFLOWS_INTEGERS_AT

此符号给出 NV 可以保存的最大整数值。此值 + 1.0 无法准确存储。它表示为常量浮点表达式,以减少十进制/二进制转换问题的可能性。如果无法确定,则给出值 0。

NV_PRESERVES_UV

如果定义了此符号,则表示类型为 NVTYPE 的变量可以保留类型为 UVTYPE 的变量的所有位。

NV_PRESERVES_UV_BITS

此符号包含类型为 NVTYPE 的变量可以保留的类型为 UVTYPE 的变量的位数。

NVSIZE

此符号包含 sizeof(NV)。请注意,某些浮点格式有未使用的字节。最显著的例子是 x86* 80 位扩展精度,它以 12 和 16 字节大小出现(分别针对 32 位和 64 位平台),但只使用 10 个字节。在 x86* 上使用 -Duselongdouble 编译的 Perl 就是这样。

NVTYPE

此符号定义了 Perl 的 NV 使用的 C 类型。

NV_ZERO_IS_ALLBITS_ZERO

如果定义了此符号,则表示类型为 NVTYPE 的变量在内存中以全零位存储 0.0。

通用配置

本节包含不在本文档更专门部分中找到的配置信息。在最后,列出了 #defines,其名称应该足以告诉您它们的作用,以及列出了 #defines,这些 #defines 告诉您是否需要 #include 文件以获得相应的功能。

ASCIIish

如果系统是 ASCII 平台,则定义的预处理器符号;此符号不会在 "EBCDIC" 平台上定义。

    #ifdef  ASCIIish
BYTEORDER

此符号包含在 byteorder 中定义的十六进制常量,在 UV 中,即 0x1234 或 0x4321 或 0x12345678 等... 如果编译器支持交叉编译或多架构二进制文件,请使用编译器定义的宏来确定字节顺序。

CHARBITS

此符号包含 char 的大小,以便 C 预处理器可以根据它做出决定。

DB_VERSION_MAJOR_CFG

如果定义了此符号,则定义了在配置 Perl 时在 db.h 标头中找到的 Berkeley DB 的主版本号。

DB_VERSION_MINOR_CFG

如果定义了此符号,则定义了在配置 Perl 时在 db.h 标头中找到的 Berkeley DB 的次版本号。对于 DB 版本 1,这始终为 0。

DB_VERSION_PATCH_CFG

如果定义了此符号,则定义了在配置 Perl 时在 db.h 标头中找到的 Berkeley DB 的补丁版本号。对于 DB 版本 1,这始终为 0。

DEFAULT_INC_EXCLUDES_DOT

如果定义了此符号,则会删除在 @INC 末尾包含 '.' 的传统默认行为。

DLSYM_NEEDS_UNDERSCORE

如果定义了此符号,则表示在调用 dlsym() 之前,我们需要在符号名称前面加上下划线。这只有在你 *有* dlsym 的情况下才有意义,我们假设如果你正在使用 dl_dlopen.xs,那么你就有 dlsym。

EBCDIC

如果定义了此符号,则表示该系统使用EBCDIC编码。

HAS_CSH

如果定义了此符号,则表示存在 C shell。

HAS_GETHOSTNAME

如果定义了此符号,则表示 C 程序可以使用gethostname()例程来获取主机名。另请参见"HAS_UNAME""PHOSTNAME"

HAS_GNULIBC

如果定义了此符号,则表示 C 程序正在使用GNU C 库。更好的检查方法是使用 glibc 提供的__GLIBC____GLIBC_MINOR__符号。

HAS_LGAMMA

如果定义了此符号,则表示lgamma例程可用,可以执行对数伽马函数。另请参见"HAS_TGAMMA""HAS_LGAMMA_R"

HAS_LGAMMA_R

如果定义了此符号,则表示lgamma_r例程可用,可以执行对数伽马函数,而无需使用全局 signgam 变量。

HAS_NON_INT_BITFIELDS

如果定义了此符号,则表示 C 编译器接受(不报错或警告)struct bitfields,这些struct bitfields声明的尺寸不是简单的 'int';例如,接受 'unsigned char'。

HAS_PRCTL_SET_NAME

如果定义了此符号,则表示 prctl 例程可用,可以设置进程标题并支持PR_SET_NAME

HAS_PROCSELFEXE

如果PROCSELFEXE_PATH是执行程序的绝对路径名的符号链接,则定义此符号。

HAS_PSEUDOFORK

如果定义了此符号,则表示 fork 例程的模拟可用。

HAS_REGCOMP

如果定义了此符号,则表示 regcomp() 例程可用,用于执行一些正则表达式匹配(通常在符合 POSIX.2 的系统上)。

HAS_SETPGID

如果定义了此符号,则表示 setpgid(pid, gpid) 例程可用,用于设置进程组 ID。

HAS_SIGSETJMP

此变量指示 C 程序 sigsetjmp() 例程可用,用于保存调用进程的寄存器和堆栈环境,以便稍后由 siglongjmp() 使用,并可以选择保存进程的信号掩码。请参阅 "Sigjmp_buf""Sigsetjmp""Siglongjmp"

HAS_STRUCT_CMSGHDR

如果定义了此符号,则表示支持 struct cmsghdr

HAS_STRUCT_MSGHDR

如果定义了此符号,则表示支持 struct msghdr

HAS_TGAMMA

如果定义了此符号,则表示 tgamma 例程可用,用于执行伽马函数。另请参阅 "HAS_LGAMMA"

HAS_UNAME

如果定义了此符号,则表示 C 程序可以使用 uname() 例程来获取主机名。另请参阅 "HAS_GETHOSTNAME""PHOSTNAME"

HAS_UNION_SEMUN

如果定义了此符号,则表示 union semun 是通过包含 sys/sem.h 定义的。如果没有,用户代码可能需要将其定义为

union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
}
I_DIRENT

如果定义了此符号,则表示 C 程序应包含 dirent.h。使用此符号还会触发 Direntry_t 定义的定义,该定义最终将是 'struct dirent' 或 'struct direct',具体取决于 dirent.h 的可用性。

    #ifdef I_DIRENT
        #include <dirent.h>
    #endif
I_POLL

如果定义了此符号,则表示 poll.h 存在,应包含该文件。(另请参阅 "HAS_POLL"

    #ifdef I_POLL
        #include <poll.h>
    #endif
I_SYS_RESOURCE

如果定义了此符号,则表示 C 程序应包含 sys/resource.h

    #ifdef I_SYS_RESOURCE
        #include <sys_resource.h>
    #endif
LIBM_LIB_VERSION

如果定义了此符号,则表示 libm 导出 _LIB_VERSION 并且 math.h 定义了用于操作它的枚举。

NEED_VA_COPY

如果定义了此符号,则表示系统以无法通过简单赋值复制的格式存储可变参数列表数据类型 va_list,因此在需要复制时必须使用其他方法。由于这些系统在提供(或不提供)复制机制方面有所不同,因此 handy.h 定义了一个平台无关的宏 Perl_va_copy(src, dst) 来完成这项工作。

OSNAME

此符号包含由 Configure 确定的操作系统名称。你不应该过分依赖它;来自 Configure 的特定功能测试通常更可靠。

OSVERS

此符号包含由 Configure 确定的操作系统版本。你不应该过分依赖它;来自 Configure 的特定功能测试通常更可靠。

PERL_USE_GCC_BRACE_GROUPS

如果定义了此 C 预处理器值,则表示允许使用 GCC 大括号组扩展。但是,不鼓励使用此扩展。请改用 static inline 函数。

扩展形式为

({ statement ... })

将由 statement ... 组成的块转换为具有值的表达式,这与普通 C 语言块不同。这可以提供优化可能性,但是,除非你确定这永远不会在没有此扩展可用且未被禁止的情况下编译,否则你需要指定一个替代方案。因此,必须维护两个代码路径,这可能会导致不同步。所有这些问题都可以通过改用 static inline 函数来解决。

可以通过将参数 -Accflags=-DPERL_GCC_BRACE_GROUPS_FORBIDDEN 传递给 Configure 来配置 Perl 以不使用此功能。

    #ifdef  PERL_USE_GCC_BRACE_GROUPS
PHOSTNAME

如果定义了此符号,则表示要馈送到 popen() 例程以获取主机名的命令。另请参阅 "HAS_GETHOSTNAME""HAS_UNAME"。请注意,该命令使用完全限定路径,因此即使由具有超级用户权限的进程使用也是安全的。

PROCSELFEXE_PATH

如果定义了 HAS_PROCSELFEXE,则此符号是指向正在执行程序的绝对路径名的符号链接的文件名。

PTRSIZE

此符号包含指针的大小,以便 C 预处理器可以根据它做出决定。如果编译器支持 (void *),它将为 sizeof(void *);否则,它将为 sizeof(char *)

RANDBITS

此符号指示用于生成归一化随机数的函数产生的位数。值包括 15、16、31 和 48。

SELECT_MIN_BITS

此符号表示 select 操作的最小位数。也就是说,如果您执行 select(n, ...),如果检测到某些活动,则至少将清除多少位掩码。通常,这要么是 n,要么是 32*ceil(n/32),特别是许多小端系统会执行后者。这只有在您有 select() 的情况下才有用。

SETUID_SCRIPTS_ARE_SECURE_NOW

如果定义了此符号,则表示阻止 setuid 脚本安全的错误在当前内核中不存在。

ST_DEV_SIGN

此符号表示 struct statst_dev 的符号性。1 表示无符号,-1 表示有符号。

ST_DEV_SIZE

此变量包含 struct statst_dev 的大小(以字节为单位)。

能力 HAS_foo 符号列表

这是一个符号列表,这些符号未出现在本文档的其他地方,它们指示当前平台是否具有某种能力。它们的名称都以 HAS_ 开头。此处仅列出其能力直接从名称派生的符号。所有其他符号的含义在本文档的其他地方进行了扩展。这个(相对)简洁的列表是因为我们认为扩展会增加很少或没有价值,并且会占用大量空间(因为符号很多)。如果您认为某些符号应该扩展,请发送电子邮件至 [email protected]

此处每个符号仅当且仅当平台具有该能力时才会被 #define。如果您需要更多详细信息,请参阅 config.h 中的相应条目。为了方便起见,该列表被拆分,以便那些指示存在某个能力的重新进入版本的符号被单独列出

HAS_ACCEPT4, HAS_ACCESS, HAS_ACCESSX, HAS_ACOSH, HAS_AINTL, HAS_ALARM, HAS_ASINH, HAS_ATANH, HAS_ATOLL, HAS_CBRT, HAS_CHOWN, HAS_CHROOT, HAS_CHSIZE, HAS_CLEARENV, HAS_COPYSIGN, HAS_COPYSIGNL, HAS_CRYPT, HAS_CTERMID, HAS_CUSERID, HAS_DIRFD, HAS_DLADDR, HAS_DLERROR, HAS_EACCESS, HAS_ENDHOSTENT, HAS_ENDNETENT, HAS_ENDPROTOENT, HAS_ENDSERVENT, HAS_ERF, HAS_ERFC, HAS_EXPM1, HAS_EXP2, HAS_FCHMOD, HAS_FCHMODAT, HAS_FCHOWN, HAS_FDIM, HAS_FD_SET, HAS_FEGETROUND, HAS_FFS, HAS_FFSL, HAS_FGETPOS, HAS_FLOCK, HAS_FMA, HAS_FMAX, HAS_FMIN, HAS_FORK, HAS_FSEEKO, HAS_FSETPOS, HAS_FSYNC, HAS_FTELLO, HAS__FWALK, HAS_GAI_STRERROR, HAS_GETADDRINFO, HAS_GETCWD, HAS_GETESPWNAM, HAS_GETGROUPS, HAS_GETHOSTBYADDR, HAS_GETHOSTBYNAME, HAS_GETHOSTENT, HAS_GETLOGIN, HAS_GETNAMEINFO, HAS_GETNETBYADDR, HAS_GETNETBYNAME, HAS_GETNETENT, HAS_GETPAGESIZE, HAS_GETPGID, HAS_GETPGRP, HAS_GETPGRP2, HAS_GETPPID, HAS_GETPRIORITY, HAS_GETPROTOBYNAME, HAS_GETPROTOBYNUMBER, HAS_GETPROTOENT, HAS_GETPRPWNAM, HAS_GETSERVBYNAME, HAS_GETSERVBYPORT, HAS_GETSERVENT, HAS_GETSPNAM, HAS_HTONL, HAS_HTONS, HAS_HYPOT, HAS_ILOGBL, HAS_INET_ATON, HAS_INETNTOP, HAS_INETPTON, HAS_IP_MREQ, HAS_IP_MREQ_SOURCE, HAS_IPV6_MREQ, HAS_IPV6_MREQ_SOURCE, HAS_ISASCII, HAS_ISBLANK, HAS_ISLESS, HAS_KILLPG, HAS_LCHOWN, HAS_LINK, HAS_LINKAT, HAS_LLROUND, HAS_LOCKF, HAS_LOGB, HAS_LOG1P, HAS_LOG2, HAS_LROUND, HAS_LSTAT, HAS_MADVISE, HAS_MBLEN, HAS_MBRLEN, HAS_MBRTOWC, HAS_MBSTOWCS, HAS_MBTOWC, HAS_MEMMEM, HAS_MEMRCHR, HAS_MKDTEMP, HAS_MKFIFO, HAS_MKOSTEMP, HAS_MKSTEMP, HAS_MKSTEMPS, HAS_MMAP, HAS_MPROTECT, HAS_MSG, HAS_MSYNC, HAS_MUNMAP, HAS_NEARBYINT, HAS_NEXTAFTER, HAS_NICE, HAS_NTOHL, HAS_NTOHS, HAS_PATHCONF, HAS_PAUSE, HAS_PHOSTNAME, HAS_PIPE, HAS_PIPE2, HAS_PRCTL, HAS_PTRDIFF_T, HAS_READLINK, HAS_READV, HAS_RECVMSG, HAS_REMQUO, HAS_RENAME, HAS_RENAMEAT, HAS_RINT, HAS_ROUND, HAS_SCALBNL, HAS_SEM, HAS_SENDMSG, HAS_SETEGID, HAS_SETENV, HAS_SETEUID, HAS_SETGROUPS, HAS_SETHOSTENT, HAS_SETLINEBUF, HAS_SETNETENT, HAS_SETPGRP, HAS_SETPGRP2, HAS_SETPRIORITY, HAS_SETPROCTITLE, HAS_SETPROTOENT, HAS_SETREGID, HAS_SETRESGID, HAS_SETRESUID, HAS_SETREUID, HAS_SETRGID, HAS_SETRUID, HAS_SETSERVENT, HAS_SETSID, HAS_SHM, HAS_SIGACTION, HAS_SIGPROCMASK, HAS_SIN6_SCOPE_ID, HAS_SNPRINTF, HAS_STAT, HAS_STRCOLL, HAS_STRERROR_L, HAS_STRLCAT, HAS_STRLCPY, HAS_STRNLEN, HAS_STRTOD, HAS_STRTOL, HAS_STRTOLL, HAS_STRTOQ, HAS_STRTOUL, HAS_STRTOULL, HAS_STRTOUQ, HAS_STRXFRM, HAS_STRXFRM_L, HAS_SYMLINK, HAS_SYSCALL, HAS_SYSCONF, HAS_SYS_ERRLIST, HAS_SYSTEM, HAS_TCGETPGRP, HAS_TCSETPGRP, HAS_TOWLOWER, HAS_TOWUPPER, HAS_TRUNCATE, HAS_TRUNCL, HAS_UALARM, HAS_UMASK, HAS_UNLINKAT, HAS_UNSETENV, HAS_VFORK, HAS_VSNPRINTF, HAS_WAITPID, HAS_WAIT4, HAS_WCRTOMB, HAS_WCSCMP, HAS_WCSTOMBS, HAS_WCSXFRM, HAS_WCTOMB, HAS_WRITEV

以及,重新进入能力

HAS_CRYPT_R, HAS_CTERMID_R, HAS_DRAND48_R, HAS_ENDHOSTENT_R, HAS_ENDNETENT_R, HAS_ENDPROTOENT_R, HAS_ENDSERVENT_R, HAS_GETGRGID_R, HAS_GETGRNAM_R, HAS_GETHOSTBYADDR_R, HAS_GETHOSTBYNAME_R, HAS_GETHOSTENT_R, HAS_GETLOGIN_R, HAS_GETNETBYADDR_R, HAS_GETNETBYNAME_R, HAS_GETNETENT_R, HAS_GETPROTOBYNAME_R, HAS_GETPROTOBYNUMBER_R, HAS_GETPROTOENT_R, HAS_GETPWNAM_R, HAS_GETPWUID_R, HAS_GETSERVBYNAME_R, HAS_GETSERVBYPORT_R, HAS_GETSERVENT_R, HAS_GETSPNAM_R, HAS_RANDOM_R, HAS_READDIR_R, HAS_SETHOSTENT_R, HAS_SETNETENT_R, HAS_SETPROTOENT_R, HAS_SETSERVENT_R, HAS_SRANDOM_R, HAS_SRAND48_R, HAS_STRERROR_R, HAS_TMPNAM_R, HAS_TTYNAME_R

示例用法

#include 所需符号列表

此列表包含指示平台上是否存在某些 #include 文件的符号。如果您的代码访问了其中一个符号的功能,则需要 #include 它,前提是此列表中的符号已 #define。有关更多详细信息,请参阅 config.h 中的相应条目。

I_ARPA_INET, I_BFD, I_CRYPT, I_DBM, I_DLFCN, I_EXECINFO, I_FP, I_FP_CLASS, I_GDBM, I_GDBMNDBM, I_GDBM_NDBM, I_GRP, I_IEEEFP, I_INTTYPES, I_LIBUTIL, I_MNTENT, I_NDBM, I_NETDB, I_NET_ERRNO, I_NETINET_IN, I_NETINET_TCP, I_PROT, I_PWD, I_RPCSVC_DBM, I_SGTTY, I_SHADOW, I_STDBOOL, I_STDINT, I_SUNMATH, I_SYS_ACCESS, I_SYS_IOCTL, I_SYSLOG, I_SYSMODE, I_SYS_MOUNT, I_SYS_PARAM, I_SYS_POLL, I_SYS_SECURITY, I_SYS_SELECT, I_SYS_STAT, I_SYS_STATVFS, I_SYS_SYSCALL, I_SYS_TIME, I_SYS_TIME_KERNEL, I_SYS_TIMES, I_SYS_TYPES, I_SYSUIO, I_SYS_UN, I_SYSUTSNAME, I_SYS_VFS, I_SYS_WAIT, I_TERMIO, I_TERMIOS, I_UNISTD, I_USTAT, I_VFORK, I_WCHAR, I_WCTYPE

示例用法

全局变量

这些变量对整个进程全局可见。它们在进程中的所有解释器和所有线程之间共享。任何未在此处记录的变量都可能会在未经通知的情况下更改或删除,因此请勿使用它们!如果您觉得确实需要使用未列出的变量,请先发送电子邮件至 [email protected]。可能有人会指出一种方法,无需使用内部变量即可完成您需要做的事情。但如果不是,您应该获得批准来记录和使用该变量。

PL_check

数组,按操作码索引,包含在编译 Perl 代码期间构建 optree 的“检查”阶段将调用的函数。对于大多数(但并非全部)类型的操作,一旦操作最初构建并填充了子操作,它将通过此数组中相应元素引用的检查函数进行过滤。新的操作作为唯一参数传递给检查函数,检查函数返回已完成的操作。检查函数可能会(顾名思义)检查操作的有效性并发出错误信号。它还可以初始化或修改操作的部分内容,或执行更激进的修改,例如添加或删除子操作,甚至丢弃操作并返回一个不同的操作来代替它。

这个函数指针数组是方便地介入编译过程的场所。XS 模块可以将自己的自定义检查函数放在任何标准检查函数的位置,以影响特定类型操作的编译。但是,自定义检查函数绝不能完全替换标准检查函数(甚至来自其他模块的自定义检查函数)。修改检查的模块必须改为**包装**预先存在的检查函数。自定义检查函数必须选择何时应用其自定义行为。在通常情况下,如果它决定不对操作执行任何特殊操作,它必须链接预先存在的操作函数。因此,检查函数以链式链接,核心基础检查器位于链的末端。

为了线程安全,模块不应直接写入此数组。相反,请使用函数 "wrap_op_checker"

PL_infix_plugin

注意:PL_infix_plugin 处于**实验性**阶段,可能会在未经通知的情况下更改或删除。

注意: 此 API 完全是为了使 CPAN 模块 XS::Parse::Infix 工作而存在的。预计不会有其他模块使用它;相反,它们应该使用 XS::Parse::Infix 来提供对新中缀运算符的解析。

函数指针,指向用于处理扩展中缀运算符的函数。该函数应声明为

int infix_plugin_function(pTHX_
        char *opname, STRLEN oplen,
        struct Perl_custom_infix **infix_ptr)

每当看到可能的 infix 运算符时,就会从词法分析器调用该函数。opname 指向解析器输入缓冲区中的运算符名称,oplen 给出应消耗的其最大字节数;它不是以 null 结尾的。该函数预计会检查运算符名称以及可能的其他状态,例如 %^H,以确定它是否要处理运算符名称。

PL_keyword_plugin 的单阶段相比,解析附加的中缀运算符发生在三个独立的阶段。这是因为它与解析器有更复杂的交互,以确保运算符优先级规则能够正确地工作。这些阶段通过使用额外的信息结构来协调。

如果该函数想要处理中缀运算符,它必须将 infix_ptr 指向的变量设置为指向提供有关后续解析阶段的附加信息的结构的地址。如果它没有,它应该调用链中的下一个函数。

此结构具有以下定义

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 *);
};

该函数必须返回一个整数,表示该运算符名称所消耗的字节数。对于名称由标识符字符组成的运算符,该值必须等于 oplen。对于由非标识符字符命名的运算符,该值可以小于 oplen,并且其后的任何额外字符都不会被中缀运算符占用,而是会被词法分析器和解析器按正常方式处理。

如果提供了可选的 parse 函数,解析器会立即调用它,让运算符的定义从源代码中消耗任何额外的语法。这不应该用于正常的操作数解析,但它在实现诸如参数化运算符或自身消耗更多语法的元运算符时可能有用。此函数可以使用指向 opdata 的变量来提供一个包含附加数据的 SV,该数据将在稍后传递到 build_op 函数中。

信息结构在 prec 字段中给出运算符的优先级级别。这用于告诉解析器在运算符前后应将多少周围语法视为运算符的操作数。

然后,词法分析器和解析器将继续按正常方式运行,直到解析了足够的额外输入来形成运算符的左右操作数,这取决于优先级级别。此时,会调用 build_op 函数,并将左右操作数作为 optree 片段传递给它。它应该将它们组合成结果 optree 片段,并返回该片段。

build_op 函数返回后,如果指向 opdata 的变量被设置为非 NULL 值,则会通过调用 SvREFCNT_dec() 来销毁它。

为了线程安全,模块不应该直接设置此变量。相反,请使用函数 "wrap_infix_plugin"

但是,上面提到的所有内容仍然适用。此变量在核心 Perl 中仅为了 XS::Parse::Infix 模块的利益而提供。该模块充当中缀运算符的中央注册表,自动处理诸如反解析支持和发现/反射等事项,而这些功能之所以能够正常工作,是因为它知道所有已注册的运算符。其他模块不应该直接使用此解释器变量来实现它们,因为这样会导致这些中央功能无法正常工作。

此外,此(实验性)API 很可能在未来的 Perl 版本中被更完整的 API 所取代,该 API 将完全实现 XS::Parse::Infix 目前提供的中央注册表和其他语义,一旦该模块经过充分的实验测试时间。当前机制仅作为一种过渡措施,以便达到这一阶段。

PL_keyword_plugin

注意:PL_keyword_plugin实验性的,可能会在没有通知的情况下更改或删除。

函数指针,指向用于处理扩展关键字的函数。该函数应声明为

int keyword_plugin_function(pTHX_
        char *keyword_ptr, STRLEN keyword_len,
        OP **op_ptr)

该函数在词法分析器遇到可能的关键字时被调用。keyword_ptr 指向解析器输入缓冲区中的单词,keyword_len 给出其长度;它不是以 null 结尾的。该函数应该检查该单词,以及可能的其他状态,例如 %^H,以决定是否要将其作为扩展关键字处理。如果它不处理,该函数应该返回 KEYWORD_PLUGIN_DECLINE,并且正常的解析器进程将继续。

如果该函数想要处理关键字,它首先必须解析关键字之后的所有内容,这些内容是关键字引入的语法的一部分。有关详细信息,请参阅 "词法分析器接口"

当处理关键字时,插件函数必须构建一个 OP 结构的树,表示已解析的代码。树的根必须存储在 *op_ptr 中。然后,该函数返回一个常量,指示它已解析的构造的语法作用:如果它是完整的语句,则为 KEYWORD_PLUGIN_STMT,如果它是表达式,则为 KEYWORD_PLUGIN_EXPR。请注意,语句构造不能在表达式中使用(除非通过 do BLOCK 和类似的),并且表达式不是完整的语句(它至少需要一个终止分号)。

当处理关键字时,插件函数也可能具有(编译时)副作用。它可以修改 %^H,定义函数,等等。通常,如果副作用是处理程序的主要目的,它不希望生成任何要包含在正常编译中的操作。在这种情况下,它仍然需要提供一个操作树,但生成一个空操作就足够了。

这就是 *PL_keyword_plugin 函数在总体上需要表现的方式。然而,按照惯例,人们不会完全替换现有的处理程序函数。相反,在将自己的函数指针分配给它之前,先复制 PL_keyword_plugin。您的处理程序函数应该查找它感兴趣的关键字并处理这些关键字。如果它不感兴趣,它应该调用保存的插件函数,并将它收到的参数传递给它。因此,PL_keyword_plugin 实际上指向一个处理程序函数链,所有这些函数都有机会处理关键字,并且通常只有链中的最后一个函数(内置在 Perl 核心中的)才会返回 KEYWORD_PLUGIN_DECLINE

为了线程安全,模块不应该直接设置此变量。相反,请使用函数 "wrap_keyword_plugin"

PL_phase

一个指示当前 Perl 解释器阶段的值。可能的值包括 PERL_PHASE_CONSTRUCTPERL_PHASE_STARTPERL_PHASE_CHECKPERL_PHASE_INITPERL_PHASE_RUNPERL_PHASE_ENDPERL_PHASE_DESTRUCT

例如,以下代码确定解释器是否处于全局销毁阶段

if (PL_phase == PERL_PHASE_DESTRUCT) {
    // we are in global destruction
}

PL_phase 在 Perl 5.14 中引入;在之前的 Perl 版本中,可以使用 PL_dirty(布尔值)来确定解释器是否处于全局销毁阶段。(从 5.14 开始不建议使用 PL_dirty。)

    enum perl_phase  PL_phase

GV 处理和符号表

GV 是一个结构,对应于 Perl 类型全局变量,即 *foo。它是一个结构,包含指向标量、数组、哈希等的指针,分别对应于 $foo、@foo、%foo。

GV 通常作为符号表(符号表哈希)中的值被找到,Perl 在其中存储其全局变量。

符号表 是一个哈希,包含在包中定义的所有变量。请参阅 "perlguts 中的符号表和全局变量"

amagic_call

执行由 method 给出的重载(主动魔法)操作。methodoverload.h 中找到的值之一。

flags 影响操作的执行方式,如下所示

AMGf_noleft

left 不应在此操作中使用。

AMGf_noright

right 不应在此操作中使用。

AMGf_unary

操作仅对一个操作数执行。

AMGf_assign

操作更改其中一个操作数,例如,$x += 1

    SV *  amagic_call(SV *left, SV *right, int method, int dir)
amagic_deref_call

ref 执行 method 重载解引用,返回解引用后的结果。method 必须是 overload.h 中给出的解引用操作之一。

如果 ref 上的重载处于非活动状态,则返回 ref 本身。

    SV *  amagic_deref_call(SV *ref, int method)
gv_add_by_type

确保 GV gv 中存在类型为 type 的插槽。

    GV *  gv_add_by_type(GV *gv, svtype type)
Gv_AMupdate

重新计算由 stash 给出的包中的重载魔法。

返回

1 表示成功并且存在一些重载
0 表示不存在重载
-1 表示发生了一些错误,并且无法抛出异常(因为 destructing 为真)。
    int  Gv_AMupdate(HV *stash, bool destructing)
gv_autoload_pv
gv_autoload_pvn
gv_autoload_sv

这些函数都会搜索一个名为 AUTOLOAD 的方法,如果找不到,则返回 NULL,否则返回指向其 GV 的指针,同时将包的 $AUTOLOAD 变量设置为 name(完全限定)。此外,如果找到并且 GV 的 CV 是一个 XSUB,则 CV 的 PV 将被设置为 name,并且其 stash 将被设置为 GV 的 stash。

搜索是在 MRO 顺序 中进行的,如 "gv_fetchmeth" 中所述,从 stash 开始(如果它不为 NULL)。

这些函数的区别仅在于 name 的指定方式。

gv_autoload_pv 中,namepv 是一个 C 语言的 NUL 结尾字符串。

gv_autoload_pvn 中,name 指向名称的第一个字节,并且一个额外的参数 len 指定其长度(以字节为单位)。因此,*name 可能包含嵌入的 NUL 字符。

gv_autoload_sv 中,*namesv 是一个 SV,并且名称是从使用 "SvPV" 从该 SV 中提取的 PV。如果 SV 被标记为 UTF-8,则提取的 PV 也会是 UTF-8。

    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)
gv_autoload4

等效于 "gv_autoload_pvn"

    GV *  gv_autoload4(HV *stash, const char *name, STRLEN len,
                       I32 method)
GvAV

从 GV 返回 AV。

    AV*  GvAV(GV* gv)
gv_AVadd
gv_HVadd
gv_IOadd
gv_SVadd

确保在 GV gv 中有一个给定类型(AV、HV、IO、SV)的槽。

    GV *  gv_AVadd(GV *gv)
gv_const_sv

如果 gv 是一个类型 glob,其子程序条目是一个常量子程序,适合内联,或者 gv 是一个占位符引用,将被提升为这样的类型 glob,则返回子程序返回的值。否则,返回 NULL

    SV *  gv_const_sv(GV *gv)
GvCV

从 GV 返回 CV。

    CV*  GvCV(GV* gv)
gv_efullname3
gv_efullname4
gv_fullname3
gv_fullname4

gv 的完整包名称放入 sv 中。gv_e* 形式返回的是有效包名称(参见 "HvENAME")。

如果 prefix 非空,则将其视为 C 语言的以 NUL 结尾的字符串,并且存储的名称将以它为前缀。

这些函数之间的另一个区别是 *4 形式有一个额外的参数 keepmain。如果为 true,则保留名称中的初始 main::;如果为 false,则将其去除。对于 *3 形式,始终保留它。

    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)
gv_fetchfile
gv_fetchfile_flags

这些函数返回由 name 参数给出的文件(由 Perl 编译)的调试器 glob。

目前,这两个函数之间只有两个区别。

gv_fetchfilename 参数是 C 字符串,这意味着它以 NUL 结尾;而 gv_fetchfile_flagsname 参数是 Perl 字符串,其长度(以字节为单位)通过 namelen 参数传递。这意味着名称可能包含嵌入的 NUL 字符。namelen 在普通的 gv_fetchfile 中不存在。

另一个区别是 gv_fetchfile_flags 有一个额外的 flags 参数,目前完全被忽略,但允许将来进行可能的扩展。

    GV *  gv_fetchfile      (const char *name)
    GV *  gv_fetchfile_flags(const char * const name,
                             const STRLEN len, const U32 flags)
gv_fetchmeth
gv_fetchmeth_pv
gv_fetchmeth_pvn
gv_fetchmeth_sv

这些函数都查找名为 name 的 glob,其中包含一个已定义的子例程,如果找到则返回该 glob 的 GV,否则返回 NULL

始终搜索 stash(首先),除非它为 NULL

如果 stash 为 NULL,或者已搜索但未在其中找到任何内容,并且 flags 中设置了 GV_SUPER 位,则接下来搜索通过 @ISA 可访问的 stash。搜索按照 MRO 顺序 进行。

最后,如果到目前为止没有找到匹配项,并且 flags 中的 GV_NOUNIVERSAL 标志未设置,则搜索 UNIVERSAL::

参数 level 应为 0 或 -1。如果为 -1,则函数将返回,没有任何副作用或缓存。如果为 0,则函数确保 stash 中存在名为 name 的 glob,如果必要则创建一个。glob 中的子例程槽将设置为在 stashSUPER:: 搜索中找到的任何子例程,因此缓存任何 SUPER:: 结果。请注意,在 UNIVERSAL:: 中找到的子例程不会被缓存。

从这些返回的 GV 可能是一个方法缓存条目,它对 Perl 代码不可见。因此,在调用 `call_sv` 时,您不应该直接使用 GV;相反,您应该使用方法的 CV,它可以通过 GV 的 `GvCV` 宏获得。

对于 `flags`,唯一其他重要的值是 `SVf_UTF8`,它表示 `name` 将被视为以 UTF-8 编码。

普通的 `gv_fetchmeth` 缺少 `flags` 参数,因此始终在 `stash` 中搜索,然后是 `UNIVERSAL::`,并且 `name` 从不为 UTF-8。否则,它与 `gv_fetchmeth_pvn` 完全相同。

其他形式确实具有 `flags` 参数,并且仅在指定全局名称的方式上有所不同。

在 `gv_fetchmeth_pv` 中,`name` 是一个 C 语言以 NUL 结尾的字符串。

在 `gv_fetchmeth_pvn` 中,`name` 指向名称的第一个字节,并且一个额外的参数 `len` 指定其长度(以字节为单位)。因此,名称可能包含嵌入的 NUL 字符。

在 `gv_fetchmeth_sv` 中,`*name` 是一个 SV,并且名称是从该 SV 中提取的 PV,使用 "SvPV"。如果 SV 被标记为 UTF-8,则提取的 PV 也会是 UTF-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)
gv_fetchmeth_autoload

这是 "gv_fetchmeth_pvn_autoload" 的旧形式,它没有 flags 参数。

    GV *  gv_fetchmeth_autoload(HV *stash, const char *name,
                                STRLEN len, I32 level)
gv_fetchmethod

参见 "gv_fetchmethod_autoload"

    GV *  gv_fetchmethod(HV *stash, const char *name)
gv_fetchmethod_autoload

返回包含用于在 `stash` 上调用方法的子例程的全局变量。实际上,在存在自动加载的情况下,这可能是 "AUTOLOAD" 的全局变量。在这种情况下,相应的变量 `$AUTOLOAD` 已经设置好了。

gv_fetchmethod_autoload 的第三个参数决定了如果给定方法不存在是否执行 AUTOLOAD 查找:非零表示是,查找 AUTOLOAD;零表示否,不查找 AUTOLOAD。调用 `gv_fetchmethod` 等同于使用非零 `autoload` 参数调用 `gv_fetchmethod_autoload`。

这些函数将 `“SUPER”` 标记作为方法名称的前缀。请注意,如果您想长时间保留返回的全局变量,您需要检查它是否为 "AUTOLOAD",因为在以后的时间,由于 `$AUTOLOAD` 更改了其值,调用可能会加载不同的子例程。使用作为副作用创建的全局变量来执行此操作。

这些函数与level==0gv_fetchmeth具有相同的副作用。将gv_fetchmeth返回的GV传递给call_sv的警告同样适用于这些函数。

    GV *  gv_fetchmethod_autoload(HV *stash, const char *name,
                                  I32 autoload)
gv_fetchmeth_pv_autoload

"gv_fetchmeth_pvn_autoload"完全相同,但接受以空字符结尾的字符串,而不是字符串/长度对。

    GV *  gv_fetchmeth_pv_autoload(HV *stash, const char *name,
                                   I32 level, U32 flags)
gv_fetchmeth_pvn_autoload

gv_fetchmeth_pvn()相同,但也会查找自动加载的子例程。返回子例程的全局变量。

对于没有GV的自动加载子例程,即使level < 0也会创建GV。对于没有存根的自动加载子例程,结果的GvCV()可能为零。

目前,flags的唯一重要值是SVf_UTF8

    GV *  gv_fetchmeth_pvn_autoload(HV *stash, const char *name,
                                    STRLEN len, I32 level, U32 flags)
gv_fetchmeth_sv_autoload

"gv_fetchmeth_pvn_autoload"完全相同,但接受以SV形式的名称字符串,而不是字符串/长度对。

    GV *  gv_fetchmeth_sv_autoload(HV *stash, SV *namesv, I32 level,
                                   U32 flags)
gv_fetchpv
gv_fetchpvn
gv_fetchpvn_flags
gv_fetchpvs
gv_fetchsv
gv_fetchsv_nomg

这些函数都返回类型为sv_type的GV,其名称由输入给出,如果找不到该名称和类型的GV,则返回NULL。参见"perlguts中的Stashes and Globs"

唯一的区别在于输入名称的指定方式,以及是否在获取该名称时通常使用“get”魔法。

不要被只有一个形式在其名称中包含flags的事实所迷惑。事实上,它们都有一个flags参数,并且所有标志位对所有函数都有相同的含义。

如果设置了任何标志GV_ADDGV_ADDMGGV_ADDWARNGV_ADDMULTIGV_NOINIT,则如果输入名称和类型不存在 GV,则会创建一个 GV。但是,GV_ADDMG 仅对魔法 GV 进行创建。对于除 GV_NOINIT 之外的所有这些标志,在添加之后会调用"gv_init_pvn"GV_ADDWARN 用于在调用者预期添加不必要的情况下使用,因为符号应该已经存在;但如果不存在,则无论如何添加它,并发出警告,说明它意外地不存在。GV_ADDMULTI 标志表示假装 GV 之前已经见过(即,抑制“使用一次”警告)。

标志GV_NOADD_NOINIT 导致如果 GV 存在但不是 PVGV,则不会调用"gv_init_pvn"

如果设置了SVf_UTF8 位,则名称被视为以 UTF-8 编码;否则,名称在pv 命名的形式中不会被认为是 UTF-8,并且基础 SV 的 UTF-8 性质将在sv 形式中使用。

如果设置了标志GV_NOTQUAL,则调用者保证输入名称是一个简单的符号名称,而不是用包限定的,否则会检查名称是否为限定名称。

gv_fetchpv 中,nambeg 是一个 C 字符串,以 NUL 结尾,没有中间的 NUL。

gv_fetchpvs 中,name 是一个文字 C 字符串,因此用双引号括起来。

gv_fetchpvngv_fetchpvn_flags 是相同的。在这些中,<nambeg> 是一个 Perl 字符串,其字节长度由 full_len 给出,并且可能包含嵌入的 NUL。

gv_fetchsvgv_fetchsv_nomg 中,名称是从输入name SV 的 PV 中提取的。这两种形式之间的唯一区别是,在gv_fetchsv 中,通常会在name 上执行“获取”魔法,而在gv_fetchsv_nomg 中始终跳过。在gv_fetchsvflags 参数中包含GV_NO_SVGMAGIC 使其行为与gv_fetchsv_nomg 相同。

    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)
GvHV

从 GV 返回 HV。

    HV*  GvHV(GV* gv)
gv_init

gv_init_pvn() 的旧形式。它不适用于 UTF-8 字符串,因为它没有 flags 参数。如果设置了multi 参数,则GV_ADDMULTI 标志将传递给gv_init_pvn()

    void  gv_init(GV *gv, HV *stash, const char *name, STRLEN len,
                  int multi)
gv_init_pv

gv_init_pvn() 相同,但使用一个以 nul 结尾的字符串作为名称,而不是单独的 char * 和长度参数。

    void  gv_init_pv(GV *gv, HV *stash, const char *name, U32 flags)
gv_init_pvn

将标量转换为类型全局变量。这是一个不可强制转换的类型全局变量;将引用分配给它将分配到它的一个槽中,而不是像由SvSetSV创建的类型全局变量那样覆盖它。转换任何SvOK()的标量可能会产生不可预测的结果,并保留供 Perl 内部使用。

gv 是要转换的标量。

stash 是父级存储区/包(如果有)。

namelen 给出名称。名称必须是未限定的;也就是说,它不能包含包名。如果 gv 是一个存储区元素,则调用者有责任确保传递给此函数的名称与元素的名称匹配。如果不匹配,Perl 的内部簿记将不同步。

flags 可以设置为 SVf_UTF8,如果 name 是一个 UTF-8 字符串,或者 SvUTF8(sv) 的返回值。它还可以接受 GV_ADDMULTI 标志,这意味着假装 GV 之前已被看到(即,抑制“使用一次”警告)。

    void  gv_init_pvn(GV *gv, HV *stash, const char *name, STRLEN len,
                      U32 flags)
gv_init_sv

gv_init_pvn() 相同,但为名称采用 SV* 而不是单独的 char* 和长度参数。flags 当前未使用。

    void  gv_init_sv(GV *gv, HV *stash, SV *namesv, U32 flags)
gv_name_set

将 GV gv 的名称设置为 name,其长度为 len 字节。因此,它可能包含嵌入的 NUL 字符。

如果 flags 包含 SVf_UTF8,则名称被视为以 UTF-8 编码;否则不。

    void  gv_name_set(GV *gv, const char *name, U32 len, U32 flags)
gv_stashpv

返回指定包的存储区的指针。使用 strlen 确定 name 的长度,然后调用 gv_stashpvn()

    HV *  gv_stashpv(const char *name, I32 flags)
gv_stashpvn

返回指定包的存储区的指针。namelen 参数指示 name 的长度(以字节为单位)。flags 传递给 gv_fetchpvn_flags(),因此如果设置为 GV_ADD,则如果包不存在,则将创建该包。如果包不存在并且 flags 为 0(或任何其他不创建包的设置),则返回 NULL

标志可以是以下之一:

GV_ADD           Create and initialize the package if doesn't
                 already exist
GV_NOADD_NOINIT  Don't create the package,
GV_ADDMG         GV_ADD iff the GV is magical
GV_NOINIT        GV_ADD, but don't initialize
GV_NOEXPAND      Don't expand SvOK() entries to PVGV
SVf_UTF8         The name is in UTF-8

其中最重要的是 GV_ADDSVf_UTF8

注意,尽可能使用 gv_stashsv 而不是 gv_stashpvn 强烈推荐,因为性能原因。

    HV *  gv_stashpvn(const char *name, U32 namelen, I32 flags)
gv_stashpvs

类似于 gv_stashpvn,但接受一个字面字符串而不是字符串/长度对。

    HV*  gv_stashpvs("name", I32 create)
gv_stashsv

返回指定包的 stash 指针。参见 "gv_stashpvn"

注意,出于性能原因,强烈建议使用此接口而不是 gv_stashpvn

    HV *  gv_stashsv(SV *sv, I32 flags)
GvSV

从 GV 中返回 SV。

在 Perl v5.9.3 之前,如果不存在,这将添加一个标量。现在,使用 "GvSVn" 来实现这一点,或者使用 -DPERL_CREATE_GVSV 编译 perl。参见 perl5100delta.

    SV*  GvSV(GV* gv)
GvSVn

类似于 "GvSV",但如果不存在,则创建一个空标量。

    SV*  GvSVn(GV* gv)
newGVgen
newGVgen_flags

在由 NUL 终止的 C 语言字符串 pack 给定的包中创建一个新的、保证唯一的 GV,并返回指向它的指针。

对于 newGVgen 或如果 newGVgen_flags 中的 flags 为 0,则 pack 被认为是使用 Latin-1 编码的。唯一合法的 flags 值是 SVf_UTF8,它表示 pack 被认为是使用 UTF-8 编码的。

    GV *  newGVgen      (const char *pack)
    GV *  newGVgen_flags(const char *pack, U32 flags)
PL_curstash

将要编译的包代码的 stash。

在多线程 Perl 中,每个线程都有此变量的独立副本;每个副本在创建时都使用创建线程副本的当前值进行初始化。

    HV*  PL_curstash
PL_defgv

表示 *_ 的 GV。对访问 $_ 有用。

在多线程 Perl 中,每个线程都有此变量的独立副本;每个副本在创建时都使用创建线程副本的当前值进行初始化。

    GV *  PL_defgv
PL_defoutgv

参见 "setdefout"

PL_defstash

perlguts 中描述。

save_gp

将 gv 的当前 GP 保存到保存堆栈中,以便在作用域退出时恢复。

如果 empty 为真,则用新的 GP 替换 GP。

如果 empty 为假,则用 GVf_INTRO 标记 gv,以便下一个分配的引用被局部化,这就是 local *foo = $someref; 的工作原理。

    void  save_gp(GV *gv, I32 empty)
setdefout

PL_defoutgv(用于输出的默认文件句柄)设置为传入的类型全局变量。由于PL_defoutgv“拥有”其类型全局变量的引用,因此传入的类型全局变量的引用计数增加 1,而PL_defoutgv指向的类型全局变量的引用计数减少 1。

    void  setdefout(GV *gv)

钩子操作

这些函数提供了操作钩子变量的便捷且线程安全的方法。

rcpv_copy

增加共享内存引用计数字符串的引用计数,当引用计数变为 0 时,使用 PerlMemShared_free() 释放它。

调用者有责任确保 pv 是 rcpv_new() 调用的结果。

返回与传入的指针相同的指针。

new = rcpv_copy(pv);
    char *  rcpv_copy(char * const pv)
rcpv_free

减少共享内存引用计数字符串的引用计数,当引用计数变为 0 时,使用 perlmemshared_free() 释放它。

调用者有责任确保 pv 是 rcpv_new() 调用的结果。

始终返回 NULL,因此它可以像这样使用

thing = rcpv_free(thing);
    char *  rcpv_free(char * const pv)
rcpv_new

使用请求的大小、请求的初始化和 1 的引用计数创建一个新的共享内存引用计数字符串。实际分配的空间将比请求的空间多 1 个字节,rcpv_new() 将确保无论任何标志设置,额外字节都是空字节。

如果设置了 RCPVf_NO_COPY 标志,则将忽略 pv 参数,否则将把 pv 指针的内容复制到新缓冲区中,或者如果它是 NULL,则该函数将不执行任何操作并返回 NULL。

如果设置了 RCPVf_USE_STRLEN 标志,则将忽略 len 参数并使用strlen(pv)重新计算。同时组合 RCPVf_USE_STRLEN 和 RCPVf_NO_COPY 是错误的。

在 DEBUGGING 下,如果 rcpv_new() 被要求创建一个长度为 0 的共享字符串,除非设置了 RCPVf_ALLOW_EMPTY 标志,否则它将断言()。

该函数的返回值适合传递给 rcpv_copy() 和 rcpv_free()。要从返回值中访问 RCPV *,请使用 RCPVx() 宏。RCPV 结构的“len”成员存储分配的长度(包括额外字节),但 RCPV_LEN() 宏返回请求的长度(不包括额外字节)。

请注意,rcpv_new() 不会使用哈希表或任何类似的东西来对给定相同文本内容的输入进行重复数据删除。每次使用非空 pv 参数调用都会生成一个具有其自身引用计数的独立指针,无论输入内容如何。

    char *  rcpv_new(const char * const pv, STRLEN len, U32 flags)
wrap_op_checker

将 C 函数放入指定操作类型的检查函数链中。这是操作 "PL_check" 数组的首选方法。opcode 指定要影响的操作类型。new_checker 是指向要添加到该操作码的检查链中的 C 函数的指针,而old_checker_p 指向存储位置,其中将存储指向链中下一个函数的指针。new_checker 的值将写入 "PL_check" 数组,而之前存储在那里的值将写入*old_checker_p

"PL_check" 是整个进程的全局变量,一个希望挂钩操作检查的模块可能会发现自己在一个进程中被调用多次,通常是在不同的线程中。为了处理这种情况,此函数是幂等的。位置 *old_checker_p 必须最初(每个进程一次)包含一个空指针。如果 C 变量没有显式初始化器,则静态持续时间(在文件范围内声明,通常也标记为 static 以使其具有内部链接)的 C 变量将被隐式适当地初始化。此函数只有在发现 *old_checker_p 为空时才会真正修改检查链。此函数在小范围内也是线程安全的。它使用适当的锁定来避免访问 "PL_check" 时出现竞争条件。

当调用此函数时,new_checker 引用的函数必须准备好被调用,除了 *old_checker_p 未填充。在多线程情况下,new_checker 可能会立即被调用,甚至在该函数返回之前。*old_checker_p 将始终在调用 new_checker 之前被适当地设置。如果 new_checker 决定不对它接收到的操作做任何特殊处理(这对于大多数操作检查挂钩使用来说是常见情况),它必须链接 *old_checker_p 引用的检查函数。

总而言之,挂钩操作检查器的 XS 代码通常应该看起来像这样

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);

如果您想影响对特定子例程的调用的编译,请使用 "cv_set_call_checker_flags" 而不是挂钩所有 entersub 操作的检查。

    void  wrap_op_checker(Optype opcode, Perl_check_t new_checker,
                          Perl_check_t *old_checker_p)

HV 处理

HV 结构表示 Perl 哈希。它主要由一个指针数组组成,每个指针指向一个 HE 结构的链表。该数组由键的哈希函数索引,因此每个链表表示所有具有相同哈希值的哈希条目。每个 HE 包含指向实际值的指针,以及指向 HEK 结构的指针,HEK 结构保存键和哈希值。

get_hv

返回指定 Perl 哈希的 HV。flags 传递给 gv_fetchpv。如果设置了 GV_ADD 并且 Perl 变量不存在,则会创建它。如果 flags 为零(忽略 SVf_UTF8)并且变量不存在,则返回 NULL

注意:perl_get_hv() 形式已弃用

    HV *  get_hv(const char *name, I32 flags)
HE

perlguts 中描述。

HEf_SVKEY

此标志用于哈希条目和魔法结构的长度槽中,指定结构包含一个SV* 指针,而预期的是一个char* 指针。(仅供参考 - 不得使用)。

HeHASH

返回存储在哈希条目中的计算出的哈希值。

    U32  HeHASH(HE* he)
HeKEY

返回存储在哈希条目键槽中的实际指针。指针可以是char*SV*,具体取决于HeKLEN() 的值。可以赋值。HePV()HeSVKEY() 宏通常更适合查找键的值。

    void*  HeKEY(HE* he)
HeKLEN

如果此值为负数,并且等于HEf_SVKEY,则表示该条目包含一个SV* 键。否则,保存键的实际长度。可以赋值。HePV() 宏通常更适合查找键的长度。

    STRLEN  HeKLEN(HE* he)
HePV

将哈希条目的键槽作为char* 值返回,对可能存在的SV* 键进行必要的解引用。字符串的长度将放在len 中(这是一个宏,因此不要使用&len)。如果您不关心键的长度,可以使用全局变量PL_na,但这比使用局部变量效率低。但请记住,perl 中的哈希键可以包含嵌入的空字符,因此使用strlen() 或类似方法不是查找哈希键长度的好方法。这与本文档其他地方描述的SvPV() 宏非常相似。另请参阅"HeUTF8"

如果您使用HePV 获取要传递给newSVpvn() 以创建新 SV 的值,您应该考虑使用newSVhek(HeKEY_hek(he)),因为它效率更高。

    char*  HePV(HE* he, STRLEN len)
HeSVKEY

将键作为SV* 返回,如果哈希条目不包含SV* 键,则返回NULL

    SV*  HeSVKEY(HE* he)
HeSVKEY_force

将键作为SV* 返回。如果哈希条目只包含char* 键,将创建并返回一个临时的 mortal SV*

    SV*  HeSVKEY_force(HE* he)
HeSVKEY_set

将键设置为给定的SV*,注意设置适当的标志以指示SV* 键的存在,并返回相同的SV*

    SV*  HeSVKEY_set(HE* he, SV* sv)
HeUTF8

返回由 HePV 返回的 char * 值是否以 UTF-8 编码,并对可能为 SV* 类型的键进行必要的解引用。返回值将为 0 或非 0,不一定是 1(甚至任何低位都设置的值),因此不要盲目地将此值分配给 bool 变量,因为 bool 可能是一个 char 的类型定义。

    U32  HeUTF8(HE* he)
HeVAL

返回存储在哈希条目中的值槽(类型 SV*)。可以赋值。

SV *foo= HeVAL(hv);
HeVAL(hv)= sv;
    SV*  HeVAL(HE* he)
HV

perlguts 中描述。

hv_assert

检查哈希是否处于内部一致状态。

注意:hv_assert 必须显式调用为 Perl_hv_assert,并带有 aTHX_ 参数。

    void  Perl_hv_assert(pTHX_ HV *hv)
hv_bucket_ratio

注意:hv_bucket_ratio实验性的,可能会在未经通知的情况下更改或删除。

如果哈希被绑定,则通过 SCALAR 绑定方法分派,否则如果哈希不包含任何键,则返回 0,否则返回一个包含字符串的 mortal sv,该字符串指定已使用桶的数量,后面跟着一个斜杠,然后是可用桶的数量。

此函数开销很大,它必须扫描所有桶以确定哪些桶已使用,并且计数缓存。在大型哈希中,这可能是很多桶。

    SV *  hv_bucket_ratio(HV *hv)
hv_clear

释放哈希的所有元素,使其为空。%hash = () 的 XS 等价物。另请参见 "hv_undef"

有关哈希在返回时可能无效的说明,请参见 "av_clear"

    void  hv_clear(HV *hv)
hv_clear_placeholders

清除哈希中的任何占位符。如果受限哈希的任何键被标记为只读,并且该键随后被删除,则该键实际上不会被删除,而是通过将其值分配为 &PL_sv_placeholder 来标记。这会对其进行标记,以便在将来的操作(例如遍历哈希)中忽略它,但仍允许哈希在将来的某个时间点将值重新分配给该键。此函数清除哈希中的任何此类占位符键。有关其用法的示例,请参见 Hash::Util::lock_keys()

    void  hv_clear_placeholders(HV *hv)
hv_copy_hints_hv

用于复制 %^H"newHVhv" 的专用版本。ohv 必须是指向哈希的指针(该哈希可能具有 %^H 魔法,但通常应该是非魔法的),或者为 NULL(解释为空哈希)。ohv 的内容被复制到一个新的哈希中,该哈希添加了 %^H 特定的魔法。返回指向新哈希的指针。

    HV *  hv_copy_hints_hv(HV * const ohv)
hv_delete

删除哈希表中的键值对。该值的 SV 将从哈希表中删除,变为可回收,并返回给调用者。klen 的绝对值为键的长度。如果 klen 为负数,则假设键为 UTF-8 编码的 Unicode。flags 值通常为零;如果设置为 G_DISCARD,则返回 NULL。如果未找到键,也会返回 NULL

    SV *  hv_delete(HV *hv, const char *key, I32 klen, I32 flags)
hv_delete_ent

删除哈希表中的键值对。该值的 SV 将从哈希表中删除,变为可回收,并返回给调用者。flags 值通常为零;如果设置为 G_DISCARD,则返回 NULL。如果未找到键,也会返回 NULLhash 可以是有效的预计算哈希值,也可以是 0,表示请求计算哈希值。

    SV *  hv_delete_ent(HV *hv, SV *keysv, I32 flags, U32 hash)
HvENAME

返回存储区的有效名称,如果不存在则返回 NULL。有效名称表示符号表中存储区所在的位置。当包被别名或删除时,它会自动更新。不再位于符号表中的存储区没有有效名称。此名称优于 HvNAME,用于 MRO 线性化和 isa 缓存。

    char*  HvENAME(HV* stash)
HvENAMELEN

返回存储区有效名称的长度。

    STRLEN  HvENAMELEN(HV *stash)
HvENAMEUTF8

如果有效名称为 UTF-8 编码,则返回 true。

    unsigned char  HvENAMEUTF8(HV *stash)
hv_exists

返回一个布尔值,指示指定的哈希键是否存在。klen 的绝对值为键的长度。如果 klen 为负数,则假设键为 UTF-8 编码的 Unicode。

    bool  hv_exists(HV *hv, const char *key, I32 klen)
hv_exists_ent

返回一个布尔值,指示指定的哈希键是否存在。hash 可以是有效的预计算哈希值,也可以是 0,表示请求计算哈希值。

    bool  hv_exists_ent(HV *hv, SV *keysv, U32 hash)
hv_fetch

返回与哈希表中指定键对应的 SV。klen 的绝对值为键的长度。如果 klen 为负数,则假设键为 UTF-8 编码的 Unicode。如果设置了 lval,则获取操作将是存储操作的一部分。这意味着如果哈希表中没有与给定键关联的值,则会创建一个值并返回指向它的指针。指向它的 SV* 可以被赋值。但在解引用它为 SV* 之前,始终检查返回值是否为非空。

有关如何在绑定哈希上使用此函数的更多信息,请参阅 "perlguts 中的绑定哈希和数组的魔法"

    SV **  hv_fetch(HV *hv, const char *key, I32 klen, I32 lval)
hv_fetch_ent

返回与哈希中指定键对应的哈希条目。hash 必须是给定 key 的有效预先计算的哈希值,或者如果您希望函数计算它,则为 0。如果设置了 lval,则获取将是存储的一部分。在访问返回值之前,请确保返回值不为空。当 hv 是绑定哈希时,返回值是指向静态位置的指针,因此如果您需要将其存储在某处,请务必复制结构。

有关如何在绑定哈希上使用此函数的更多信息,请参阅 "perlguts 中的绑定哈希和数组的魔法"

    HE *  hv_fetch_ent(HV *hv, SV *keysv, I32 lval, U32 hash)
hv_fetchs

hv_fetch 相似,但接受文字字符串而不是字符串/长度对。

    SV**  hv_fetchs(HV* tb, "key", I32 lval)
HvFILL

返回正在使用的哈希桶的数量。

从 Perl 5.25 开始,此函数仅用于调试目的,并且正在使用的哈希桶数量不会以任何方式缓存,因此此函数的执行可能很昂贵,因为它必须遍历哈希中的所有桶。

    STRLEN  HvFILL(HV *const hv)
HvHasAUX

如果 HV 具有 struct xpvhv_aux 扩展,则返回 true。使用此方法检查是否可以调用 HvAUX()

    bool  HvHasAUX(HV *const hv)
hv_iterinit

准备一个起点来遍历哈希表。返回哈希中键的数量,包括占位符(即与 HvTOTALKEYS(hv) 相同)。返回值目前仅对没有绑定魔法的哈希有意义。

注意:在 5.004_65 版本之前,hv_iterinit 用于返回正在使用的哈希桶的数量。如果您仍然需要这个深奥的值,可以通过宏 HvFILL(hv) 获取它。

    I32  hv_iterinit(HV *hv)
hv_iterkey

返回哈希迭代器当前位置的键。参见 "hv_iterinit"

    char *  hv_iterkey(HE *entry, I32 *retlen)
hv_iterkeysv

返回哈希迭代器当前位置的键作为 SV*。返回值始终是键的临时副本。另请参见 "hv_iterinit"

    SV *  hv_iterkeysv(HE *entry)
hv_iternext

从哈希迭代器返回条目。参见 "hv_iterinit"

您可以在迭代器当前指向的哈希条目上调用 hv_deletehv_delete_ent,而不会丢失您的位置或使迭代器失效。请注意,在这种情况下,当前条目将从您的迭代器持有对它的最后一个引用时从哈希中删除。您的迭代器被标记为在下次调用 hv_iternext 时释放条目,因此您不能立即丢弃您的迭代器,否则条目将泄漏 - 调用 hv_iternext 以触发资源释放。

    HE *  hv_iternext(HV *hv)
hv_iternext_flags

注意:hv_iternext_flags实验性的,可能会在不通知的情况下更改或删除。

从哈希迭代器中返回条目。参见 "hv_iterinit""hv_iternext"flags 值通常为零;如果设置了 HV_ITERNEXT_WANTPLACEHOLDERS,则除了正常键之外,还会返回占位符键(对于受限哈希)。默认情况下,占位符会自动跳过。目前,占位符使用值为 &PL_sv_placeholder 的值实现。请注意,占位符和受限哈希的实现可能会发生变化,并且当前的实现对于任何更改来说都不够抽象,无法整洁地进行更改。

    HE *  hv_iternext_flags(HV *hv, I32 flags)
hv_iternextsv

在一个操作中执行 hv_iternexthv_iterkeyhv_iterval

    SV *  hv_iternextsv(HV *hv, char **key, I32 *retlen)
hv_iterval

返回哈希迭代器当前位置的值。参见 "hv_iterkey"

    SV *  hv_iterval(HV *hv, HE *entry)
hv_ksplit

尝试扩展哈希 hv,使其至少有 newmax 个桶可用。Perl 会根据其需要选择实际数量。

这与在 Perl 代码中执行以下操作相同

keys %hv = newmax;
    void  hv_ksplit(HV *hv, IV newmax)
hv_magic

向哈希添加魔法。参见 "sv_magic"

    void  hv_magic(HV *hv, GV *gv, int how)
HvNAME

返回存储区的包名,如果 stash 不是存储区,则返回 NULL。参见 "SvSTASH""CvSTASH"

    char*  HvNAME(HV* stash)
HvNAMELEN

返回存储区名称的长度。

HvNAME 和 HvNAMELEN 的不受欢迎形式;禁止提及它们

    STRLEN  HvNAMELEN(HV *stash)
hv_name_set
hv_name_sets

这些都将存储区 hv 的名称设置为指定名称。

它们的区别仅在于名称的指定方式。

hv_name_sets 中,名称是包含在双引号中的文字 C 字符串。

hv_name_set 中,name 指向名称的第一个字节,并且一个额外的参数 len 指定其字节长度。因此,名称可能包含嵌入的 NUL 字符。

如果 flags 中设置了 SVf_UTF8,则名称被视为 UTF-8 编码;否则不是。

如果 flags 中设置了 HV_NAME_SETALL,则名称和有效名称都将被设置。

    void  hv_name_set (HV *hv, const char *name, U32 len, U32 flags)
    void  hv_name_sets(HV *hv, "name", U32 flags)
HvNAMEUTF8

如果名称为 UTF-8 编码,则返回 true。

    unsigned char  HvNAMEUTF8(HV *stash)
hv_scalar

在标量上下文中评估哈希并返回结果。

当哈希被绑定时,它会通过 SCALAR 方法进行调度,否则返回一个包含哈希中键数量的 mortal SV。

注意,在 5.25 之前,此函数返回的值现在由 hv_bucket_ratio() 函数返回。

    SV *  hv_scalar(HV *hv)
hv_store
hv_stores

这些函数将 SV val 与指定键存储在哈希 hv 中,如果操作失败或值不需要实际存储在哈希中(例如绑定哈希),则返回 NULL。否则,它可以被解引用以获取原始的 SV*

它们的区别仅在于哈希键的指定方式。

hv_stores 中,键是一个用双引号括起来的 C 语言字符串字面量。它永远不会被视为 UTF-8 编码。

hv_store 中,key 为 NULL 或指向指定键的字符串的第一个字节,其字节长度由一个额外的参数 klen 的绝对值给出。NULL 键表示键将被视为 undef,并且 klen 被忽略;否则,键字符串可能包含嵌入的 NUL 字节。如果 klen 为负数,则字符串被视为 UTF-8 编码;否则不是。

hv_store 还有一个额外的参数 hash,它是键字符串的预先计算的哈希值,如果它没有被预先计算,则为零。此参数从 hv_stores 中省略,因为它在编译时自动计算。

如果 <hv> 为 NULL,则返回 NULL 并且不执行任何操作。

如果 val 为 NULL,则将其视为 undef;否则,调用者有责任在调用之前适当地增加 val 的引用计数,并在函数返回 NULL 时减少它。实际上,成功的 hv_store 会获取对 val 的一个引用的所有权。这通常是你想要的;新创建的 SV 的引用计数为 1,因此,如果你的代码只创建 SV 并将它们存储在哈希中,hv_store 将拥有对新 SV 的唯一引用,并且你的代码不需要做任何进一步的操作来清理。

hv_store 未实现为对 "hv_store_ent" 的调用,并且不会为键创建临时 SV,因此,如果你的键数据尚未以 SV 形式存在,则优先使用 hv_store 而不是 hv_store_ent

有关如何在绑定哈希上使用此函数的更多信息,请参阅 "perlguts 中的绑定哈希和数组的魔法"

    SV **  hv_store (HV *hv, const char *key, I32 klen, SV *val,
                     U32 hash)
    SV **  hv_stores(HV *hv, "key", SV *val)
hv_store_ent

val 存储在哈希中。哈希键指定为 keyhash 参数是预先计算的哈希值;如果它为零,则 Perl 将计算它。返回值是新创建的哈希条目。如果操作失败或值不需要实际存储在哈希中(如绑定哈希的情况),它将为 NULL。否则,可以使用此处描述的 He? 宏访问返回值的内容。请注意,调用者有责任在调用之前适当地增加 val 的引用计数,并在函数返回 NULL 时减少它。实际上,成功的 hv_store_ent 会获取对 val 的一个引用的所有权。这通常是你想要的;新创建的 SV 的引用计数为 1,因此,如果你的代码只创建 SV 并将它们存储在哈希中,hv_store 将拥有对新 SV 的唯一引用,并且你的代码不需要做任何进一步的操作来清理。请注意,hv_store_ent 仅读取 key;与 val 不同,它不会获取它的所有权,因此维护 key 上的正确引用计数完全是调用者的责任。它不获取所有权的原因是,key 在此函数返回后不再使用,因此可以立即释放。hv_store 未实现为对 hv_store_ent 的调用,并且不会为键创建临时 SV,因此,如果你的键数据尚未以 SV 形式存在,则优先使用 hv_store 而不是 hv_store_ent

有关如何在绑定哈希上使用此函数的更多信息,请参阅 "perlguts 中的绑定哈希和数组的魔法"

    HE *  hv_store_ent(HV *hv, SV *key, SV *val, U32 hash)
hv_undef

取消定义哈希。undef(%hash) 的 XS 等效项。

除了释放哈希的所有元素(如 hv_clear())之外,它还会释放与哈希关联的任何辅助数据和存储。

有关哈希在返回时可能无效的说明,请参见 "av_clear"

    void  hv_undef(HV *hv)
newHV

创建一个新的 HV。引用计数设置为 1。

    HV *  newHV()
newHVhv

ohv 的内容被复制到一个新的哈希中。返回指向新哈希的指针。

    HV *  newHVhv(HV *hv)
Nullhv

已弃用! 计划从未来版本的 Perl 中移除 Nullhv。不要在新的代码中使用它;从现有代码中移除它。

空 HV 指针。

(已弃用 - 改用 (HV *)NULL)

PERL_HASH

perlguts 中描述。

    void  PERL_HASH(U32 hash, char *key, STRLEN klen)
PL_modglobal

PL_modglobal 是一个通用的解释器全局 HV,供需要在每个解释器基础上保留信息的扩展使用。在紧急情况下,它也可以用作扩展的符号表,以便在彼此之间共享数据。最好使用以扩展所属包名称为前缀的键。

在多线程 Perl 中,每个线程都有此变量的独立副本;每个副本在创建时都使用创建线程副本的当前值进行初始化。

    HV*  PL_modglobal

输入/输出

do_close

关闭 I/O 流。这实现了 Perl "close" in perlfunc

gv 是与流关联的 glob。

is_explict 如果这是对流的显式关闭,则为 true;如果它是另一个操作的一部分,例如关闭管道(这涉及隐式关闭两端),则为 false

如果成功,则返回 true;否则返回 false 并设置 errno 以指示原因。

    bool  do_close(GV *gv, bool is_explicit)
IoDIRP

perlguts 中描述。

    DIR *  IoDIRP(IO *io)
IOf_FLUSH

perlguts 中描述。

IoFLAGS

perlguts 中描述。

    U8  IoFLAGS(IO *io)
IOf_UNTAINT

perlguts 中描述。

IoIFP

perlguts 中描述。

    PerlIO *  IoIFP(IO *io)
IoOFP

perlguts 中描述。

    PerlIO *  IoOFP(IO *io)
IoTYPE

perlguts 中描述。

    char  IoTYPE(IO *io)
my_chsize

如果可用,则为 C 库 chsize(3),否则为 Perl 的实现。

    I32  my_chsize(int fd, Off_t length)
my_dirfd

如果可用,则为 C 库 dirfd(3),否则为 Perl 的实现,或者如果不容易模拟,则会报错。

    int  my_dirfd(DIR *dir)
my_pclose

C 库 pclose(3) 的包装器。不要使用后者,因为 Perl 版本知道与 Perl 解释器其余部分交互的事项。

    I32  my_pclose(PerlIO *ptr)
my_popen

C 库 popen(3) 的包装器。不要使用后者,因为 Perl 版本知道与 Perl 解释器其余部分交互的内容。

    PerlIO *  my_popen(const char *cmd, const char *mode)
newIO

创建一个新的 IO,将引用计数设置为 1。

    IO *  newIO()
PERL_FLUSHALL_FOR_CHILD

这定义了一种刷新所有输出缓冲区的方法。这可能是一个性能问题,因此我们允许人们禁用它。此外,如果我们使用 stdio,则存在 fflush(NULL) 的错误实现,Solaris 是最突出的例子。

    void  PERL_FLUSHALL_FOR_CHILD
PerlIO_apply_layers
PerlIO_binmode
PerlIO_canset_cnt
PerlIO_clearerr
PerlIO_close
PerlIO_debug
PerlIO_eof
PerlIO_error
PerlIO_exportFILE
PerlIO_fast_gets
PerlIO_fdopen
PerlIO_fileno
PerlIO_fill
PerlIO_findFILE
PerlIO_flush
PerlIO_get_base
PerlIO_get_bufsiz
PerlIO_get_cnt
PerlIO_get_ptr
PerlIO_getc
PerlIO_getpos
PerlIO_has_base
PerlIO_has_cntptr
PerlIO_importFILE
PerlIO_open
PerlIO_printf
PerlIO_putc
PerlIO_puts
PerlIO_read
PerlIO_releaseFILE
PerlIO_reopen
PerlIO_rewind
PerlIO_seek
PerlIO_set_cnt
PerlIO_set_ptrcnt
PerlIO_setlinebuf
PerlIO_setpos
PerlIO_stderr
PerlIO_stdin
PerlIO_stdout
PerlIO_stdoutf
PerlIO_tell
PerlIO_ungetc
PerlIO_unread
PerlIO_vprintf
PerlIO_write

perlapio 中描述。

    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)
PERLIO_F_APPEND
PERLIO_F_CANREAD
PERLIO_F_CANWRITE
PERLIO_F_CRLF
PERLIO_F_EOF
PERLIO_F_ERROR
PERLIO_F_FASTGETS
PERLIO_F_LINEBUF
PERLIO_F_OPEN
PERLIO_F_RDBUF
PERLIO_F_TEMP
PERLIO_F_TRUNCATE
PERLIO_F_UNBUF
PERLIO_F_UTF8
PERLIO_F_WRBUF

perliol 中描述。

PERLIO_FUNCS_CAST

将指针 func 转换为类型 PerlIO_funcs *

PERLIO_FUNCS_DECL

声明 ftab 为 PerlIO 函数表,即类型为 PerlIO_funcs

    PERLIO_FUNCS_DECL(PerlIO * ftab)
PERLIO_K_BUFFERED
PERLIO_K_CANCRLF
PERLIO_K_FASTGETS
PERLIO_K_MULTIARG
PERLIO_K_RAW

perliol 中描述。

PERLIO_NOT_STDIO

perlapio 中描述。

PL_maxsysfd

perliol 中描述。

repeatcpy

将从from开始的len字节复制count次,并将它们放置到从to开始的内存中,该内存必须足够大以容纳所有复制的字节。

    void  repeatcpy(char *to, const char *from, I32 len, IV count)
USE_STDIO

perlapio 中描述。

整数

CASTI32

如果 C 编译器可以将负数或大浮点数转换为 32 位整数,则定义此符号。

HAS_INT64_T

如果 C 编译器支持int64_t,则将定义此符号。通常需要包含inttypes.h,但有时sys/types.h就足够了。

HAS_LONG_LONG

如果 C 编译器支持 long long,则将定义此符号。

HAS_QUAD

如果定义了此符号,则表示存在 64 位整数类型Quad_t及其无符号对应类型Uquad_tQUADKIND将是QUAD_IS_INTQUAD_IS_LONGQUAD_IS_LONG_LONGQUAD_IS_INT64_TQUAD_IS___INT64之一。

I32df

此符号定义用于将 Perl I32 作为带符号十进制整数打印的格式字符串。

INT16_C
INT32_C
INT64_C

返回 C 编译器识别的对应整数类型在机器上的常量number的标记。

如果机器没有 64 位类型,则INT64_C未定义。使用"INTMAX_C"获取平台上可用的最大类型。

    I16  INT16_C(number)
    I32  INT32_C(number)
    I64  INT64_C(number)
INTMAX_C

返回 C 编译器识别的机器上最宽整数类型的常量number的标记。例如,如果机器有long long,则INTMAX_C(-1)将产生

-1LL

另请参见,例如,"INT32_C"

使用"IV"声明此平台上最大可用大小的变量。

    INTMAX_C(number)
INTSIZE

此符号包含sizeof(int)的值,以便 C 预处理器可以根据它做出决策。

I8SIZE

此符号包含sizeof(I8)

I16SIZE

此符号包含sizeof(I16)

I32SIZE

此符号包含sizeof(I32)

I64SIZE

此符号包含sizeof(I64)

I8TYPE

此符号定义用于 Perl 的 I8 的 C 类型。

I16TYPE

此符号定义用于 Perl 的 I16 的 C 类型。

I32TYPE

此符号定义用于 Perl 的 I32 的 C 类型。

I64TYPE

此符号定义用于 Perl 的 I64 的 C 类型。

IV
I8
I16
I32
I64

perlguts 中描述。

IV_MAX

此平台上 IV 中可以容纳的最大有符号整数。

    IV  IV_MAX
IV_MIN

此平台上 IV 中可以容纳的最远离 0 的负有符号整数。

    IV  IV_MIN
IVSIZE

此符号包含sizeof(IV)

IVTYPE

此符号定义用于 Perl 的 IV 的 C 类型。

line_t

用于声明要保存行号的变量的 typedef。

LONGLONGSIZE

此符号包含 long long 的大小,以便 C 预处理器可以根据它做出决策。它仅在系统支持 long long 时定义。

LONGSIZE

此符号包含sizeof(long)的值,以便 C 预处理器可以根据它做出决策。

memzero

将从*d开始的l字节全部设置为零。

    void  memzero(void * d, Size_t l)
PERL_INT_FAST8_T
PERL_INT_FAST16_T
PERL_UINT_FAST8_T
PERL_UINT_FAST16_T

这些等效于在具有这些类型的平台上的相应命名的 C99 类型定义;它们在没有这些类型的平台上评估为 intunsigned int,因此您可以移植地利用此 C99 功能。

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

这些给出当前平台上相应类型变量中可表示的最大和最小数字。

对于有符号类型,可表示的最小数字是最负的数字,即离零最远的数字。

对于 C99 及更高版本的编译器,这些对应于诸如 INT_MAX 之类的东西,这些东西可供 C 代码使用。但是这些常量由 Perl 提供,允许在早期编译器上编译的代码移植地访问相同的常量。

    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
SHORTSIZE

此符号包含 sizeof(short) 的值,以便 C 预处理器可以根据它做出决策。

UINT16_C
UINT32_C
UINT64_C

返回 C 编译器识别的标记,用于机器上相应无符号整数类型的常量 number

如果机器没有 64 位类型,则 UINT64_C 未定义。使用 "UINTMAX_C" 获取平台上可用的最大类型。

    U16  UINT16_C(number)
    U32  UINT32_C(number)
    U64  UINT64_C(number)
UINTMAX_C

返回 C 编译器识别的令牌,用于表示机器上最宽无符号整数类型的常量 number。例如,如果机器有 long 类型,UINTMAX_C(1) 将产生

1UL

另请参见,例如,"UINT32_C"

使用 "UV" 声明此平台上最大可用大小的变量。

    UINTMAX_C(number)
U32of

此符号定义用于将 Perl U32 作为无符号八进制整数打印的格式字符串。

U8SIZE

此符号包含 sizeof(U8)

U16SIZE

此符号包含 sizeof(U16)

U32SIZE

此符号包含 sizeof(U32)

U64SIZE

此符号包含 sizeof(U64)

U8TYPE

此符号定义用于 Perl 的 U8 的 C 类型。

U16TYPE

此符号定义用于 Perl 的 U16 的 C 类型。

U32TYPE

此符号定义用于 Perl 的 U32 的 C 类型。

U64TYPE

此符号定义用于 Perl 的 U64 的 C 类型。

U32uf

此符号定义用于将 Perl U32 作为无符号十进制整数打印的格式字符串。

UV
U8
U16
U32
U64

perlguts 中描述。

UV_MAX

此平台上 UV 中可以容纳的最大无符号整数。

    UV  UV_MAX
UV_MIN

此平台上 UV 中可以容纳的最小无符号整数。它应该等于零。

    UV  UV_MIN
UVSIZE

此符号包含 sizeof(UV)

UVTYPE

此符号定义用于 Perl 的 UV 的 C 类型。

U32Xf

此符号定义用于将 Perl U32 作为大写 ABCDEF 的无符号十六进制整数打印的格式字符串。

U32xf

此符号定义用于将 Perl U32 作为小写 abcdef 的无符号十六进制整数打印的格式字符串。

WIDEST_UTYPE

生成平台上最宽的无符号整数类型,目前是 U32U64。这可以在声明中使用,例如

WIDEST_UTYPE my_uv;

或强制转换

my_uv = (WIDEST_UTYPE) val;

I/O 格式

这些用于格式化相应的类型。例如,不要说

Perl_newSVpvf(pTHX_ "Create an SV with a %d in it\n", iv);

使用

Perl_newSVpvf(pTHX_ "Create an SV with a " IVdf " in it\n", iv);

这可以避免你必须知道,例如 IV,是否需要以 %d%ld 或其他方式打印。

HvNAMEf

perlguts 中描述。

HvNAMEf_QUOTEDPREFIX

perlguts 中描述。

IVdf

此符号定义用于将 Perl IV 作为带符号十进制整数打印的格式字符串。

NVef

此符号定义用于使用 %e 式浮点格式打印 Perl NV 的格式字符串。

NVff

此符号定义用于使用 %f 式浮点格式打印 Perl NV 的格式字符串。

NVgf

此符号定义用于使用 %g 式浮点格式打印 Perl NV 的格式字符串。

PERL_PRIeldbl

如果定义了此符号,它包含 stdio 用于格式化长双精度数(格式 'e')以进行输出的字符串。

PERL_PRIfldbl

如果定义了此符号,它包含 stdio 用于格式化长双精度数(格式 'f')以进行输出的字符串。

PERL_PRIgldbl

如果定义了此符号,它包含 stdio 用于格式化长双精度数(格式 'g')以进行输出的字符串。

PERL_SCNfldbl

如果定义了此符号,它包含 stdio 用于格式化长双精度数(格式 'f')以进行输入的字符串。

PRINTF_FORMAT_NULL_OK

允许在检查 printf 风格时 __printf__ 格式为 null。

SVf

perlguts 中描述。

SVfARG

perlguts 中描述。

    SVfARG(SV *sv)
SVf_QUOTEDPREFIX

perlguts 中描述。

UTF8f

perlguts 中描述。

UTF8fARG

perlguts 中描述。

    UTF8fARG(bool is_utf8, Size_t byte_len, char *str)
UTF8f_QUOTEDPREFIX

perlguts 中描述。

UVf

已弃用! 计划在未来的 Perl 版本中移除 UVf。不要在新的代码中使用它;从现有代码中删除它。

UVuf 的过时形式,您应该将其转换为使用它。

    const char *  UVf
UVof

此符号定义用于将 Perl UV 打印为无符号八进制整数的格式字符串。

UVuf

此符号定义用于将 Perl UV 打印为无符号十进制整数的格式字符串。

UVXf

此符号定义用于将 Perl UV 打印为使用大写 ABCDEF 的无符号十六进制整数的格式字符串。

UVxf

此符号定义用于将 Perl UV 打印为使用小写 abcdef 的无符号十六进制整数的格式字符串。

词法分析器接口

这是 Perl 解析器的底层,管理字符和标记。

BHK

perlguts 中描述。

lex_bufutf8

注意:lex_bufutf8实验性的,可能会在未经通知的情况下更改或删除。

指示词法分析器缓冲区中的八位字节 ("PL_parser->linestr") 是否应解释为 Unicode 字符的 UTF-8 编码。如果不是,则应将其解释为 Latin-1 字符。这类似于标量的 SvUTF8 标志。

在 UTF-8 模式下,不能保证词法分析器缓冲区实际上包含有效的 UTF-8。词法分析代码必须能够在无效编码的情况下保持健壮性。

"PL_parser->linestr" 标量的实际 SvUTF8 标志很重要,但它不是关于输入字符编码的全部内容。通常,当读取文件时,标量包含八位字节,并且其 SvUTF8 标志处于关闭状态,但如果 use utf8 编译指示有效,则应将八位字节解释为 UTF-8。然而,在字符串求值期间,标量可能具有 SvUTF8 标志,在这种情况下,其八位字节应解释为 UTF-8,除非 use bytes 编译指示有效。此逻辑将来可能会更改;使用此函数而不是自己实现此逻辑。

    bool  lex_bufutf8()
lex_discard_to

注意:lex_discard_to实验性的,可能会在未经通知的情况下更改或删除。

丢弃 "PL_parser->linestr" 缓冲区的第一部分,直到 ptr。缓冲区的剩余内容将被移动,并且所有指向缓冲区的指针将相应更新。ptr 必须不晚于 "PL_parser->bufptr" 的位置:不允许丢弃尚未词法分析的文本。

通常,没有必要直接执行此操作,因为使用 "lex_next_chunk" 及其相关内容的隐式丢弃行为就足够了。但是,如果一个标记跨越多行,并且词法分析代码为此目的在缓冲区中保留了多行文本,那么在标记完成之后,最好显式丢弃现在不再需要的早期行,以避免未来的多行标记无限地增长缓冲区。

    void  lex_discard_to(char *ptr)
lex_grow_linestr

注意:lex_grow_linestr 处于实验阶段,可能会在未经通知的情况下更改或删除。

重新分配词法分析器缓冲区("PL_parser->linestr"),以容纳至少 len 个字节(包括终止的 NUL)。返回指向重新分配的缓冲区的指针。在对缓冲区进行任何会增加其长度的直接修改之前,这都是必要的。 "lex_stuff_pvn" 提供了一种更方便的方法来将文本插入缓冲区。

不要直接在 PL_parser->linestr 上使用 SvGROWsv_grow;此函数会更新所有直接指向缓冲区的词法分析器变量。

    char *  lex_grow_linestr(STRLEN len)
lex_next_chunk

注意:lex_next_chunk 处于实验阶段,可能会在未经通知的情况下更改或删除。

读取要进行词法分析的下一块文本,并将其追加到 "PL_parser->linestr"。当词法分析代码已查看当前块的末尾并希望了解更多信息时,应调用此函数。通常(但并非必须)在此时词法分析已消耗当前块的全部内容。

如果 "PL_parser->bufptr" 指向当前块的末尾(即,当前块已被完全消耗),通常在读取新块的同时会丢弃当前块。如果 flags 设置了 LEX_KEEP_PREVIOUS 位,则不会丢弃当前块。如果当前块尚未完全消耗,则无论标志如何,都不会丢弃它。

如果向缓冲区添加了一些新文本,则返回 true;如果缓冲区已到达输入文本的末尾,则返回 false。

    bool  lex_next_chunk(U32 flags)
lex_peek_unichar

注意:lex_peek_unichar 处于实验阶段,可能会在未经通知的情况下更改或删除。

在当前正在进行词法分析的文本中向前查看一个(Unicode)字符。返回下一个字符的代码点(无符号整数值),如果词法分析已到达输入文本的末尾,则返回 -1。要消耗已查看的字符,请使用 "lex_read_unichar"

如果下一个字符位于(或扩展到)输入文本的下一块中,则会读取下一块。通常会同时丢弃当前块,但如果 flags 设置了 LEX_KEEP_PREVIOUS 位,则不会丢弃当前块。

如果输入被解释为 UTF-8 并且遇到 UTF-8 编码错误,则会生成异常。

    I32  lex_peek_unichar(U32 flags)
lex_read_space

注意:lex_read_space 处于实验阶段,可能会在未经通知的情况下更改或删除。

在当前正在进行词法分析的文本中读取可选空格,以 Perl 风格。空格可能包括普通的空白字符和 Perl 风格的注释。如果遇到 #line 指令,则会处理它们。 "PL_parser->bufptr" 会移过空格,以便它指向非空格字符(或输入文本的末尾)。

如果空格延伸到下一块输入文本,则会读取下一块文本。通常,当前块会同时被丢弃,但如果flags设置了LEX_KEEP_PREVIOUS位,则当前块不会被丢弃。

    void  lex_read_space(U32 flags)
lex_read_to

注意:lex_read_to实验性的,可能会在不通知的情况下更改或删除。

"PL_parser->bufptr"ptr,消耗词法分析器缓冲区中的文本。这将"PL_parser->bufptr"推进到与ptr匹配,并在每次遇到换行符时执行正确的簿记。这是消耗词法分析文本的正常方式。

可以使用稍微高级的函数"lex_peek_unichar""lex_read_unichar"来抽象出缓冲区中八位字节的解释。

    void  lex_read_to(char *ptr)
lex_read_unichar

注意:lex_read_unichar实验性的,可能会在不通知的情况下更改或删除。

读取当前正在进行词法分析的文本中的下一个(Unicode)字符。返回读取的字符的代码点(无符号整数值),并将"PL_parser->bufptr"移到字符的后面,或者如果词法分析已到达输入文本的末尾,则返回 -1。要非破坏性地检查下一个字符,请使用"lex_peek_unichar"

如果下一个字符位于(或扩展到)输入文本的下一块中,则会读取下一块。通常会同时丢弃当前块,但如果 flags 设置了 LEX_KEEP_PREVIOUS 位,则不会丢弃当前块。

如果输入被解释为 UTF-8 并且遇到 UTF-8 编码错误,则会生成异常。

    I32  lex_read_unichar(U32 flags)
lex_start

注意:lex_start实验性的,可能会在不通知的情况下更改或删除。

创建一个新的词法分析器/解析器状态对象并初始化它,提供一个上下文,以便从新的 Perl 代码源进行词法分析和解析。指向新状态对象的指针将被放置在"PL_parser"中。在保存堆栈上进行条目,以便在展开时,新的状态对象将被销毁,并且"PL_parser"的先前值将被恢复。无需执行其他操作来清理解析上下文。

要解析的代码来自linersfpline(如果非空)提供一个包含要解析的代码的字符串(以 SV 形式)。将复制字符串,因此随后对line的修改不会影响解析。rsfp(如果非空)提供一个输入流,从中将读取代码以进行解析。如果两者都不为空,则line中的代码将首先出现,并且必须包含完整的输入行,而rsfp将提供源代码的其余部分。

flags参数保留供将来使用。目前它仅由 perl 内部使用,因此扩展应该始终传递零。

    void  lex_start(SV *line, PerlIO *rsfp, U32 flags)
lex_stuff_pv

注意:lex_stuff_pv实验性的,可能会在不通知的情况下更改或删除。

将字符插入词法分析器缓冲区("PL_parser->linestr"),紧接在当前词法分析点("PL_parser->bufptr")之后,如果需要则重新分配缓冲区。这意味着稍后运行的词法分析代码将看到这些字符,就好像它们出现在输入中一样。不建议在正常的解析过程中执行此操作,并且大多数使用此功能的操作都存在插入的字符被意外解释的风险。

要插入的字符串由从 pv 开始到第一个空字符结束的八位字节表示。这些八位字节被解释为 UTF-8 或 Latin-1,具体取决于 flags 中是否设置了 LEX_STUFF_UTF8 标志。根据缓冲区当前的解释方式("lex_bufutf8"),字符将被重新编码为词法分析器缓冲区。如果无法方便地以空字符结尾要插入的字符串,则 "lex_stuff_pvn" 函数更合适。

    void  lex_stuff_pv(const char *pv, U32 flags)
lex_stuff_pvn

注意:lex_stuff_pvn 是 **实验性** 的,可能会在未经通知的情况下更改或删除。

将字符插入词法分析器缓冲区("PL_parser->linestr"),紧接在当前词法分析点("PL_parser->bufptr")之后,如果需要则重新分配缓冲区。这意味着稍后运行的词法分析代码将看到这些字符,就好像它们出现在输入中一样。不建议在正常的解析过程中执行此操作,并且大多数使用此功能的操作都存在插入的字符被意外解释的风险。

要插入的字符串由从 pv 开始的 len 个八位字节表示。这些八位字节被解释为 UTF-8 或 Latin-1,具体取决于 flags 中是否设置了 LEX_STUFF_UTF8 标志。根据缓冲区当前的解释方式("lex_bufutf8"),字符将被重新编码为词法分析器缓冲区。如果要插入的字符串可用作 Perl 标量,则 "lex_stuff_sv" 函数更方便。

    void  lex_stuff_pvn(const char *pv, STRLEN len, U32 flags)
lex_stuff_pvs

注意:lex_stuff_pvs 是 **实验性** 的,可能会在未经通知的情况下更改或删除。

"lex_stuff_pvn" 相似,但接受一个文字字符串而不是字符串/长度对。

    void  lex_stuff_pvs("pv", U32 flags)
lex_stuff_sv

注意:lex_stuff_sv 是 **实验性** 的,可能会在未经通知的情况下更改或删除。

将字符插入词法分析器缓冲区("PL_parser->linestr"),紧接在当前词法分析点("PL_parser->bufptr")之后,如果需要则重新分配缓冲区。这意味着稍后运行的词法分析代码将看到这些字符,就好像它们出现在输入中一样。不建议在正常的解析过程中执行此操作,并且大多数使用此功能的操作都存在插入的字符被意外解释的风险。

要插入的字符串是 sv 的字符串值。根据缓冲区当前的解释方式("lex_bufutf8"),字符将被重新编码为词法分析器缓冲区。如果要插入的字符串不是 Perl 标量,则 "lex_stuff_pvn" 函数避免了构建标量的需要。

    void  lex_stuff_sv(SV *sv, U32 flags)
lex_unstuff

注意:lex_unstuff 是 **实验性** 的,可能会在未经通知的情况下更改或删除。

丢弃即将被词法分析的文本,从 "PL_parser->bufptr"ptrptr 之后的文本将被移动,缓冲区将被缩短。这将隐藏任何后续运行的词法分析代码的丢弃文本,就好像文本从未出现过一样。

这不是消耗词法分析文本的正常方式。为此,请使用 "lex_read_to"

    void  lex_unstuff(char *ptr)
parse_arithexpr

注意:parse_arithexpr 处于实验阶段,可能会在未经通知的情况下更改或删除。

解析 Perl 算术表达式。这可能包含优先级低于位移运算符的运算符。表达式必须以比较运算符或更低优先级的运算符(或通常会终止表达式的分号等)结尾(并因此终止)。如果 flags 设置了 PARSE_OPTIONAL 位,则表达式是可选的,否则是必需的。调用者有责任确保动态解析器状态("PL_parser" 等)正确设置,以反映要解析的代码的来源和表达式的词法上下文。

返回表示表达式的操作树。如果可选表达式不存在,则返回空指针,否则指针将非空。

如果解析或编译过程中发生错误,在大多数情况下,仍然会返回有效的操作树。错误反映在解析器状态中,通常会导致解析顶层出现单个异常,该异常涵盖了所有发生的编译错误。但是,某些编译错误会立即抛出异常。

    OP *  parse_arithexpr(U32 flags)
parse_barestmt

注意:parse_barestmt 处于实验阶段,可能会在未经通知的情况下更改或删除。

解析单个未修饰的 Perl 语句。这可以是正常的命令式语句或具有编译时效果的声明。它不包括任何标签或其他附加内容。调用者有责任确保动态解析器状态("PL_parser" 等)正确设置,以反映要解析的代码的来源和语句的词法上下文。

返回表示该语句的操作树。如果语句为空,例如它实际上是一个子程序定义(具有编译时副作用),则这可能是一个空指针。如果不是空,它将是直接实现语句的操作,适合传递给 "newSTATEOP"。它通常不包含 nextstate 或等效操作(除了那些完全包含在语句中的作用域中嵌入的操作)。

如果在解析或编译过程中发生错误,在大多数情况下,仍然会返回一个有效的操作树(最可能是空)。错误反映在解析器状态中,通常会导致解析顶层出现单个异常,该异常涵盖了所有发生的编译错误。但是,某些编译错误会立即抛出异常。

flags 参数保留供将来使用,并且必须始终为零。

    OP *  parse_barestmt(U32 flags)
parse_block

注意:parse_block实验性的,可能会在未经通知的情况下更改或删除。

解析单个完整的 Perl 代码块。它由一个左花括号、一系列语句和一个右花括号组成。该块构成一个词法作用域,因此 my 变量和各种编译时效果可以包含在其中。调用者有责任确保动态解析器状态("PL_parser" 等)正确设置以反映要解析的代码的来源和语句的词法上下文。

返回表示代码块的操作树。这始终是一个真实的操作,而不是空指针。它通常是一个 lineseq 列表,包括 nextstate 或等效操作。由于它是一个块,因此不包含任何构建任何类型的运行时作用域的操作。

如果在解析或编译过程中发生错误,在大多数情况下,仍然会返回一个有效的操作树(最可能是空)。错误反映在解析器状态中,通常会导致解析顶层出现单个异常,该异常涵盖了所有发生的编译错误。但是,某些编译错误会立即抛出异常。

flags 参数保留供将来使用,并且必须始终为零。

    OP *  parse_block(U32 flags)
parse_fullexpr

注意:parse_fullexpr实验性的,可能会在未经通知的情况下更改或删除。

解析单个完整的 Perl 表达式。这允许使用完整的表达式语法,包括最低优先级的运算符,例如 or。表达式必须后跟(因此终止)一个表达式通常会终止的标记:文件结尾、关闭括号标点符号、分号或其中一个表示后缀表达式语句修饰符的关键字。如果 flags 设置了 PARSE_OPTIONAL 位,则表达式是可选的,否则它是必需的。调用者有责任确保动态解析器状态("PL_parser" 等)正确设置以反映要解析的代码的来源和表达式的词法上下文。

返回表示表达式的操作树。如果可选表达式不存在,则返回空指针,否则指针将非空。

如果解析或编译过程中发生错误,在大多数情况下,仍然会返回有效的操作树。错误反映在解析器状态中,通常会导致解析顶层出现单个异常,该异常涵盖了所有发生的编译错误。但是,某些编译错误会立即抛出异常。

    OP *  parse_fullexpr(U32 flags)
parse_fullstmt

注意:parse_fullstmt 处于实验阶段,可能会在未经通知的情况下更改或删除。

解析单个完整的 Perl 语句。这可以是正常的命令式语句或具有编译时效果的声明,并且可以包含可选的标签。调用者有责任确保动态解析器状态("PL_parser" 等)被正确设置,以反映要解析的代码的来源和语句的词法上下文。

返回表示语句的 op 树。如果语句为空,则这可能是一个空指针,例如,如果它实际上是一个子程序定义(具有编译时副作用)。如果非空,它将是 "newSTATEOP" 调用的结果,通常包括一个 nextstate 或等效的 op。

如果在解析或编译过程中发生错误,在大多数情况下,仍然会返回一个有效的操作树(最可能是空)。错误反映在解析器状态中,通常会导致解析顶层出现单个异常,该异常涵盖了所有发生的编译错误。但是,某些编译错误会立即抛出异常。

flags 参数保留供将来使用,并且必须始终为零。

    OP *  parse_fullstmt(U32 flags)
parse_label

注意:parse_label 处于实验阶段,可能会在未经通知的情况下更改或删除。

解析单个标签,可能可选,类型是可能在 Perl 语句之前添加的。调用者有责任确保动态解析器状态("PL_parser" 等)被正确设置,以反映要解析的代码的来源。如果 flags 设置了 PARSE_OPTIONAL 位,则标签是可选的,否则是必需的。

标签的名称以新标量的形式返回。如果可选标签不存在,则返回一个空指针。

如果在解析过程中发生错误,这只能在标签是必需的情况下发生,则无论如何都会返回一个有效的标签。错误反映在解析器状态中,通常会导致在解析的顶层出现单个异常,该异常涵盖了发生的编译错误。

    SV *  parse_label(U32 flags)
parse_listexpr

注意:parse_listexpr 处于实验阶段,可能会在未经通知的情况下更改或删除。

解析 Perl 列表表达式。这可能包含优先级降至逗号运算符的运算符。表达式必须后跟(因此终止)低优先级逻辑运算符(如 or)或通常终止表达式的某些内容,例如分号。如果 flags 设置了 PARSE_OPTIONAL 位,则表达式是可选的,否则是必需的。调用者有责任确保动态解析器状态("PL_parser" 等)被正确设置,以反映要解析的代码的来源和表达式的词法上下文。

返回表示表达式的操作树。如果可选表达式不存在,则返回空指针,否则指针将非空。

如果解析或编译过程中发生错误,在大多数情况下,仍然会返回有效的操作树。错误反映在解析器状态中,通常会导致解析顶层出现单个异常,该异常涵盖了所有发生的编译错误。但是,某些编译错误会立即抛出异常。

    OP *  parse_listexpr(U32 flags)
parse_stmtseq

注意:parse_stmtseq 处于实验阶段,可能会在未经通知的情况下更改或删除。

解析一个包含零个或多个 Perl 语句的序列。这些语句可以是普通的命令式语句,包括可选的标签,或者具有编译时效果的声明,或者它们的任何组合。语句序列在遇到一个闭合大括号或文件末尾时结束,此时一个新的语句可以有效地开始。调用者有责任确保动态解析器状态("PL_parser" 等)被正确设置,以反映要解析的代码的来源和语句的词法上下文。

返回表示语句序列的运算符树。如果所有语句都是空的,则这可能是一个空指针,例如,如果没有语句或只有子程序定义(具有编译时副作用)。如果非空,它将是一个 lineseq 列表,通常包括 nextstate 或等效的运算符。

如果解析或编译过程中发生错误,在大多数情况下,仍然会返回有效的操作树。错误反映在解析器状态中,通常会导致解析顶层出现单个异常,该异常涵盖了所有发生的编译错误。但是,某些编译错误会立即抛出异常。

flags 参数保留供将来使用,并且必须始终为零。

    OP *  parse_stmtseq(U32 flags)
parse_subsignature

注意:parse_subsignature实验性的,可能会在不通知的情况下更改或删除。

解析一个子程序签名声明。这是在启用 signatures 特性时,在命名或匿名子程序声明后的括号中的内容。请注意,此函数既不期望也不消耗签名周围的开括号和闭括号;处理这些括号是调用者的工作。

此函数只能在解析子程序期间调用;在调用 "start_subparse" 之后。它可能会为当前子程序的垫子分配词法变量。

返回用于在运行时从堆栈中解包参数的运算符树。此运算符树应该出现在已编译函数的开头。调用者可能希望使用 "op_append_list" 在其函数体之后构建函数体,或者在调用 "newATTRSUB" 之前将其与函数体拼接在一起。

flags 参数保留供将来使用,并且必须始终为零。

    OP *  parse_subsignature(U32 flags)
parse_termexpr

注意:parse_termexpr实验性的,可能会在不通知的情况下更改或删除。

解析一个 Perl 术语表达式。这可能包含优先级降至赋值运算符的运算符。表达式必须后跟(因此终止)逗号或更低优先级的运算符,或者由通常会终止表达式的某些内容终止,例如分号。如果 flags 设置了 PARSE_OPTIONAL 位,则表达式是可选的,否则它是必需的。调用者有责任确保动态解析器状态("PL_parser" 等)被正确设置,以反映要解析的代码的来源和表达式的词法上下文。

返回表示表达式的操作树。如果可选表达式不存在,则返回空指针,否则指针将非空。

如果解析或编译过程中发生错误,在大多数情况下,仍然会返回有效的操作树。错误反映在解析器状态中,通常会导致解析顶层出现单个异常,该异常涵盖了所有发生的编译错误。但是,某些编译错误会立即抛出异常。

    OP *  parse_termexpr(U32 flags)
PL_parser

指向一个结构体的指针,该结构体封装了当前正在进行的解析操作的状态。该指针可以在本地更改以执行嵌套解析,而不会干扰外部解析的状态。PL_parser 的各个成员有自己的文档。

PL_parser->bufend

注意:PL_parser->bufend实验性的,可能会在未经通知的情况下更改或删除。

指向当前正在进行词法分析的文本块的末尾的直接指针,即词法分析器缓冲区的末尾。这等于 SvPVX(PL_parser->linestr) + SvCUR(PL_parser->linestr)。缓冲区末尾始终有一个 NUL 字符(零字节),它不计入缓冲区内容的一部分。

PL_parser->bufptr

注意:PL_parser->bufptr实验性的,可能会在未经通知的情况下更改或删除。

指向词法分析器缓冲区内当前词法分析位置的指针。可以在 SvPVX("PL_parser->linestr")"PL_parser->bufend" 限定的范围内自由检查此点周围的字符。缓冲区的字节可以被解释为 UTF-8 或 Latin-1,具体取决于 "lex_bufutf8" 的指示。

词法分析代码(无论是在 Perl 核心内还是核心外)都会将此指针移过它所消耗的字符。还期望它在消耗换行符时执行一些簿记工作。可以使用 "lex_read_to" 函数更方便地执行此移动,该函数会适当地处理换行符。

可以使用稍微高级的函数"lex_peek_unichar""lex_read_unichar"来抽象出缓冲区中八位字节的解释。

PL_parser->linestart

注意:PL_parser->linestart实验性的,可能会在未经通知的情况下更改或删除。

指向词法分析器缓冲区内当前行的开头的指针。这对于指示错误发生在哪个列很有用,除此之外没有其他用途。任何消耗换行符的词法分析代码都必须更新此值;"lex_read_to" 函数会处理此细节。

PL_parser->linestr

注意:PL_parser->linestr实验性的,可能会在未经通知的情况下更改或删除。

包含当前正在考虑的文本块的缓冲区标量,即当前正在进行词法分析的文本。这始终是一个普通字符串标量(对于它,SvPOK 为真)。它不打算通过正常的标量方式用作标量;而是通过下面描述的指针变量直接引用缓冲区。

词法分析器维护指向 PL_parser->linestr 缓冲区中内容的各种 char* 指针。如果 PL_parser->linestr 曾经被重新分配,所有这些指针都必须更新。不要尝试手动执行此操作,而是使用 "lex_grow_linestr",如果你需要重新分配缓冲区。

缓冲区中文本块的内容通常恰好是一行完整的输入,包括换行符,但也有例外情况。缓冲区中的字节可能被解释为 UTF-8 或 Latin-1。函数 "lex_bufutf8" 会告诉你哪个。不要在这个标量上使用 SvUTF8 标志,它可能与之不一致。

要直接检查缓冲区,变量 "PL_parser->bufend" 指向缓冲区的末尾。当前词法分析位置由 "PL_parser->bufptr" 指向。直接使用这些指针通常比通过普通标量方式检查标量更可取。

suspend_compcv

实现“挂起编译 CV”的概念的一部分,它可以用来在解析 CV 时暂停解析器和编译器,以便稍后返回。

此函数将正在编译的子例程的当前状态 (PL_compcv) 保存到提供的缓冲区中。这应该最初用于在缓冲区中创建状态,作为块内 LEAVE 之前的最后一步。

ENTER;
start_subparse(0);
...

suspend_compcv(&buffer);
LEAVE;

挂起后,resume_compcvresume_compcv_and_save 函数可以稍后用于从停止的地方继续解析。

    void  suspend_compcv(struct suspended_compcv *buffer)
wrap_infix_plugin

注意:wrap_infix_plugin 实验性,可能会在未经通知的情况下更改或删除。

注意: 此 API 完全是为了使 CPAN 模块 XS::Parse::Infix 工作而存在的。预计不会有其他模块使用它;相反,它们应该使用 XS::Parse::Infix 来提供对新中缀运算符的解析。

将 C 函数放入中缀插件链中。这是操作 "PL_infix_plugin" 变量的首选方式。new_plugin 是指向要添加到中缀插件链的 C 函数的指针,old_plugin_p 指向一个存储位置,其中将存储指向链中下一个函数的指针。new_plugin 的值将写入 "PL_infix_plugin" 变量,而先前存储在那里的值将写入 *old_plugin_p

应避免直接访问 "PL_infix_plugin"

    void  wrap_infix_plugin(Perl_infix_plugin_t new_plugin,
                            Perl_infix_plugin_t *old_plugin_p)
wrap_keyword_plugin

注意:wrap_keyword_plugin 实验性,可能会在未经通知的情况下更改或删除。

将 C 函数放入关键字插件链中。这是操作 "PL_keyword_plugin" 变量的首选方式。new_plugin 是指向要添加到关键字插件链的 C 函数的指针,old_plugin_p 指向一个存储位置,其中将存储指向链中下一个函数的指针。new_plugin 的值将写入 "PL_keyword_plugin" 变量,而先前存储在那里的值将写入 *old_plugin_p

"PL_keyword_plugin" 是整个进程的全局变量,一个希望挂钩关键字解析的模块可能会发现自己在一个进程中被调用多次,通常是在不同的线程中。为了处理这种情况,此函数是幂等的。位置 *old_plugin_p 必须最初(每个进程一次)包含一个空指针。如果 C 变量没有显式初始化器,则静态持续时间(在文件范围内声明,通常也标记为 static 以赋予其内部链接)的 C 变量将被隐式适当地初始化。此函数只有在发现 *old_plugin_p 为空时才会真正修改插件链。此函数在小范围内也是线程安全的。它使用适当的锁定来避免访问 "PL_keyword_plugin" 时出现竞争条件。

当调用此函数时,new_plugin 引用的函数必须准备好被调用,除了 *old_plugin_p 未填充。在多线程情况下,即使在该函数返回之前,也可能会立即调用 new_plugin*old_plugin_p 将始终在调用 new_plugin 之前适当地设置。如果 new_plugin 决定不对其给定的标识符执行任何特殊操作(这对于大多数对关键字插件的调用来说是常见情况),它必须链接 *old_plugin_p 引用的插件函数。

总而言之,安装关键字插件的 XS 代码通常应该类似于以下内容

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);

应避免直接访问 "PL_keyword_plugin"

    void  wrap_keyword_plugin(Perl_keyword_plugin_t new_plugin,
                              Perl_keyword_plugin_t *old_plugin_p)

区域设置

DECLARATION_FOR_LC_NUMERIC_MANIPULATION

此宏应作为语句使用。它声明一个私有变量(其名称以下划线开头),该变量是本节中其他宏所需的。未能正确包含此宏会导致语法错误。为了与 C89 C 编译器兼容,它应该放在任何可执行语句之前的块中。

    void  DECLARATION_FOR_LC_NUMERIC_MANIPULATION
foldEQ_locale

如果字符串 s1s2 的前 len 个字节在当前区域设置中不区分大小写地相同,则返回 true;否则返回 false。

    I32  foldEQ_locale(const char *a, const char *b, I32 len)
HAS_DUPLOCALE

如果定义了此符号,则表示duplocale例程可用,用于复制区域设置对象。

HAS_FREELOCALE

如果定义了此符号,则表示freelocale例程可用,用于释放与区域设置对象关联的资源。

HAS_LC_MONETARY_2008

如果定义了此符号,则表示localeconv例程可用,并且具有在POSIX 1003.1-2008 中添加的附加成员。

HAS_LOCALECONV

如果定义了此符号,则表示localeconv例程可用,用于数字和货币格式约定。

HAS_LOCALECONV_L

如果定义了此符号,则表示localeconv_l例程可用,用于查询有关区域设置的某些信息。

HAS_NEWLOCALE

如果定义了此符号,则表示newlocale例程可用,用于返回新的区域设置对象或修改现有的区域设置对象。

HAS_NL_LANGINFO

如果定义了此符号,则表示nl_langinfo例程可用,用于返回本地数据。您还需要langinfo.h,因此也需要I_LANGINFO

HAS_NL_LANGINFO_L

定义此符号时,表示存在nl_langinfo_l()函数。

HAS_QUERYLOCALE

如果定义了此符号,则表示querylocale例程可用,用于返回类别掩码的区域设置名称。

HAS_SETLOCALE

如果定义了此符号,则表示setlocale例程可用,用于处理特定于区域设置的 ctype 实现。

HAS_SETLOCALE_R

如果定义了此符号,则表示setlocale_r例程可用,用于以可重入方式设置区域设置。

HAS_THREAD_SAFE_NL_LANGINFO_L

定义此符号时,表示存在nl_langinfo_l()函数,并且它是线程安全的。

HAS_USELOCALE

如果定义了此符号,则表示uselocale例程可用,用于为调用线程设置当前区域设置。

I_LANGINFO

如果定义了此符号,则表示langinfo.h存在,应包含该文件。

    #ifdef I_LANGINFO
        #include <langinfo.h>
    #endif
I_LOCALE

如果定义了此符号,则表示 C 程序应包含locale.h

    #ifdef I_LOCALE
        #include <locale.h>
    #endif
IN_LOCALE

如果未带参数的简单 locale 编译指示(use locale)生效,则评估为 TRUE。

    bool  IN_LOCALE
IN_LOCALE_COMPILETIME

如果在编译 Perl 程序(包括 eval)时,未带参数的简单 locale 编译指示(use locale)生效,则评估为 TRUE。

    bool  IN_LOCALE_COMPILETIME
IN_LOCALE_RUNTIME

如果在执行 Perl 程序(包括 eval)时,未带参数的简单 locale 编译指示(use locale)生效,则评估为 TRUE。

    bool  IN_LOCALE_RUNTIME
I_XLOCALE

如果定义了此符号,则表示 C 程序可以使用xlocale.h头文件。另请参见 "NEED_XLOCALE_H"

    #ifdef I_XLOCALE
        #include <xlocale.h>
    #endif
NEED_XLOCALE_H

如果定义了此符号,则表示 C 程序应包含xlocale.h,以获取 newlocale() 及其相关函数。

Perl_langinfo
Perl_langinfo8

Perl_langinfo 是系统 nl_langinfo(3) 的(几乎)直接替换,它采用相同的 item 参数值,并返回相同的信息。但它比常规 nl_langinfo() 更线程安全,它隐藏了 Perl 本地化处理的怪癖,并且可以在没有本地 nl_langinfo 的系统上使用。

但是,您应该使用此函数的改进版本:"Perl_langinfo8",它的行为完全相同,只是多了一个参数,一个指向声明为 "utf8ness_t" 的变量的指针,它会将返回给您的字符串是否以 UTF-8 编码的信息返回给您。

关于这些函数与普通 nl_langinfo() 之间的区别

a.

Perl_langinfo8 有一个额外的参数,如上所述。除此之外,它们并非完全可直接替换的另一个原因实际上是一个优势。返回值的 const 特性允许编译器捕获试图写入返回缓冲区的尝试,这是非法的,可能会导致运行时崩溃。

b.

它们在无需您编写额外代码的情况下,为 RADIXCHARTHOUSEP 项目提供正确的结果。编写额外代码的原因是,这些项目来自 LC_NUMERIC 本地化类别,该类别通常由 Perl 保持设置,以便无论底层本地化应该是什么,基数都是一个点,分隔符是空字符串,因此要获得预期结果,您必须暂时切换到底层本地化,然后切换回来。(您可以使用普通的 nl_langinfo"STORE_LC_NUMERIC_FORCE_TO_UNDERLYING" 来实现这一点,但那样您将无法获得 Perl_langinfo() 的其他优势;不将 LC_NUMERIC 保持在 C(或等效)本地化中会破坏许多 CPAN,因为 CPAN 预期基数(小数点)字符为点。)

c.

它们替换的系统函数的静态返回缓冲区可能会被破坏,不仅是由于对该函数的后续调用,还会由于 freelocalesetlocale 或其他本地化更改而被破坏。这些函数的返回缓冲区在对其中一个函数的下一个调用之前不会更改,因此缓冲区永远不会处于被破坏状态。

d.

返回缓冲区是每个线程的,因此它也不会被来自另一个线程的对这些函数的调用覆盖;与它替换的函数不同。

e.

但最重要的是,它们在没有 nl_langinfo 的系统(如 Windows)上也能正常工作,因此使您的代码更具可移植性。在 POSIX 2008 标准中指定的五十多个可能的项目中,http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html,只有一个是完全未实现的,尽管在非 Windows 平台上,另一个重要的项目也没有完全实现)。它们使用各种技术来恢复其他项目,包括调用 localeconv(3)strftime(3),这两个函数都在 C89 中指定,因此应该始终可用。后来的 strftime() 版本具有额外的功能;C 本地化产生的结果或 "" 将返回给系统上不可用的任何项目。

需要注意的是,当使用localeconv获取的项目调用时,来自任何先前对localeconv(3)的显式调用的缓冲区将被覆盖。但无论如何你都不应该使用localeconv,因为它不是线程安全的,并且它返回的由LC_NUMERIC区域设置类别控制的字段存在与上面项目“b”中概述的相同问题。相反,通过调用"Perl_localeconv"(它是线程安全的)来避免所有这些问题;或者使用perlcall中给出的方法来调用POSIX::localeconv(),它也是线程安全的。

对于可能偏离此模拟返回的内容和原生nl_langinfo()返回的内容的那些项目,其详细信息在I18N::Langinfo中指定。

在没有原生nl_langinfo()的系统上使用Perl_langinfo8(或普通Perl_langinfo)时,您必须

#include "perl_langinfo.h"

perl.h #include之前。您可以用此替换您的langinfo.h #include。(这样做可以排除普通langinfo.h尝试导入到不需要它的代码的命名空间中的符号。)

    const char *  Perl_langinfo (const int item)
    const char *  Perl_langinfo8(const int item, utf8ness_t *utf8ness)
Perl_localeconv

这是 libc localeconv(3) 的线程安全版本。它与POSIX::localeconv 相同(返回一个包含localeconv() 字段的哈希表),但可以直接从 XS 代码调用。

    HV *  Perl_localeconv(pTHX)
Perl_setlocale

这是系统 setlocale(3) 的(几乎)直接替换,它接受相同的参数,并返回相同的信息,只是它返回正确的底层LC_NUMERIC 区域设置。普通setlocale 将改为返回C,如果底层区域设置具有非点小数点字符,或者非空的千位分隔符用于显示浮点数。这是因为 perl 保持该区域设置类别,使其具有点和空分隔符,在需要底层区域设置的操作期间短暂地更改区域设置。Perl_setlocale 知道这一点,并进行补偿;普通setlocale 不知道。

另一个原因它不是完全的直接替换,是因为它被声明为返回 const char *,而系统 setlocale 省略了const(可能是因为它的 API 很久以前就指定了,无法更新;更改setlocale 返回的信息是非法的;这样做会导致段错误。)

最后,Perl_setlocale 在所有情况下都能正常工作,而普通setlocale 在某些平台上某些配置下可能完全无效。

在多线程运行的情况下,更改区域设置不是一个好主意,除非在系统中预定义变量${^SAFE_LOCALES}为 1。这是因为在这样的系统中,区域设置是全局的,对整个进程有效,而不是仅对调用该函数的线程局部。因此,在一个线程中更改它会立即在所有线程中更改它。在某些此类系统上,系统setlocale()无效,返回错误的信息,并且无法实际更改区域设置。z/OS 拒绝在创建第二个线程后尝试更改区域设置。Perl_setlocale应该为您提供有关这些问题平台上实际发生情况的准确结果,如果系统禁止更改区域设置,则返回 NULL。

返回值指向一个每个线程的静态缓冲区,该缓冲区在下次从同一线程调用Perl_setlocale时会被覆盖。

    const char *  Perl_setlocale(const int category,
                                 const char *locale)
RESTORE_LC_NUMERIC

它与宏 "STORE_LC_NUMERIC_SET_TO_NEEDED""STORE_LC_NUMERIC_FORCE_TO_UNDERLYING" 结合使用,以正确恢复LC_NUMERIC状态。

必须调用 "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" 来在编译时声明此宏和两个STORE宏使用的私有变量。此宏应作为单个语句调用,而不是表达式,但应使用空参数列表,如下所示

{
   DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
    ...
   RESTORE_LC_NUMERIC();
    ...
}
    void  RESTORE_LC_NUMERIC()
SETLOCALE_ACCEPTS_ANY_LOCALE_NAME

如果定义了此符号,则表示setlocale例程可用,并且它接受任何输入区域设置名称作为有效名称。

STORE_LC_NUMERIC_FORCE_TO_UNDERLYING

它由LC_NUMERIC区域设置感知的 XS 代码使用,以强制类别LC_NUMERIC的区域设置为 perl 认为的当前底层区域设置。(如果某些 C 或 XS 代码在背后调用了 C 库函数 setlocale(3),perl 解释器可能会错误地判断底层区域设置的实际情况;在调用此宏之前调用 "sync_locale" 将更新 perl 的记录。)

必须调用 "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" 来在编译时声明此宏使用的私有变量。此宏应作为单个语句调用,而不是表达式,但应使用空参数列表,如下所示

{
   DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
    ...
   STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
    ...
   RESTORE_LC_NUMERIC();
    ...
}

私有变量用于保存当前区域设置状态,以便对 "RESTORE_LC_NUMERIC" 的必要匹配调用可以恢复它。

在没有使用线程安全功能的线程化 Perl 中,此宏使用互斥锁来强制执行临界区。因此,匹配的 RESTORE 应该在附近,并保证被调用。

    void  STORE_LC_NUMERIC_FORCE_TO_UNDERLYING()
STORE_LC_NUMERIC_SET_TO_NEEDED

这用于帮助包装对 LC_NUMERIC 本地化敏感的 XS 或 C 代码。此本地化类别通常设置为小数点为点,数字组之间的分隔符为空的本地化。这是因为大多数读取浮点数的 XS 代码都期望它们具有这种语法。

此宏确保当前的 LC_NUMERIC 状态设置正确,以便在从 Perl 程序调用 XS 或 C 代码时,如果调用在 use locale 范围内,则可以感知本地化;或者如果调用在该范围之外,则忽略本地化。

此宏是包装 C 或 XS 代码的开始;包装结束是在操作之后调用 "RESTORE_LC_NUMERIC" 宏完成的。否则,状态可能会发生变化,从而对其他 XS 代码产生不利影响。

必须调用 "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" 来在编译时声明此宏使用的私有变量。此宏应作为单个语句调用,而不是表达式,但应使用空参数列表,如下所示

{
   DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
    ...
   STORE_LC_NUMERIC_SET_TO_NEEDED();
    ...
   RESTORE_LC_NUMERIC();
    ...
}

在没有使用线程安全功能的线程化 Perl 中,此宏使用互斥锁来强制执行临界区。因此,匹配的 RESTORE 应该在附近,并保证被调用;有关更受限的确保方法,请参阅 "WITH_LC_NUMERIC_SET_TO_NEEDED"

    void  STORE_LC_NUMERIC_SET_TO_NEEDED()
STORE_LC_NUMERIC_SET_TO_NEEDED_IN

"STORE_LC_NUMERIC_SET_TO_NEEDED" 相同,但提供了 in_lc_numeric 作为 IN_LC(LC_NUMERIC) 的预先计算值。调用者有责任确保 PL_compilingPL_hints 的状态在预先计算之后没有发生变化。

    void  STORE_LC_NUMERIC_SET_TO_NEEDED_IN(bool in_lc_numeric)
WITH_LC_NUMERIC_SET_TO_NEEDED

此宏在 "STORE_LC_NUMERIC_SET_TO_NEEDED" .. "RESTORE_LC_NUMERIC" 对的上下文中调用提供的语句或块,如果需要,例如

WITH_LC_NUMERIC_SET_TO_NEEDED(
  SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis)
);

等效于

{
#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
}
    void  WITH_LC_NUMERIC_SET_TO_NEEDED(block)
WITH_LC_NUMERIC_SET_TO_NEEDED_IN

"WITH_LC_NUMERIC_SET_TO_NEEDED" 相同,但提供了 in_lc_numeric 作为 IN_LC(LC_NUMERIC) 的预先计算值。调用者有责任确保 PL_compilingPL_hints 的状态在预先计算之后没有发生变化。

    void  WITH_LC_NUMERIC_SET_TO_NEEDED_IN(bool in_lc_numeric, block)

Magic

"Magic" 是附加到 SV 结构上的特殊数据,用于赋予它们“神奇”的属性。当任何 Perl 代码尝试读取或分配标记为神奇的 SV 时,它会调用与该 SV 的 magic 关联的“get”或“set”函数。在读取 SV 之前调用 get,以便它有机会更新其内部值(在 $. 上的 get 将最后读取的文件句柄的行号写入 SV 的 IV 槽中),而 set 在写入 SV 之后调用,以便它可以使用其更改后的值(在 $/ 上的 set 将 SV 的新值复制到 PL_rs 全局变量中)。

Magic 是作为附加到 SV 的 MAGIC 结构的链接列表实现的。每个 MAGIC 结构都包含 magic 的类型,指向实现 get()、set()、length() 等函数的函数数组的指针,以及一些标志和指针的空间。例如,一个绑定的变量有一个 MAGIC 结构,它包含指向与绑定关联的对象的指针。

mg_clear

清除 SV 代表的某些神奇内容。参见 "sv_magic"

    int  mg_clear(SV *sv)
mg_copy

将 magic 从一个 SV 复制到另一个 SV。参见 "sv_magic"

    int  mg_copy(SV *sv, SV *nsv, const char *key, I32 klen)
MGf_COPY
MGf_DUP
MGf_LOCAL

perlguts 中描述。

mg_find

查找与 SV 匹配的 type 的 magic 指针。参见 "sv_magic"

    MAGIC *  mg_find(const SV *sv, int type)
mg_findext

查找 SV 的具有给定 vtbltype 的 magic 指针。参见 "sv_magicext"

    MAGIC *  mg_findext(const SV *sv, int type, const MGVTBL *vtbl)
mg_free

释放 SV 使用的任何 magic 存储。参见 "sv_magic"

    int  mg_free(SV *sv)
mg_freeext

从 SV sv 中删除使用虚拟表 vtbl 的类型为 how 的任何 magic。参见 "sv_magic".

mg_freeext(sv, how, NULL) 等效于 mg_free_type(sv, how)

    void  mg_freeext(SV *sv, int how, const MGVTBL *vtbl)
mg_free_type

从 SV sv 中删除类型为 how 的任何 magic。参见 "sv_magic".

    void  mg_free_type(SV *sv, int how)
mg_get

在从 SV 中检索值之前执行魔法操作。SV 的类型必须大于等于 SVt_PVMG。参见 "sv_magic"

    int  mg_get(SV *sv)
mg_magical

打开 SV 的魔法状态。参见 "sv_magic"

    void  mg_magical(SV *sv)
mg_set

在将值分配给 SV 后执行魔法操作。参见 "sv_magic"

    int  mg_set(SV *sv)
MGVTBL

perlguts 中描述。

PERL_MAGIC_arylen
PERL_MAGIC_arylen_p
PERL_MAGIC_backref
PERL_MAGIC_bm
PERL_MAGIC_checkcall
PERL_MAGIC_collxfrm
PERL_MAGIC_dbfile
PERL_MAGIC_dbline
PERL_MAGIC_debugvar
PERL_MAGIC_defelem
PERL_MAGIC_destruct
PERL_MAGIC_env
PERL_MAGIC_envelem
PERL_MAGIC_ext
PERL_MAGIC_extvalue
PERL_MAGIC_fm
PERL_MAGIC_hints
PERL_MAGIC_hintselem
PERL_MAGIC_hook
PERL_MAGIC_hookelem
PERL_MAGIC_isa
PERL_MAGIC_isaelem
PERL_MAGIC_lvref
PERL_MAGIC_nkeys
PERL_MAGIC_nonelem
PERL_MAGIC_overload_table
PERL_MAGIC_pos
PERL_MAGIC_qr
PERL_MAGIC_regdata
PERL_MAGIC_regdatum
PERL_MAGIC_regex_global
PERL_MAGIC_rhash
PERL_MAGIC_shared
PERL_MAGIC_shared_scalar
PERL_MAGIC_sig
PERL_MAGIC_sigelem
PERL_MAGIC_substr
PERL_MAGIC_sv
PERL_MAGIC_symtab
PERL_MAGIC_taint
PERL_MAGIC_tied
PERL_MAGIC_tiedelem
PERL_MAGIC_tiedscalar
PERL_MAGIC_utf8
PERL_MAGIC_uvar
PERL_MAGIC_uvar_elem
PERL_MAGIC_vec
PERL_MAGIC_vstring

perlguts 中描述。

SvTIED_obj

perlinterp 中描述。

    SvTIED_obj(SV *sv, MAGIC *mg)

内存管理

dump_mstats

当使用-DDEBUGGING_MSTATS编译时启用,打印关于 malloc 的统计信息,两行数字,一行显示每个大小类别的空闲列表长度,第二行显示每个大小类别的mallocs - frees数量。

s,如果非空,用于在输出中包含短语,例如"after compilation"

    void  dump_mstats(const char *s)
HASATTRIBUTE_MALLOC

我们是否可以处理GCC为 malloc 样式函数提供的属性。

HAS_MALLOC_GOOD_SIZE

如果定义了此符号,则表示malloc_good_size例程可用。

HAS_MALLOC_SIZE

如果定义了此符号,则表示malloc_size例程可用。

I_MALLOCMALLOC

如果定义了此符号,则表示 C 程序应包含malloc/malloc.h

    #ifdef I_MALLOCMALLOC
        #include <mallocmalloc.h>
    #endif
MYMALLOC

如果定义了此符号,则表示我们使用的是自己的 malloc。

Newx
safemalloc

XSUB 编写者对 C malloc 函数的接口。

通过此获得的内存 **只能** 使用 "Safefree" 释放。

在 5.9.3 中,Newx() 及其相关函数取代了旧的 New() API,并删除了第一个参数 x,这是一个调试辅助工具,允许调用者识别自己。此辅助工具已被新的构建选项 PERL_MEM_LOG 取代(参见 "perlhacktips 中的 PERL_MEM_LOG")。旧的 API 仍然存在,供支持旧版 perl 的 XS 模块使用。

    void   Newx      (void* ptr, int nitems, type)
    void*  safemalloc(size_t size)
Newxc

XSUB 编写者对 C malloc 函数的接口,带强制类型转换。另请参见 "Newx"

通过此获得的内存 **只能** 使用 "Safefree" 释放。

    void  Newxc(void* ptr, int nitems, type, cast)
Newxz
safecalloc

XSUB 编写者对 C malloc 函数的接口。分配的内存使用 memzero 清零。另请参见 "Newx"

通过此获得的内存 **只能** 使用 "Safefree" 释放。

    void   Newxz     (void* ptr, int nitems, type)
    void*  safecalloc(size_t nitems, size_t item_size)
PERL_MALLOC_WRAP

如果定义了此符号,则表示我们希望进行 malloc 包裹检查。

Renew
saferealloc

XSUB 编写者对 C realloc 函数的接口。

通过此获得的内存 **只能** 使用 "Safefree" 释放。

    void   Renew      (void* ptr, int nitems, type)
    void*  saferealloc(void *ptr, size_t size)
Renewc

XSUB 编写者对 C realloc 函数的接口,带强制类型转换。

通过此获得的内存 **只能** 使用 "Safefree" 释放。

    void  Renewc(void* ptr, int nitems, type, cast)
Safefree

XSUB 编写者对 C free 函数的接口。

此函数 **只能** 用于使用 "Newx" 及其相关函数获得的内存。

    void  Safefree(void* ptr)
safesyscalloc

系统 calloc() 的安全版本

    Malloc_t  safesyscalloc(MEM_SIZE elements, MEM_SIZE size)
safesysfree

系统 free() 的安全版本

    Free_t  safesysfree(Malloc_t where)
safesysmalloc

系统 malloc() 的谨慎版本

    Malloc_t  safesysmalloc(MEM_SIZE nbytes)
safesysrealloc

系统 realloc() 的谨慎版本

    Malloc_t  safesysrealloc(Malloc_t where, MEM_SIZE nbytes)

MRO

这些函数与 perl 类的方法解析顺序相关。另请参见 perlmroapi

HvMROMETA

perlmroapi 中描述。

    struct mro_meta *  HvMROMETA(HV *hv)
mro_get_from_name

返回先前使用给定 name 注册的 mro,如果未注册则返回 NULL。参见 "mro_register"

注意:mro_get_from_name 必须显式调用为 Perl_mro_get_from_name,并带有一个 aTHX_ 参数。

    const struct mro_alg *  Perl_mro_get_from_name(pTHX_ SV *name)
mro_get_linear_isa

返回给定 stash 的 MRO 线性化。默认情况下,这将是 mro_get_linear_isa_dfs 返回的值,除非 stash 中存在其他 MRO。返回值是一个只读 AV*,其值是字符串 SV,表示类名。

如果您打算将返回值存储在任何半永久性位置,则需要对返回值进行 SvREFCNT_inc() 操作(否则,下次缓存失效时,它可能会被删除)。

    AV *  mro_get_linear_isa(HV *stash)
MRO_GET_PRIVATE_DATA

perlmroapi 中描述。

    SV*  MRO_GET_PRIVATE_DATA(struct mro_meta *const smeta,
                              const struct mro_alg *const which)
mro_method_changed_in

使给定 stash 的所有子类的缓存失效,以便它们可以注意到此 stash 中的变化。

理想情况下,perl 源代码中所有 PL_sub_generation++ 的实例(除了 mro.c 中的实例)都应该被调用此方法的调用所替换。

Perl 自动处理方法可能被重新定义的大多数常见方式。但是,有一些方法可以更改 stash 中的方法而不会被缓存代码注意到,在这种情况下,您需要在之后调用此方法。

1) 从 XS 代码中直接操作 stash HV 条目。

2) 将对只读标量常量的引用分配到 stash 条目中,以创建常量子例程(如 constant.pm 所做的那样)。

可以通过纯 Perl 使用相同的方法,即 mro::method_changed_in(classname)

    void  mro_method_changed_in(HV *stash)
mro_register

注册自定义 MRO 插件。有关此插件和其他 MRO 函数的详细信息,请参阅 perlmroapi

注意:mro_register 必须显式调用为 Perl_mro_register,并带有一个 aTHX_ 参数。

    void  Perl_mro_register(pTHX_ const struct mro_alg *mro)
mro_set_mro

meta 设置为已注册的 MRO 插件(其名称为 name)中包含的值。

如果 name 未注册,则会发出错误信息。

注意:mro_set_mro 必须显式调用为 Perl_mro_set_mro,并带有一个 aTHX_ 参数。

    void  Perl_mro_set_mro(pTHX_ struct mro_meta * const meta,
                           SV * const name)
mro_set_private_data

perlmroapi 中描述。

注意:mro_set_private_data 必须显式调用为 Perl_mro_set_private_data,并带有一个 aTHX_ 参数。

    SV *  Perl_mro_set_private_data(pTHX_
                                   struct mro_meta * const smeta,
                                   const struct mro_alg * const which,
                                   SV * const data)

多重调用函数

dMULTICALL

为多重调用声明局部变量。请参阅 "perlcall 中的轻量级回调"

    dMULTICALL;
MULTICALL

创建一个轻量级回调。参见 "perlcall 中的 LIGHTWEIGHT CALLBACKS"

    MULTICALL;
POP_MULTICALL

轻量级回调的结束括号。参见 "perlcall 中的 LIGHTWEIGHT CALLBACKS"

    POP_MULTICALL;
PUSH_MULTICALL

轻量级回调的开始括号。参见 "perlcall 中的 LIGHTWEIGHT CALLBACKS"

    PUSH_MULTICALL(CV* the_cv);

数值函数

Atol

已弃用! 计划在未来的 Perl 版本中移除 Atol。不要在新的代码中使用它;从现有代码中移除它。

perlhacktips 中描述。

    Atol(const char * nptr)
Atoul

已弃用! 计划在未来的 Perl 版本中移除 Atoul。不要在新的代码中使用它;从现有代码中移除它。

perlhacktips 中描述。

    Atoul(const char * nptr)
Drand01

此宏用于生成范围在 [0., 1.[ 之间的均匀分布随机数。您可能需要在程序中提供一个 'extern double drand48();',因为 SunOS 4.1.3 在其头文件中没有提供任何相关内容。参见 "HAS_DRAND48_PROTO"

    double  Drand01()
Gconvert

此预处理器宏定义为将浮点数转换为字符串,不带尾随小数点。这模拟了 sprintf("%g") 的行为,但在某些情况下效率更高。如果 gconvert() 不可用,但 gcvt() 丢弃了尾随小数点,则使用 gcvt()。如果所有方法都失败,则使用使用 sprintf("%g") 的宏。Gconvert 宏的参数是:值、位数、是否保留尾随零以及输出缓冲区。通常的值是

d_Gconvert='gconvert((x),(n),(t),(b))'
d_Gconvert='gcvt((x),(n),(b))'
d_Gconvert='sprintf((b),"%.*g",(n),(x))'

最后两个假设不保留尾随零。

    char *  Gconvert(double x, Size_t n, bool t, char * b)
grok_atoUV

解析字符串,查找十进制无符号整数。

在进入时,pv 指向字符串的开头;valptr 指向一个 UV,如果找到,它将接收转换后的值;endptr 为 NULL 或指向一个变量,该变量指向 pv 中此例程应检查的点之外的一个字节。如果 endptr 为 NULL,则假定 pv 以 NUL 结尾。

如果 pv 不表示有效的无符号整数值(没有前导零),则返回 FALSE。否则,它返回 TRUE,并将 *valptr 设置为该值。

如果您限制了此函数查看的pv部分(通过传递非 NULL 的endptr),并且该部分的初始字节形成了一个有效的值,它将返回 TRUE,并将*endptr设置为该值的最后一位数字之后的字节。但是,如果没有对查看的内容进行限制,则必须使pv中的所有内容都有效才能返回 TRUE。如果返回 FALSE,则*endptr与其输入值保持不变;

此函数仅接受十进制数字 '0'..'9'。

atoi(3)strtol(3) 不同,grok_atoUV不允许可选的前导空格,也不允许负输入。如果需要这些功能,则调用代码需要显式地实现它们。

请注意,此函数对于会溢出 UV 或具有前导零的输入返回 FALSE。因此,单个0被接受,但0001002等不被接受。

背景:atoi在非法输入方面存在严重问题,它不能用于增量解析,因此应避免使用atoistrtol也会受到区域设置的影响,这也可能被视为错误(由用户环境控制的全局状态)。

    bool  grok_atoUV(const char *pv, UV *valptr, const char **endptr)
grok_bin

将表示二进制数字的字符串转换为数字形式。

在进入时,start*len_p 给出要扫描的字符串,*flags 给出转换标志,result 应为 NULL 或指向 NV 的指针。扫描在字符串末尾或第一个无效字符之前的任何位置停止。除非在*flags 中设置了PERL_SCAN_SILENT_ILLDIGIT,否则遇到无效字符(除了 NUL)也会触发警告。在返回时,*len_p 设置为扫描字符串的长度,*flags 给出输出标志。

如果该值 <= UV_MAX,则将其作为 UV 返回,输出标志清除,并且不会写入*result。如果该值 > UV_MAX,则grok_bin 返回UV_MAX,在输出标志中设置PERL_SCAN_GREATER_THAN_UV_MAX,并将正确值的近似值写入*result(这是一个 NV;或者如果result 为 NULL,则丢弃近似值)。

二进制数字可以选择性地以"0b""b" 为前缀,除非在进入时在*flags 中设置了PERL_SCAN_DISALLOW_PREFIX

如果在*flags 中设置了PERL_SCAN_ALLOW_UNDERSCORES,则任何或所有数字对都可以用单个下划线彼此分隔;此外,还接受单个前导下划线。

    UV  grok_bin(const char *start, STRLEN *len_p, I32 *flags,
                 NV *result)
grok_hex

将表示十六进制数字的字符串转换为数值形式。

在进入时,start*len_p 给出要扫描的字符串,*flags 给出转换标志,result 应为 NULL 或指向 NV 的指针。扫描在字符串末尾或第一个无效字符之前的任何位置停止。除非在*flags 中设置了PERL_SCAN_SILENT_ILLDIGIT,否则遇到无效字符(除了 NUL)也会触发警告。在返回时,*len_p 设置为扫描字符串的长度,*flags 给出输出标志。

如果值 <= UV_MAX,则将其作为 UV 返回,输出标志将被清除,并且不会写入 *result。如果值 > UV_MAXgrok_hex 将返回 UV_MAX,在输出标志中设置 PERL_SCAN_GREATER_THAN_UV_MAX,并将正确值的近似值写入 *result(这是一个 NV;或者如果 result 为 NULL,则丢弃近似值)。

除非在输入时在 *flags 中设置了 PERL_SCAN_DISALLOW_PREFIX,否则十六进制数字可以选择性地以 "0x""x" 为前缀。

如果在*flags 中设置了PERL_SCAN_ALLOW_UNDERSCORES,则任何或所有数字对都可以用单个下划线彼此分隔;此外,还接受单个前导下划线。

    UV  grok_hex(const char *start, STRLEN *len_p, I32 *flags,
                 NV *result)
grok_infnan

grok_number() 的辅助函数,接受各种拼写“无穷大”或“非数字”的方式,并返回以下标志组合之一

IS_NUMBER_INFINITY
IS_NUMBER_NAN
IS_NUMBER_INFINITY | IS_NUMBER_NEG
IS_NUMBER_NAN | IS_NUMBER_NEG
0

可能与 IS_NUMBER_TRAILING 进行 |-ed 操作。

如果识别出无穷大或非数字,*sp 将指向识别字符串末尾后的一个字节。如果识别失败,则返回零,并且 *sp 不会移动。

    int  grok_infnan(const char **sp, const char *send)
grok_number

flags 设置为零的 grok_number_flags() 相同。

    int  grok_number(const char *pv, STRLEN len, UV *valuep)
grok_number_flags

识别(或不识别)数字。返回数字的类型(如果未识别,则为 0),否则它是 IS_NUMBER_IN_UVIS_NUMBER_GREATER_THAN_UV_MAXIS_NUMBER_NOT_INTIS_NUMBER_NEGIS_NUMBER_INFINITYIS_NUMBER_NAN(在 perl.h 中定义)的按位或组合。

如果数字的值可以放入 UV 中,则将其返回到 *valuep 中。IS_NUMBER_IN_UV 将被设置为指示 *valuep 有效,IS_NUMBER_IN_UV 永远不会被设置,除非 *valuep 有效,但即使在返回时未设置 IS_NUMBER_IN_UV*valuep 也可能在处理过程中被分配。如果 valuepNULL,则 IS_NUMBER_IN_UV 将在与 valuepNULL 相同的情况下被设置,但不会发生实际的分配(或 SEGV)。

如果看到尾随小数(在这种情况下,*valuep 给出截断为整数的真实值),并且如果数字为负(在这种情况下,*valuep 持有绝对值),则 IS_NUMBER_NOT_INT 将与 IS_NUMBER_IN_UV 一起设置。如果使用 e 表示法或数字大于 UV,则不会设置 IS_NUMBER_IN_UV

flags 仅允许 PERL_SCAN_TRAILING,它允许在其他成功的 grok 上使用尾随非数字文本,在结果上设置 IS_NUMBER_TRAILING

    int  grok_number_flags(const char *pv, STRLEN len, UV *valuep,
                           U32 flags)
GROK_NUMERIC_RADIX

"grok_numeric_radix" 的同义词。

    bool  GROK_NUMERIC_RADIX(NN const char **sp, NN const char *send)
grok_numeric_radix

扫描并跳过数字小数点(基数)。

    bool  grok_numeric_radix(const char **sp, const char *send)
grok_oct

将表示八进制数的字符串转换为数字形式。

在进入时,start*len_p 给出要扫描的字符串,*flags 给出转换标志,result 应为 NULL 或指向 NV 的指针。扫描在字符串末尾或第一个无效字符之前的任何位置停止。除非在*flags 中设置了PERL_SCAN_SILENT_ILLDIGIT,否则遇到无效字符(除了 NUL)也会触发警告。在返回时,*len_p 设置为扫描字符串的长度,*flags 给出输出标志。

如果值 <= UV_MAX,则将其作为 UV 返回,输出标志被清除,并且不会写入 *result。如果值 > UV_MAXgrok_oct 返回 UV_MAX,在输出标志中设置 PERL_SCAN_GREATER_THAN_UV_MAX,并将正确值的近似值写入 *result(这是一个 NV;或者如果 result 为 NULL,则丢弃近似值)。

如果在*flags 中设置了PERL_SCAN_ALLOW_UNDERSCORES,则任何或所有数字对都可以用单个下划线彼此分隔;此外,还接受单个前导下划线。

对于此函数,始终将 PERL_SCAN_DISALLOW_PREFIX 标志视为已设置。

    UV  grok_oct(const char *start, STRLEN *len_p, I32 *flags,
                 NV *result)
isinfnan

Perl_isinfnan() 是一个实用程序函数,如果 NV 参数是无穷大或 NaN,则返回 true,否则返回 false。要更详细地测试,请使用 Perl_isinf()Perl_isnan()

这也是 Perl_isfinite() 的逻辑反义词。

    bool  isinfnan(NV nv)
my_atof

atof(3),但与 Perl 本地化处理配合使用,始终接受点基数字符,但仅当从 Perl use locale 语句的词法范围内调用时才接受当前本地的基数字符。

注意:s 必须以 NUL 结尾。

    NV  my_atof(const char *s)
my_strtod

此函数等效于 libc strtod() 函数,即使在缺少普通 strtod() 的平台上也可以使用。它的返回值是根据平台功能和Configure选项确定的最佳精度。

它正确地处理本地基数字符,这意味着它期望一个点,除非从 use locale 的范围内调用,在这种情况下,基数字符应该是当前本地指定的字符。

可以使用同义词 Strtod() 代替。

    NV  my_strtod(const char * const s, char **e)
PERL_ABS

无类型 absfabs 等。(下面的用法表明它是针对整数的,但它适用于任何类型。)使用它代替这些,因为 C 库中的这些函数会强制其参数成为它期望的类型,这可能会导致灾难。但也要注意,它会评估其参数两次,因此没有 x++

    int  PERL_ABS(int x)
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

这些函数对操作数执行相应的数学运算,使用为该任务设计的 libc 函数,该函数对该平台上的 NV 具有足够的精度。如果不存在具有足够精度的此类函数,则使用可用的最高精度函数。

    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)
Perl_signbit

注意:Perl_signbit 是 **实验性的**,可能会在未经通知的情况下更改或删除。

如果 NV 上的符号位被设置,则返回一个非零整数;如果未设置,则返回 0。

如果 Configure 检测到该系统具有一个与我们的 NV 兼容的 signbit(),那么我们只需通过 perl.h 中的 #define 使用它。否则,回退到此实现。此函数的主要用途是捕获 -0.0

Configure 说明:此函数被称为 'Perl_signbit' 而不是简单的 'signbit',因为很容易想象一个系统具有一个 signbit() 函数或宏,而该函数或宏恰好不适用于我们选择的 NV。我们不应该简单地重新 #define signbitPerl_signbit 并期望标准系统头文件能够正常工作。此外,这是一个无上下文函数(没有 pTHX_),因为 Perl_signbit() 通常在 perl.h 中重新 #defined 为对系统 signbit() 的简单宏调用。用户应该始终调用 Perl_signbit()

    int  Perl_signbit(NV f)
PL_hexdigit

这个数组由整数索引,将该值转换为表示它的字符。例如,如果输入为 8,则返回的字符串的第一个字符为 '8'。实际上返回的是指向字符串的指针。你只关心该字符串的第一个字符。要获取大写字母(对于值 10..15),在索引中添加 16。因此,PL_hexdigit[11]'b',而 PL_hexdigit[11+16]'B'。将 16 添加到表示为 '0'..'9' 的索引中,与不添加 16 相同。索引超出范围 0..31 会导致(错误的)未定义行为。

READ_XDIGIT

返回 ASCII 范围十六进制数字的值,并前进字符串指针。当 isXDIGIT(*str) 为真时,行为才定义良好。

    U8  READ_XDIGIT(char str*)
scan_bin

为了向后兼容。请使用 grok_bin 代替。

    NV  scan_bin(const char *start, STRLEN len, STRLEN *retlen)
scan_hex

为了向后兼容。请使用 grok_hex 代替。

    NV  scan_hex(const char *start, STRLEN len, STRLEN *retlen)
scan_oct

为了向后兼容。请使用 grok_oct 代替。

    NV  scan_oct(const char *start, STRLEN len, STRLEN *retlen)
seedDrand01

此符号定义用于播种随机数生成器的宏(参见 "Drand01")。

    void  seedDrand01(Rand_seed_t x)
Strtod

这是 "my_strtod" 的同义词。

    NV  Strtod(NN const char * const s, NULLOK char ** e)
Strtol

与平台和配置无关的 strtol。这将根据平台和 Configure 选项扩展到适当的 strotol 类函数。例如,它可以扩展到 strtollstrtoq 而不是 strtol

    NV  Strtol(NN const char * const s, NULLOK char ** e, int base)
Strtoul

与平台和配置无关的 strtoul。这将根据平台和 Configure 选项扩展到适当的 strotoul 类函数。例如,它可以扩展到 strtoullstrtouq 而不是 strtoul

    NV  Strtoul(NN const char * const s, NULLOK char ** e, int base)

Optrees

alloccopstash

注意:alloccopstash实验性的,可能会在未经通知的情况下更改或删除。

仅在多线程构建中可用,此函数在传递给它的存储区的 PL_stashpad 中分配一个条目。

    PADOFFSET  alloccopstash(HV *hv)
BINOP

perlguts 中描述。

block_end

处理编译时范围退出。floor 是由 block_start 返回的 savestack 索引,seq 是块的主体。返回块,可能已修改。

    OP *  block_end(I32 floor, OP *seq)
block_start

处理编译时作用域进入。安排在块退出时恢复提示,并处理填充序列号以使词法变量作用域正确。返回一个用于block_end的 savestack 索引。

    int  block_start(int full)
ck_entersub_args_list

执行entersub操作树的参数部分的默认修复。这包括将列表上下文应用于每个参数操作。这是在标记为&的调用、方法调用、通过子例程引用进行的调用或任何其他在编译时无法识别被调用者的调用或被调用者没有原型的情况下使用的标准处理。

    OP *  ck_entersub_args_list(OP *entersubop)
ck_entersub_args_proto

根据子例程原型执行entersub操作树的参数部分的修复。这会对参数操作进行各种修改,从应用上下文到插入refgen操作,以及根据原型检查参数的数量和语法类型。这是在子例程调用(未标记为&)上使用的标准处理,其中被调用者可以在编译时识别,并且具有原型。

protosv提供要应用于调用的子例程原型。它可以是普通的已定义标量,其字符串值将被使用。或者,为了方便起见,它可以是子例程对象(一个已转换为SV*CV*),它具有原型。无论以哪种形式提供的原型,都不需要与操作树引用的实际被调用者匹配。

如果参数操作与原型不一致,例如参数数量不可接受,则仍会返回有效的操作树。错误会反映在解析器状态中,通常会导致在解析的顶层出现单个异常,该异常涵盖了所有发生的编译错误。在错误消息中,被调用者由namegv参数定义的名称引用。

    OP *  ck_entersub_args_proto(OP *entersubop, GV *namegv,
                                 SV *protosv)
ck_entersub_args_proto_or_list

根据子程序原型或使用默认列表上下文处理,执行entersub操作树的参数部分的修正。 这是在没有标记为&的子程序调用中使用的标准处理方式,其中调用者可以在编译时识别。

protosv提供要应用于调用的子程序原型,或指示没有原型。 它可以是一个普通的标量,在这种情况下,如果它被定义,则字符串值将被用作原型,如果它未定义,则没有原型。 或者,为了方便起见,它可以是一个子程序对象(一个被强制转换为SV*CV*),如果它有一个原型,则将使用它的原型。 提供的原型(或缺乏原型),无论以何种形式,都不需要与操作树引用的实际调用者匹配。

如果参数操作与原型不一致,例如参数数量不可接受,则仍会返回有效的操作树。错误会反映在解析器状态中,通常会导致在解析的顶层出现单个异常,该异常涵盖了所有发生的编译错误。在错误消息中,被调用者由namegv参数定义的名称引用。

    OP *  ck_entersub_args_proto_or_list(OP *entersubop, GV *namegv,
                                         SV *protosv)
cv_const_sv

如果cv是一个适合内联的常量子程序,则返回子程序返回的常量值。 否则,返回NULL

常量子程序可以使用newCONSTSUB创建,或者如"perlsub中的常量函数"中所述。

    SV *  cv_const_sv(const CV * const cv)
cv_get_call_checker

"cv_get_call_checker_flags"的原始形式,它不返回检查器标志。 当使用此函数返回的检查器函数时,仅当使用真正的 GV 作为其namegv参数时,调用它才是安全的。

    void  cv_get_call_checker(CV *cv, Perl_call_checker *ckfun_p,
                              SV **ckobj_p)
cv_get_call_checker_flags

检索将用于修正对cv的调用的函数。 具体来说,该函数应用于一个entersub操作树,用于一个没有标记为&的子程序调用,其中调用者可以在编译时识别为cv

C 级函数指针在*ckfun_p中返回,它的 SV 参数在*ckobj_p中返回,控制标志在*ckflags_p中返回。 该函数旨在以这种方式调用

entersubop = (*ckfun_p)(aTHX_ entersubop, namegv, (*ckobj_p));

在此调用中,entersubop是指向entersub操作的指针,它可能被检查函数替换,namegv提供检查函数应使用以引用entersub操作的调用者的名称,如果它需要发出任何诊断。 允许在非标准情况下应用检查函数,例如对不同子程序的调用或对方法调用的调用。

namegv 实际上可能不是一个 GV。如果 *ckflags_p 中的 CALL_CHECKER_REQUIRE_GV 位被清除,则允许传递 CV 或其他 SV,任何可以作为 "cv_name" 的第一个参数的东西。如果 *ckflags_p 中的 CALL_CHECKER_REQUIRE_GV 位被设置,则检查函数要求 namegv 是一个真正的 GV。

默认情况下,检查函数是 Perl_ck_entersub_args_proto_or_list,SV 参数是 cv 本身,CALL_CHECKER_REQUIRE_GV 标志被清除。这实现了标准原型处理。它可以通过 "cv_set_call_checker_flags" 为特定子例程更改。

如果 gflags 中的 CALL_CHECKER_REQUIRE_GV 位被设置,则表示调用者只知道 namegv 的真实 GV 版本,因此相应的位将始终在 *ckflags_p 中被设置,无论检查函数记录的要求如何。如果 gflags 中的 CALL_CHECKER_REQUIRE_GV 位被清除,则表示调用者知道将除 GV 之外的其他东西作为 namegv 传递的可能性,因此相应的位可能在 *ckflags_p 中被设置或清除,表示检查函数记录的要求。

gflags 是传递到 cv_get_call_checker_flags 的一个位集,其中目前只有 CALL_CHECKER_REQUIRE_GV 位具有定义的含义(如上所述)。所有其他位都应该被清除。

    void  cv_get_call_checker_flags(CV *cv, U32 gflags,
                                    Perl_call_checker *ckfun_p,
                                    SV **ckobj_p, U32 *ckflags_p)
cv_set_call_checker

"cv_set_call_checker_flags" 的原始形式,它为了向后兼容性而传递了 CALL_CHECKER_REQUIRE_GV 标志。该标志设置的效果是,检查函数保证会得到一个真正的 GV 作为其 namegv 参数。

    void  cv_set_call_checker(CV *cv, Perl_call_checker ckfun,
                              SV *ckobj)
cv_set_call_checker_flags

设置将用于修复对 cv 的调用的函数。具体来说,该函数应用于一个 entersub 操作树,该操作树用于一个没有标记为 & 的子例程调用,其中调用者可以在编译时被识别为 cv

C 级函数指针在 ckfun 中提供,它的 SV 参数在 ckobj 中提供,控制标志在 ckflags 中提供。该函数应该像这样定义

STATIC OP * ckfun(pTHX_ OP *op, GV *namegv, SV *ckobj)

它应该以这种方式调用

entersubop = ckfun(aTHX_ entersubop, namegv, ckobj);

在此调用中,entersubop是指向entersub操作的指针,它可能被检查函数替换,namegv提供检查函数应使用以引用entersub操作的调用者的名称,如果它需要发出任何诊断。 允许在非标准情况下应用检查函数,例如对不同子程序的调用或对方法调用的调用。

namegv 实际上可能不是 GV。为了提高效率,perl 可能会传递 CV 或其他 SV。传递的任何内容都可以用作 "cv_name" 的第一个参数。可以通过在 ckflags 中包含 CALL_CHECKER_REQUIRE_GV 来强制 perl 传递 GV。

ckflags 是一个位集,其中目前只有 CALL_CHECKER_REQUIRE_GV 位具有定义的含义(参见上文)。所有其他位都应清除。

可以使用 "cv_get_call_checker_flags" 检索特定 CV 的当前设置。

    void  cv_set_call_checker_flags(CV *cv, Perl_call_checker ckfun,
                                    SV *ckobj, U32 ckflags)
finalize_optree

此函数完成 optree。应在构建完整 optree 后立即调用。它会进行一些额外的检查,这些检查在正常的 ck_xxx 函数中无法完成,并使树线程安全。

    void  finalize_optree(OP *o)
forbid_outofblock_ops

注意:forbid_outofblock_ops实验性的,可能会在未经通知的情况下更改或删除。

检查实现块的 optree,以确保没有尝试离开块的控制流操作。任何 OP_RETURN 都被禁止,任何 OP_GOTO 也被禁止。循环会被分析,因此任何影响包含在块中的循环的 LOOPEX 操作(OP_NEXTOP_LASTOP_REDO)都是允许的,但那些不影响的循环是被禁止的。

如果检测到任何这些禁止的结构,则会使用操作名称和块名称参数构造适当的消息,并抛出异常。

此函数本身不足以确保 optree 在运行时不会执行任何这些禁止的活动,因为它可能会调用执行非本地 LOOPEX 的不同函数,或执行 goto 的字符串 eval(),或其他各种操作。它纯粹是为了那些可以静态检测到的内容进行编译时检查。根据使用场景,可能需要额外的运行时检查。

请注意,目前所有 OP_GOTO 操作都被禁止,即使在它们可能在其他情况下安全执行的情况下也是如此。这可能在以后的版本中被允许。

    void  forbid_outofblock_ops(OP *o, const char *blockname)

给定 optree 的根,使用 op_next 指针按执行顺序链接树,并返回第一个执行的操作。如果已经完成此操作,则不会重新执行,并将返回 o->op_next。如果 o->op_next 尚未设置,则 o 至少应为 UNOP

    OP*  LINKLIST(OP *o)
LISTOP

perlguts 中描述。

LOGOP

perlguts 中描述。

LOOP

perlguts 中描述。

newARGDEFELEMOP

构造并返回一个新的 OP_ARGDEFELEM 操作符,该操作符为索引为 argindex 的签名参数提供由 expr 给出的默认表达式。表达式 optree 被此函数消耗,并成为返回的 optree 的一部分。

    OP *  newARGDEFELEMOP(I32 flags, OP *expr, I32 argindex)
newASSIGNOP

构造、检查并返回一个赋值操作符。leftright 提供赋值的参数;它们被此函数消耗,并成为构造的 op 树的一部分。

如果 optypeOP_ANDASSIGNOP_ORASSIGNOP_DORASSIGN,则会构造一个合适的条件 optree。如果 optype 是二元运算符的操作码,例如 OP_BIT_OR,则会构造一个执行二元运算并将结果赋值给左参数的操作符。无论哪种方式,如果 optype 非零,则 flags 不会产生任何影响。

如果 optype 为零,则会构造一个简单的标量或列表赋值。赋值的类型会自动确定。flags 给出 op_flags 的八位,除了 OPf_KIDS 会自动设置,以及向上移八位的 op_private 的八位,除了值为 1 或 2 的位会根据需要自动设置。

    OP *  newASSIGNOP(I32 flags, OP *left, I32 optype, OP *right)
newATTRSUB

构造一个 Perl 子例程,同时执行一些周围的任务。

这与 "perlintern 中的 newATTRSUB_x" 相同,其 o_is_gv 参数设置为 FALSE。这意味着如果 o 为空,则新子例程将是匿名的;否则,名称将从 o 中派生,方式与 "perlintern 中的 newATTRSUB_x" 中描述的(以及所有其他细节)相同。

    CV *  newATTRSUB(I32 floor, OP *o, OP *proto, OP *attrs,
                     OP *block)
newBINOP

构造、检查并返回任何二元类型的操作符。type 是操作码。flags 给出 op_flags 的八位,除了 OPf_KIDS 将自动设置,以及向上移八位的 op_private 的八位,除了值为 1 或 2 的位将根据需要自动设置。firstlast 提供最多两个操作符作为二元操作符的直接子节点;它们被此函数消耗并成为构造的操作符树的一部分。

    OP *  newBINOP(I32 type, I32 flags, OP *first, OP *last)
newCONDOP

构造、检查并返回一个条件表达式 (cond_expr) 操作符。flags 给出 op_flags 的八位,除了 OPf_KIDS 将自动设置,以及向上移八位的 op_private 的八位,除了值为 1 的位将自动设置。first 提供在两个分支之间进行选择的表达式,trueopfalseop 提供分支;它们被此函数消耗并成为构造的操作符树的一部分。

    OP *  newCONDOP(I32 flags, OP *first, OP *trueop, OP *falseop)
newCONSTSUB

行为类似于 "newCONSTSUB_flags",除了 name 是以空字符结尾而不是计数长度,并且没有设置标志。(这意味着 name 始终被解释为 Latin-1。)

    CV *  newCONSTSUB(HV *stash, const char *name, SV *sv)
newCONSTSUB_flags

构造一个常量子程序,同时执行一些周围的任务。一个标量常量值子程序有资格在编译时内联,在 Perl 代码中可以通过 sub FOO () { 123 } 创建。其他类型的常量子程序有其他处理方式。

该子程序将具有空原型,并在调用时忽略任何参数。其恒定行为由sv决定。如果sv为空,则子程序将生成一个空列表。如果sv指向一个标量,则子程序将始终生成该标量。如果sv指向一个数组,则子程序将始终在列表上下文中生成该数组元素的列表,或在标量上下文中生成数组元素的数量。此函数将获取对标量或数组的一个计数引用,并将安排该对象在子程序存在期间保持活动状态。如果sv指向一个标量,则内联假设标量的值永远不会改变,因此调用者必须确保该标量不会随后被写入。如果sv指向一个数组,则不会做出这样的假设,因此表面上可以安全地修改数组或其元素,但实际上是否支持这一点尚未确定。

该子程序将根据PL_curcop设置CvFILE。子程序的其他方面将保留在默认状态。调用者可以在此函数返回后自由地修改子程序,使其超出其初始状态。

如果name为空,则子程序将是匿名的,其CvGV将引用一个__ANON__全局变量。如果name非空,则子程序将相应地命名,由相应的全局变量引用。name是一个长度为len字节的字符串,表示一个无符号的符号名称,如果flags设置了SVf_UTF8位,则为 UTF-8,否则为 Latin-1。该名称可以是限定的或非限定的。如果名称是非限定的,则它默认在由stash指定的存储区中,如果stash非空,则在PL_curstash中,如果stash为空。该符号始终在必要时添加到存储区中,具有GV_ADDMULTI语义。

flags不应设置除SVf_UTF8之外的位。

如果已经存在一个指定名称的子程序,则新的子程序将替换全局变量中的现有子程序。可能会生成有关重新定义的警告。

如果子程序具有几个特殊名称中的一个,例如BEGINEND,则它将被相应的队列声明,用于自动运行与阶段相关的子程序。在这种情况下,相关的全局变量将不再包含任何子程序,即使它之前包含一个子程序。子程序的执行很可能是一个空操作,除非sv是一个绑定的数组,或者调用者在子程序执行之前以某种有趣的方式修改了子程序。在BEGIN的情况下,处理存在错误:子程序将在仅构建一半时执行,并且可能过早地删除,这可能会导致崩溃。

该函数返回指向已构造子程序的指针。如果子程序是匿名的,则对子程序的一个计数引用的所有权将转移给调用者。如果子程序已命名,则调用者不会获得引用的所有权。在大多数情况下,如果子程序具有非阶段名称,则子程序将在由其命名的全局变量包含的点处处于活动状态。一个阶段命名的子程序通常会因为阶段的自动运行队列拥有的引用而处于活动状态。一个BEGIN子程序可能在该函数返回时已经被销毁,但目前在调用者获得控制权之前会发生错误。调用者有责任确保知道这些情况中的哪一种适用。

    CV *  newCONSTSUB_flags(HV *stash, const char *name, STRLEN len,
                            U32 flags, SV *sv)
newDEFEROP

注意:newDEFEROP 处于实验阶段,可能会在未经通知的情况下更改或删除。

构造并返回一个实现defer语义的延迟块语句。block optree 被此函数消耗,并成为返回的 optree 的一部分。

flags 参数承载要设置在返回的 op 上的附加标志,包括op_private 字段。

    OP *  newDEFEROP(I32 flags, OP *block)
newDEFSVOP

构造并返回一个访问$_ 的 op。

    OP *  newDEFSVOP()
newFOROP

构造、检查并返回一个表示foreach 循环(遍历值列表)的 op 树。这是一个重量级循环,其结构允许通过last 等退出循环。

sv 可选地提供将依次与每个项目别名的变量;如果为空,则默认为$_expr 提供要迭代的值列表。block 提供循环的主体,cont 可选地提供一个continue 块,它充当主体的第二部分。所有这些 optree 输入都被此函数消耗,并成为构造的 op 树的一部分。

flags 给出了leaveloop op 的op_flags 的八位,以及向上移八位的leaveloop op 的op_private 的八位,但(在这两种情况下)某些位将自动设置。

    OP *  newFOROP(I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
newGIVENOP

构造、检查并返回一个表示given 块的 op 树。cond 提供表达式,其值将被局部别名为$_block 提供given 结构的主体;它们被此函数消耗,并成为构造的 op 树的一部分。defsv_off 必须为零(它用于标识词法 $_ 的填充槽位)。

    OP *  newGIVENOP(OP *cond, OP *block, PADOFFSET defsv_off)
newGVOP

构造、检查并返回任何类型的 op,该 op 包含对 GV 的嵌入式引用。type 是操作码。flags 给出了op_flags 的八位。gv 标识 op 应该引用的 GV;调用此函数不会转移对它的任何引用的所有权。

    OP *  newGVOP(I32 type, I32 flags, GV *gv)
newLISTOP

构造、检查并返回任何列表类型的 op。type 是操作码。flags 给出了op_flags 的八位,但如果需要,OPf_KIDS 将自动设置。firstlast 提供最多两个 op,作为列表 op 的直接子节点;它们被此函数消耗,并成为构造的 op 树的一部分。

对于大多数列表运算符,检查函数期望所有子 op 已经存在,因此调用newLISTOP(OP_JOIN, ...)(例如)是不合适的。在这种情况下,您想要做的是创建一个类型为OP_LIST 的 op,向其追加更多子节点,然后调用"op_convert_list"。有关更多信息,请参阅"op_convert_list"

    OP *  newLISTOP(I32 type, I32 flags, OP *first, OP *last)
newLOGOP

构建、检查并返回一个逻辑(流程控制)操作符。type 是操作码。flags 给出了 op_flags 的八位,除了 OPf_KIDS 会自动设置,以及向上移八位,op_private 的八位,除了值为 1 的位会自动设置。first 提供控制流程的表达式,other 提供侧边(备用)操作符链;它们会被此函数消耗,并成为构建的操作符树的一部分。

    OP *  newLOGOP(I32 optype, I32 flags, OP *first, OP *other)
newLOOPEX

构建、检查并返回一个循环退出操作符(例如 gotolast)。type 是操作码。label 提供确定操作符目标的参数;它会被此函数消耗,并成为构建的操作符树的一部分。

    OP *  newLOOPEX(I32 type, OP *label)
newLOOPOP

构建、检查并返回一个表示循环的操作符树。这仅仅是操作符树中控制流的循环;它没有允许通过 last 等退出循环的重量级循环结构。flags 给出了顶层操作符的 op_flags 的八位,除了某些位会根据需要自动设置。expr 提供控制循环迭代的表达式,block 提供循环体;它们会被此函数消耗,并成为构建的操作符树的一部分。debuggable 目前未使用,应始终为 1。

    OP *  newLOOPOP(I32 flags, I32 debuggable, OP *expr, OP *block)
newMETHOP

构建、检查并返回一个具有在运行时评估的方法名称的方法类型操作符。type 是操作码。flags 给出了 op_flags 的八位,除了 OPf_KIDS 会自动设置,以及向上移八位,op_private 的八位,除了值为 1 的位会自动设置。dynamic_meth 提供一个评估方法名称的操作符;它会被此函数消耗,并成为构建的操作符树的一部分。支持的操作符类型:OP_METHOD

    OP *  newMETHOP(I32 type, I32 flags, OP *dynamic_meth)
newMETHOP_named

构建、检查并返回一个具有常量方法名称的方法类型操作符。type 是操作码。flags 给出了 op_flags 的八位,以及向上移八位,op_private 的八位。const_meth 提供一个常量方法名称;它必须是一个共享的 COW 字符串。支持的操作符类型:OP_METHOD_NAMED

    OP *  newMETHOP_named(I32 type, I32 flags, SV * const_meth)
newNULLLIST

构建、检查并返回一个新的 stub 操作符,它表示一个空列表表达式。

    OP *  newNULLLIST()
newOP

构建、检查并返回任何基本类型(任何没有额外字段的类型)的操作符。type 是操作码。flags 给出了 op_flags 的八位,以及向上移八位的 op_private 的八位。

    OP *  newOP(I32 optype, I32 flags)
newPADOP

构建、检查并返回任何涉及对填充元素的引用的操作符。type 是操作码。flags 给出了 op_flags 的八位。填充槽位会自动分配,并填充 sv;此函数会获取对它的一个引用。

此函数仅在 Perl 编译为使用 ithreads 时存在。

    OP *  newPADOP(I32 type, I32 flags, SV *sv)
newPMOP

构建、检查并返回任何模式匹配类型操作符。type 是操作码。flags 给出了 op_flags 的八位,以及向上移八位的 op_private 的八位。

    OP *  newPMOP(I32 type, I32 flags)
newPVOP

构建、检查并返回任何涉及嵌入式 C 级指针 (PV) 的操作符。type 是操作码。flags 给出了 op_flags 的八位。pv 提供 C 级指针。根据操作符类型,当操作符被销毁时,pv 引用的内存可能会被释放。如果操作符是释放类型,则 pv 必须使用 PerlMemShared_malloc 分配。

    OP *  newPVOP(I32 type, I32 flags, char *pv)
newRANGE

构建并返回一个 range 操作符,带有从属的 flipflop 操作符。flags 给出了 flip 操作符的 op_flags 的八位,以及向上移八位的 fliprange 操作符的 op_private 的八位,除了值为 1 的位会自动设置。leftright 提供控制范围端点的表达式;它们会被此函数消耗,并成为构建的操作符树的一部分。

    OP *  newRANGE(I32 flags, OP *left, OP *right)
newSLICEOP

构建、检查并返回一个 lslice(列表切片)操作符。flags 给出了 op_flags 的八位,除了 OPf_KIDS 会自动设置,以及向上移八位的 op_private 的八位,除了值为 1 或 2 的位会根据需要自动设置。listvalsubscript 提供切片的参数;它们会被此函数消耗,并成为构建的操作符树的一部分。

    OP *  newSLICEOP(I32 flags, OP *subscript, OP *listop)
newSTATEOP

构建一个状态操作符 (COP)。状态操作符通常是 nextstate 操作符,但如果当前编译的代码启用了调试,则将是 dbstate 操作符。状态操作符从 PL_curcop(或 PL_compiling)填充。如果 label 非空,则提供要附加到状态操作符的标签名称;此函数拥有指向 label 的内存,并将释放它。flags 给出状态操作符的 op_flags 的八位。

如果 o 为空,则返回状态操作符。否则,将状态操作符与 o 组合成一个 lineseq 列表操作符,并返回。o 被此函数消耗,并成为返回的操作符树的一部分。

    OP *  newSTATEOP(I32 flags, char *label, OP *o)
newSUB

"newATTRSUB" 相似,但没有属性。

    CV *  newSUB(I32 floor, OP *o, OP *proto, OP *block)
newSVOP

构建、检查并返回任何类型的操作符,该操作符包含嵌入的 SV。type 是操作码。flags 给出 op_flags 的八位。sv 给出要嵌入操作符的 SV;此函数拥有对它的一个引用。

    OP *  newSVOP(I32 type, I32 flags, SV *sv)
newTRYCATCHOP

注意:newTRYCATCHOP实验性的,可能会在未经通知的情况下更改或删除。

构建并返回一个条件执行语句,该语句实现 try/catch 语义。首先执行 tryblock 中的操作符树,在捕获异常的上下文中。如果发生异常,则执行 catchblock 中的操作符树,并将捕获的异常设置为 catchvar 给出的词法变量(必须是类型为 OP_PADSV 的操作符)。所有操作符树都被此函数消耗,并成为返回的操作符树的一部分。

flags 参数目前被忽略。

    OP *  newTRYCATCHOP(I32 flags, OP *tryblock, OP *catchvar,
                        OP *catchblock)
newUNOP

构造、检查并返回任何一元类型的操作。type 是操作码。flags 提供了 op_flags 的八位,除了 OPf_KIDS 将在需要时自动设置,以及向上移八位的 op_private 的八位,除了值为 1 的位将自动设置。first 提供了一个可选的操作作为一元操作的直接子节点;它被此函数消耗并成为构造的操作树的一部分。

    OP *  newUNOP(I32 type, I32 flags, OP *first)
newUNOP_AUX

类似于 newUNOP,但创建了一个 UNOP_AUX 结构,其中 op_aux 初始化为 aux

    OP *  newUNOP_AUX(I32 type, I32 flags, OP *first,
                      UNOP_AUX_item *aux)
newWHENOP

构造、检查并返回一个表示 when 块的操作树。cond 提供测试表达式,block 提供如果测试结果为真将执行的块;它们被此函数消耗并成为构造的操作树的一部分。cond 将被 DWIM 式地解释,通常作为与 $_ 的比较,并且可以为空以生成 default 块。

    OP *  newWHENOP(OP *cond, OP *block)
newWHILEOP

构造、检查并返回一个表示 while 循环的操作树。这是一个重量级循环,其结构允许通过 last 等退出循环。

loop 是一个可选的预先构造的 enterloop 操作,用于循环中;如果它为空,则将自动构造一个合适的操作。expr 提供循环的控制表达式。block 提供循环的主体,cont 可选地提供一个 continue 块,它作为主体的第二部分运行。所有这些 optree 输入都被此函数消耗并成为构造的操作树的一部分。

flags 提供了 leaveloop 操作的 op_flags 的八位,以及向上移八位的 leaveloop 操作的 op_private 的八位,除了(在两种情况下)某些位将自动设置。debuggable 目前未使用,应该始终为 1。has_my 可以设置为 true 以强制循环主体包含在自己的作用域中。

    OP *  newWHILEOP(I32 flags, I32 debuggable, LOOP *loop, OP *expr,
                     OP *block, OP *cont, I32 has_my)
newXS

xsubpp 用于将 XSUB 连接为 Perl 子例程。filename 需要是静态存储,因为它直接用作 CvFILE(),不会进行复制。

OA_BASEOP
OA_BINOP
OA_COP
OA_LISTOP
OA_LOGOP
OA_LOOP
OA_PADOP
OA_PMOP
OA_PVOP_OR_SVOP
OA_SVOP
OA_UNOP

perlguts 中描述。

OP

perlguts 中描述。

op_append_elem

将一个项目追加到列表类型操作符中直接包含的操作符列表中,返回加长的列表。first 是列表类型操作符,last 是要追加到列表中的操作符。optype 指定列表的预期操作码。如果 first 不是已经正确的列表类型,它将被升级为一个。如果 firstlast 为空,则返回另一个不变。

    OP *  op_append_elem(I32 optype, OP *first, OP *last)
op_append_list

连接两个列表类型操作符中直接包含的操作符列表,返回组合后的列表。firstlast 是要连接的列表类型操作符。optype 指定列表的预期操作码。如果 firstlast 不是已经正确的列表类型,它将被升级为一个。如果 firstlast 为空,则返回另一个不变。

    OP *  op_append_list(I32 optype, OP *first, OP *last)
OP_CLASS

返回提供的 OP 的类:即它使用的 *OP 结构。对于核心操作符,这目前从 PL_opargs 中获取信息,它并不总是准确地反映使用的类型;在 v5.26 及更高版本中,还可以参考 "op_class" 函数,它可以更好地确定使用的类型。

对于自定义操作符,类型从注册中返回,由注册者确保其准确性。返回的值将是 op.h 中的 OA_* 常量之一。

    U32  OP_CLASS(OP *o)
op_contextualize

将语法上下文应用于表示表达式的操作符树。o 是操作符树,context 必须是 G_SCALARG_LISTG_VOID,以指定要应用的上下文。返回修改后的操作符树。

    OP *  op_contextualize(OP *o, I32 context)
op_convert_list

如果 o 不是列表操作符,则将其转换为列表操作符,然后将其转换为指定的 type,调用其检查函数,如果需要则分配目标,并折叠常量。

列表类型操作符通常通过 newLISTOPop_prepend_elemop_append_elem 一次一个孩子地构建。然后最后将其传递给 op_convert_list 以使其成为正确的类型。

    OP *  op_convert_list(I32 optype, I32 flags, OP *o)
OP_DESC

返回提供的 OP 的简短描述。

    const char *  OP_DESC(OP *o)
op_force_list

如果 o 及其兄弟节点不是 OP_LIST,则将其提升为 OP_LIST。如果创建了新的 OP_LIST 操作符,其第一个子节点将是 OP_PUSHMARK。返回的节点本身将被置空,只保留其子节点。

这通常是您在将 optree 放入列表上下文之前想要做的事情;因为

o = op_contextualize(op_force_list(o), G_LIST);
    OP *  op_force_list(OP *o)
op_free

释放操作符及其子节点。仅当操作符不再与任何 optree 链接时使用此方法。

请记住,任何设置了 OPf_KIDS 的操作符都应该具有有效的 op_first 指针。如果您尝试释放操作符但保留其子操作符,请确保在调用 op_free() 之前清除该标志。例如

OP *kid = o->op_first; o->op_first = NULL;
o->op_flags &= ~OPf_KIDS;
op_free(o);
    void  op_free(OP *arg)
OpHAS_SIBLING

如果 o 有兄弟节点,则返回 true

    bool  OpHAS_SIBLING(OP *o)
OpLASTSIB_set

o 标记为没有更多兄弟节点,并将 o 标记为具有指定的父节点。另请参见 "OpMORESIB_set"OpMAYBESIB_set。对于更高级别的接口,请参见 "op_sibling_splice"

    void  OpLASTSIB_set(OP *o, OP *parent)

此函数是 "LINKLIST" 宏的实现。不应直接调用它。

    OP *  op_linklist(OP *o)
op_lvalue

注意:op_lvalue 实验性,可能会在未经通知的情况下更改或删除。

将左值(“可修改”)上下文传播到操作符及其子节点。type 表示上下文类型,大致基于执行修改的操作符的类型,尽管 local()OP_NULL 表示,因为它没有自己的操作符类型(它由左值操作符上的标志表示)。

此函数检测无法修改的内容,例如 $x+1,并为其生成错误。例如,$x+1 = 2 将导致它被调用,操作符类型为 OP_ADDtype 参数为 OP_SASSIGN

它还标记在左值上下文中需要特殊行为的内容,例如 $$x = 5,它可能需要在 $x 中激活引用。

    OP *  op_lvalue(OP *o, I32 type)
OpMAYBESIB_set

根据 sib 是否为空,有条件地执行 OpMORESIB_setOpLASTSIB_set。对于更高级别的接口,请参见 "op_sibling_splice"

    void  OpMAYBESIB_set(OP *o, OP *sib, OP *parent)
OpMORESIB_set

o 的兄弟节点设置为非零值 sib。另请参见 "OpLASTSIB_set""OpMAYBESIB_set"。有关更高级别的接口,请参见 "op_sibling_splice"

    void  OpMORESIB_set(OP *o, OP *sib)
OP_NAME

返回提供的 OP 的名称。对于核心操作,这会从 op_type 中查找名称;对于自定义操作,则从 op_ppaddr 中查找。

    const char *  OP_NAME(OP *o)
op_null

当不再需要操作但仍从其他操作链接时,将其中和。

    void  op_null(OP *o)
op_parent

返回o 的父 OP,如果它有父节点。否则返回 NULL

    OP *  op_parent(OP *o)
op_prepend_elem

将一个项目添加到列表类型操作中直接包含的操作列表的开头,返回加长的列表。first 是要添加到列表开头的操作,last 是列表类型操作。optype 指定列表的预期操作码。如果 last 还没有成为正确类型的列表,它将被升级为一个列表。如果 firstlast 为空,则返回另一个不变。

    OP *  op_prepend_elem(I32 optype, OP *first, OP *last)
op_scope

注意:op_scope实验性的,可能会在未经通知的情况下更改或删除。

用一些额外的操作包装一个操作树,以便在运行时创建动态范围。原始操作在新的动态范围内运行,然后,只要它们正常退出,范围就会被展开。用于创建和展开动态范围的额外操作通常是 enter/leave 对,但如果操作足够简单,不需要完整的动态范围结构,则可以使用 scope 操作。

    OP *  op_scope(OP *o)
OpSIBLING

返回o 的兄弟节点,如果没有兄弟节点则返回 NULL

    OP*  OpSIBLING(OP *o)
op_sibling_splice

一个用于编辑现有 op_sibling 节点链结构的通用函数。通过类比 perl 级别的 splice() 函数,允许您删除零个或多个连续节点,用零个或多个不同的节点替换它们。对父节点执行必要的 op_first/op_last 家务管理,并对子节点执行 op_sibling 操作。最后一个删除的节点将被标记为最后一个节点,方法是更新 op_sibling/op_sibparent 或 op_moresib 字段,具体取决于情况。

请注意,op_next 不会被操作,节点也不会被释放;这是调用者的责任。它也不会为一个空列表创建一个新的列表操作等;为此,请使用更高级别的函数,如 op_append_elem()。

parent 是兄弟节点链的父节点。如果拼接不影响链中的第一个或最后一个操作,则可以将其作为 NULL 传递。

start 是要拼接的第一个节点之前的节点。它后面的节点将被删除,并且操作将插入到它之后。如果它是 NULL,则从第一个节点开始删除,并且节点将插入到开头。

del_count 是要删除的节点数量。如果为零,则不删除任何节点。如果为 -1 或大于或等于剩余子节点的数量,则删除所有剩余子节点。

insert 是要插入以代替节点的节点链的第一个节点。如果为 NULL,则不插入任何节点。

返回已删除操作链的头部,如果未删除任何操作,则返回 NULL

例如

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

有关 op_sibparentop_moresib 的更低级别直接操作,请参见 "OpMORESIB_set""OpLASTSIB_set""OpMAYBESIB_set"

    OP *  op_sibling_splice(OP *parent, OP *start, int del_count,
                            OP *insert)
optimize_optree

此函数按自上而下的顺序对 optree 应用一些优化。它在窥孔优化器之前调用,窥孔优化器按执行顺序处理操作。请注意,finalize_optree() 也执行自上而下的扫描,但它是在窥孔优化器 *之后* 调用的。

    void  optimize_optree(OP *o)
OP_TYPE_IS

如果给定的 OP 不是 NULL 指针并且它是给定类型,则返回 true。

此宏的否定 OP_TYPE_ISNT 也可用,以及 OP_TYPE_IS_NNOP_TYPE_ISNT_NN,它们省略了 NULL 指针检查。

    bool  OP_TYPE_IS(OP *o, Optype type)
OP_TYPE_IS_OR_WAS

如果给定的 OP 不是 NULL 指针并且它是给定类型或在被类型为 OP_NULL 的 OP 替换之前曾经是,则返回 true。

此宏的否定 OP_TYPE_ISNT_AND_WASNT 也可用,以及 OP_TYPE_IS_OR_WAS_NNOP_TYPE_ISNT_AND_WASNT_NN,它们省略了 NULL 指针检查。

    bool  OP_TYPE_IS_OR_WAS(OP *o, Optype type)
op_wrap_finally

注意:op_wrap_finally实验性的,可能会在未经通知的情况下更改或删除。

将给定的 block optree 片段包装在它自己的作用域块中,安排在任何原因导致离开该块时调用 finally optree 片段。两个 optree 片段都被使用,并返回组合结果。

    OP *  op_wrap_finally(OP *block, OP *finally)
peep_t

perlguts 中描述。

Perl_cpeep_t

perlguts 中描述。

PL_opfreehook

当此变量指向的函数不为 NULL 时,每次使用相应的 OP 释放 OP 时,都会调用该函数。这允许扩展释放它们在本地附加到 OP 的任何额外属性。还可以确保先对父 OP 触发,然后对子 OP 触发。

当您替换此变量时,最好存储可能先前安装的钩子,并在您自己的钩子中调用它。

在多线程 Perl 中,每个线程都有此变量的独立副本;每个副本在创建时都使用创建线程副本的当前值进行初始化。

    Perl_ophook_t  PL_opfreehook
PL_peepp

指向每个子例程窥视孔优化器的指针。这是一个函数,在编译 Perl 子例程(或等效的独立 Perl 代码段)结束时被调用,以执行某些操作的修复并执行小规模优化。该函数对每个编译的子例程调用一次,并以指向子例程入口点的操作的指针作为唯一参数传递。它会修改操作树,使其就地生效。

窥视孔优化器永远不应该被完全替换。相反,通过包装现有的优化器来添加代码。在 "perlguts 中的编译阶段 3:窥视孔优化" 中可以看到执行此操作的基本方法。如果新代码希望对整个子例程结构中的操作进行操作,而不仅仅是在顶层进行操作,那么包装 "PL_rpeepp" 钩子可能会更方便。

在多线程 Perl 中,每个线程都有此变量的独立副本;每个副本在创建时都使用创建线程副本的当前值进行初始化。

    peep_t  PL_peepp
PL_rpeepp

指向递归窥视孔优化器的指针。这是一个函数,在编译 Perl 子例程(或等效的独立 Perl 代码段)结束时被调用,以执行某些操作的修复并执行小规模优化。该函数对通过其 op_next 字段链接的每个操作链调用一次;它被递归调用以处理每个侧链。它以指向链头的操作的指针作为唯一参数传递。它会修改操作树,使其就地生效。

窥视孔优化器永远不应该被完全替换。相反,通过包装现有的优化器来添加代码。在 "perlguts 中的编译阶段 3:窥视孔优化" 中可以看到执行此操作的基本方法。如果新代码希望仅对子例程顶层的操作进行操作,而不是对整个结构进行操作,那么包装 "PL_peepp" 钩子可能会更方便。

在多线程 Perl 中,每个线程都有此变量的独立副本;每个副本在创建时都使用创建线程副本的当前值进行初始化。

    peep_t  PL_rpeepp
PMOP

perlguts 中描述。

rv2cv_op_cv

检查一个操作符,该操作符预期在运行时识别一个子例程,并尝试在编译时确定它识别的子例程。这通常在 Perl 编译期间使用,以确定是否可以将原型应用于函数调用。cvop 是正在考虑的操作符,通常是 rv2cv 操作符。如果可以在静态地确定,则返回指向已识别子例程的指针;如果无法静态地确定,则返回空指针。

目前,如果 rv2cv 要操作的 RV 由合适的 gvconst 操作符提供,则可以静态地识别子例程。如果 GV 的 CV 槽已填充,则 gv 操作符是合适的。如果常量值必须是指向 CV 的 RV,则 const 操作符是合适的。此过程的详细信息可能会在未来的 Perl 版本中发生变化。如果 rv2cv 操作符设置了 OPpENTERSUB_AMPER 标志,则不会尝试静态地识别子例程:此标志用于抑制对子例程调用的编译时魔法,强制它使用默认的运行时行为。

如果 flags 设置了 RV2CVOPCV_MARK_EARLY 位,则 GV 引用处理方式将被修改。如果检查了 GV 并发现其 CV 槽为空,则 gv 操作符将设置 OPpEARLY_CV 标志。如果操作符没有被优化掉,并且 CV 槽后来被填充了具有原型的子例程,则该标志最终会触发警告“调用过早,无法检查原型”。

如果 flags 设置了 RV2CVOPCV_RETURN_NAME_GV 位,则它不会返回指向子例程的指针,而是返回指向 GV 的指针,该 GV 在此上下文中为子例程提供最合适的名称。通常这只是子例程的 CvGV,但对于通过 GV 引用的匿名 (CvANON) 子例程,它将是引用 GV。生成的 GV* 被转换为 CV* 以进行返回。如果不存在静态可确定的子例程,则照常返回空指针。

    CV *  rv2cv_op_cv(OP *cvop, U32 flags)
UNOP

perlguts 中描述。

XOP

perlguts 中描述。

打包和解包

packlist

实现 pack() Perl 函数的引擎。

    void  packlist(SV *cat, const char *pat, const char *patend,
                   SV **beglist, SV **endlist)
unpackstring

实现 unpack() Perl 函数的引擎。

使用模板 pat..patend,此函数将字符串 s..strend 解包成多个临时的 SVs,并将其推送到 perl 参数 (@_) 栈上(因此您需要在调用此函数之前发出 PUTBACK,并在调用之后发出 SPAGAIN)。它返回已推送元素的数量。

strendpatend 指针应指向每个字符串最后一个字符之后的字节。

虽然此函数在 perl 参数栈上返回其值,但它不从该栈中获取任何参数(因此特别地,不需要在调用它之前进行 PUSHMARK,例如与 "call_pv" 不同)。

    SSize_t  unpackstring(const char *pat, const char *patend,
                          const char *s, const char *strend,
                          U32 flags)

Pad 数据结构

CvPADLIST

注意:CvPADLIST实验性的,可能会在未经通知的情况下更改或删除。

CV 可以将 CvPADLIST(cv) 设置为指向 PADLIST。这是 CV 的临时存储区,用于存储词法变量和操作码临时值以及每个线程的值。

出于这些目的,“格式”是一种 CV;eval""s 也是(除了它们不能随意调用,并且在 eval"" 完成执行后总是被丢弃)。Require'd 文件只是没有外部词法范围的 evals。

XSUB 没有 CvPADLISTdXSTARGPL_curpad 中获取值,但这实际上是调用者的 pad(每个 entersub 会分配一个插槽)。如果 CV 是 XSUB(由 CvISXSUB() 确定),请不要获取或设置 CvPADLISTCvPADLIST 插槽在 XSUB 中被重新用于不同的内部目的。

PADLIST 具有存储 pad 的 C 数组。

PADLIST 的第 0 个条目是 PADNAMELIST,它表示词法的“名称”或更确切地说是“静态类型信息”。PADNAMELIST 的各个元素是 PADNAME。未来的重构可能会停止将 PADNAMELIST 存储在 PADLIST 的数组中,因此不要依赖它。请参阅 "PadlistNAMES"

PADLIST 的 CvDEPTH'th 条目是 PAD(一个 AV),它是 CV 中递归到该深度的堆栈帧。帧 AV 的第 0 个插槽是 AV,即 @_。其他条目是变量和操作目标的存储空间。

遍历 PADNAMELIST 会遍历所有可能的 pad 项目。目标的 pad 插槽 (SVs_PADTMP) 和 GVs 最终会拥有 &PL_padname_undef “名称”,而常量的插槽会拥有 &PL_padname_const “名称”(请参阅 "pad_alloc")。使用 &PL_padname_undef&PL_padname_const 是一个实现细节,可能会发生变化。要测试它们,请分别使用 !PadnamePV(name)PadnamePV(name) && !PadnameLEN(name)

只有my/our 变量槽位获得有效名称。其余的是操作目标/全局变量/常量,它们在编译时被静态分配或解析。这些没有名称,无法通过 Perl 代码在运行时通过 eval"" 的方式查找,就像 my/our 变量一样。由于它们无法通过“名称”查找,只能通过编译时分配的索引(通常在 PL_op->op_targ 中)查找,因此为它们浪费一个名称 SV 没有意义。

PADNAMELIST 中的填充名称的 PV 存储变量的名称。COP_SEQ_RANGE_LOW_HIGH 字段形成一个范围(low+1..high 包含),该范围内的 cop_seq 编号对该名称有效。在编译期间,这些字段可能包含特殊值 PERL_PADSEQ_INTRO,以指示不同的阶段

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); .... }

当一个词法变量尚未被引入时,它从重复声明的角度来看已经存在,但对于变量查找来说则不存在,例如

my ($x, $x); # '"my" variable $x masks earlier declaration'
my $x = $x;  # equal to my $x = $::x;

对于类型化的词法变量,PadnameTYPE 指向类型存储区。对于 our 词法变量,PadnameOURSTASH 指向关联全局变量的存储区(以便可以检测到同一个包中的重复 our 声明)。PadnameGEN 有时用于在编译期间存储生成号。

如果在填充名称上设置了 PadnameOUTER,则框架 AV 中的该槽位是对来自“外部”的词法变量的 REFCNT 引用。这些条目有时被称为“伪造”。在这种情况下,名称不使用“low”和“high”来存储 cop_seq 范围,因为它在整个范围内都有效。相反,“high”存储一些包含有关实际词法变量信息的标志(它是在匿名中声明的吗?它是否能够被多次实例化?),对于伪造的 ANON,'low' 包含父级填充中词法变量值的索引,以使克隆更快。

如果“name”是 &,则 PAD 中的相应条目是一个 CV,表示一个可能的闭包。

请注意,格式被视为匿名子程序,并且每次调用 write 时都会被克隆(如果需要)。

标志 SVs_PADSTALE 在每次执行 my() 时都会在词法变量上被清除,并在作用域退出时被设置。这允许在 evals 中生成“变量 $x 不可用”警告,例如

{ my $x = 1; sub f { eval '$x'} } f();

对于状态变量,SVs_PADSTALE 被重载为表示“尚未初始化”,但这种内部状态存储在单独的填充条目中。

    PADLIST *  CvPADLIST(CV *cv)
pad_add_name_pvs

"pad_add_name_pvn" 完全相同,但接受一个文字字符串而不是一个字符串/长度对。

    PADOFFSET  pad_add_name_pvs("name", U32 flags, HV *typestash,
                                HV *ourstash)
PadARRAY

注意:PadARRAY实验性的,可能会在没有通知的情况下更改或删除。

填充条目的 C 数组。

    SV **  PadARRAY(PAD * pad)
pad_findmy_pvs

"pad_findmy_pvn" 完全相同,但接受的是一个字面字符串,而不是字符串/长度对。

    PADOFFSET  pad_findmy_pvs("name", U32 flags)
PadlistARRAY

注意:PadlistARRAY 处于实验阶段,可能会在未经通知的情况下更改或删除。

padlist 的 C 数组,包含所有 pad。只能用大于等于 1 的数字作为下标,因为第 0 个元素不能保证始终可用。

    PAD **  PadlistARRAY(PADLIST * padlist)
PadlistMAX

注意:PadlistMAX 处于实验阶段,可能会在未经通知的情况下更改或删除。

padlist 中最后一个分配空间的索引。请注意,最后一个 pad 可能位于更早的槽位。在这种情况下,任何后续条目都将为 NULL

    SSize_t  PadlistMAX(PADLIST * padlist)
PadlistNAMES

注意:PadlistNAMES 处于实验阶段,可能会在未经通知的情况下更改或删除。

与 pad 条目关联的名称。

    PADNAMELIST *  PadlistNAMES(PADLIST * padlist)
PadlistNAMESARRAY

注意:PadlistNAMESARRAY 处于实验阶段,可能会在未经通知的情况下更改或删除。

pad 名称的 C 数组。

    PADNAME **  PadlistNAMESARRAY(PADLIST * padlist)
PadlistNAMESMAX

注意:PadlistNAMESMAX 处于实验阶段,可能会在未经通知的情况下更改或删除。

最后一个 pad 名称的索引。

    SSize_t  PadlistNAMESMAX(PADLIST * padlist)
PadlistREFCNT

注意:PadlistREFCNT 处于实验阶段,可能会在未经通知的情况下更改或删除。

padlist 的引用计数。目前始终为 1。

    U32  PadlistREFCNT(PADLIST * padlist)
PadMAX

注意:PadMAX 处于实验阶段,可能会在未经通知的情况下更改或删除。

最后一个 pad 条目的索引。

    SSize_t  PadMAX(PAD * pad)
PadnameLEN

注意:PadnameLEN 处于实验阶段,可能会在未经通知的情况下更改或删除。

名称的长度。

    STRLEN  PadnameLEN(PADNAME * pn)
PadnamelistARRAY

注意:PadnamelistARRAY 处于实验阶段,可能会在未经通知的情况下更改或删除。

pad 名称的 C 数组。

    PADNAME **  PadnamelistARRAY(PADNAMELIST * pnl)
PadnamelistMAX

注意:PadnamelistMAX 处于实验阶段,可能会在未经通知的情况下更改或删除。

最后一个 pad 名称的索引。

    SSize_t  PadnamelistMAX(PADNAMELIST * pnl)
PadnamelistREFCNT

注意:PadnamelistREFCNT 处于实验阶段,可能会在未经通知的情况下更改或删除。

pad 名称列表的引用计数。

    SSize_t  PadnamelistREFCNT(PADNAMELIST * pnl)
PadnamelistREFCNT_dec

注意:PadnamelistREFCNT_dec 处于实验阶段,可能会在未经通知的情况下更改或删除。

降低 pad 名称列表的引用计数。

    void  PadnamelistREFCNT_dec(PADNAMELIST * pnl)
PadnamePV

注意:PadnamePV 处于实验阶段,可能会在未经通知的情况下更改或删除。

存储在 pad 名称结构中的名称。对于目标槽位,此函数返回 NULL

    char *  PadnamePV(PADNAME * pn)
PadnameREFCNT

注意:PadnameREFCNT 处于实验阶段,可能会在未经通知的情况下更改或删除。

pad 名称的引用计数。

    SSize_t  PadnameREFCNT(PADNAME * pn)
PadnameREFCNT_dec

注意:PadnameREFCNT_dec实验性的,可能会在不通知的情况下更改或删除。

降低垫子名称的引用计数。

    void  PadnameREFCNT_dec(PADNAME * pn)
PadnameREFCNT_inc

注意:PadnameREFCNT_inc实验性的,可能会在不通知的情况下更改或删除。

增加垫子名称的引用计数。返回垫子名称本身。

    PADNAME *  PadnameREFCNT_inc(PADNAME * pn)
PadnameSV

注意:PadnameSV实验性的,可能会在不通知的情况下更改或删除。

将垫子名称作为 mortal SV 返回。

    SV *  PadnameSV(PADNAME * pn)
PadnameUTF8

注意:PadnameUTF8实验性的,可能会在不通知的情况下更改或删除。

PadnamePV 是否为 UTF-8。目前,这始终为真。

    bool  PadnameUTF8(PADNAME * pn)
pad_new

创建一个新的垫子列表,更新用于当前正在编译的垫子列表的全局变量,使其指向新的垫子列表。以下标志可以按位或运算组合在一起

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
    PADLIST *  pad_new(int flags)
PL_comppad

注意:PL_comppad实验性的,可能会在不通知的情况下更改或删除。

在编译期间,它指向包含当前正在编译的代码的垫子值部分的数组。(在运行时,一个 CV 可能有多个这样的值数组;在编译时,只构造一个。)在运行时,它指向包含当前正在执行的代码的垫子的当前相关值的数组。

PL_comppad_name

注意:PL_comppad_name实验性的,可能会在不通知的情况下更改或删除。

在编译期间,它指向包含当前正在编译的代码的垫子名称部分的数组。

PL_curpad

注意:PL_curpad实验性的,可能会在不通知的情况下更改或删除。

直接指向 "PL_comppad" 数组的主体。(即,这是 PadARRAY(PL_comppad)。)

SVs_PADMY

已弃用! 计划从 Perl 的未来版本中删除 SVs_PADMY。不要在新的代码中使用它;从现有代码中删除它。

perlguts 中描述。

SVs_PADTMP

perlguts 中描述。

密码和组访问

GRPASSWD

如果定义了此符号,则表示 C 程序中的 struct groupgrp.h 中包含 gr_passwd

HAS_ENDGRENT

如果定义了此符号,则表示 getgrent 函数可用于完成对组数据库的顺序访问。

HAS_ENDGRENT_R

如果定义了此符号,则表示 endgrent_r 函数可用于以可重入方式结束 endgrent

HAS_ENDPWENT

如果定义了此符号,则表示 endpwent 函数可用于完成对 passwd 数据库的顺序访问。

HAS_ENDPWENT_R

如果定义了此符号,则表示 endpwent_r 函数可用于以可重入方式结束 endpwent

HAS_GETGRENT

如果定义了此符号,则表示 getgrent 函数可用于顺序访问组数据库。

HAS_GETGRENT_R

如果定义了此符号,则表示 getgrent_r 函数可用于以可重入方式获取 getgrent

HAS_GETPWENT

如果定义了此符号,则表示 getpwent 函数可用于顺序访问 passwd 数据库。如果此函数不可用,则可能可以使用旧的 getpw() 函数。

HAS_GETPWENT_R

如果定义了此符号,则表示 getpwent_r 函数可用于以可重入方式获取 getpwent

HAS_SETGRENT

如果定义了此符号,则表示 setgrent 函数可用于初始化对组数据库的顺序访问。

HAS_SETGRENT_R

如果定义了此符号,则表示 setgrent_r 函数可用于以可重入方式设置 setgrent

HAS_SETPWENT

如果定义了此符号,则表示 setpwent 函数可用于初始化对 passwd 数据库的顺序访问。

HAS_SETPWENT_R

如果定义了此符号,则表示 setpwent_r 函数可用于以可重入方式设置 setpwent

PWAGE

如果定义了此符号,则表示 C 程序中的 struct passwd 包含 pw_age

PWCHANGE

如果定义了此符号,则表示 C 程序中的 struct passwd 包含 pw_change

PWCLASS

如果定义了此符号,则表示 C 程序中的 struct passwd 包含 pw_class

PWCOMMENT

如果定义了此符号,则表示 C 程序中的 struct passwd 包含 pw_comment

PWEXPIRE

如果定义了此符号,则表示 C 程序中的 struct passwd 包含 pw_expire

PWGECOS

如果定义了此符号,则表示 C 程序中的 struct passwd 包含 pw_gecos

PWPASSWD

如果定义了此符号,则表示 C 程序中的 struct passwd 包含 pw_passwd

PWQUOTA

如果定义了此符号,则表示 C 程序中的 struct passwd 包含 pw_quota

系统命令路径

CSH

如果定义了此符号,则包含 csh 的完整路径名。

LOC_SED

此符号包含 sed 程序的完整路径名。

SH_PATH

此符号包含此系统上用于执行 Bourne shell 脚本的 shell 的完整路径名。通常,这将是 /bin/sh,但某些系统可能会有 /bin/ksh/bin/pdksh/bin/ash/bin/bash,甚至像 D:/bin/sh.exe 这样的东西。

原型信息

CRYPT_R_PROTO

此符号编码 crypt_r 的原型。如果 d_crypt_r 未定义,则为零;如果 d_crypt_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

CTERMID_R_PROTO

此符号编码了ctermid_r的原型。如果d_ctermid_r未定义,则为零;如果d_ctermid_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

DRAND48_R_PROTO

此符号编码了drand48_r的原型。如果d_drand48_r未定义,则为零;如果d_drand48_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

ENDGRENT_R_PROTO

此符号编码了endgrent_r的原型。如果d_endgrent_r未定义,则为零;如果d_endgrent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

ENDHOSTENT_R_PROTO

此符号编码了endhostent_r的原型。如果d_endhostent_r未定义,则为零;如果d_endhostent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

ENDNETENT_R_PROTO

此符号编码了endnetent_r的原型。如果d_endnetent_r未定义,则为零;如果d_endnetent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

ENDPROTOENT_R_PROTO

此符号编码了endprotoent_r的原型。如果d_endprotoent_r未定义,则为零;如果d_endprotoent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

ENDPWENT_R_PROTO

此符号编码了endpwent_r的原型。如果d_endpwent_r未定义,则为零;如果d_endpwent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

ENDSERVENT_R_PROTO

此符号编码了endservent_r的原型。如果d_endservent_r未定义,则为零;如果d_endservent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GDBMNDBM_H_USES_PROTOTYPES

如果定义了此符号,则表示gdbm/ndbm.h使用真正的ANSI C 原型,而不是没有参数信息的 K&R 风格函数声明。虽然ANSI C 原型在 C++ 中受支持,但 K&R 风格函数声明会导致错误。

GDBM_NDBM_H_USES_PROTOTYPES

如果定义了此符号,则表示<gdbm-ndbm.h>使用真正的ANSI C 原型,而不是没有参数信息的 K&R 风格函数声明。虽然ANSI C 原型在 C++ 中受支持,但 K&R 风格函数声明会导致错误。

GETGRENT_R_PROTO

此符号编码了getgrent_r的原型。如果d_getgrent_r未定义,则为零,如果d_getgrent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GETGRGID_R_PROTO

此符号编码了getgrgid_r的原型。如果d_getgrgid_r未定义,则为零,如果d_getgrgid_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GETGRNAM_R_PROTO

此符号编码了getgrnam_r的原型。如果d_getgrnam_r未定义,则为零,如果d_getgrnam_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GETHOSTBYADDR_R_PROTO

此符号编码了gethostbyaddr_r的原型。如果d_gethostbyaddr_r未定义,则为零,如果d_gethostbyaddr_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GETHOSTBYNAME_R_PROTO

此符号编码了gethostbyname_r的原型。如果d_gethostbyname_r未定义,则为零,如果d_gethostbyname_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GETHOSTENT_R_PROTO

此符号编码了gethostent_r的原型。如果d_gethostent_r未定义,则为零,如果d_gethostent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GETLOGIN_R_PROTO

此符号编码了getlogin_r的原型。如果d_getlogin_r未定义,则为零,如果d_getlogin_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GETNETBYADDR_R_PROTO

此符号编码了getnetbyaddr_r的原型。如果d_getnetbyaddr_r未定义,则为零,如果d_getnetbyaddr_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

GETNETBYNAME_R_PROTO

此符号编码了 getnetbyname_r 的原型。如果 d_getnetbyname_r 未定义,则为零;如果 d_getnetbyname_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETNETENT_R_PROTO

此符号编码了 getnetent_r 的原型。如果 d_getnetent_r 未定义,则为零;如果 d_getnetent_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETPROTOBYNAME_R_PROTO

此符号编码了 getprotobyname_r 的原型。如果 d_getprotobyname_r 未定义,则为零;如果 d_getprotobyname_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETPROTOBYNUMBER_R_PROTO

此符号编码了 getprotobynumber_r 的原型。如果 d_getprotobynumber_r 未定义,则为零;如果 d_getprotobynumber_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETPROTOENT_R_PROTO

此符号编码了 getprotoent_r 的原型。如果 d_getprotoent_r 未定义,则为零;如果 d_getprotoent_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETPWENT_R_PROTO

此符号编码了 getpwent_r 的原型。如果 d_getpwent_r 未定义,则为零;如果 d_getpwent_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETPWNAM_R_PROTO

此符号编码了 getpwnam_r 的原型。如果 d_getpwnam_r 未定义,则为零;如果 d_getpwnam_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETPWUID_R_PROTO

此符号编码了 getpwuid_r 的原型。如果 d_getpwuid_r 未定义,则为零;如果 d_getpwuid_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETSERVBYNAME_R_PROTO

此符号编码了 getservbyname_r 的原型。如果 d_getservbyname_r 未定义,则为零;如果 d_getservbyname_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETSERVBYPORT_R_PROTO

此符号编码了 getservbyport_r 的原型。如果 d_getservbyport_r 未定义,则为零;如果 d_getservbyport_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETSERVENT_R_PROTO

此符号编码了 getservent_r 的原型。如果 d_getservent_r 未定义,则为零;如果 d_getservent_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GETSPNAM_R_PROTO

此符号编码了getspnam_r的原型。如果d_getspnam_r未定义,则为零;如果d_getspnam_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

HAS_DBMINIT_PROTO

如果定义了此符号,则表示系统提供了dbminit()函数的原型。否则,由程序提供。一个好的猜测是

extern int dbminit(char *);
HAS_DRAND48_PROTO

如果定义了此符号,则表示系统提供了drand48()函数的原型。否则,由程序提供。一个好的猜测是

extern double drand48(void);
HAS_FLOCK_PROTO

如果定义了此符号,则表示系统提供了flock()函数的原型。否则,由程序提供。一个好的猜测是

extern int flock(int, int);
HAS_GETHOST_PROTOS

如果定义了此符号,则表示netdb.h包含gethostent()gethostbyname()gethostbyaddr()的原型。否则,由程序猜测它们。有关探测各种Netdb_xxx_t类型的详细信息,请参见netdbtype.U(元配置的一部分)。

HAS_GETNET_PROTOS

如果定义了此符号,则表示netdb.h包含getnetent()getnetbyname()getnetbyaddr()的原型。否则,由程序猜测它们。有关探测各种Netdb_xxx_t类型的详细信息,请参见netdbtype.U(元配置的一部分)。

HAS_GETPROTO_PROTOS

如果定义了此符号,则表示netdb.h包含getprotoent()getprotobyname()getprotobyaddr()的原型。否则,由程序猜测它们。有关探测各种Netdb_xxx_t类型的详细信息,请参见netdbtype.U(元配置的一部分)。

HAS_GETSERV_PROTOS

如果定义了此符号,则表示netdb.h包含getservent()getservbyname()getservbyaddr()的原型。否则,由程序猜测它们。有关探测各种Netdb_xxx_t类型的详细信息,请参见netdbtype.U(元配置的一部分)。

HAS_MODFL_PROTO

如果定义了此符号,则表示系统提供了modfl()函数的原型。否则,由程序提供。

HAS_SBRK_PROTO

如果定义了此符号,则表示系统提供了sbrk()函数的原型。否则,由程序提供。一个好的猜测是

extern void* sbrk(int);
extern void* sbrk(size_t);
HAS_SETRESGID_PROTO

如果定义了此符号,则表示系统为setresgid()函数提供了一个原型。 否则,程序需要自行提供一个。 好的猜测是

extern int setresgid(uid_t ruid, uid_t euid, uid_t suid);
HAS_SETRESUID_PROTO

如果定义了此符号,则表示系统为setresuid()函数提供了一个原型。 否则,程序需要自行提供一个。 好的猜测是

extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);
HAS_SHMAT_PROTOTYPE

如果定义了此符号,则表示sys/shm.h包含shmat()的原型。 否则,程序需要自行猜测一个。 Shmat_t shmat(int, Shmat_t, int)是一个不错的猜测,但并不总是正确,因此只有在未定义HAS_SHMAT_PROTOTYPE时,程序才应发出它,以避免冲突的定义。

HAS_SOCKATMARK_PROTO

如果定义了此符号,则表示系统为sockatmark()函数提供了一个原型。 否则,程序需要自行提供一个。 一个好的猜测是

extern int sockatmark(int);
HAS_SYSCALL_PROTO

如果定义了此符号,则表示系统为syscall()函数提供了一个原型。 否则,程序需要自行提供一个。 好的猜测是

extern int syscall(int,  ...);
extern int syscall(long, ...);
HAS_TELLDIR_PROTO

如果定义了此符号,则表示系统为telldir()函数提供了一个原型。 否则,程序需要自行提供一个。 一个好的猜测是

extern long telldir(DIR*);
NDBM_H_USES_PROTOTYPES

如果定义了此符号,则表示ndbm.h使用真正的ANSI C 原型,而不是没有参数信息的 K&R 风格函数声明。 虽然 C++ 支持ANSI C 原型,但 K&R 风格的函数声明会导致错误。

RANDOM_R_PROTO

此符号编码了random_r的原型。如果d_random_r未定义,则为零;如果d_random_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

READDIR_R_PROTO

此符号编码了readdir_r的原型。如果d_readdir_r未定义,则为零;如果d_readdir_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SETGRENT_R_PROTO

此符号编码了setgrent_r的原型。如果d_setgrent_r未定义,则为零;如果d_setgrent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SETHOSTENT_R_PROTO

此符号编码了sethostent_r的原型。如果d_sethostent_r未定义,则为零;如果d_sethostent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SETLOCALE_R_PROTO

此符号编码了setlocale_r的原型。如果d_setlocale_r未定义,则为零;如果d_setlocale_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SETNETENT_R_PROTO

此符号编码了setnetent_r的原型。如果d_setnetent_r未定义,则为零;如果d_setnetent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SETPROTOENT_R_PROTO

此符号编码了setprotoent_r的原型。如果d_setprotoent_r未定义,则为零;如果d_setprotoent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SETPWENT_R_PROTO

此符号编码了setpwent_r的原型。如果d_setpwent_r未定义,则为零;如果d_setpwent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SETSERVENT_R_PROTO

此符号编码了setservent_r的原型。如果d_setservent_r未定义,则为零;如果d_setservent_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SRANDOM_R_PROTO

此符号编码了srandom_r的原型。如果d_srandom_r未定义,则为零;如果d_srandom_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

SRAND48_R_PROTO

此符号编码了srand48_r的原型。如果d_srand48_r未定义,则为零;如果d_srand48_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

STRERROR_R_PROTO

此符号编码了strerror_r的原型。如果d_strerror_r未定义,则为零;如果d_strerror_r已定义,则为reentr.h中的REENTRANT_PROTO_T_ABC宏之一。

TMPNAM_R_PROTO

此符号编码了 tmpnam_r 的原型。如果 d_tmpnam_r 未定义,则为零;如果 d_tmpnam_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

TTYNAME_R_PROTO

此符号编码了 ttyname_r 的原型。如果 d_ttyname_r 未定义,则为零;如果 d_ttyname_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

正则表达式函数

pregcomp

perlreguts 中描述。

    REGEXP *  pregcomp(SV * const pattern, const U32 flags)
pregexec

perlreguts 中描述。

    I32  pregexec(REGEXP * const prog, char *stringarg, char *strend,
                  char *strbeg, SSize_t minend, SV *screamer,
                  U32 nosave)
re_compile

编译正则表达式模式 pattern,返回指向已编译对象的指针,以便稍后与内部正则表达式引擎匹配。

此函数通常由自定义正则表达式引擎 .comp() 函数使用,以将它不想自己处理的模式传递给核心正则表达式引擎(通常传递与调用时相同的标志)。在几乎所有其他情况下,正则表达式都应通过调用 "pregcomp" 来编译,以使用当前活动的正则表达式引擎进行编译。

如果 pattern 已经是 REGEXP,则此函数不做任何操作,只返回指向输入的指针。否则,将提取 PV 并将其视为表示模式的字符串。参见 perlre

rx_flags 的可能标志在 perlreapi 中有记录。它们的名称都以 RXf_ 开头。

    REGEXP *  re_compile(SV * const pattern, U32 orig_rx_flags)
re_dup_guts

复制正则表达式。

此例程预计会克隆给定的正则表达式结构。它只在 USE_ITHREADS 下编译。

在复制 struct regexp 中存储的所有核心数据后,将使用 regexp_engine.dupe 方法复制存储在 *pprivate 指针中的任何私有数据。这允许扩展处理它们需要执行的任何复制。

    void  re_dup_guts(const REGEXP *sstr, REGEXP *dstr,
                      CLONE_PARAMS *param)
REGEX_LOCALE_CHARSET

perlreapi 中描述。

REGEXP

perlreapi 中描述。

regexp_engine

编译正则表达式时,它的 engine 字段将设置为指向相应的结构,以便在需要使用它时,Perl 可以找到执行此操作的正确例程。

为了安装新的正则表达式处理程序,$^H{regcomp} 被设置为一个整数,该整数(在适当的情况下进行强制转换)解析为这些结构之一。编译时,将执行 comp 方法,并且生成的 regexp 结构的 engine 字段预计将指向同一个结构。

定义中的 pTHX_ 符号是 Perl 在线程下使用的宏,用于为例程提供一个额外的参数,该参数保存指向正在执行正则表达式的解释器的指针。因此,在多线程下,所有例程都将获得一个额外的参数。

regexp_paren_pair

perlreapi 中描述。

regmatch_info

由 Perl_regexec_flags 创建并传递给 regtry()、regmatch() 等的当前匹配的一些基本信息。它被分配为堆栈上的局部变量,因此不应该在其中存储需要在 croak() 上保存或清除的任何内容。为此,请参见 regmatch_state 联合体的 aux_info 和 aux_info_eval 成员。

REXEC_COPY_SKIP_POST
REXEC_COPY_SKIP_PRE
REXEC_COPY_STR

perlreapi 中描述。

RXapif_ALL
RXapif_CLEAR
RXapif_DELETE
RXapif_EXISTS
RXapif_FETCH
RXapif_FIRSTKEY
RXapif_NEXTKEY
RXapif_ONE
RXapif_REGNAME
RXapif_REGNAMES
RXapif_REGNAMES_COUNT
RXapif_SCALAR
RXapif_STORE

perlreapi 中描述。

RX_BUFF_IDX_CARET_FULLMATCH
RX_BUFF_IDX_CARET_POSTMATCH
RX_BUFF_IDX_CARET_PREMATCH
RX_BUFF_IDX_FULLMATCH
RX_BUFF_IDX_POSTMATCH
RX_BUFF_IDX_PREMATCH

perlreapi 中描述。

RXf_NO_INPLACE_SUBST
RXf_NULL
RXf_SKIPWHITE
RXf_SPLIT
RXf_START_ONLY
RXf_WHITE

perlreapi 中描述。

RXf_PMf_EXTENDED
RXf_PMf_FOLD
RXf_PMf_KEEPCOPY
RXf_PMf_MULTILINE
RXf_PMf_SINGLELINE

perlreapi 中描述。

RX_MATCH_COPIED

perlreapi 中描述。

    RX_MATCH_COPIED(const REGEXP * rx)
RX_OFFS

perlreapi 中描述。

    RX_OFFS(const REGEXP * rx_sv)
SvRX

从 SV 获取 REGEXP 的便捷宏。这大致等同于以下代码段

if (SvMAGICAL(sv))
    mg_get(sv);
if (SvROK(sv))
    sv = MUTABLE_SV(SvRV(sv));
if (SvTYPE(sv) == SVt_REGEXP)
    return (REGEXP*) sv;

如果未找到 REGEXP*,则返回 NULL

    REGEXP *  SvRX(SV *sv)
SvRXOK

返回一个布尔值,指示 SV(或它引用的 SV)是否为 REGEXP。

如果您想稍后对 REGEXP* 做些操作,请使用 SvRX 并检查是否为 NULL。

    bool  SvRXOK(SV* sv)
SV_SAVED_COPY

perlreapi 中描述。

报告和格式

这些用于 Perl 的简单报告生成功能。参见 perlform

IoBOTTOM_GV

perlguts 中描述。

    GV *  IoBOTTOM_GV(IO *io)
IoBOTTOM_NAME

perlguts 中描述。

    char *  IoBOTTOM_NAME(IO *io)
IoFMT_GV

perlguts 中描述。

    GV *  IoFMT_GV(IO *io)
IoFMT_NAME

perlguts 中描述。

    char *  IoFMT_NAME(IO *io)
IoLINES

perlguts 中描述。

    IV  IoLINES(IO *io)
IoLINES_LEFT

perlguts 中描述。

    IV  IoLINES_LEFT(IO *io)
IoPAGE

perlguts 中描述。

    IV  IoPAGE(IO *io)
IoPAGE_LEN

perlguts 中描述。

    IV  IoPAGE_LEN(IO *io)
IoTOP_GV

perlguts 中描述。

    GV *  IoTOP_GV(IO *io)
IoTOP_NAME

perlguts 中描述。

    char *  IoTOP_NAME(IO *io)

信号

HAS_SIGINFO_SI_ADDR

如果定义了此符号,则表示 siginfo_t 具有 si_addr 成员

HAS_SIGINFO_SI_BAND

如果定义了此符号,则表示 siginfo_t 具有 si_band 成员

HAS_SIGINFO_SI_ERRNO

如果定义了此符号,则表示 siginfo_t 具有 si_errno 成员

HAS_SIGINFO_SI_PID

如果定义了此符号,则表示 siginfo_t 具有 si_pid 成员

HAS_SIGINFO_SI_STATUS

如果定义了此符号,则表示 siginfo_t 具有 si_status 成员

HAS_SIGINFO_SI_UID

如果定义了此符号,则表示 siginfo_t 具有 si_uid 成员

HAS_SIGINFO_SI_VALUE

如果定义了此符号,则表示 siginfo_t 具有 si_value 成员

PERL_SIGNALS_UNSAFE_FLAG

如果 PL_signals 中的此位被设置,则系统正在使用 Perl 5.8 之前的非安全信号。请参阅 "perlrun 中的 PERL_SIGNALS""perlipc 中的延迟信号(安全信号)"

    U32  PERL_SIGNALS_UNSAFE_FLAG
rsignal

C 库函数 sigaction(2)signal(2) 的包装器。使用此函数而不是这些 libc 函数,因为 Perl 版本提供了最安全的可用实现,并且了解与 Perl 解释器其余部分交互的事项。

    Sighandler_t  rsignal(int i, Sighandler_t t)
rsignal_state

返回信号 signo 的当前信号处理程序。请参阅 "rsignal"

    Sighandler_t  rsignal_state(int i)
Sigjmp_buf

这是要与 Sigsetjmp 和 Siglongjmp 一起使用的缓冲区类型。

Siglongjmp

此宏的使用方式与 siglongjmp() 相同,但如果 siglongjmp 不可用,则会调用传统的 longjmp()。请参阅 "HAS_SIGSETJMP"

    void  Siglongjmp(jmp_buf env, int val)
SIG_NAME

此符号包含按信号编号顺序排列的信号名称列表。它旨在用作静态数组初始化,例如

char *sig_name[] = { SIG_NAME };

列表中的信号用逗号分隔,每个信号都用双引号括起来。信号名称前面没有 SIG,即 SIGQUIT 称为 "QUIT"。信号编号中的间隙(最多 NSIG)用 NUMnn 等填充,其中 nn 是实际的信号编号(例如 NUM37)。sig_name[i] 的信号编号存储在 sig_num[i] 中。最后一个元素为 0,以 NULL 终止列表。这对应于 sig_name_init 列表末尾的 0。请注意,此变量是从 sig_name_init 初始化的,而不是从 sig_name 初始化的(sig_name 未使用)。

SIG_NUM

此符号包含信号编号列表,顺序与 SIG_NAME 列表相同。它适用于静态数组初始化,如

int sig_num[] = { SIG_NUM };

列表中的信号用逗号分隔,列表中的索引与SIG_NAME列表中的索引匹配,因此可以轻松地在数字和信号名称之间进行转换,只需进行一次小的动态线性查找。允许重复,但会移到列表的末尾。与sig_name[i]对应的信号编号为sig_number[i]。如果 (i < NSIG),则sig_number[i] == i。最后一个元素为 0,对应于sig_name_init列表末尾的 0。请注意,此变量是从sig_num_init初始化的,而不是从sig_num(未使用)初始化的。

Sigsetjmp

此宏的使用方式与sigsetjmp()相同,但如果 sigsetjmp 不可用,则会调用传统的setjmp()。请参阅"HAS_SIGSETJMP"

    int  Sigsetjmp(jmp_buf env, int savesigs)
SIG_SIZE

此变量包含SIG_NAMESIG_NUM数组的元素数量,不包括最后的NULL条目。

whichsig
whichsig_pv
whichsig_pvn
whichsig_sv

这些函数将信号名称转换为其对应的信号编号;如果未找到对应的编号,则返回 -1。

它们的区别仅在于信号名称的来源

whichsig_pv从以sig开头的NUL终止的字符串中获取名称。

whichsig只是whichsig_pv的另一种拼写,是它的同义词。

whichsig_pvn从以sig开头的字符串中获取名称,长度为len字节。

whichsig_sv从 SV sigsv中存储的 PV 中获取名称。

    I32  whichsig    (const char *sig)
    I32  whichsig_pv (const char *sig)
    I32  whichsig_pvn(const char *sig, STRLEN len)
    I32  whichsig_sv (SV *sigsv)

站点配置

这些变量提供了有关各种库、安装目标等的位置以及选择了哪些安装选项的详细信息

ARCHLIB

如果定义了此变量,它将保存用户希望放置 perl5 架构相关公共库文件的目录名称。它通常是本地目录,例如/usr/local/lib。使用此变量的程序必须准备好处理文件名扩展。如果ARCHLIBPRIVLIB相同,则不会定义它,因为程序可能已经搜索了PRIVLIB

ARCHLIB_EXP

此符号包含ARCHLIB的~name 扩展版本,用于在运行时不准备处理~扩展的程序中。

ARCHNAME

此符号保存一个字符串,表示架构名称。它可用于构建架构相关的路径名,其中库文件可能保存在私有库下,例如。

BIN

此符号保存包将安装到的 bin 目录的路径。程序必须准备好处理~name 替换。

BIN_EXP

此符号是BIN符号的文件名扩展版本,用于不想在运行时处理此问题的程序。

INSTALL_USR_BIN_PERL

如果定义了此符号,则表示 Perl 也将安装为/usr/bin/perl

MULTIARCH

如果定义了此符号,则表示构建过程将生成一些将在跨平台环境中使用的二进制文件。例如,NeXT 的“fat”二进制文件包含适用于多个CPU的可执行文件。

PERL_INC_VERSION_LIST

此变量指定perl.c:incpush()lib/lib.pm在将目录添加到 @INC时将自动搜索的子目录列表,格式适合 C 初始化字符串。有关更多详细信息,请参阅 Porting/Glossary 中的inc_version_list 条目。

PERL_OTHERLIBDIRS

此变量包含一个冒号分隔的路径集,用于 perl 二进制文件搜索其他库文件或模块。这些目录将附加到 @INC的末尾。Perl 将自动在每个路径下搜索版本和架构特定的目录。有关更多详细信息,请参阅"PERL_INC_VERSION_LIST"

PERL_RELOCATABLE_INC

如果定义了此符号,则表示我们希望在运行时根据 perl 二进制文件的位置重新定位 @INC中的条目。

PERL_TARGETARCH

如果定义了此符号,则表示 Perl 已交叉编译到目标架构。如果未进行交叉编译,则未定义。

PERL_USE_DEVEL

如果定义了此符号,则表示 Perl 使用-Dusedevel配置,以启用开发功能。生产环境构建不应执行此操作。

PERL_VENDORARCH

如果定义,此符号包含私有库的名称。该库是私有的,因为它不需要在任何人的执行路径中,但应该对全世界可用。它可能在前面有一个 ~。标准发行版不会将任何内容放入此目录中。分发 perl 的供应商可能希望将他们自己的体系结构相关模块和扩展放入此目录中,方法是

MakeMaker Makefile.PL INSTALLDIRS=vendor

或等效项。有关详细信息,请参见 INSTALL

PERL_VENDORARCH_EXP

此符号包含 PERL_VENDORARCH 的 ~name 扩展版本,用于在未准备在运行时处理 ~ 扩展的程序中。

PERL_VENDORLIB_EXP

此符号包含 VENDORLIB 的 ~name 扩展版本,用于在未准备在运行时处理 ~ 扩展的程序中。

PERL_VENDORLIB_STEM

此定义是 PERL_VENDORLIB_EXP,去掉了任何尾随的版本特定组件。inc_version_listinc_version_list.U(元配置的一部分))中的元素可以附加到此变量,以生成要搜索的目录列表。

PRIVLIB

此符号包含此包的私有库的名称。该库是私有的,因为它不需要在任何人的执行路径中,但应该对全世界可用。该程序应该准备进行 ~ 扩展。

PRIVLIB_EXP

此符号包含 PRIVLIB 的 ~name 扩展版本,用于在未准备在运行时处理 ~ 扩展的程序中。

SITEARCH

此符号包含此包的私有库的名称。该库是私有的,因为它不需要在任何人的执行路径中,但应该对全世界可用。该程序应该准备进行 ~ 扩展。标准发行版不会将任何内容放入此目录中。在安装 perl 后,用户可以在此目录中安装他们自己的本地体系结构相关模块,方法是

MakeMaker Makefile.PL

或等效项。有关详细信息,请参见 INSTALL

SITEARCH_EXP

此符号包含 SITEARCH 的 ~name 扩展版本,用于在未准备在运行时处理 ~ 扩展的程序中。

SITELIB

此符号包含此包的私有库名称。该库是私有的,因为它不需要在任何人的执行路径中,但应该对全世界可见。程序应该准备好进行 ~ 扩展。标准发行版不会将任何内容放在此目录中。在安装 perl 后,用户可以使用以下命令在此目录中安装自己的本地架构无关模块:

MakeMaker Makefile.PL

或等效项。有关详细信息,请参见 INSTALL

SITELIB_EXP

此符号包含 SITELIB 的 ~name 扩展版本,用于在运行时不准备处理 ~ 扩展的程序中。

SITELIB_STEM

此定义是 SITELIB_EXP,去掉了任何尾随的版本特定组件。inc_version_listinc_version_list.U(metaconfig 的一部分))中的元素可以附加到此变量上,以生成要搜索的目录列表。

STARTPERL

此变量包含要放在 perl 脚本前面的字符串,以确保(希望)它使用 perl 而不是 shell 运行。

USE_64_BIT_ALL

如果定义了此符号,则表示在可用时应使用 64 位整数。如果未定义,则将使用本机整数(无论是 32 位还是 64 位)。采用最大可能的 64 位:LP64 或 ILP64,这意味着您可以使用超过 2 GB 的内存。此模式比 USE_64_BIT_INT 更不兼容二进制。您可能根本无法在 32 位 CPU 中运行生成的执行文件,或者您可能至少需要将操作系统重新启动到 64 位模式。

USE_64_BIT_INT

如果定义了此符号,则表示在可用时应使用 64 位整数。如果未定义,则将使用本机整数(无论是 32 位还是 64 位)。使用最小可能的 64 位,足以将 64 位整数引入 Perl。这可能意味着使用例如“长长”,而您的内存可能仍然限制在 2 GB。

USE_BSD_GETPGRP

如果定义了此符号,则表示 getpgrp 需要一个参数,而 USG 需要零个参数。

USE_BSD_SETPGRP

如果定义了此符号,则表示 setpgrp 需要两个参数,而 USG 需要零个参数。另请参见 "HAS_SETPGID" 以获取 POSIX 接口。

USE_C_BACKTRACE

如果定义了此符号,则表示 Perl 应该构建为支持回溯。

USE_CPLUSPLUS

如果定义了此符号,则表示使用 C++ 编译器编译 Perl,并将用于编译扩展。

USE_CROSS_COMPILE

如果定义了此符号,则表示 Perl 正在进行交叉编译。

USE_DTRACE

如果定义了此符号,则表示 Perl 应该构建为支持 DTrace。

USE_DYNAMIC_LOADING

如果定义了此符号,则表示某种形式的动态加载可用。

USE_FAST_STDIO

如果定义了此符号,则表示 Perl 应该构建为使用“快速 stdio”。在 Perl 5.8 及更早版本中默认定义,在之后的版本中默认取消定义。

USE_ITHREADS

如果定义了此符号,则表示 Perl 应该构建为使用基于解释器的线程实现。

USE_KERN_PROC_PATHNAME

如果定义了此符号,则表示我们可以使用带有 KERN_PROC_PATHNAME 的 sysctl 获取可执行文件的完整路径,从而将 $^X 转换为绝对路径。

USE_LARGE_FILES

如果定义了此符号,则表示在可用时应使用大文件支持。

USE_LONG_DOUBLE

如果定义了此符号,则表示在可用时应使用长双精度。

USE_MORE_BITS

如果定义了此符号,则表示在可用时应使用 64 位接口和长双精度。

USE_NSGETEXECUTABLEPATH

如果定义了此符号,则表示我们可以使用 _NSGetExecutablePath 和 realpath 获取可执行文件的完整路径,从而将 $^X 转换为绝对路径。

USE_PERLIO

如果定义了此符号,则表示应在整个过程中使用 PerlIO 抽象。如果未定义,则应以完全向后兼容的方式使用 stdio。

USE_QUADMATH

如果定义了此符号,则表示在可用时应使用 quadmath 库。

USE_REENTRANT_API

如果定义了此符号,则表示 Perl 应该尝试使用各种库函数的 _r 版本。这属于极度实验性功能。

USE_SEMCTL_SEMID_DS

如果定义了此符号,则表示 struct semid_ds * 用于 semctl IPC_STAT

USE_SEMCTL_SEMUN

如果定义了此符号,则表示 union semun 用于 semctl IPC_STAT

USE_SITECUSTOMIZE

如果定义了此符号,则表示应该使用 sitecustomize。

USE_SOCKS

如果定义了此符号,则表示 Perl 应该构建为使用 socks。

USE_STAT_BLOCKS

如果此系统具有声明 st_blksizest_blocks 的 stat 结构,则定义此符号。

USE_STDIO_BASE

如果 stdio FILE 结构的 _base 字段(或类似字段)可用于访问文件句柄的 stdio 缓冲区,则定义此符号。如果定义了此符号,则 FILE_base(fp) 宏也将被定义,应该使用它来访问此字段。此外,FILE_bufsiz(fp) 宏也将被定义,应该使用它来确定缓冲区中的字节数。除非 USE_STDIO_PTR 已定义,否则 USE_STDIO_BASE 永远不会被定义。

USE_STDIO_PTR

如果 stdio FILE 结构的 _ptr_cnt 字段(或类似字段)可用于访问文件句柄的 stdio 缓冲区,则定义此符号。如果定义了此符号,则 FILE_ptr(fp)FILE_cnt(fp) 宏也将被定义,应该使用它们来访问这些字段。

USE_STRICT_BY_DEFAULT

如果定义了此符号,则启用其他默认值。目前,它仅默认启用隐式严格模式。

USE_THREADS

如果定义了此符号,则表示 Perl 应该构建为使用线程。目前,它与 USE_ITHREADS 是同义词,但最终源代码应该更改为使用它来表示 _any_ 线程实现。

套接字配置值

HAS_SOCKADDR_IN6

如果定义了此符号,则表示 struct sockaddr_in6 可用;

HAS_SOCKADDR_SA_LEN

如果定义了此符号,则表示 struct sockaddr 结构体包含名为 sa_len 的成员,用于指示结构体的长度。

HAS_SOCKADDR_STORAGE

如果定义了此符号,则表示 struct sockaddr_storage 可用。

HAS_SOCKATMARK

如果定义了此符号,则表示 sockatmark 函数可用,用于测试套接字是否处于带外标记。

HAS_SOCKET

如果定义了此符号,则表示支持 BSD socket 接口。

HAS_SOCKETPAIR

如果定义了此符号,则表示支持 BSD socketpair() 调用。

HAS_SOCKS5_INIT

如果定义了此符号,则表示 socks5_init 函数可用,用于初始化 SOCKS 5。

I_SOCKS

如果定义了此符号,则表示 socks.h 存在,应该包含它。

    #ifdef I_SOCKS
        #include <socks.h>
    #endif
I_SYS_SOCKIO

如果定义了此符号,则表示应该包含 sys/sockio.h,以获取套接字 ioctl 选项,例如 SIOCATMARK

    #ifdef I_SYS_SOCKIO
        #include <sys_sockio.h>
    #endif

源过滤器

apply_builtin_cv_attributes

给定一个包含属性定义的 OP_LIST,对其进行过滤,以查找已知的内置属性,并将这些属性应用于 cv,返回一个可能更小的列表,其中只包含剩余的属性。

    OP *  apply_builtin_cv_attributes(CV *cv, OP *attrlist)
filter_add

perlfilter 中描述。

    SV *  filter_add(filter_t funcp, SV *datasv)
filter_del

删除最近添加的过滤器函数参数实例。

    void  filter_del(filter_t funcp)
filter_read

perlfilter 中描述。

    I32  filter_read(int idx, SV *buf_sv, int maxlen)
scan_vstring

返回解析后的 vstring 之后下一个字符的指针,并更新传入的 sv。

函数必须像这样调用

sv = sv_2mortal(newSV(5));
s = scan_vstring(s,e,sv);

其中 s 和 e 是字符串的开始和结束。为了性能原因,sv 应该已经足够大,可以存储传入的 vstring。

如果在调用范围内启用了致命警告,则此函数可能会 croak,因此示例中使用了 sv_2mortal(以防止泄漏)。如果使用 sv_2mortal,请确保之后执行 SvREFCNT_inc。

    char *  scan_vstring(const char *s, const char * const e, SV *sv)
start_subparse

设置解析子程序的准备工作。

如果 is_format 非零,则输入将被视为格式子程序(用于实现 perl 的 format 功能的专用子程序);否则为普通 sub

flags 将添加到 PL_compcv 的标志中。flags 可能包含 CVf_IsMETHOD 位,这会导致新子程序成为方法。

此函数返回进入函数时生效的 PL_savestack_ix 值;

    I32  start_subparse(I32 is_format, U32 flags)

堆栈操作宏

dMARK

为 XSUB 声明一个堆栈标记变量 mark。参见 "MARK""dORIGMARK"

    dMARK;
dORIGMARK

保存 XSUB 的原始堆栈标记。参见 "ORIGMARK"

    dORIGMARK;
dSP

为 XSUB 声明一个 Perl 堆栈指针的本地副本,可以通过 SP 宏访问。参见 "SP"

    dSP;
dTARGET

声明此函数使用 TARG,并初始化它。

    dTARGET;
EXTEND

用于扩展 XSUB 返回值的参数堆栈。一旦使用,保证堆栈至少有空间可以推送 nitems 个元素。

    void  EXTEND(SP, SSize_t nitems)
MARK

XSUB 的堆栈标记变量。参见 "dMARK"

mPUSHi

将一个整数推入堆栈。堆栈必须有空间容纳此元素。不使用 TARG。另见 "PUSHi""mXPUSHi""XPUSHi"

    void  mPUSHi(IV iv)
mPUSHn

将一个双精度数推入堆栈。堆栈必须有空间容纳此元素。不使用 TARG。另见 "PUSHn""mXPUSHn""XPUSHn"

    void  mPUSHn(NV nv)
mPUSHp

将一个字符串推入堆栈。堆栈必须有空间容纳此元素。len 指示字符串的长度。不使用 TARG。另见 "PUSHp""mXPUSHp""XPUSHp"

    void  mPUSHp(char* str, STRLEN len)
mPUSHpvs

mPUSHp 的变体,它接受一个文字字符串并直接计算其大小。

    void  mPUSHpvs("literal string")
mPUSHs

将一个 SV 推入堆栈并使 SV 成为临时的。堆栈必须有空间容纳此元素。不使用 TARG。另见 "PUSHs""mXPUSHs"

    void  mPUSHs(SV* sv)
mPUSHu

将一个无符号整数推入堆栈。堆栈必须有空间容纳此元素。不使用 TARG。另见 "PUSHu""mXPUSHu""XPUSHu"

    void  mPUSHu(UV uv)
mXPUSHi

将一个整数压入堆栈,如果需要则扩展堆栈。不使用 TARG。另请参见 "XPUSHi""mPUSHi""PUSHi"

    void  mXPUSHi(IV iv)
mXPUSHn

将一个双精度浮点数压入堆栈,如果需要则扩展堆栈。不使用 TARG。另请参见 "XPUSHn""mPUSHn""PUSHn"

    void  mXPUSHn(NV nv)
mXPUSHp

将一个字符串压入堆栈,如果需要则扩展堆栈。len 指示字符串的长度。不使用 TARG。另请参见 "XPUSHp"mPUSHpPUSHp

    void  mXPUSHp(char* str, STRLEN len)
mXPUSHpvs

mXPUSHp 的变体,它接受一个字面字符串并直接计算其大小。

    void  mXPUSHpvs("literal string")
mXPUSHs

将一个 SV 压入堆栈,如果需要则扩展堆栈并使 SV 永久化。不使用 TARG。另请参见 "XPUSHs""mPUSHs"

    void  mXPUSHs(SV* sv)
mXPUSHu

将一个无符号整数压入堆栈,如果需要则扩展堆栈。不使用 TARG。另请参见 "XPUSHu""mPUSHu""PUSHu"

    void  mXPUSHu(UV uv)
newXSproto

xsubpp 用于将 XSUB 连接为 Perl 子例程。为子例程添加 Perl 原型。

ORIGMARK

XSUB 的原始堆栈标记。参见 "dORIGMARK"

PL_markstack

perlguts 中描述。

PL_markstack_ptr

perlguts 中描述。

PL_savestack

perlguts 中描述。

PL_savestack_ix

perlguts 中描述。

PL_scopestack

perlguts 中描述。

PL_scopestack_ix

perlguts 中描述。

PL_scopestack_name

perlguts 中描述。

PL_stack_base

perlguts 中描述。

PL_stack_sp

perlguts 中描述。

PL_tmps_floor

perlguts 中描述。

PL_tmps_ix

perlguts 中描述。

PL_tmps_stack

perlguts 中描述。

POPi

从堆栈中弹出整数。

    IV  POPi
POPl

从堆栈中弹出长整型。

    long  POPl
POPn

从堆栈中弹出双精度浮点数。

    NV  POPn
POPp

从堆栈中弹出字符串。

    char*  POPp
POPpbytex

从堆栈中弹出字符串,该字符串必须由字节组成,即字符 < 256。

    char*  POPpbytex
POPpx

从堆栈中弹出字符串。与 POPp 相同。有两个名称是出于历史原因。

    char*  POPpx
POPs

从堆栈中弹出 SV。

    SV*  POPs
POPu

从堆栈中弹出无符号整数。

    UV  POPu
POPul

从堆栈中弹出无符号长整型。

    long  POPul
PUSHi

将整数推入堆栈。堆栈必须有空间容纳此元素。处理“set”魔法。使用 TARG,因此应调用 dTARGETdXSTARG 来声明它。不要调用多个 TARG 导向的宏来从 XSUB 返回列表 - 请改用 "mPUSHi"。另请参见 "XPUSHi""mXPUSHi"

    void  PUSHi(IV iv)
PUSHMARK

回调上参数的左括号。参见 "PUTBACK"perlcall.

    void  PUSHMARK(SP)
PUSHmortal

将新的 mortal SV 推入堆栈。堆栈必须有空间容纳此元素。不使用 TARG。另请参见 "PUSHs""XPUSHmortal""XPUSHs"

    void  PUSHmortal
PUSHn

将双精度浮点数推入堆栈。堆栈必须有空间容纳此元素。处理“set”魔法。使用 TARG,因此应调用 dTARGETdXSTARG 来声明它。不要调用多个 TARG 导向的宏来从 XSUB 返回列表 - 请改用 "mPUSHn"。另请参见 "XPUSHn""mXPUSHn"

    void  PUSHn(NV nv)
PUSHp

将字符串推入堆栈。堆栈必须有空间容纳此元素。len 指示字符串的长度。处理“set”魔法。使用 TARG,因此应调用 dTARGETdXSTARG 来声明它。不要调用多个 TARG 导向的宏来从 XSUB 返回列表 - 请改用 "mPUSHp"。另请参见 "XPUSHp""mXPUSHp"

    void  PUSHp(char* str, STRLEN len)
PUSHpvs

PUSHp 的变体,它接受一个文字字符串并直接计算其大小。

    void  PUSHpvs("literal string")
PUSHs

将一个 SV 推入栈中。栈必须有空间容纳此元素。不处理“set”魔法。不使用TARG。另请参见"PUSHmortal""XPUSHs""XPUSHmortal"

    void  PUSHs(SV* sv)
PUSHu

将一个无符号整数推入栈中。栈必须有空间容纳此元素。处理“set”魔法。使用TARG,因此应调用dTARGETdXSTARG 来声明它。不要调用多个TARG 方向宏来从 XSUB 中返回列表 - 请改用"mPUSHu"。另请参见"XPUSHu""mXPUSHu"

    void  PUSHu(UV uv)
PUTBACK

XSUB 参数的结束括号。这通常由xsubpp 处理。有关其他用途,请参见"PUSHMARK"perlcall

    PUTBACK;
SAVEt_INT

perlguts 中描述。

SP

栈指针。这通常由xsubpp 处理。请参见"dSP"SPAGAIN

SPAGAIN

重新获取栈指针。在回调后使用。请参见 perlcall

    SPAGAIN;
SSNEW
SSNEWa
SSNEWat
SSNEWt

这些在 savestack 上临时分配数据,返回一个 SSize_t 索引到 savestack 中,因为如果 savestack 在重新分配时移动,指针将被破坏。使用 "SSPTR" 将返回的索引转换为指针。

这些形式的不同之处在于,普通的SSNEW 分配size 字节;SSNEWtSSNEWat 分配size 个对象,每个对象都是type 类型;而 <SSNEWa> 和 SSNEWat 确保将新数据对齐到align 边界。对齐的最有用值可能是 "MEM_ALIGNBYTES"。对齐将仅在 realloc 返回对齐到可被“align”整除的大小的数据时,才能通过 savestack 重新分配来保留!

    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)
SSPTR
SSPTRt

这些将 L/<SSNEW> 及其同类返回的index 转换为实际指针。

不同之处在于,SSPTR 将结果强制转换为type,而 SSPTRt 将其强制转换为该type 的指针。

    type    SSPTR (SSize_t index, type)
    type *  SSPTRt(SSize_t index, type)
TARG

TARG 是“target”的缩写。它是 pad 中的一个条目,OP 的op_targ 指向它。它是临时空间,通常用作 OP 的返回值,但有些将其用于其他目的。

    TARG;
TOPs

perlguts 中描述。

XPUSHi

将一个整数压入堆栈,如果需要则扩展堆栈。处理“set”魔法。使用TARG,因此应调用dTARGETdXSTARG来声明它。不要调用多个面向TARG的宏来从 XSUB 返回列表 - 请改用"mXPUSHi"。另请参见"PUSHi""mPUSHi"

    void  XPUSHi(IV iv)
XPUSHmortal

将一个新的 mortal SV 压入堆栈,如果需要则扩展堆栈。不使用TARG。另请参见"XPUSHs""PUSHmortal""PUSHs"

    void  XPUSHmortal
XPUSHn

将一个双精度浮点数压入堆栈,如果需要则扩展堆栈。处理“set”魔法。使用TARG,因此应调用dTARGETdXSTARG来声明它。不要调用多个面向TARG的宏来从 XSUB 返回列表 - 请改用"mXPUSHn"。另请参见"PUSHn""mPUSHn"

    void  XPUSHn(NV nv)
XPUSHp

将一个字符串压入堆栈,如果需要则扩展堆栈。len表示字符串的长度。处理“set”魔法。使用TARG,因此应调用dTARGETdXSTARG来声明它。不要调用多个面向TARG的宏来从 XSUB 返回列表 - 请改用"mXPUSHp"。另请参见"PUSHp""mPUSHp"

    void  XPUSHp(char* str, STRLEN len)
XPUSHpvs

XPUSHp的一个变体,它接受一个字面字符串并直接计算其大小。

    void  XPUSHpvs("literal string")
XPUSHs

将一个 SV 压入堆栈,如果需要则扩展堆栈。不处理“set”魔法。不使用TARG。另请参见"XPUSHmortal"PUSHsPUSHmortal

    void  XPUSHs(SV* sv)
XPUSHu

将一个无符号整数压入堆栈,如果需要则扩展堆栈。处理“set”魔法。使用TARG,因此应调用dTARGETdXSTARG来声明它。不要调用多个面向TARG的宏来从 XSUB 返回列表 - 请改用"mXPUSHu"。另请参见"PUSHu""mPUSHu"

    void  XPUSHu(UV uv)
XS_APIVERSION_BOOTCHECK

宏,用于验证 XS 模块编译时使用的 Perl API 版本是否与加载它的 Perl 解释器的 API 版本匹配。

    XS_APIVERSION_BOOTCHECK;
XSRETURN

从 XSUB 返回,指示堆栈上的项目数量。这通常由xsubpp处理。

    void  XSRETURN(int nitems)
XSRETURN_EMPTY

立即从 XSUB 返回一个空列表。

    XSRETURN_EMPTY;
XSRETURN_IV

从 XSUB 中立即返回一个整数。使用 XST_mIV

    void  XSRETURN_IV(IV iv)
XSRETURN_NO

从 XSUB 中立即返回 &PL_sv_no。使用 XST_mNO

    XSRETURN_NO;
XSRETURN_NV

从 XSUB 中立即返回一个双精度浮点数。使用 XST_mNV

    void  XSRETURN_NV(NV nv)
XSRETURN_PV

从 XSUB 中立即返回一个字符串的副本。使用 XST_mPV

    void  XSRETURN_PV(char* str)
XSRETURN_UNDEF

从 XSUB 中立即返回 &PL_sv_undef。使用 XST_mUNDEF

    XSRETURN_UNDEF;
XSRETURN_UV

从 XSUB 中立即返回一个整数。使用 XST_mUV

    void  XSRETURN_UV(IV uv)
XSRETURN_YES

从 XSUB 中立即返回 &PL_sv_yes。使用 XST_mYES

    XSRETURN_YES;
XST_mIV

将一个整数放置到堆栈上的指定位置 pos。该值存储在一个新的 mortal SV 中。

    void  XST_mIV(int pos, IV iv)
XST_mNO

&PL_sv_no 放置到堆栈上的指定位置 pos

    void  XST_mNO(int pos)
XST_mNV

将一个双精度浮点数放置到堆栈上的指定位置 pos。该值存储在一个新的 mortal SV 中。

    void  XST_mNV(int pos, NV nv)
XST_mPV

将一个字符串的副本放置到堆栈上的指定位置 pos。该值存储在一个新的 mortal SV 中。

    void  XST_mPV(int pos, char* str)
XST_mUNDEF

&PL_sv_undef 放置到堆栈上的指定位置 pos

    void  XST_mUNDEF(int pos)
XST_mUV

将一个无符号整数放置到堆栈上的指定位置 pos。该值存储在一个新的 mortal SV 中。

    void  XST_mUV(int pos, UV uv)
XST_mYES

&PL_sv_yes 放置到堆栈上的指定位置 pos

    void  XST_mYES(int pos)
XS_VERSION

XS 模块的版本标识符。这通常由 ExtUtils::MakeMaker 自动处理。参见 "XS_VERSION_BOOTCHECK"

XS_VERSION_BOOTCHECK

宏,用于验证 PM 模块的 $VERSION 变量是否与 XS 模块的 XS_VERSION 变量匹配。这通常由 xsubpp 自动处理。参见 "perlxs 中的 VERSIONCHECK: 关键字".

    XS_VERSION_BOOTCHECK;

字符串处理

另请参阅 "Unicode 支持"

CAT2

此宏将两个标记连接在一起。

    token  CAT2(token x, token y)
Copy
CopyD

XSUB 编写器对 C memcpy 函数的接口。src 是源,dest 是目标,nitems 是项目数量,type 是类型。可能在重叠复制时失败。另请参阅 "Move"

CopyDCopy 相似,但返回 dest。这对于鼓励编译器进行尾调用优化很有用。

    void    Copy (void* src, void* dest, int nitems, type)
    void *  CopyD(void* src, void* dest, int nitems, type)
delimcpy

将源缓冲区复制到目标缓冲区,在源中第一个未转义(定义如下)的分隔符字节 delim 处停止(但不包括)。源是 fromfrom_end - 1 之间的字节。类似地,目标是 toto_end

复制的字节数写入 *retlen

返回 from 缓冲区中第一个未复制的 delim 的位置,但如果在 from_end 之前没有这样的出现,则返回 from_end,并且整个缓冲区 from .. from_end - 1 被复制。

如果在复制后目标缓冲区中还有空间,则会附加一个额外的终止安全 NUL 字节(不包含在返回的长度中)。

错误情况是目标缓冲区不足以容纳所有应该复制的内容。在这种情况下,一个大于 to_end - to 的值将写入 *retlen,并且尽可能多的源将被写入目标。没有足够的空间容纳安全 NUL 不被视为错误。

在以下示例中,令 x 为分隔符,0 代表 NUL 字节(不是数字 0)。然后我们将有

 Source     Destination
abcxdef        abc0

前提是目标缓冲区至少有 4 个字节长。

转义的分隔符是指紧接其前有一个反斜杠的分隔符。转义的分隔符会被复制,并且复制会继续到分隔符之后;反斜杠不会被复制

 Source       Destination
abc\xdef       abcxdef0

(前提是目标缓冲区至少有 8 个字节长)。

实际上,这比这要复杂一些。任何奇数个反斜杠的序列都会转义后面的分隔符,并且复制将继续,只删除一个反斜杠。

    Source         Destination
    abc\xdef          abcxdef0
  abc\\\xdef        abc\\xdef0
abc\\\\\xdef      abc\\\\xdef0

(如常,如果目标足够大)

偶数个前面的反斜杠不会转义分隔符,因此复制在分隔符之前停止,并且包含所有反斜杠(不删除;零被认为是偶数)

    Source         Destination
    abcxdef          abc0
  abc\\xdef          abc\\0
abc\\\\xdef          abc\\\\0
    char *  delimcpy(char *to, const char *to_end, const char *from,
                     const char *from_end, const int delim,
                     I32 *retlen)
do_join

这执行一个 Perl join,将连接后的输出放入 sv 中。

要连接的元素在 SV 中,存储在指向 SV 的 C 指针数组中,从 **mark**sp - 1。因此 *mark 是对第一个 SV 的引用。每个 SV 如果不是 PV,将被强制转换为 PV。

delim 包含要分隔每个连接元素的字符串(或强制转换为字符串)。

如果任何组件是 UTF-8,结果也将是 UTF-8,并且所有非 UTF-8 组件将根据需要转换为 UTF-8。

处理魔法和污染。

    void  do_join(SV *sv, SV *delim, SV **mark, SV **sp)
do_sprintf

这执行一个 Perl sprintf,将字符串输出放入 sv 中。

要格式化的元素在 SV 中,存储在长度为 len> 且从 **sarg 开始的指向 SV 的 C 指针数组中。*sarg 引用的元素是格式。

处理魔法和污染。

    void  do_sprintf(SV *sv, SSize_t len, SV **sarg)
fbm_compile

分析字符串以使用 fbm_instr()(Boyer-Moore 算法)对其进行快速搜索。

    void  fbm_compile(SV *sv, U32 flags)
fbm_instr

返回字符串中由 bigbigend 分隔的 SV 的位置(bigend 是最后一个字符之后的字符)。如果找不到字符串,则返回 NULLsv 不必是 fbm_compiled,但搜索速度不会那么快。

    char *  fbm_instr(unsigned char *big, unsigned char *bigend,
                      SV *littlestr, U32 flags)
foldEQ

如果字符串 s1s2 的前 len 个字节在不区分大小写的情况下相同,则返回 true;否则返回 false。大写和小写 ASCII 范围字节匹配自身及其相反情况的对应字节。非大小写和非 ASCII 范围字节仅匹配自身。

    I32  foldEQ(const char *a, const char *b, I32 len)
ibcmp

这是 (! foldEQ()) 的同义词

    I32  ibcmp(const char *a, const char *b, I32 len)
ibcmp_locale

这是 (! foldEQ_locale()) 的同义词

    I32  ibcmp_locale(const char *a, const char *b, I32 len)
ibcmp_utf8

这是 (! foldEQ_utf8()) 的同义词。

    I32  ibcmp_utf8(const char *s1, char **pe1, UV l1, bool u1,
                    const char *s2, char **pe2, UV l2, bool u2)
instr

strstr(3) 相同,它查找并返回在以 NUL 结尾的字符串 big 中第一个出现的以 NUL 结尾的子字符串 little 的指针,如果未找到则返回 NULL。 终止的 NUL 字节不会被比较。

    char *  instr(const char *big, const char *little)
memCHRs

返回字节 c 在字面字符串 "list" 中第一次出现的 位置,如果 c 不出现在 "list" 中,则返回 NULL。 所有字节都被视为无符号字符。 因此,此宏可用于确定 c 是否在一组特定字符中。 与 strchr(3) 不同,即使 cNUL(并且集合不包含 NUL),它也能正常工作。

    bool  memCHRs("list", char c)
memEQ

测试两个缓冲区(可能包含嵌入的 NUL 字符),以查看它们是否相等。 len 参数指示要比较的字节数。 返回真或假。 如果两个缓冲区中任何一个都不包含至少 len 个字节,则行为未定义。

    bool  memEQ(char* s1, char* s2, STRLEN len)
memEQs

"memEQ" 相同,但第二个字符串是包含在双引号中的字面量,l1 给出 s1 中的字节数。 返回真或假。

    bool  memEQs(char* s1, STRLEN l1, "s2")
memNE

测试两个缓冲区(可能包含嵌入的 NUL 字符),以查看它们是否不相等。 len 参数指示要比较的字节数。 返回真或假。 如果两个缓冲区中任何一个都不包含至少 len 个字节,则行为未定义。

    bool  memNE(char* s1, char* s2, STRLEN len)
memNEs

"memNE" 相同,但第二个字符串是包含在双引号中的字面量,l1 给出 s1 中的字节数。 返回真或假。

    bool  memNEs(char* s1, STRLEN l1, "s2")
Move
MoveD

XSUB 编写器对 C memmove 函数的接口。 src 是源,dest 是目标,nitems 是项目数,type 是类型。 可以进行重叠移动。 另见 "Copy"

MoveD 类似于 Move,但返回 dest。这有助于鼓励编译器进行尾调用优化。

    void    Move (void* src, void* dest, int nitems, type)
    void *  MoveD(void* src, void* dest, int nitems, type)
my_snprintf

如果可用且符合标准(实际上使用 vsnprintf),则使用 C 库 snprintf 功能。但是,如果 vsnprintf 不可用,则不幸的是将使用不安全的 vsprintf,它可能会导致缓冲区溢出(存在溢出检查,但这可能为时已晚)。考虑改用 sv_vcatpvf,或获取 vsnprintf

    int  my_snprintf(char *buffer, const Size_t len,
                     const char *format, ...)
my_sprintf

已弃用! 计划从 Perl 的未来版本中删除 my_sprintf。不要在新代码中使用它;从现有代码中删除它。

由于可能溢出 buffer,请不要使用它。请改用 my_snprintf()

    int  my_sprintf(NN char *buffer, NN const char *pat, ...)
my_strnlen

如果可用,则使用 C 库 strnlen,否则使用 Perl 的实现。

my_strnlen() 计算字符串的长度,最多 maxlen 个字符。它永远不会尝试访问超过 maxlen 个字符,使其适合用于不保证以 NUL 结尾的字符串。

    Size_t  my_strnlen(const char *str, Size_t maxlen)
my_vsnprintf

如果可用且符合标准,则使用 C 库 vsnprintf。但是,如果 vsnprintf 不可用,则不幸的是将使用不安全的 vsprintf,它可能会导致缓冲区溢出(存在溢出检查,但这可能为时已晚)。考虑改用 sv_vcatpvf,或获取 vsnprintf

    int  my_vsnprintf(char *buffer, const Size_t len,
                      const char *format, va_list ap)
NewCopy

将 Newx() 和 Copy() 合并到一个宏中。Dest 将使用 Newx() 分配,然后将 src 复制到其中。

    void  NewCopy(void* src, void* dest, int nitems, type)
ninstr

在另一个序列中查找字节序列的第一个(最左侧)出现位置。这是 strstr() 的 Perl 版本,扩展为处理任意序列,可能包含嵌入的 NUL 字符(NUL 是函数名称中初始 n 所代表的;某些系统具有等效的 memmem(),但具有略微不同的 API)。

另一种理解此函数的方法是在干草堆中查找一根针。big 指向干草堆中的第一个字节。big_end 指向干草堆中最后一个字节之后的字节。little 指向针中的第一个字节。little_end 指向针中最后一个字节之后的字节。所有参数都必须是非 NULL

如果 big 中没有出现 little,则该函数返回 NULL。如果 little 是空字符串,则返回 big

由于此函数在字节级别运行,并且由于 UTF-8(或 UTF-EBCDIC)的固有特性,如果针和干草堆都是具有相同 UTF-8 性质的字符串,它将正常工作,但如果 UTF-8 性质不同,则不会正常工作。

    char *  ninstr(const char *big, const char *bigend,
                   const char *little, const char *lend)
Nullch

空字符指针。(当定义了 PERL_CORE 时不再可用。)

PL_na

一个用于存储STRLEN值的临时变量。如果命名为PL_temp_strlen会更好。

它通常与SvPV一起使用,当实际上计划丢弃返回的长度时(因此长度为“不适用”,这就是该变量名称的由来)。

但请注意,如果在使用它的某个东西位于使用它的另一个东西的调用栈中的情况下使用它,这个变量会被清除,导致难以诊断的错误。

通常更有效的方法是声明一个局部变量并使用它,或者使用SvPV_nolen宏。

    STRLEN  PL_na
rninstr

类似于"ninstr",但它查找另一个序列中字节序列的最后一个(最右边)出现位置,如果不存在这样的出现位置,则返回NULL

    char *  rninstr(const char *big, const char *bigend,
                    const char *little, const char *lend)
savepv

Perl 版本的strdup()。返回指向新分配的字符串的指针,该字符串是pv的副本。字符串的大小由strlen()确定,这意味着它可能不包含嵌入的NUL字符,并且必须有一个尾随的NUL。为了防止内存泄漏,需要在不再需要时释放为新字符串分配的内存。这可以通过"Safefree"函数或SAVEFREEPV来完成。

在某些平台(例如 Windows)上,当线程结束时,会释放线程拥有的所有分配的内存。因此,如果您需要防止这种情况发生,则需要使用共享内存函数,例如"savesharedpv"

    char *  savepv(const char *pv)
savepvn

Perl 版本的strndup()(如果存在)。返回指向新分配的字符串的指针,该字符串是pv中前len个字节的副本,加上一个尾随的NUL字节。可以使用Safefree()函数释放为新字符串分配的内存。

在某些平台(例如 Windows)上,当线程结束时,会释放线程拥有的所有分配的内存。因此,如果您需要防止这种情况发生,则需要使用共享内存函数,例如"savesharedpvn"

    char *  savepvn(const char *pv, Size_t len)
savepvs

类似于savepvn,但它接受一个文字字符串而不是字符串/长度对。

    char*  savepvs("literal string")
savesharedpv

savepv()的版本,它在线程之间共享的内存中分配副本字符串。

    char *  savesharedpv(const char *pv)
savesharedpvn

savepvn() 的一个版本,它在内存中分配共享线程的重复字符串。(与特定区别在于 NULL 指针是不可接受的)

    char *  savesharedpvn(const char * const pv, const STRLEN len)
savesharedpvs

savepvs() 的一个版本,它在内存中分配共享线程的重复字符串。

    char*  savesharedpvs("literal string")
savesharedsvpv

savesharedpv() 的一个版本,它在内存中分配共享线程的重复字符串。

    char *  savesharedsvpv(SV *sv)
savesvpv

savepv()/savepvn() 的一个版本,它使用 SvPV() 从传入的 SV 获取要复制的字符串。

在某些平台上,例如 Windows,当线程结束时,线程拥有的所有分配的内存都会被释放。因此,如果您需要避免这种情况,则需要使用共享内存函数,例如 "savesharedsvpv"

    char *  savesvpv(SV *sv)
strEQ

测试两个以 NUL 结尾的字符串是否相等。返回真或假。

    bool  strEQ(char* s1, char* s2)
strGE

测试两个以 NUL 结尾的字符串,以查看第一个 s1 是否大于或等于第二个 s2。返回真或假。

    bool  strGE(char* s1, char* s2)
strGT

测试两个以 NUL 结尾的字符串,以查看第一个 s1 是否大于第二个 s2。返回真或假。

    bool  strGT(char* s1, char* s2)
STRINGIFY

此宏用双引号包围其标记。

    string  STRINGIFY(token x)
strLE

测试两个以 NUL 结尾的字符串,以查看第一个 s1 是否小于或等于第二个 s2。返回真或假。

    bool  strLE(char* s1, char* s2)
STRLEN

perlguts 中描述。

strLT

测试两个以 NUL 结尾的字符串,以查看第一个 s1 是否小于第二个 s2。返回真或假。

    bool  strLT(char* s1, char* s2)
strNE

测试两个以 NUL 结尾的字符串是否不同。返回真或假。

    bool  strNE(char* s1, char* s2)
strnEQ

测试两个以 NUL 结尾的字符串是否相等。len 参数指示要比较的字节数。返回真或假。(strncmp 的包装器)。

    bool  strnEQ(char* s1, char* s2, STRLEN len)
strnNE

测试两个以 NUL 结尾的字符串是否不同。len 参数指示要比较的字节数。返回真或假。(strncmp 的包装器)。

    bool  strnNE(char* s1, char* s2, STRLEN len)
STR_WITH_LEN

返回输入字面字符串的两个逗号分隔的标记及其长度。这是一个方便的宏,有助于某些 API 调用。请注意,它不能用作宏或函数的参数,这些宏或函数在某些配置下可能是宏,这意味着它需要完整的 Perl_xxx(aTHX_ ...) 形式,用于任何使用它的 API 调用。

    pair  STR_WITH_LEN("literal string")
Zero
ZeroD

XSUB 编写者对 C memzero 函数的接口。dest 是目标,nitems 是项目数,type 是类型。

ZeroDZero 相似,但返回 dest。这对于鼓励编译器进行尾调用优化很有用。

    void    Zero (void* dest, int nitems, type)
    void *  ZeroD(void* dest, int nitems, type)

SV 标志

SVt_IV

标量的类型标志。请参阅 "svtype"

SVt_NULL

标量的类型标志。请参阅 "svtype"

SVt_NV

标量的类型标志。请参阅 "svtype"

SVt_PV

标量的类型标志。请参阅 "svtype"

SVt_PVAV

数组的类型标志。请参阅 "svtype"

SVt_PVCV

子例程的类型标志。请参阅 "svtype"

SVt_PVFM

格式的类型标志。请参阅 "svtype"

SVt_PVGV

类型全局变量的类型标志。请参阅 "svtype"

SVt_PVHV

哈希的类型标志。请参阅 "svtype"

SVt_PVIO

I/O 对象的类型标志。请参阅 "svtype"

SVt_PVIV

标量的类型标志。请参阅 "svtype"

SVt_PVLV

标量的类型标志。请参阅 "svtype"

SVt_PVMG

标量的类型标志。请参阅 "svtype"

SVt_PVNV

标量的类型标志。请参阅 "svtype"

SVt_PVOBJ

注意:SVt_PVOBJ实验性的,可能会在未经通知的情况下更改或删除。

对象实例的类型标志。请参阅 "svtype"

SVt_REGEXP

正则表达式的类型标志。请参阅 "svtype"

svtype

Perl 类型标志的枚举。这些标志在文件 sv.h 中的 svtype 枚举中定义。可以使用 SvTYPE 宏测试这些标志。

这些类型是:

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

最容易从下往上解释。

SVt_PVOBJ 用于新 use feature 'class' 类型的对象实例。SVt_PVIO 用于 I/O 对象,SVt_PVFM 用于格式,SVt_PVCV 用于子程序,SVt_PVHV 用于哈希,SVt_PVAV 用于数组。

所有其他类型都是标量类型,也就是说,可以绑定到 $ 变量的类型。对于这些类型,内部类型大多与 Perl 语言中的类型正交。

因此,检查 SvTYPE(sv) < SVt_PVAV 是判断某个东西是否是标量的最佳方法。

SVt_PVGV 表示一个类型全局变量。如果 !SvFAKE(sv),则它是一个真正的、不可强制转换的类型全局变量。如果 SvFAKE(sv),则它是一个已分配类型全局变量的标量。再次对其赋值将使其不再是类型全局变量。SVt_PVLV 表示一个在幕后委托给另一个标量的标量。它用于例如 substr 的返回值以及绑定哈希和数组元素。它可以保存任何标量值,包括类型全局变量。SVt_REGEXP 用于正则表达式。SVt_INVLIST 仅供 Perl 核心内部使用。

SVt_PVMG 表示一个“普通”标量(不是类型全局变量、正则表达式或委托)。由于大多数标量不需要 PVMG 的所有内部字段,因此我们尽可能分配更小的结构体来节省内存。所有其他类型只是 SVt_PVMG 的更简单形式,具有更少的内部字段。SVt_NULL 只能保存 undef。SVt_IV 可以保存 undef、整数或引用。(SVt_RVSVt_IV 的别名,为了向后兼容而存在。)SVt_NV 可以保存 undef 或双精度浮点数。(在支持无头 NV 的构建中,这些也可以通过合适的偏移量保存引用,就像 SVt_IV 一样,但这目前不支持,似乎是一个罕见的用例。)SVt_PV 可以保存 undef、字符串或引用。SVt_PVIVSVt_PVSVt_IV 的超集。SVt_PVNVSVt_PVSVt_NV 的超集。SVt_PVMG 可以保存 SVt_PVNV 可以保存的任何东西,但它也可能被祝福或具有魔法属性。

SV 处理

AV_FROM_REF
CV_FROM_REF
HV_FROM_REF

*V_FROM_REF 宏从给定的引用 SV 中提取 SvRV(),并返回一个适当类型转换后的指向引用 SV 的指针。在 -DDEBUGGING 模式下,还会应用断言来检查 ref 是否确实是一个引用 SV,并且引用的是正确类型的 SV。

    AV *  AV_FROM_REF(SV * ref)
    CV *  CV_FROM_REF(SV * ref)
    HV *  HV_FROM_REF(SV * ref)
BOOL_INTERNALS_sv_isbool

检查一个 SvBoolFlagsOK() sv 是否为布尔值。注意,调用者有责任在调用此函数之前确保 sv 是 SvBoolFlagsOK()。这仅在序列化代码等性能至关重要的特殊逻辑中有用,并且已经检查过标志是否正确。几乎所有情况下,你应该使用 sv_isbool(sv) 代替。

    bool  BOOL_INTERNALS_sv_isbool(SV* sv)
BOOL_INTERNALS_sv_isbool_false

检查一个 SvBoolFlagsOK() sv 是否为假布尔值。注意,调用者有责任在调用此函数之前确保 sv 是 SvBoolFlagsOK()。这仅在序列化代码等性能至关重要的特殊逻辑中有用,并且已经检查过标志是否正确。这不是你用来检查 SV 是否为“假”的函数,为此你应该使用 !SvTRUE(sv) 代替。

    bool  BOOL_INTERNALS_sv_isbool_false(SV* sv)
BOOL_INTERNALS_sv_isbool_true

检查一个 SvBoolFlagsOK() sv 是否为真布尔值。注意,调用者有责任在调用此函数之前确保 sv 是 SvBoolFlagsOK()。这仅在序列化代码等性能至关重要的特殊逻辑中有用,并且已经检查过标志是否正确。这不是你用来检查 SV 是否为“真”的函数,为此你应该使用 SvTRUE(sv) 代替。

    bool  BOOL_INTERNALS_sv_isbool_true(SV* sv)
boolSV

如果 b 为真值,则返回一个真 SV;如果 b 为 0,则返回一个假 SV。

另请参见 "PL_sv_yes""PL_sv_no"

    SV *  boolSV(bool b)
croak_xs_usage

croak() 的一个专门变体,用于发出 xsubs 的使用信息

croak_xs_usage(cv, "eee_yow");

cv 中找出包名和子例程名,然后调用 croak()。因此,如果 cv&ouch::awk,它将调用 croak 如下:

Perl_croak(aTHX_ "Usage: %" SVf "::%" SVf "(%s)", "ouch" "awk",
                                                    "eee_yow");
    void  croak_xs_usage(const CV * const cv,
                         const char * const params)
DEFSV

返回与 $_ 关联的 SV。

    SV *  DEFSV
DEFSV_set

sv$_ 关联。

    void  DEFSV_set(SV * sv)
get_sv

返回指定 Perl 标量的 SV。flags 传递给 "gv_fetchpv"。如果设置了 GV_ADD 并且 Perl 变量不存在,则会创建它。如果 flags 为零并且变量不存在,则返回 NULL。

注意:perl_get_sv() 形式已弃用

    SV *  get_sv(const char *name, I32 flags)
isGV_with_GP

返回一个布尔值,表示 sv 是否为具有指向 GP(全局指针)的指针的 GV。

    bool  isGV_with_GP(SV * sv)
looks_like_number

测试 SV 的内容是否看起来像数字(或是一个数字)。InfInfinity 被视为数字(因此不会发出非数字警告),即使您的 atof() 不识别它们。忽略获取魔法。

    I32  looks_like_number(SV * const sv)
MUTABLE_AV
MUTABLE_CV
MUTABLE_GV
MUTABLE_HV
MUTABLE_IO
MUTABLE_PTR
MUTABLE_SV

MUTABLE_*() 宏将指针转换为显示的类型,以一种方式(编译器允许)使取消 const 性质会导致警告;例如:

const SV *sv = ...;
AV *av1 = (AV*)sv;        <== BAD:  the const has been silently
                                    cast away
AV *av2 = MUTABLE_AV(sv); <== GOOD: it may warn

MUTABLE_PTR 是用于派生新转换的基本宏。其他已内置的宏返回指向其名称指示的内容的指针。

    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)
newRV
newRV_inc

这些是相同的。它们为 SV 创建一个 RV 包装器。原始 SV 的引用计数会增加。

    SV *  newRV(SV * const sv)
newRV_noinc

为 SV 创建一个 RV 包装器。原始 SV 的引用计数不会增加。

    SV *  newRV_noinc(SV * const tmpRef)
newSV

创建一个新的 SV。非零 len 参数表示 SV 应该具有的预分配字符串空间的字节数。还为尾随 NUL 预留了一个额外的字节。(即使分配了字符串空间,也不会为 SV 设置 SvPOK。)新 SV 的引用计数设置为 1。

在 5.9.3 中,newSV() 替换了旧的 NEWSV() API,并删除了第一个参数 x,这是一个调试辅助工具,允许调用者识别自己。此辅助工具已被新的构建选项 PERL_MEM_LOG 取代(参见 "PERL_MEM_LOG" in perlhacktips)。旧的 API 仍然存在,供支持旧版本的 Perl 的 XS 模块使用。

    SV *  newSV(const STRLEN len)
newSVbool

创建一个新的 SV 布尔值。

    SV *  newSVbool(const bool bool_val)
newSV_false

创建一个新的 SV,它是一个布尔值 false。

    SV *  newSV_false()
newSVhek

从哈希键结构创建一个新的 SV。它将生成指向共享字符串表的标量,如果可能的话。如果 hek 为 NULL,则返回一个新的(未定义的)SV。

    SV *  newSVhek(const HEK * const hek)
newSVhek_mortal

从哈希键结构创建一个新的 mortal SV。它将生成指向共享字符串表的标量,如果可能的话。如果 hek 为 NULL,则返回一个新的(未定义的)SV。

这比使用 sv_2mortal(newSVhek( ... )) 更有效。

    SV *  newSVhek_mortal(const HEK * const hek)
newSViv

创建一个新的 SV 并将一个整数复制到其中。SV 的引用计数设置为 1。

    SV *  newSViv(const IV i)
newSVnv

创建一个新的 SV 并将一个浮点数复制到其中。SV 的引用计数设置为 1。

    SV *  newSVnv(const NV n)
newSVpadname

注意:newSVpadname实验性的,可能会在没有通知的情况下更改或删除。

创建一个包含 pad 名称的新 SV。

    SV*  newSVpadname(PADNAME *pn)
newSVpv

创建一个新的 SV 并将一个字符串(可能包含 NUL (\0) 字符)复制到其中。SV 的引用计数设置为 1。如果 len 为零,Perl 将使用 strlen() 计算长度(这意味着如果你使用此选项,s 不能包含嵌入的 NUL 字符,并且必须有一个终止的 NUL 字节)。

如果你可能传递空字符串,这些字符串不是以 null 结尾的,那么此函数会导致可靠性问题,因为它将在字符串上运行 strlen,并可能运行到有效内存之外。

使用 "newSVpvn" 是非 NUL 结尾字符串的更安全的替代方案。对于字符串文字,请使用 "newSVpvs"。此函数对于 NUL 结尾字符串可以正常工作,但如果你想避免关于是否调用 strlen 的 if 语句,请改用 newSVpvn(自己调用 strlen)。

    SV *  newSVpv(const char * const s, const STRLEN len)
newSVpvf

创建一个新的 SV 并使用类似于 sv_catpvf 的格式化字符串对其进行初始化。

注意:newSVpvf 必须显式地调用为 Perl_newSVpvf,并带有一个 aTHX_ 参数。

    SV *  Perl_newSVpvf(pTHX_ const char * const pat, ...)
newSVpvf_nocontext

"newSVpvf" 相似,但它不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

    SV *  newSVpvf_nocontext(const char * const pat, ...)
newSVpvn

创建一个新的 SV 并将一个字符串复制到其中,该字符串可能包含 NUL 字符 (\0) 和其他二进制数据。SV 的引用计数设置为 1。请注意,如果 len 为零,Perl 将创建一个零长度 (Perl) 字符串。您有责任确保源缓冲区至少有 len 字节长。如果 buffer 参数为 NULL,则新的 SV 将是未定义的。

    SV *  newSVpvn(const char * const buffer, const STRLEN len)
newSVpvn_flags

创建一个新的 SV 并将一个字符串(可能包含 NUL (\0) 字符)复制到其中。SV 的引用计数设置为 1。请注意,如果 len 为零,Perl 将创建一个零长度字符串。您有责任确保源字符串至少有 len 字节长。如果 s 参数为 NULL,则新的 SV 将是未定义的。目前,唯一接受的标志位是 SVf_UTF8SVs_TEMP。如果设置了 SVs_TEMP,则在返回之前将对结果调用 sv_2mortal()。如果设置了 SVf_UTF8,则 s 被认为是 UTF-8,并且 SVf_UTF8 标志将被设置在新 SV 上。newSVpvn_utf8() 是此函数的便捷包装器,定义为

#define newSVpvn_utf8(s, len, u)			\
    newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0)
    SV *  newSVpvn_flags(const char * const s, const STRLEN len,
                         const U32 flags)
newSVpvn_share

创建一个新的 SV,其 SvPVX_const 指向字符串表中的共享字符串。如果字符串在表中不存在,则先创建它。打开 SvIsCOW 标志(或 5.16 及更早版本中的 READONLYFAKE)。如果 hash 参数非零,则使用该值;否则计算哈希值。字符串的哈希值随后可以使用 "SvSHARED_HASH" 宏从 SV 中检索。这里的想法是,由于字符串表用于共享哈希键,因此这些字符串将具有 SvPVX_const == HeKEY,并且哈希查找将避免字符串比较。

    SV *  newSVpvn_share(const char *s, I32 len, U32 hash)
newSVpvn_utf8

创建一个新的 SV 并将一个字符串(可能包含NUL\0)字符)复制到其中。如果utf8为真,则在新的 SV 上调用SvUTF8_on。实现为newSVpvn_flags的包装器。

    SV*  newSVpvn_utf8(const char* s, STRLEN len, U32 utf8)
newSVpvs

newSVpvn类似,但接受一个文字字符串而不是字符串/长度对。

    SV*  newSVpvs("literal string")
newSVpvs_flags

newSVpvn_flags类似,但接受一个文字字符串而不是字符串/长度对。

    SV*  newSVpvs_flags("literal string", U32 flags)
newSVpv_share

newSVpvn_share类似,但接受一个以NUL结尾的字符串而不是字符串/长度对。

    SV *  newSVpv_share(const char *s, U32 hash)
newSVpvs_share

newSVpvn_share类似,但接受一个文字字符串而不是字符串/长度对,并省略哈希参数。

    SV*  newSVpvs_share("literal string")
newSVrv

为现有的 RV rv 创建一个新的 SV,使其指向。如果rv不是 RV,则将其升级为 RV。如果classname不为空,则新的 SV 将在指定的包中被祝福。返回新的 SV,其引用计数为 1。引用计数 1 由rv拥有。另请参见 newRV_inc() 和 newRV_noinc(),了解如何正确创建新的 RV。

    SV *  newSVrv(SV * const rv, const char * const classname)
newSVsv
newSVsv_flags
newSVsv_nomg

这些创建一个新的 SV,它是原始 SV 的精确副本(使用sv_setsv)。

它们的区别仅在于newSVsv执行“获取”魔法;newSVsv_nomg跳过任何魔法;而newSVsv_flags允许您显式设置flags参数。

    SV *  newSVsv      (SV * const old)
    SV *  newSVsv_flags(SV * const old, I32 flags)
    SV *  newSVsv_nomg (SV * const old)
newSV_true

创建一个新的 SV,它是一个布尔真值。

    SV *  newSV_true()
newSV_type

创建一个新的 SV,类型由指定。新 SV 的引用计数设置为 1。

    SV *  newSV_type(const svtype type)
newSV_type_mortal

创建一个新的 mortal SV,类型由指定。新 SV 的引用计数设置为 1。

这等效于 SV* sv = sv_2mortal(newSV_type(<some type>)) 和 SV* sv = sv_newmortal(); sv_upgrade(sv, <some_type>),但应该比它们两者都更有效率。(除非 sv_2mortal 在将来的某个时间点被内联。)

    SV *  newSV_type_mortal(const svtype type)
newSVuv

创建一个新的 SV 并将一个无符号整数复制到其中。SV 的引用计数设置为 1。

    SV *  newSVuv(const UV u)
Nullsv

空 SV 指针。(当定义了 PERL_CORE 时不再可用。)

PL_sv_no

这是 false SV。它是只读的。参见 "PL_sv_yes"。始终将其引用为 &PL_sv_no

    SV  PL_sv_no
PL_sv_undef

这是 undef SV。它是只读的。始终将其引用为 &PL_sv_undef

    SV  PL_sv_undef
PL_sv_yes

这是 true SV。它是只读的。参见 "PL_sv_no"。始终将其引用为 &PL_sv_yes

    SV  PL_sv_yes
PL_sv_zero

此只读 SV 具有零数值和 "0" 字符串值。它类似于 "PL_sv_no",但其字符串值不同。例如,可以用作 mXPUSHi(0) 的廉价替代方案。始终将其引用为 &PL_sv_zero。在 5.28 中引入。

    SV  PL_sv_zero
SAVE_DEFSV

本地化 $_。参见 "perlguts 中的本地化更改"

    void  SAVE_DEFSV
sortsv

使用给定的比较例程对 SV 指针数组进行就地排序。

目前,这始终使用归并排序。有关更灵活的例程,请参见 "sortsv_flags"

    void  sortsv(SV **array, size_t num_elts, SVCOMPARE_t cmp)
sortsv_flags

使用给定的比较例程对 SV 指针数组进行就地排序,并使用各种 SORTf_* 标志选项。

    void  sortsv_flags(SV **array, size_t num_elts, SVCOMPARE_t cmp,
                       U32 flags)
SV

perlguts 中描述。

SvAMAGIC

返回一个布尔值,指示 sv 是否启用了重载(活动魔法)。

    bool  SvAMAGIC(SV * sv)
SvAMAGIC_off

指示 sv 已禁用重载(活动魔法)。

    void  SvAMAGIC_off(SV *sv)
SvAMAGIC_on

指示 sv 已启用重载(活动魔法)。

    void  SvAMAGIC_on(SV *sv)
sv_backoff

删除任何字符串偏移量。您通常应该使用 SvOOK_off 宏包装器代替。

    void  sv_backoff(SV * const sv)
sv_bless

将一个 SV 放入指定的包中。SV 必须是一个 RV。包必须由其 stash 指定(参见 "gv_stashpv")。SV 的引用计数不受影响。

    SV *  sv_bless(SV * const sv, HV * const stash)
SvBoolFlagsOK

返回一个布尔值,指示 SV 是否具有正确的标志设置,以便安全地调用 BOOL_INTERNALS_sv_isbool()BOOL_INTERNALS_sv_isbool_true()BOOL_INTERNALS_sv_isbool_false()。目前等效于 SvIandPOK(sv)SvIOK(sv) && SvPOK(sv)。序列化可能需要展开此检查。如果是这样,强烈建议您在使用任何 BOOL_INTERNALS 宏之前添加类似 assert(SvBoolFlagsOK(sv)); 的代码。

    U32  SvBoolFlagsOK(SV* sv)
sv_catpv
sv_catpv_flags
sv_catpv_mg
sv_catpv_nomg

这些将 NUL 终止的字符串 sstr 连接到 SV 中的字符串的末尾。如果 SV 设置了 UTF-8 状态,则附加的字节应该是有效的 UTF-8。

它们仅在处理魔法的方式上有所不同

sv_catpv_mg 执行“获取”和“设置”魔法。

sv_catpv 仅执行“获取”魔法。

sv_catpv_nomg 跳过所有魔法。

sv_catpv_flags 有一个额外的 flags 参数,允许您指定任何魔法处理组合(使用 SV_GMAGIC 和/或 SV_SMAGIC),并覆盖 UTF-8 处理。通过提供 SV_CATUTF8 标志,附加的字符串将被强制解释为 UTF-8;通过提供 SV_CATBYTES 标志,它将被解释为字节。如果需要,SV 或附加的字符串将被升级到 UTF-8。

    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)
sv_catpvf
sv_catpvf_mg
sv_catpvf_mg_nocontext
sv_catpvf_nocontext

这些函数处理它们的实参就像 sprintf 一样,并将格式化的输出追加到一个 SV 上。与 sv_vcatpvfn 一样,当使用非空 C 风格可变参数列表调用时,不支持实参重新排序。

如果追加的数据包含“宽”字符(包括但不限于使用 %s 格式化的带有 UTF-8 PV 的 SV,以及使用 %c 格式化的大于 255 的字符),则原始 SV 可能会升级到 UTF-8。

如果原始 SV 是 UTF-8,则模式应为有效的 UTF-8;如果原始 SV 是字节,则模式也应为字节。

所有函数都执行“获取”魔法,但只有 sv_catpvf_mgsv_catpvf_mg_nocontext 执行“设置”魔法。

sv_catpvf_nocontextsv_catpvf_mg_nocontext 不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

注意:sv_catpvf 必须显式地调用为 Perl_sv_catpvf,并带有 aTHX_ 参数。

注意:sv_catpvf_mg 必须显式地调用为 Perl_sv_catpvf_mg,并带有 aTHX_ 参数。

    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, ...)
sv_catpvn
sv_catpvn_flags
sv_catpvn_mg
sv_catpvn_nomg

这些函数将从 ptr 开始的字符串的 len 个字节连接到 dsv 中的字符串的末尾。调用者必须确保 ptr 包含至少 len 个字节。

对于除 sv_catpvn_flags 之外的所有函数,如果 SV 设置了 UTF-8 状态,则追加的字符串被假定为有效的 UTF-8,否则为字节字符串。

它们的区别在于

sv_catpvn_mgdsv 执行“获取”和“设置”魔法。

sv_catpvn 只执行“获取”魔法。

sv_catpvn_nomg 跳过所有魔法。

sv_catpvn_flags 有一个额外的 flags 参数,它允许您指定任何魔法处理组合(使用 SV_GMAGIC 和/或 SV_SMAGIC),并覆盖 UTF-8 处理。通过提供 SV_CATBYTES 标志,追加的字符串被解释为普通字节;通过提供 SV_CATUTF8 标志,它将被解释为 UTF-8,并且 dsv 将在必要时升级到 UTF-8。

sv_catpvnsv_catpvn_mgsv_catpvn_nomg 是根据 sv_catpvn_flags 实现的。

    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)
sv_catpvs

sv_catpvn 相似,但接受一个字面字符串而不是字符串/长度对。

    void  sv_catpvs(SV* sv, "literal string")
sv_catpvs_flags

sv_catpvn_flags 相似,但接受一个字面字符串而不是字符串/长度对。

    void  sv_catpvs_flags(SV* sv, "literal string", I32 flags)
sv_catpvs_mg

sv_catpvn_mg 相似,但接受一个字面字符串而不是字符串/长度对。

    void  sv_catpvs_mg(SV* sv, "literal string")
sv_catpvs_nomg

sv_catpvn_nomg 相似,但接受一个字面字符串而不是字符串/长度对。

    void  sv_catpvs_nomg(SV* sv, "literal string")
sv_catsv
sv_catsv_flags
sv_catsv_mg
sv_catsv_nomg

这些函数将 SV sstr 中的字符串连接到 SV dsv 中字符串的末尾。如果 sstr 为空,则这些函数不执行任何操作;否则,只有 dsv 会被修改。

它们的区别仅在于它们执行的魔法操作。

sv_catsv_mg 在复制之前对两个 SV 执行“获取”魔法,并在之后对 dsv 执行“设置”魔法。

sv_catsv 仅对两个 SV 执行“获取”魔法。

sv_catsv_nomg 跳过所有魔法操作。

sv_catsv_flags 有一个额外的 flags 参数,允许您使用 SV_GMAGIC 和/或 SV_SMAGIC 来指定任何组合的魔法处理(尽管两个 SV 都会应用“获取”魔法,或者都不会应用)。

sv_catsvsv_catsv_mgsv_catsv_nomg 是基于 sv_catsv_flags 实现的。

    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)
SV_CHECK_THINKFIRST

移除 sv 中任何需要在修改之前处理的负担。例如,如果它是写时复制(COW),现在是进行复制的时候。

如果您知道要更改 sv 的 PV 值,请改用 "SV_CHECK_THINKFIRST_COW_DROP" 来避免立即写入的写入操作。

    void  SV_CHECK_THINKFIRST(SV * sv)
SV_CHECK_THINKFIRST_COW_DROP

当您要替换 sv 中的 PV 值时调用此函数,该值可能是写时复制的。它会停止与其他 SV 的任何共享,因此不会发生任何写时复制(COW)。这种 COW 将是无用的,因为它会立即被更改为其他内容。此函数还会移除在更改 sv 时会造成问题的任何其他负担。

    void  SV_CHECK_THINKFIRST_COW_DROP(SV * sv)
sv_chop

从字符串缓冲区的开头高效地移除字符。SvPOK(sv),或者至少 SvPOKp(sv),必须为真,并且 ptr 必须是指向字符串缓冲区内部的某个位置的指针。ptr 将成为调整后的字符串的第一个字符。使用 OOK 技巧。在返回时,只有 SvPOK(sv)SvPOKp(sv)OK 标志中将为真。

注意:此函数返回后,ptr 和 SvPVX_const(sv) 可能不再引用相同的内存块。

此函数名称与 Perl 的 chop 运算符不幸地相似,这纯粹是巧合。此函数从左侧开始工作;chop 从右侧开始工作。

    void  sv_chop(SV * const sv, const char * const ptr)
sv_clear

清除一个 SV:调用任何析构函数,释放主体使用的任何内存,并释放主体本身。SV 的头部不会被释放,尽管它的类型被设置为全 1,以便在全局销毁等过程中不会意外地被认为是活动的。此函数只应在 REFCNT 为零时调用。大多数情况下,您会想要调用 SvREFCNT_dec 而不是它。

    void  sv_clear(SV * const orig_sv)
sv_cmp

比较两个 SV 中的字符串。返回 -1、0 或 1,表示 sv1 中的字符串是否小于、等于或大于 sv2 中的字符串。支持 UTF-8 和 'use bytes',处理 get magic,并在必要时将参数强制转换为字符串。另请参见 "sv_cmp_locale"

    I32  sv_cmp(SV * const sv1, SV * const sv2)
sv_cmp_flags

比较两个 SV 中的字符串。返回 -1、0 或 1,表示 sv1 中的字符串是否小于、等于或大于 sv2 中的字符串。支持 UTF-8 和 'use bytes',并在必要时将参数强制转换为字符串。如果标志包含 SV_GMAGIC 位,则它会处理 get magic。另请参见 "sv_cmp_locale_flags"

    I32  sv_cmp_flags(SV * const sv1, SV * const sv2, const U32 flags)
sv_cmp_locale

以区域设置感知的方式比较两个 SV 中的字符串。支持 UTF-8 和 'use bytes',处理 get magic,并在必要时将参数强制转换为字符串。另请参见 "sv_cmp"

    I32  sv_cmp_locale(SV * const sv1, SV * const sv2)
sv_cmp_locale_flags

以区域设置感知的方式比较两个 SV 中的字符串。支持 UTF-8 和 'use bytes',并在必要时将参数强制转换为字符串。如果标志包含 SV_GMAGIC,则它会处理 get magic。另请参见 "sv_cmp_flags"

    I32  sv_cmp_locale_flags(SV * const sv1, SV * const sv2,
                             const U32 flags)
sv_collxfrm

此函数使用 SV_GMAGIC 标志调用 sv_collxfrm_flags。请参见 "sv_collxfrm_flags"

    char *  sv_collxfrm(SV * const sv, STRLEN * const nxp)
sv_collxfrm_flags

如果 SV 还没有 Collate Transform magic,则为其添加此 magic。如果标志包含 SV_GMAGIC,则它会处理 get-magic。

任何标量变量都可以携带 PERL_MAGIC_collxfrm magic,其中包含变量的标量数据,但已转换为这样的格式,以便可以使用正常的内存比较来根据区域设置比较数据。

    char *  sv_collxfrm_flags(SV * const sv, STRLEN * const nxp,
                              I32 const flags)
sv_copypv
sv_copypv_flags
sv_copypv_nomg

这些函数将源 SV 的字符串化表示复制到目标 SV 中。它们会自动将数值强制转换为字符串。保证即使从重载对象中也能保留 UTF8 标志。与 sv_2pv[_flags] 的性质类似,但它们直接对 SV 操作,而不是只操作字符串。大多数情况下,它们使用 "sv_2pv_flags" 来完成工作,除非这样做会丢失 PV 的 UTF-8 属性。

这三种形式的区别仅在于它们是否对 sv 执行“获取魔法”。sv_copypv_nomg 跳过“获取魔法”;sv_copypv 执行它;而 sv_copypv_flags 则根据 flags 中是否设置了 SV_GMAGIC 位来决定是否执行它。

    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)
SvCUR

返回 SV 内部 PV 的字节长度。请注意,这可能与 Perl 的 length 不匹配;要获得 Perl 的长度,请使用 sv_len_utf8(sv)。另请参见 "SvLEN"

    STRLEN  SvCUR(SV* sv)
SvCUR_set

设置 SV 中的 C 字符串的当前字节长度。参见 "SvCUR"SvIV_set>。

    void  SvCUR_set(SV* sv, STRLEN len)
sv_2cv

使用各种策略,尝试从 SV 获取 CV;此外,如果可能,尝试将 *st*gvp 设置为与其关联的 stash 和 GV。lref 中的标志将传递给 gv_fetchsv

    CV *  sv_2cv(SV *sv, HV ** const st, GV ** const gvp,
                 const I32 lref)
sv_dec
sv_dec_nomg

这些函数会自动递减 SV 中的值,并在必要时进行字符串到数值的转换。它们都处理运算符重载。

它们的区别仅在于

sv_dec 处理“获取”魔法;sv_dec_nomg 跳过“获取”魔法。

    void  sv_dec(SV * const sv)
sv_derived_from

"sv_derived_from_pv" 完全相同,但没有 flags 参数。

    bool  sv_derived_from(SV *sv, const char * const name)
sv_derived_from_hv

"sv_derived_from_pvn" 完全相同,但将名称字符串作为给定 HV 的 HvNAME(它可能代表一个 stash)。

    bool  sv_derived_from_hv(SV *sv, HV *hv)
sv_derived_from_pv

"sv_derived_from_pvn" 完全相同,但使用以空字符结尾的字符串而不是字符串/长度对。

    bool  sv_derived_from_pv(SV *sv, const char * const name,
                             U32 flags)
sv_derived_from_pvn

返回一个布尔值,指示 SV 是否在C 级别从指定的类派生而来。要检查 Perl 级别上的派生,请将 isa() 作为正常的 Perl 方法调用。

目前,flags 的唯一重要值是 SVf_UTF8。

    bool  sv_derived_from_pvn(SV *sv, const char * const name,
                              const STRLEN len, U32 flags)
sv_derived_from_sv

"sv_derived_from_pvn" 完全相同,但使用 SV 而不是字符串/长度对来获取名称字符串。这是建议的形式。

    bool  sv_derived_from_sv(SV *sv, SV *namesv, U32 flags)
sv_does

"sv_does_pv" 相似,但不接受 flags 参数。

    bool  sv_does(SV *sv, const char * const name)
sv_does_pv

"sv_does_sv" 相似,但接受以空字符结尾的字符串而不是 SV。

    bool  sv_does_pv(SV *sv, const char * const name, U32 flags)
sv_does_pvn

"sv_does_sv" 相似,但接受字符串/长度对而不是 SV。

    bool  sv_does_pvn(SV *sv, const char * const name,
                      const STRLEN len, U32 flags)
sv_does_sv

返回一个布尔值,指示 SV 是否执行特定命名的角色。SV 可以是 Perl 对象或 Perl 类的名称。

    bool  sv_does_sv(SV *sv, SV *namesv, U32 flags)
SvEND

返回指向 SV 中字符串最后一个字符后的位置的指针,该位置通常包含一个尾随的 NUL 字符(即使 Perl 标量并不严格要求它)。参见 "SvCUR"。访问字符的方式为 *(SvEND(sv))

警告:如果 SvCUR 等于 SvLEN,则 SvEND 指向未分配的内存。

    char*  SvEND(SV* sv)
sv_eq

返回一个布尔值,指示两个 SV 中的字符串是否完全相同。支持 UTF-8 和 'use bytes',处理获取魔法,并在必要时将参数强制转换为字符串。

此函数不处理运算符重载。有关支持运算符重载的版本,请参见 sv_streq

    I32  sv_eq(SV *sv1, SV *sv2)
sv_eq_flags

返回一个布尔值,指示两个 SV 中的字符串是否完全相同。支持 UTF-8 和 'use bytes',并在必要时将参数强制转换为字符串。如果 flags 设置了 SV_GMAGIC 位,它也会处理获取魔法。

此函数不处理运算符重载。有关支持运算符重载的版本,请参见 sv_streq_flags

    I32  sv_eq_flags(SV *sv1, SV *sv2, const U32 flags)
sv_force_normal

撤销 SV 上各种类型的伪造:如果 PV 是共享字符串,则创建私有副本;如果我们是引用,则停止引用;如果我们是 glob,则降级为 xpvmg。另请参见 "sv_force_normal_flags"

    void  sv_force_normal(SV *sv)
sv_force_normal_flags

撤销 SV 上各种类型的伪造,其中伪造意味着“超过”字符串:如果 PV 是共享字符串,则创建私有副本;如果我们是引用,则停止引用;如果我们是 glob,则降级为 xpvmg;如果我们是写时复制标量,这是我们进行复制的写时时间,并且也在本地使用;如果这是一个 vstring,则删除 vstring 魔法。如果设置了 SV_COW_DROP_PV,则写时复制标量会丢弃其 PV 缓冲区(如果有)并变为 SvPOK_off,而不是创建副本。(用于此标量即将设置为其他值的地方。)此外,flags 参数在取消引用时传递给 sv_unref_flags()sv_force_normal 使用设置为 0 的标志调用此函数。

此函数预计用于向 perl 信号此 SV 即将被写入,并且需要处理任何额外的簿记。因此,它在只读值上会抛出异常。

    void  sv_force_normal_flags(SV * const sv, const U32 flags)
sv_free

减少 SV 的引用计数,如果它降至零,则调用 sv_clear 来调用析构函数并释放主体使用的任何内存;最后,释放 SV 的头本身。通常通过包装宏 SvREFCNT_dec 调用。

    void  sv_free(SV * const sv)
SvGAMAGIC

如果 SV 具有获取魔法或重载,则返回 true。如果两者都为 true,则标量是活动数据,并且每次访问时都有可能返回一个新值。因此,您必须注意每个用户逻辑操作只读取一次并使用该返回值。如果两者都不为 true,则标量的值不会改变,除非写入。

    U32  SvGAMAGIC(SV* sv)
sv_get_backrefs

注意:sv_get_backrefs实验性的,可能会在未经通知的情况下更改或删除。

如果 sv 是弱引用的目标,则它返回与 sv 关联的反向引用结构;否则返回 NULL

当返回非空结果时,返回值的类型是相关的。如果它是一个 AV,那么 AV 的元素是指向该项目的弱引用 RV。如果它是任何其他类型,那么项目本身就是弱引用。

另请参阅 Perl_sv_add_backref()Perl_sv_del_backref()Perl_sv_kill_backrefs()

    SV *  sv_get_backrefs(SV * const sv)
SvGETMAGIC

如果 SV 具有“get”魔法,则调用 "mg_get"。例如,这将调用绑定变量上的 FETCH。从 5.37.1 开始,此函数保证其参数只会被评估一次。

    void  SvGETMAGIC(SV *sv)
sv_gets

从文件句柄中获取一行并将其存储到 SV 中,可以选择将其附加到当前存储的字符串。如果 append 不为 0,则该行将附加到 SV 而不是覆盖它。append 应设置为附加字符串在 SV 中的起始字节偏移量(通常,SvCUR(sv) 是一个合适的选择)。

    char *  sv_gets(SV * const sv, PerlIO * const fp, I32 append)
SvGROW

扩展 SV 中的字符缓冲区,使其有足够的空间容纳指示的字节数(请记住为额外的尾随 NUL 字符保留空间)。如果需要,调用 sv_grow 来执行扩展。返回指向字符缓冲区的指针。SV 必须是类型 >= SVt_PV。另一种选择是,如果您不确定 SV 的类型,可以调用 sv_grow

您可能会错误地认为 len 是要添加到现有大小的字节数,但实际上它是 sv 应该具有的总大小。

    char *  SvGROW(SV* sv, STRLEN len)
SvIandPOK

返回一个布尔值,指示 SV 是否同时为 SvPOK()SvIOK()。等效于 SvIOK(sv) && SvPOK(sv),但效率更高。

    U32  SvIandPOK(SV* sv)
SvIandPOK_off

在一个操作中取消设置 SV 的 PV 和 IV 状态。等效于 SvIOK_off(sv); SvPK_off(v);,但效率更高。

    void  SvIandPOK_off(SV* sv)
SvIandPOK_on

在一个操作中告诉 SV 它是一个字符串和一个数字。等效于 SvIOK_on(sv); SvPOK_on(sv);,但效率更高。

    void  SvIandPOK_on(SV* sv)
sv_inc
sv_inc_nomg

这些自动递增 SV 中的值,如果需要,进行字符串到数字的转换。它们都处理运算符重载。

它们的区别仅在于 sv_inc 执行“get”魔法;sv_inc_nomg 跳过任何魔法。

    void  sv_inc(SV * const sv)
sv_insert

在 SV 中指定的偏移量/长度处插入和/或替换字符串。类似于 Perl 的 substr() 函数,从 little 开始的 littlelen 字节替换 bigstr 中从 offset 开始的 len 字节。处理获取魔法。

    void  sv_insert(SV * const bigstr, const STRLEN offset,
                    const STRLEN len, const char * const little,
                    const STRLEN littlelen)
sv_insert_flags

sv_insert 相同,但额外的 flags 传递给应用于 bigstrSvPV_force_flags

    void  sv_insert_flags(SV * const bigstr, const STRLEN offset,
                          const STRLEN len, const char *little,
                          const STRLEN littlelen, const U32 flags)
sv_2io

使用各种策略,尝试从 SV 获取 IO:如果它是 GV,则为 IO 槽;如果我们是 RV,则为递归结果;如果我们是字符串,则为以 PV 命名的符号的 IO 槽。

传入的 sv 上忽略“获取”魔法,但如果 sv 是 RV,则会在 SvRV(sv) 上调用。

    IO *  sv_2io(SV * const sv)
SvIOK

返回一个 U32 值,指示 SV 是否包含整数。

    U32  SvIOK(SV* sv)
SvIOK_notUV

返回一个布尔值,指示 SV 是否包含有符号整数。

    bool  SvIOK_notUV(SV* sv)
SvIOK_off

取消 SV 的 IV 状态。

    void  SvIOK_off(SV* sv)
SvIOK_on

告诉 SV 它是一个整数。

    void  SvIOK_on(SV* sv)
SvIOK_only

告诉 SV 它是一个整数,并禁用所有其他 OK 位。

    void  SvIOK_only(SV* sv)
SvIOK_only_UV

告诉 SV 它是一个无符号整数,并禁用所有其他 OK 位。

    void  SvIOK_only_UV(SV* sv)
SvIOKp

返回一个 U32 值,指示 SV 是否包含整数。检查私有设置。请改用 SvIOK

    U32  SvIOKp(SV* sv)
SvIOK_UV

返回一个布尔值,指示 SV 是否包含必须解释为无符号的整数。一个非负整数,其值在 IV 和 UV 的范围内,可以标记为 SvUOKSvIOK

    bool  SvIOK_UV(SV* sv)
sv_isa

返回一个布尔值,指示 SV 是否被祝福到指定的类中。

这不会检查子类型或方法重载。使用 sv_isa_sv 来验证继承关系,就像 isa 运算符一样,通过尊重任何 isa() 方法重载;或者使用 sv_derived_from_sv 直接测试实际对象类型。

    int  sv_isa(SV *sv, const char * const name)
sv_isa_sv

注意:sv_isa_sv 实验性,可能会在未经通知的情况下更改或删除。

返回一个布尔值,指示 SV 是否为对象引用,并且是否派生自指定的类,尊重它可能具有的任何 isa() 方法重载。如果 sv 不是对对象的引用,或者没有从指定的类派生,则返回 false。

这是用于实现 isa 运算符行为的函数。

不会对 sv 执行魔法。

不要与旧的 sv_isa 函数混淆,该函数不使用重载的 isa() 方法,也不会检查子类化。

    bool  sv_isa_sv(SV *sv, SV *namesv)
SvIsBOOL

如果 SV 是特殊的布尔常量之一(PL_sv_yes 或 PL_sv_no),或者是一个常规的 SV,其最后一次赋值存储了其中一个的副本,则返回 true。

    bool  SvIsBOOL(SV* sv)
SvIsCOW

返回一个 U32 值,指示 SV 是否为 Copy-On-Write(共享哈希键标量,或者如果 5.9.0 配置为 COW,则为完整的 Copy On Write 标量)。

    U32  SvIsCOW(SV* sv)
SvIsCOW_shared_hash

返回一个布尔值,指示 SV 是否为 Copy-On-Write 共享哈希键标量。

    bool  SvIsCOW_shared_hash(SV* sv)
sv_isobject

返回一个布尔值,指示 SV 是否为指向已祝福对象的 RV。如果 SV 不是 RV,或者对象没有祝福,则返回 false。

    int  sv_isobject(SV *sv)
SvIV
SvIV_nomg
SvIVx

这些都将给定的 SV 强制转换为 IV 并返回它。在许多情况下,返回值将存储在 sv 的 IV 槽中,但并非在所有情况下。 (使用 "sv_setiv" 来确保它这样做)。

从 5.37.1 开始,所有都保证只评估 sv 一次。

SvIVx 现在与 SvIV 相同,但在 5.37.1 之前,它是唯一保证只评估 sv 一次的表单。

SvIV_nomgSvIV 相同,但不会执行“获取”魔法。

    IV  SvIV(SV *sv)
sv_2iv_flags

返回 SV 的整数值,执行任何必要的字符串转换。如果 flags 设置了 SV_GMAGIC 位,则先执行 mg_get()。通常通过 SvIV(sv)SvIVx(sv) 宏使用。

    IV  sv_2iv_flags(SV * const sv, const I32 flags)
SvIV_set

将 sv 中的 IV 指针的值设置为 val。可以使用对 SvIVX 的左值赋值来执行与该宏相同的功能。但是,在未来的 Perl 版本中,使用 SvIV_set 比对 SvIVX 的左值赋值效率更高。

    void  SvIV_set(SV* sv, IV val)
SvIVX

返回 SV 的 IV 槽中的原始值,不进行检查或转换。仅在确定 SvIOK 为真时使用。另请参见 "SvIV"

    IV  SvIVX(SV* sv)
SvLEN

返回 SV 中字符串缓冲区的大小,不包括任何归因于 SvOOK 的部分。参见 "SvCUR"

    STRLEN  SvLEN(SV* sv)
sv_len

返回 SV 中字符串的长度。处理魔法和类型强制,并适当地设置 UTF8 标志。另请参见 "SvCUR",它提供对 xpv_cur 槽的原始访问。

    STRLEN  sv_len(SV * const sv)
SvLEN_set

设置 SV 的字符串缓冲区的大小。参见 "SvLEN"

    void  SvLEN_set(SV* sv, STRLEN len)
sv_len_utf8
sv_len_utf8_nomg

这些返回 SV 中字符串的字符数,将宽 UTF-8 字节计为单个字符。两者都处理类型强制。它们的区别仅在于 sv_len_utf8 执行“获取”魔法;sv_len_utf8_nomg 跳过任何魔法。

    STRLEN  sv_len_utf8(SV * const sv)
SvLOCK

如果已加载合适的模块,则安排对 sv 获取互斥锁。

    void  SvLOCK(SV* sv)
sv_magic

向 SV 添加魔法。如果需要,首先将 sv 升级到类型 SVt_PVMG,然后将类型为 how 的新魔法项添加到魔法列表的头部。

参见 "sv_magicext"sv_magic 现在调用它)以了解对 namenamlen 参数的处理描述。

您需要使用 sv_magicextSvREADONLY SV 添加魔法,以及添加多个相同 how 的实例。

    void  sv_magic(SV * const sv, SV * const obj, const int how,
                   const char * const name, const I32 namlen)
sv_magicext

向 SV 添加魔法,并在必要时进行升级。应用提供的 vtable 并返回指向添加的魔法的指针。

请注意,sv_magicext 允许 sv_magic 不允许的操作。特别是,您可以向 SvREADONLY SV 添加魔法,以及添加多个相同 how 的实例。

如果 namlen 大于零,则存储 namesavepvn 副本;如果 namlen 为零,则按原样存储 name;作为另一种特殊情况,如果 (name && namlen == HEf_SVKEY),则假定 name 包含一个 SV*,并按原样存储,同时将其 REFCNT 加 1。

(现在,这被用作 sv_magic 的子例程。)

    MAGIC *  sv_magicext(SV * const sv, SV * const obj, const int how,
                         const MGVTBL * const vtbl,
                         const char * const name, const I32 namlen)
SvMAGIC_set

sv 中的 MAGIC 指针的值设置为 val。参见 "SvIV_set"

    void  SvMAGIC_set(SV* sv, MAGIC* val)
sv_2mortal

将现有 SV 标记为 mortal。该 SV 将“很快”被销毁,要么通过显式调用 FREETMPS,要么通过在语句边界等位置的隐式调用。SvTEMP() 被打开,这意味着如果复制此 SV,则可以“窃取”SV 的字符串缓冲区。另请参见 "sv_newmortal""sv_mortalcopy"

    SV *  sv_2mortal(SV * const sv)
sv_mortalcopy

创建一个新的 SV,它是原始 SV 的副本(使用 sv_setsv)。新 SV 被标记为 mortal。它将“很快”被销毁,要么通过显式调用 FREETMPS,要么通过在语句边界等位置的隐式调用。另请参见 "sv_newmortal""sv_2mortal"

    SV *  sv_mortalcopy(SV * const oldsv)
sv_mortalcopy_flags

sv_mortalcopy 相似,但额外的 flags 被传递给 sv_setsv_flags

    SV *  sv_mortalcopy_flags(SV * const oldsv, U32 flags)
sv_newmortal

创建一个新的空 SV,它是 mortal。SV 的引用计数设置为 1。它将“很快”被销毁,要么通过显式调用 FREETMPS,要么通过在语句边界等位置的隐式调用。另请参见 "sv_mortalcopy""sv_2mortal"

    SV *  sv_newmortal()
SvNIOK

返回一个 U32 值,指示 SV 是否包含一个数字、整数或双精度数。

    U32  SvNIOK(SV* sv)
SvNIOK_off

取消设置 SV 的 NV/IV 状态。

    void  SvNIOK_off(SV* sv)
SvNIOKp

返回一个 U32 值,指示 SV 是否包含一个数字、整数或双精度数。检查私有设置。请使用 SvNIOK 代替。

    U32  SvNIOKp(SV* sv)
SvNOK

返回一个 U32 值,指示 SV 是否包含双精度浮点数。

    U32  SvNOK(SV* sv)
SvNOK_off

取消 SV 的 NV 状态。

    void  SvNOK_off(SV* sv)
SvNOK_on

告诉 SV 它是一个双精度浮点数。

    void  SvNOK_on(SV* sv)
SvNOK_only

告诉 SV 它是一个双精度浮点数,并禁用所有其他 OK 位。

    void  SvNOK_only(SV* sv)
SvNOKp

返回一个 U32 值,指示 SV 是否包含双精度浮点数。检查私有设置。使用SvNOK代替。

    U32  SvNOKp(SV* sv)
sv_nolocking

已弃用! 计划从未来版本的 Perl 中删除sv_nolocking。不要在新的代码中使用它;从现有代码中删除它。

当没有锁定模块存在时,用于“锁定”SV 的虚拟例程。存在是为了避免测试NULL函数指针,并且因为它可能在某些严格级别下发出警告。

sv_nosharing()“取代”。

    void  sv_nolocking(SV *sv)
sv_nounlocking

已弃用! 计划从未来版本的 Perl 中删除sv_nounlocking。不要在新的代码中使用它;从现有代码中删除它。

当没有锁定模块存在时,用于“解锁”SV 的虚拟例程。存在是为了避免测试NULL函数指针,并且因为它可能在某些严格级别下发出警告。

sv_nosharing()“取代”。

    void  sv_nounlocking(SV *sv)
sv_numeq

使用SV_GMAGIC标志调用sv_numeq_flags的便捷快捷方式。此函数的行为基本上与 Perl 代码$sv1 == $sv2相同。

    bool  sv_numeq(SV *sv1, SV *sv2)
sv_numeq_flags

返回一个布尔值,指示两个 SV 中的数字是否相同。如果 flags 参数设置了SV_GMAGIC位,它也会处理 get-magic。如果需要,会将其参数强制转换为数字。将NULL视为未定义。

如果 flags 没有设置SV_SKIP_OVERLOAD位,则会尝试使用==重载。如果这种重载不存在或设置了标志,则将使用常规的数值比较。

    bool  sv_numeq_flags(SV *sv1, SV *sv2, const U32 flags)
SvNV
SvNV_nomg
SvNVx

这些函数将给定的 SV 强制转换为 NV 并返回。在许多情况下,返回值将存储在 sv 的 NV 槽中,但并非所有情况下都是如此。(使用 "sv_setnv" 来确保它确实如此)。

从 5.37.1 开始,所有都保证只评估 sv 一次。

SvNVx 现在与 SvNV 相同,但在 5.37.1 之前,它是唯一保证只评估 sv 一次的形式。

SvNV_nomgSvNV 相同,但不执行“获取”魔法。

    NV  SvNV(SV *sv)
sv_2nv_flags

返回 SV 的数字值,执行任何必要的字符串或整数转换。如果 flags 设置了 SV_GMAGIC 位,则首先执行 mg_get()。通常通过 SvNV(sv)SvNVx(sv) 宏使用。

    NV  sv_2nv_flags(SV * const sv, const I32 flags)
SvNV_set

sv 中的 NV 指针的值设置为 val。参见 "SvIV_set"

    void  SvNV_set(SV* sv, NV val)
SvNVX

返回 SV 的 NV 槽中的原始值,不进行检查或转换。仅在您确定 SvNOK 为真时使用。另请参见 "SvNV"

    NV  SvNVX(SV* sv)
SvOK

返回一个 U32 值,指示该值是否已定义。这仅对标量有意义。

    U32  SvOK(SV* sv)
SvOOK

返回一个 U32,指示指向字符串缓冲区的指针是否已偏移。此技巧在内部使用以加速从 "SvPV" 开头删除字符。当 SvOOK 为真时,分配的字符串缓冲区的开头实际上是在 SvPVX 之前 SvOOK_offset() 字节。此偏移量以前存储在 SvIVX 中,但现在存储在缓冲区的备用部分中。

    U32  SvOOK(SV* sv)
SvOOK_off

删除任何字符串偏移量。

    void  SvOOK_off(SV * sv)
SvOOK_offset

SvPVX 到分配的缓冲区真实开头的偏移量读入 len,如果已使用 sv_chop 有效地从缓冲区的开头删除字符,则该偏移量将不为零。实现为宏,它接受 len 的地址,该地址必须为 STRLEN 类型。多次评估 sv。如果 SvOOK(sv) 为假,则将 len 设置为 0。

    void  SvOOK_offset(SV*sv, STRLEN len)
SvPOK

返回一个 U32 值,指示 SV 是否包含一个字符字符串。

    U32  SvPOK(SV* sv)
SvPOK_off

取消 SV 的 PV 状态。

    void  SvPOK_off(SV* sv)
SvPOK_on

告诉 SV 它是一个字符串。

    void  SvPOK_on(SV* sv)
SvPOK_only

告诉 SV 它是一个字符串,并禁用所有其他 OK 位。还会关闭 UTF-8 状态。

    void  SvPOK_only(SV* sv)
SvPOK_only_UTF8

告诉 SV 它是一个字符串,并禁用所有其他 OK 位,并保留 UTF-8 状态不变。

    void  SvPOK_only_UTF8(SV* sv)
SvPOKp

返回一个 U32 值,指示 SV 是否包含一个字符字符串。检查私有设置。请使用 SvPOK 代替。

    U32  SvPOKp(SV* sv)
sv_pos_b2u

offsetp 指向的值从字符串开头的字节数转换为等效的 UTF-8 字符数。处理魔法和类型强制。

优先使用 sv_pos_b2u_flags,它可以正确处理超过 2Gb 的字符串。

    void  sv_pos_b2u(SV * const sv, I32 * const offsetp)
sv_pos_b2u_flags

offset 从字符串开头的字节数转换为等效的 UTF-8 字符数。处理类型强制。flags 传递给 SvPV_flags,通常应为 SV_GMAGIC|SV_CONST_RETURN 以处理魔法。

    STRLEN  sv_pos_b2u_flags(SV * const sv, STRLEN const offset,
                             U32 flags)
sv_pos_u2b

offsetp 指向的值从字符串开头的 UTF-8 字符数转换为等效的字节数;如果 lenp 非零,则对 lenp 执行相同的操作,但这次从偏移量开始,而不是从字符串开头开始。处理魔法和类型强制。

优先使用 sv_pos_u2b_flags,它可以正确处理超过 2Gb 的字符串。

    void  sv_pos_u2b(SV * const sv, I32 * const offsetp,
                     I32 * const lenp)
sv_pos_u2b_flags

将偏移量从字符串开头的 UTF-8 字符数转换为等效的字节数;如果 lenp 非零,则对 lenp 执行相同的操作,但这次从 offset 开始,而不是从字符串开头开始。处理类型强制。flags 传递给 SvPV_flags,通常应为 SV_GMAGIC|SV_CONST_RETURN 以处理魔法。

    STRLEN  sv_pos_u2b_flags(SV * const sv, STRLEN uoffset,
                             STRLEN * const lenp, U32 flags)
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

这些函数都返回 sv 中字符串的指针,如果 sv 不包含字符串,则返回 sv 的字符串形式。SV 可能会缓存字符串形式,变为 SvPOK

这是一个非常基本且常见的操作,因此有许多略微不同的版本。

请注意,例如,SvPV(sv) 的返回值不保证等于 SvPVX(sv),也不保证 SvPVX(sv) 包含有效数据,也不保证对 SvPV(sv)(或这些形式中的其他形式)的连续调用每次都会返回相同的指针值。这是由于诸如重载和写时复制之类的处理方式造成的。在这些情况下,返回值可能指向临时缓冲区或类似内容。如果您绝对需要 SvPVX 字段有效(例如,如果您打算写入它),请参阅 "SvPV_force"

这些形式之间的区别是

名称中既没有 byte 也没有 utf8 的形式(例如,SvPVSvPV_nolen)可以公开 SV 的内部字符串缓冲区。如果该缓冲区完全由字节 0-255 组成,并且包含任何大于 127 的字节,那么您 **必须** 查询 SvUTF8 以确定字符串应包含的实际代码点。一般来说,最好优先使用 SvPVbyteSvPVutf8 等。有关更多详细信息,请参阅 "perlguts 中的如何将 Perl 字符串传递给 C 库?"

名称中带有flags 的形式允许您使用flags 参数来指定处理“get”魔法(通过设置SV_GMAGIC 标志)或跳过“get”魔法(通过清除它)。其他形式处理“get”魔法,除了名称中带有nomg 的形式,它们会跳过“get”魔法。

带有len 参数的形式会将该变量设置为结果字符串的字节长度(这些是宏,所以不要使用&len)。

名称中带有nolen 的形式表示它们没有len 参数。它们应该只在已知 PV 是一个以 NUL 字节结尾的 C 字符串,并且没有中间的 NUL 字符时使用;或者当您不关心它的长度时。

名称中带有const 的形式返回const char *,这样编译器有望在您尝试修改字符串内容时发出警告(除非您自己取消 const)。

其他形式返回一个可变指针,以便字符串可以被调用者修改;对于名称中带有mutable 的形式,这一点尤其强调。

从 5.38 版本开始,所有形式都保证只评估sv 一次。对于更早的 Perl 版本,请使用名称以x 结尾的形式进行单次评估。

SvPVutf8 类似于SvPV,但如果sv 不是 UTF-8 编码,则会先将其转换为 UTF-8。类似地,名称中带有utf8 的其他形式对应于它们各自没有utf8 的形式。

SvPVutf8_or_nullSvPVutf8_or_null_nomg 没有对应的非utf8 形式。相反,它们类似于SvPVutf8_nomg,但当sv 为 undef 时,它们会返回NULL

SvPVbyte 类似于SvPV,但如果sv 当前以 UTF-8 编码,则会先将其转换为字节表示形式。如果sv 不能从 UTF-8 降级,则会报错。类似地,名称中带有byte 的其他形式对应于它们各自没有byte 的形式。

SvPVbyte_or_null 没有对应的非byte 形式。相反,它类似于SvPVbyte,但当sv 为 undef 时,它会返回NULL

    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)
sv_2pv
sv_2pv_flags

这些实现了"SvPV" in perlapi 宏的各种形式。宏是首选的接口。

这些返回指向 SV 的字符串值的指针(如果需要,则将其强制转换为字符串),并将*lp 设置为其字节长度。

这些形式的不同之处在于,普通的 sv_2pvbyte 始终处理“get”魔法;而 sv_2pvbyte_flags 仅当 flags 包含 SV_GMAGIC 时才处理“get”魔法。

    char *  sv_2pv      (SV *sv, STRLEN *lp)
    char *  sv_2pv_flags(SV * const sv, STRLEN * const lp,
                         const U32 flags)
sv_2pvbyte
sv_2pvbyte_flags

这些实现了 "SvPVbyte" in perlapi 宏的各种形式。宏是首选接口。

这些返回指向 SV 的字节编码表示的指针,并将 *lp 设置为其长度。如果 SV 被标记为以 UTF-8 编码,则它将尽可能降级为字节字符串。如果 SV 无法降级,它们会报错。

这些形式的不同之处在于,普通的 sv_2pvbyte 始终处理“get”魔法;而 sv_2pvbyte_flags 仅当 flags 包含 SV_GMAGIC 时才处理“get”魔法。

    char *  sv_2pvbyte      (SV *sv, STRLEN * const lp)
    char *  sv_2pvbyte_flags(SV *sv, STRLEN * const lp,
                             const U32 flags)
SvPVCLEAR

确保 sv 是 SVt_PV 并且其 SvCUR 为 0,并且它被正确地以空字符结尾。等效于 sv_setpvs(""),但效率更高。

    char *  SvPVCLEAR(SV* sv)
SvPVCLEAR_FRESH

与 SvPVCLEAR 相似,但针对已经分配了 PV 缓冲区但没有 SvTHINKFIRST 的新创建的 SVt_PV/PVIV/PVNV/PVMG 进行了优化。

    char *  SvPVCLEAR_FRESH(SV* sv)
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

这些类似于 "SvPV",返回 SV 中的字符串,但会强制 SV 包含字符串 ("SvPOK"),并且只包含字符串 ("SvPOK_only"),无论如何。如果您要直接更新 "SvPVX",则需要使用其中一个 force 例程。

请注意,将任意标量强制转换为普通 PV 可能会从其中剥离有用的数据。例如,如果 SV 是 SvROK,那么引用将减少其引用计数,而 SV 本身可能会转换为 SvPOK 标量,其字符串缓冲区包含类似 "ARRAY(0x1234)" 的值。

这些形式之间的区别是

名称中包含 flags 的形式允许您使用 flags 参数指定执行“get”魔法(通过设置 SV_GMAGIC 标志)或跳过“get”魔法(通过清除它)。其他形式执行“get”魔法,除了名称中包含 nomg 的形式,它们跳过“get”魔法。

带有len 参数的形式会将该变量设置为结果字符串的字节长度(这些是宏,所以不要使用&len)。

名称中带有nolen 的形式表示它们没有len 参数。它们应该只在已知 PV 是一个以 NUL 字节结尾的 C 字符串,并且没有中间的 NUL 字符时使用;或者当您不关心它的长度时。

名称中包含 mutable 的形式实际上与不包含 mutable 的形式相同,但名称强调了字符串可以被调用者修改,这在所有形式中都是如此。

SvPVutf8_force 类似于 SvPV_force,但如果 sv 尚未为 UTF-8,则先将其转换为 UTF-8。

SvPVutf8x_force 类似于 SvPVutf8_force,但保证只评估 sv 一次;否则使用更高效的 SvPVutf8_force

SvPVbyte_forceSvPV_force 类似,但如果当前编码为 UTF-8,则会先将 sv 转换为字节表示形式。如果 SV 无法从 UTF-8 降级,则会抛出异常。

SvPVbytex_forceSvPVbyte_force 类似,但保证仅评估 sv 一次;否则使用更高效的 SvPVbyte_force

    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)
SvPV_free

释放 sv 中的 PV 缓冲区,使状态变得不稳定,因此应仅作为更大操作的一部分使用。

    void  SvPV_free(SV * sv)
sv_pvn_force_flags

以某种方式从 SV 中获取一个合理的字符串。如果 flags 设置了 SV_GMAGIC 位,则将对 sv 执行 "mg_get"(如果适用),否则不执行。sv_pvn_forcesv_pvn_force_nomg 是根据此函数实现的。通常,您希望使用各种包装宏,请参见 "SvPV_force""SvPV_force_nomg"

    char *  sv_pvn_force_flags(SV * const sv, STRLEN * const lp,
                               const U32 flags)
SvPV_renew

"SvGROW" 的低级微优化。通常最好使用 SvGROW。这是因为 SvPV_renew 忽略了 SvGROW 处理的潜在问题。sv 需要拥有一个真实的 PV,不受 COW 等因素的影响。在调用此函数之前使用 SV_CHECK_THINKFIRSTSV_CHECK_THINKFIRST_COW_DROP 可以清理它,但如果您不确定来源,为什么不直接使用 SvGROW 呢?

    void  SvPV_renew(SV* sv, STRLEN len)
SvPV_set

这可能不是您要使用的,您可能需要使用 "sv_usepvn_flags""sv_setpvn""sv_setpvs"

sv 中的 PV 指针的值设置为 Perl 分配的以 NUL 结尾的字符串 val。另请参见 "SvIV_set"

请记住释放之前的 PV 缓冲区。有很多事情需要检查。请注意,现有指针可能涉及写时复制或其他操作,因此请先执行 SvOOK_off(sv) 并使用 sv_force_normalSvPV_force(或检查 SvIsCOW 标志)以确保此修改是安全的。最后,如果它不是 COW,请调用 "SvPV_free" 以释放之前的 PV 缓冲区。

    void  SvPV_set(SV* sv, char* val)
SvPV_shrink_to_cur

修剪 sv 的 PV 中任何未使用的尾部内存,该内存需要拥有一个真实的 PV,不受 COW 等因素的影响。在使用此功能之前,请先考虑一下。节省空间是否真的值得放弃 COW?sv 的所需大小会保持不变吗?

如果两个答案都是肯定的,则在调用此函数之前使用 "SV_CHECK_THINKFIRST""SV_CHECK_THINKFIRST_COW_DROP"

    void  SvPV_shrink_to_cur(SV* sv)
sv_2pvutf8
sv_2pvutf8_flags

这些实现了 "SvPVutf8" in perlapi 宏的各种形式。宏是首选接口。

这些返回指向 SV 的 UTF-8 编码表示的指针,并将 *lp 设置为其字节长度。它们可能会导致 SV 作为副作用升级到 UTF-8。

这些形式的不同之处在于,普通的 sv_2pvutf8 始终处理“获取”魔法;而 sv_2pvutf8_flags 仅当 flags 包含 SV_GMAGIC 时才处理“获取”魔法。

    char *  sv_2pvutf8      (SV *sv, STRLEN * const lp)
    char *  sv_2pvutf8_flags(SV *sv, STRLEN * const lp,
                             const U32 flags)
SvPVX
SvPVX_const
SvPVX_mutable
SvPVXx

这些返回指向 SV 中物理字符串的指针。SV 必须包含一个字符串。在 5.9.3 之前,除非 SV 的类型 >= SVt_PV,否则执行这些操作是不安全的。

这些还用于在 XS AUTOLOAD 例程中存储自动加载子例程的名称。参见 "Autoloading with XSUBs" in perlguts

SvPVXxSvPVX 相同。

SvPVX_mutable 只是 SvPVX 的同义词,但它的名称强调了该字符串可以被调用者修改。

SvPVX_const 的不同之处在于,返回值已被强制转换,因此如果您尝试修改字符串的内容,编译器会报错(除非您自己取消 const 强制转换)。

    char*        SvPVX        (SV* sv)
    const char*  SvPVX_const  (SV* sv)
    char*        SvPVX_mutable(SV* sv)
    char*        SvPVXx       (SV* sv)
SvPVXtrue

返回一个布尔值,表示 sv 是否包含一个被认为是 TRUE 的 PV。如果 sv 不包含 PV,或者它包含的 PV 长度为零,或者仅包含单个字符 '0',则返回 FALSE。所有其他 PV 值都被认为是 TRUE。

从 Perl v5.37.1 开始,sv 仅被评估一次;在早期版本中,它可能会被评估多次。

    bool  SvPVXtrue(SV *sv)
SvREADONLY

如果参数是只读的,则返回 true,否则返回 false。通过 Internals::SvREADONLY() 公开给 perl 代码。

    U32  SvREADONLY(SV* sv)
SvREADONLY_off

将对象标记为非只读。这到底意味着什么取决于对象类型。通过 Internals::SvREADONLY() 公开给 perl 代码。

    U32  SvREADONLY_off(SV* sv)
SvREADONLY_on

将对象标记为只读。这到底意味着什么取决于对象类型。通过 Internals::SvREADONLY() 公开给 perl 代码。

    U32  SvREADONLY_on(SV* sv)
sv_ref

返回一个 SV,描述传递进来的 SV 是对什么的引用。

dst 可以是一个 SV,设置为描述,也可以是 NULL,在这种情况下,将返回一个临时的 SV。

如果 ob 为真且 SV 被祝福,则描述是类名,否则是 SV 的类型,“SCALAR”、“ARRAY” 等。

    SV *  sv_ref(SV *dst, const SV * const sv, const int ob)
SvREFCNT

返回对象的引用计数的值。通过 Internals::SvREFCNT() 公开给 perl 代码。

    U32  SvREFCNT(SV* sv)
SvREFCNT_dec
SvREFCNT_dec_set_NULL
SvREFCNT_dec_ret_NULL
SvREFCNT_dec_NN

这些会递减给定 SV 的引用计数。

SvREFCNT_dec_NN 只能在 sv 已知不为 NULL 时使用。

函数 SvREFCNT_dec_ret_NULL()SvREFCNT_dec() 相同,只是它返回一个 NULL SV *。它被 SvREFCNT_dec_set_NULL() 使用,后者是一个宏,当传递一个非 NULL 参数时,它会递减其参数的引用计数,然后将其设置为 NULL。您可以用以下形式的代码替换

if (sv) {
   SvREFCNT_dec_NN(sv);
   sv = NULL;
}

with

SvREFCNT_dec_set_NULL(sv);
    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)
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

这些都会递增给定 SV 的引用计数。没有 void 的名称返回 SV。

SvREFCNT_inc 是基本操作;其余的是在已知各种输入约束为真的情况下进行的优化;因此,所有都可以用 SvREFCNT_inc 替换。

SvREFCNT_inc_NN 只能在你知道 sv 不为 NULL 时使用。由于我们不需要检查 NULL,所以它更快更小。

SvREFCNT_inc_void 只能在你不需要返回值时使用。宏不需要返回有意义的值。

SvREFCNT_inc_void_NN 只能在你不需要返回值,并且你知道 sv 不为 NULL 时使用。宏不需要返回有意义的值,也不需要检查 NULL,所以它更小更快。

SvREFCNT_inc_simple 只能用于没有副作用的表达式。由于我们不需要存储临时值,所以它更快。

SvREFCNT_inc_simple_NN 只能用于没有副作用的表达式,并且你知道 sv 不为 NULL。由于我们不需要存储临时值,也不需要检查 NULL,所以它更快更小。

SvREFCNT_inc_simple_void 只能用于没有副作用的表达式,并且你不需返回值。

SvREFCNT_inc_simple_void_NN 只能用于没有副作用的表达式,你不需返回值,并且你知道 sv 不为 NULL

    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)
sv_reftype

返回一个字符串,描述 SV 是对什么的引用。

如果 ob 为真,并且 SV 被祝福,则字符串是类名,否则它是 SV 的类型,“SCALAR”、“ARRAY” 等。

    const char *  sv_reftype(const SV * const sv, const int ob)
sv_replace

将第一个参数设置为第二个参数的副本,然后删除原始参数。目标 SV 会物理地接管源 SV 的主体并继承其标志;但是,目标会保留其拥有的任何魔法,而源中的任何魔法都会被丢弃。请注意,这是一个相当专业的 SV 复制操作;大多数情况下,您需要使用sv_setsv或其众多宏前端。

    void  sv_replace(SV * const sv, SV * const nsv)
sv_report_used

转储所有尚未释放的 SV 的内容(调试辅助)。

    void  sv_report_used()
sv_reset

reset Perl 函数的底层实现。请注意,perl 级别的函数已基本弃用。

    void  sv_reset(const char *s, HV * const stash)
SvROK

测试 SV 是否为 RV。

    U32  SvROK(SV* sv)
SvROK_off

取消设置 SV 的 RV 状态。

    void  SvROK_off(SV* sv)
SvROK_on

告诉 SV 它是一个 RV。

    void  SvROK_on(SV* sv)
SvRV

取消引用 RV 以返回 SV。

    SV*  SvRV(SV* sv)
SvRV_set

sv中的 RV 指针的值设置为 val。参见"SvIV_set"

    void  SvRV_set(SV* sv, SV* val)
sv_rvunweaken

取消引用:清除此 RV 上的SvWEAKREF标志;从与目标 SV 关联的后向引用数组中删除对此 RV 的后向引用;增加目标的引用计数。静默忽略undef,并在非弱引用上发出警告。

    SV *  sv_rvunweaken(SV * const sv)
sv_rvweaken

弱化引用:设置此 RV 上的SvWEAKREF标志;如果目标 SV 还没有,则为其提供PERL_MAGIC_backref魔法;并将对此 RV 的后向引用推送到与该魔法关联的后向引用数组中。如果 RV 是魔法的,则在清除 RV 后会调用设置魔法。静默忽略undef,并在已弱化的引用上发出警告。

    SV *  sv_rvweaken(SV * const sv)
sv_setbool
sv_setbool_mg

这些将 SV 设置为真或假布尔值,如果需要,先升级。

它们的区别仅在于sv_setbool_mg处理“set”魔法;sv_setbool不处理。

    void  sv_setbool(SV *sv, bool b)
sv_set_bool

等效于sv_setsv(sv, bool_val ? &Pl_sv_yes : &PL_sv_no),但将来可能会变得更高效。不处理设置魔法。

perl 等效项是$sv = !!$expr;

在 perl 5.35.11 中引入。

    void  sv_set_bool(SV *sv, const bool bool_val)
sv_set_false

等效于 sv_setsv(sv, &PL_sv_no),但将来可能会变得更高效。不处理设置魔法。

Perl 等效项为 $sv = !1;

在 perl 5.35.11 中引入。

    void  sv_set_false(SV *sv)
sv_setiv
sv_setiv_mg

这些将一个整数复制到给定的 SV 中,如果需要先进行升级。

它们的区别仅在于 sv_setiv_mg 处理“设置”魔法;sv_setiv 不处理。

    void  sv_setiv   (SV * const sv, const IV num)
    void  sv_setiv_mg(SV * const sv, const IV i)
SvSETMAGIC

如果 SV 具有“设置”魔法,则调用 "mg_set"。在修改标量后,这很有必要,因为它可能是一个魔法变量,例如 $| 或一个绑定变量(它调用 STORE)。此宏会多次评估其参数。

    void  SvSETMAGIC(SV* sv)
SvSetMagicSV
SvSetMagicSV_nosteal
SvSetSV
SvSetSV_nosteal

如果 dsvssv 相同,则这些操作不会执行任何操作。否则,它们都会调用某种形式的 "sv_setsv"。它们可能会多次评估其参数。

唯一的区别是

SvSetMagicSVSvSetMagicSV_nosteal 随后在目标 SV 上执行任何必需的“设置”魔法;SvSetSVSvSetSV_nosteal 不会执行。

SvSetSV_nosteal SvSetMagicSV_nosteal 调用 sv_setsv 的非破坏性版本。

    void  SvSetMagicSV(SV* dsv, SV* ssv)
sv_setnv
sv_setnv_mg

这些将一个双精度数复制到给定的 SV 中,如果需要先进行升级。

它们的区别仅在于 sv_setnv_mg 处理“设置”魔法;sv_setnv 不处理。

    void  sv_setnv(SV * const sv, const NV num)
sv_setpv
sv_setpv_mg
sv_setpvn
sv_setpvn_fresh
sv_setpvn_mg
sv_setpvs
sv_setpvs_mg

这些将一个字符串复制到 SV sv 中,确保它是 "SvPOK_only"

pvs 形式中,字符串必须是 C 字面量字符串,用双引号括起来。

pvn 形式中,字符串的第一个字节由 ptr 指向,len 指示要复制的字节数,可能包括嵌入的 NUL 字符。

在普通 pv 形式中,ptr 指向一个以 NUL 结尾的 C 字符串。也就是说,它指向字符串的第一个字节,复制操作一直进行到遇到第一个 NUL 字节为止。

在接受 ptr 参数的表单中,如果它是 NULL,则 SV 将变为未定义。

这些函数不会更改 UTF-8 标志。结果中保证存在终止的 NUL 字节。

_mg 表单处理“设置”魔法;其他表单跳过所有魔法。

sv_setpvn_freshsv_setpvn 的简化替代方案,仅用于具有已升级为 SVt_PV、SVt_PVIV、SVt_PVNV 或 SVt_PVMG 的新 sv。

    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")
sv_setpv_bufsize

将 SV 设置为长度为 cur 字节的字符串,至少有 len 字节可用。确保 SvEND 处存在空字节。返回指向 SvPV 缓冲区的 char * 指针。

    char  *  sv_setpv_bufsize(SV * const sv, const STRLEN cur,
                              const STRLEN len)
sv_setpvf
sv_setpvf_mg
sv_setpvf_mg_nocontext
sv_setpvf_nocontext

这些函数的工作方式类似于 "sv_catpvf",但将文本复制到 SV 中而不是追加它。

这些函数之间的区别是

sv_setpvf_mgsv_setpvf_mg_nocontext 执行“设置”魔法;sv_setpvfsv_setpvf_nocontext 跳过所有魔法。

sv_setpvf_nocontextsv_setpvf_mg_nocontext 不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

注意:sv_setpvf 必须显式调用为 Perl_sv_setpvf,并带有 aTHX_ 参数。

注意:sv_setpvf_mg 必须显式调用为 Perl_sv_setpvf_mg,并带有 aTHX_ 参数。

    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, ...)
sv_setref_iv

将整数复制到新的 SV 中,可以选择对 SV 进行祝福。rv 参数将升级为 RV。该 RV 将被修改为指向新的 SV。classname 参数指示祝福的包。将 classname 设置为 NULL 以避免祝福。新的 SV 将具有 1 的引用计数,并且将返回 RV。

    SV *  sv_setref_iv(SV * const rv, const char * const classname,
                       const IV iv)
sv_setref_nv

将双精度数复制到新的 SV 中,可以选择对 SV 进行祝福。rv 参数将升级为 RV。该 RV 将被修改为指向新的 SV。classname 参数指示祝福的包。将 classname 设置为 NULL 以避免祝福。新的 SV 将具有 1 的引用计数,并且将返回 RV。

    SV *  sv_setref_nv(SV * const rv, const char * const classname,
                       const NV nv)
sv_setref_pv

将指针复制到新的 SV 中,可以选择对 SV 进行祝福。rv 参数将升级为 RV。该 RV 将被修改为指向新的 SV。如果 pv 参数为 NULL,则 PL_sv_undef 将被放置到 SV 中。classname 参数指示祝福的包。将 classname 设置为 NULL 以避免祝福。新的 SV 将具有 1 的引用计数,并且将返回 RV。

不要与其他 Perl 类型(如 HV、AV、SV、CV)一起使用,因为这些对象会在指针复制过程中被破坏。

请注意,sv_setref_pvn 复制字符串,而此函数复制指针。

    SV *  sv_setref_pv(SV * const rv, const char * const classname,
                       void * const pv)
sv_setref_pvn

将字符串复制到新的 SV 中,可以选择对 SV 进行祝福。字符串的长度必须使用 n 指定。rv 参数将被升级为 RV。该 RV 将被修改为指向新的 SV。classname 参数指示祝福的包。将 classname 设置为 NULL 以避免祝福。新的 SV 将具有 1 的引用计数,并将返回 RV。

请注意,sv_setref_pv 复制指针,而此函数复制字符串。

    SV *  sv_setref_pvn(SV * const rv, const char * const classname,
                        const char * const pv, const STRLEN n)
sv_setref_pvs

sv_setref_pvn 相似,但接受文字字符串而不是字符串/长度对。

    SV *  sv_setref_pvs(SV *const rv, const char *const classname,
                        "literal string")
sv_setref_uv

将无符号整数复制到新的 SV 中,可以选择对 SV 进行祝福。rv 参数将被升级为 RV。该 RV 将被修改为指向新的 SV。classname 参数指示祝福的包。将 classname 设置为 NULL 以避免祝福。新的 SV 将具有 1 的引用计数,并将返回 RV。

    SV *  sv_setref_uv(SV * const rv, const char * const classname,
                       const UV uv)
sv_setrv_inc
sv_setrv_inc_mg

sv_setrv_noinc 相同,但会增加 ref 的引用计数。

sv_setrv_inc_mg 将在 SV 上调用“set”魔法;sv_setrv_inc 不会。

    void  sv_setrv_inc(SV * const sv, SV * const ref)
sv_setrv_noinc
sv_setrv_noinc_mg

将 SV 指针复制到给定的 SV 中作为 SV 引用,并在必要时进行升级。在此之后,SvRV(sv) 等于 ref。这不会调整 ref 的引用计数。引用 ref 必须不为 NULL。

sv_setrv_noinc_mg 将在 SV 上调用“set”魔法;sv_setrv_noinc 不会。

    void  sv_setrv_noinc(SV * const sv, SV * const ref)
sv_setsv
sv_setsv_flags
sv_setsv_mg
sv_setsv_nomg

这些函数将源 SV ssv 的内容复制到目标 SV dsv 中。如果 ssv 是可销毁的,它可能会被销毁,因此如果需要重用源 SV,请不要使用这些函数。简单来说,它们执行按值复制,覆盖目标中任何以前的内容。

它们的区别仅在于

sv_setsvssv 调用 'get' 魔法,但跳过 dsv 上的 'set' 魔法。

sv_setsv_mgssv 调用 'get' 魔法,并对 dsv 调用 'set' 魔法。

sv_setsv_nomg 跳过所有魔法。

sv_setsv_flags 具有一个 flags 参数,您可以使用它来指定任何魔法处理组合,您还可以指定 SV_NOSTEAL,以便不会窃取临时变量的缓冲区。

您可能希望改为使用各种包装器之一,例如 "SvSetSV""SvSetSV_nosteal""SvSetMagicSV""SvSetMagicSV_nosteal"

sv_setsv_flags 是复制标量的主要函数,大多数其他类似复制的函数和宏都在其内部使用它。

    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)
sv_set_true

等效于 sv_setsv(sv, &PL_sv_yes),但将来可能会变得更高效。不处理设置魔法。

Perl 等效项为 $sv = !0;

在 perl 5.35.11 中引入。

    void  sv_set_true(SV *sv)
sv_set_undef

等效于 sv_setsv(sv, &PL_sv_undef),但更高效。不处理设置魔法。

Perl 等效项为 $sv = undef;。请注意,它不会释放任何字符串缓冲区,与 undef $sv 不同。

在 perl 5.25.12 中引入。

    void  sv_set_undef(SV *sv)
sv_setuv
sv_setuv_mg

这些函数将无符号整数复制到给定的 SV 中,如果需要,先进行升级。

它们的区别仅在于 sv_setuv_mg 处理 'set' 魔法;sv_setuv 不处理。

    void  sv_setuv   (SV * const sv, const UV num)
    void  sv_setuv_mg(SV * const sv, const UV u)
SvSHARE

如果已加载合适的模块,则安排 sv 在线程之间共享。

    void  SvSHARE(SV* sv)
SvSHARED_HASH

返回由 "newSVpvn_share" 创建的 sv 的哈希值。

    struct hek*  SvSHARED_HASH(SV * sv)
SvSTASH

返回 SV 的存储区。

    HV*  SvSTASH(SV* sv)
SvSTASH_set

sv 中的 STASH 指针的值设置为 val。请参阅 "SvIV_set"

    void  SvSTASH_set(SV* sv, HV* val)
sv_streq

调用 sv_streq_flags 函数并使用 SV_GMAGIC 标志的便捷快捷方式。此函数的行为类似于 Perl 代码 $sv1 eq $sv2

    bool  sv_streq(SV *sv1, SV *sv2)
sv_streq_flags

返回一个布尔值,指示两个 SV 中的字符串是否相同。如果 flags 参数设置了 SV_GMAGIC 位,它也会处理 get-magic。如果需要,会将它的参数强制转换为字符串。将 NULL 视为 undef。正确处理 UTF8 标志。

如果 flags 没有设置 SV_SKIP_OVERLOAD 位,则会尝试使用 eq 重载。如果不存在此类重载或设置了标志,则将使用常规字符串比较。

    bool  sv_streq_flags(SV *sv1, SV *sv2, const U32 flags)
SvTRUE
SvTRUE_NN
SvTRUE_nomg
SvTRUE_nomg_NN
SvTRUEx

这些返回一个布尔值,指示 Perl 是否会将 SV 评估为真或假。有关已定义/未定义测试,请参阅 "SvOK"

从 Perl 5.32 开始,所有函数都保证只评估 sv 一次。在该版本之前,只有 SvTRUEx 保证单次评估;现在 SvTRUExSvTRUE 相同。

SvTRUE_nomgTRUE_nomg_NN 不执行“get”魔法;其他函数会执行,除非标量已经是 SvPOKSvIOKSvNOK(公共标志,而不是私有标志)。

SvTRUE_NN 类似于 "SvTRUE",但假设 sv 非空 (NN)。如果可能为空,请使用普通的 SvTRUE

SvTRUE_nomg_NN 类似于 "SvTRUE_nomg",但假设 sv 非空 (NN)。如果可能为空,请使用普通的 SvTRUE_nomg

    bool  SvTRUE(SV *sv)
SvTYPE

返回 SV 的类型。请参阅 "svtype"

    svtype  SvTYPE(SV* sv)
SvUNLOCK

如果已加载合适的模块,则释放 sv 上的互斥锁。

    void  SvUNLOCK(SV* sv)
sv_unmagic

从 SV 中删除所有类型为 type 的魔法。

    int  sv_unmagic(SV * const sv, const int type)
sv_unmagicext

从 SV 中移除所有类型为 type 且具有指定 vtbl 的魔法。

    int  sv_unmagicext(SV * const sv, const int type,
                       const MGVTBL *vtbl)
sv_unref

取消 SV 的 RV 状态,并递减被 RV 引用的对象的引用计数。这几乎可以看作是 newSVrv 的逆操作。这相当于 sv_unref_flags,其中 flag 为零。参见 "SvROK_off"

    void  sv_unref(SV *sv)
sv_unref_flags

取消 SV 的 RV 状态,并递减被 RV 引用的对象的引用计数。这几乎可以看作是 newSVrv 的逆操作。cflags 参数可以包含 SV_IMMEDIATE_UNREF 来强制递减引用计数(否则递减操作取决于引用计数是否为 1 或引用是否为只读 SV)。参见 "SvROK_off"

    void  sv_unref_flags(SV * const ref, const U32 flags)
SvUOK

返回一个布尔值,指示 SV 是否包含必须解释为无符号的整数。一个非负整数,其值在 IV 和 UV 的范围内,可以标记为 SvUOKSvIOK

    bool  SvUOK(SV* sv)
SvUPGRADE

用于将 SV 升级到更复杂的形态。如果需要,使用 sv_upgrade 来执行升级。参见 "svtype"

    void  SvUPGRADE(SV* sv, svtype type)
sv_upgrade

将 SV 升级到更复杂的形态。通常会为 SV 添加一个新的主体类型,然后将尽可能多的信息从旧主体复制到新主体。如果 SV 已经处于比请求的更复杂的形态,则会报错。通常情况下,您应该使用 SvUPGRADE 宏包装器,它会在调用 sv_upgrade 之前检查类型,因此不会报错。另请参见 "svtype"

    void  sv_upgrade(SV * const sv, svtype new_type)
sv_usepvn
sv_usepvn_flags
sv_usepvn_mg

这些函数告诉 SV 使用 ptr 作为其字符串值。通常情况下,SV 会将字符串存储在 SV 内部,但这些函数告诉 SV 使用外部字符串。

ptr 应该指向由 "Newx" 分配的内存。它必须是 Newx 分配的内存块的起始位置,而不是指向其中间位置的指针(注意 OOK 和写时复制),并且不能来自非 Newx 内存分配器,例如 malloc。字符串长度 len 必须提供。默认情况下,此函数将 "Renew"(即重新分配,移动)指向 ptr 的内存,因此在将指针传递给 sv_usepvn 后,程序员不应该释放或使用该指针,也不应该使用该指针“后面”的任何指针(例如,ptr + 1)。

sv_usepvn_flags 函数中,如果 flags & SV_SMAGIC 为真,则在返回之前调用 SvSETMAGIC。如果 flags & SV_HAS_TRAILING_NUL 为真,则 ptr[len] 必须为 NUL,并且将跳过重新分配(即,缓冲区实际上至少比 len 长 1 字节,并且已经满足存储在 SvPVX 中的要求)。

sv_usepvn 只是 sv_usepvn_flags,其中 flags 设置为 0,因此跳过“设置”魔法。

sv_usepvn_mg 只是 sv_usepvn_flags,其中 flags 设置为 SV_SMAGIC,因此执行“设置”魔法。

    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)
sv_utf8_decode

如果 SV 的 PV 是 Perl 扩展 UTF-8 中的八位字节序列,并且包含多字节字符,则会打开 SvUTF8 标志,使其看起来像一个字符。如果 PV 仅包含单字节字符,则 SvUTF8 标志保持关闭。扫描 PV 以验证其有效性,如果 PV 是无效的 UTF-8,则返回 FALSE。

    bool  sv_utf8_decode(SV * const sv)
sv_utf8_downgrade
sv_utf8_downgrade_flags
sv_utf8_downgrade_nomg

这些尝试将 SV 的 PV 从字符转换为字节。如果 PV 包含无法放入一个字节的字符,则此转换将失败;在这种情况下,如果 fail_ok 为真,则返回 FALSE;否则它们会抛出异常。

它们不是通用的 Unicode 到字节编码接口:请使用 Encode 扩展来实现这一点。

它们的区别仅在于

sv_utf8_downgradesv 上处理“获取”魔法。

sv_utf8_downgrade_nomg 不会。

sv_utf8_downgrade_flags 有一个额外的 flags 参数,您可以在其中指定 SV_GMAGIC 来处理“获取”魔法,或者将其清除以不处理“获取”魔法。

    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)
sv_utf8_encode

将 SV 的 PV 转换为 UTF-8,但随后关闭 SvUTF8 标志,使其看起来像八位字节序列。

    void  sv_utf8_encode(SV * const sv)
SvUTF8_off

取消设置 SV 的 UTF-8 状态(数据不会更改,只是标志)。不要随意使用。

    void  SvUTF8_off(SV *sv)
SvUTF8_on

打开 SV 的 UTF-8 状态(数据不会更改,只是标志)。不要随意使用。

    void  SvUTF8_on(SV *sv)
sv_utf8_upgrade
sv_utf8_upgrade_flags
sv_utf8_upgrade_flags_grow
sv_utf8_upgrade_nomg

这些函数将 SV 的 PV 转换为其 UTF-8 编码形式。如果 SV 尚未为字符串形式,则会强制转换为字符串形式。它们始终设置 SvUTF8 标志,以避免将来进行有效性检查,即使整个字符串在 UTF-8 中与非 UTF-8 相同也是如此。它们返回转换后的字符串中的字节数。

这些函数仅在两个方面有所不同。主要区别在于它们是否对 sv 执行“获取魔法”。sv_utf8_upgrade_nomg 跳过“获取魔法”;sv_utf8_upgrade 执行“获取魔法”;而 sv_utf8_upgrade_flagssv_utf8_upgrade_flags_grow 则根据 flags 中是否设置了 SV_GMAGIC 位来执行或不执行“获取魔法”。

另一个区别是 sv_utf8_upgrade_flags_grow 有一个额外的参数 extra,它允许调用者指定要保留的额外空间量,超出实际转换所需的量。当调用者知道很快将需要更多空间时,使用此形式可以更有效地通过一次调用从系统请求空间。除了这一点,此形式与 sv_utf8_upgrade_flags 相同。

这些函数不是通用的字节编码到 Unicode 接口:请使用 Encode 扩展来实现此目的。

SV_FORCE_UTF8_UPGRADE 标志现在已被忽略。

    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)
SvUTF8

返回一个 U32 值,指示 SV 的 UTF-8 状态。如果设置正确,这将指示 SV 是否包含 UTF-8 编码的数据。您应该在调用 "SvPV" 或其变体之后使用此函数,以防对字符串重载的任何调用更新内部标志。

如果您想考虑 bytes 编译指示,请使用 "DO_UTF8" 代替。

    U32  SvUTF8(SV* sv)
SvUV
SvUV_nomg
SvUVx

这些函数将给定的 SV 强制转换为 UV 并返回它。在许多情况下,返回值将存储在 sv 的 UV 槽中,但并非所有情况下都是如此。(使用 "sv_setuv" 来确保它确实存储在 UV 槽中)。

从 5.37.1 开始,所有都保证只评估 sv 一次。

SvUVx 现在与 SvUV 相同,但在 5.37.1 之前,它是唯一保证仅评估 sv 一次的表单。

    UV  SvUV(SV *sv)
sv_2uv_flags

返回 SV 的无符号整数值,执行任何必要的字符串转换。如果 flags 设置了 SV_GMAGIC 位,则首先执行 mg_get()。通常通过 SvUV(sv)SvUVx(sv) 宏使用。

    UV  sv_2uv_flags(SV * const sv, const I32 flags)
SvUV_set

sv 中的 UV 指针的值设置为 val。参见 "SvIV_set"

    void  SvUV_set(SV* sv, UV val)
SvUVX

返回 SV 的 UV 槽中的原始值,不进行检查或转换。仅在您确定 SvIOK 为真时使用。另请参见 "SvUV"

    UV  SvUVX(SV* sv)
SvUVXx

已弃用! 计划从 Perl 的未来版本中删除 SvUVXx。不要在新的代码中使用它;从现有代码中删除它。

这是 "SvUVX" 的不必要同义词。

    UV  SvUVXx(SV* sv)
sv_vcatpvf
sv_vcatpvf_mg

这些处理它们的论据,就像 sv_vcatpvfn 被调用为一个非空的 C 样式可变参数列表一样,并将格式化的输出追加到 sv

它们的区别仅在于 sv_vcatpvf_mg 执行“设置”魔法;sv_vcatpvf 跳过“设置”魔法。

两者都执行“获取”魔法。

它们通常通过其前端 "sv_catpvf""sv_catpvf_mg" 访问。

    void  sv_vcatpvf(SV * const sv, const char * const pat,
                     va_list * const args)
sv_vcatpvfn
sv_vcatpvfn_flags

这些处理它们的论据,就像 vsprintf(3) 一样,并将格式化的输出追加到 SV。如果 C 样式可变参数列表缺失(NULL),则它们使用 SV 数组。仅当使用 SV 数组时才支持参数重新排序(使用格式说明符,如 %2$d%*2$d);使用 C 样式 va_list 参数列表和使用参数重新排序的格式字符串将导致异常。

在启用 taint 检查的情况下运行时,它们通过 maybe_tainted 指示结果是否不可信(通常是由于使用了区域设置)。

它们假设 patsv 具有相同的 utf8 属性。确保这一点是调用者的责任。

它们的区别在于 sv_vcatpvfn_flags 有一个 flags 参数,您可以在其中设置或清除 SV_GMAGIC 和/或 SV_SMAGIC 标志,以指定要处理或不处理的魔法;而普通的 sv_vcatpvfn 始终指定“获取”和“设置”魔法。

它们通常通过以下前端之一使用:"sv_vcatpvf""sv_vcatpvf_mg"

    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)
SvVOK

返回一个布尔值,指示 SV 是否包含一个 v-string。

    bool  SvVOK(SV* sv)
sv_vsetpvf
sv_vsetpvf_mg

这些函数的工作方式类似于 "sv_vcatpvf",但它们将文本复制到 SV 中,而不是追加它。

它们的区别仅在于 sv_vsetpvf_mg 执行“设置”魔法;sv_vsetpvf 跳过所有魔法。

它们通常通过它们的前端使用,即 "sv_setpvf""sv_setpvf_mg"

    void  sv_vsetpvf(SV * const sv, const char * const pat,
                     va_list * const args)
sv_vsetpvfn

工作方式类似于 sv_vcatpvfn,但它将文本复制到 SV 中,而不是追加它。

通常通过以下前端之一使用:"sv_vsetpvf""sv_vsetpvf_mg"

    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)
SvVSTRING_mg

返回 vstring 魔法,如果没有则返回 NULL。

    MAGIC*  SvVSTRING_mg(SV * sv)
vnewSVpvf

类似于 "newSVpvf",但参数是一个封装的参数列表。

    SV *  vnewSVpvf(const char * const pat, va_list * const args)

污染

SvTAINT

如果启用了污染,并且当前表达式的某些输入被污染(通常是变量,但也可能是区域设置等隐式输入),则会污染 SV。SvTAINT 以悲观的方式将该污染传播到表达式的输出;即,不关注哪些输出受哪些输入的影响。

    void  SvTAINT(SV* sv)
SvTAINTED

检查 SV 是否被污染。如果被污染,则返回 TRUE,否则返回 FALSE。

    bool  SvTAINTED(SV* sv)
SvTAINTED_off

取消污染 SV。使用此例程时要非常小心,因为它会绕过 Perl 的一些基本安全功能。XS 模块作者不应使用此函数,除非他们完全理解无条件取消污染值的所有含义。取消污染应该以标准的 Perl 方式完成,通过精心设计的正则表达式,而不是直接取消污染变量。

    void  SvTAINTED_off(SV* sv)
SvTAINTED_on

如果启用了污染,则将 SV 标记为污染。

    void  SvTAINTED_on(SV* sv)

时间

ASCTIME_R_PROTO

此符号编码 asctime_r 的原型。如果 d_asctime_r 未定义,则为零;如果 d_asctime_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

CTIME_R_PROTO

此符号编码 ctime_r 的原型。如果 d_ctime_r 未定义,则为零;如果 d_ctime_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

GMTIME_MAX

此符号包含系统函数 gmtime () 接受的 time_t 偏移量的最大值,默认值为 0。

GMTIME_MIN

此符号包含系统函数 gmtime () 接受的 time_t 偏移量的最小值,默认值为 0。

GMTIME_R_PROTO

此符号编码 gmtime_r 的原型。如果 d_gmtime_r 未定义,则为零;如果 d_gmtime_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

HAS_ASCTIME_R

如果定义了此符号,则表示 asctime_r 例程可用于以可重入方式执行 asctime。

HAS_ASCTIME64

如果定义了此符号,则表示 asctime64 () 例程可用于执行 asctime () 的 64 位变体。

HAS_CTIME_R

如果定义了此符号,则表示 ctime_r 例程可用于以可重入方式执行 ctime。

HAS_CTIME64

如果定义了此符号,则表示 ctime64 () 例程可用于执行 ctime () 的 64 位变体。

HAS_DIFFTIME

如果定义了此符号,则表示 difftime 例程可用。

HAS_DIFFTIME64

如果定义了此符号,则表示 difftime64 () 例程可用于执行 difftime () 的 64 位变体。

HAS_FUTIMES

如果定义了此符号,则表示 futimes 例程可用于使用 struct timevals 更改文件描述符时间戳。

HAS_GETITIMER

如果定义了此符号,则表示 getitimer 例程可用于返回间隔计时器。

HAS_GETTIMEOFDAY

如果定义了此符号,则表示 gettimeofday() 系统调用可用于亚秒精度时钟。通常,需要包含文件 sys/resource.h(参见 "I_SYS_RESOURCE")。类型“Timeval”应用于引用“struct timeval”。

HAS_GMTIME_R

如果定义了此符号,则表示 gmtime_r 例程可用于以可重入方式执行 gmtime。

HAS_GMTIME64

如果定义了此符号,则表示 gmtime64 () 例程可用于执行 gmtime () 的 64 位变体。

HAS_LOCALTIME_R

如果定义了此符号,则表示 localtime_r 例程可用于以可重入方式执行 localtime。

HAS_LOCALTIME64

如果定义了此符号,则表示 localtime64 () 例程可用于执行 localtime () 的 64 位变体。

HAS_MKTIME

如果定义了此符号,则表示 mktime 例程可用。

HAS_MKTIME64

如果定义了此符号,则表示 mktime64 () 例程可用于执行 mktime () 的 64 位变体。

HAS_NANOSLEEP

如果定义了此符号,则表示 nanosleep 系统调用可用于以 1E-9 秒精度休眠。

HAS_SETITIMER

如果定义了此符号,则表示 setitimer 例程可用于设置间隔计时器。

HAS_STRFTIME

如果定义了此符号,则表示 strftime 例程可用于执行时间格式化。

HAS_TIME

如果定义了此符号,则表示 time() 例程存在。

HAS_TIMEGM

如果定义了此符号,则表示 timegm 例程可用于执行 gmtime () 的反向操作。

HAS_TIMES

如果定义了此符号,则表示 times() 例程存在。请注意,这在某些系统(SUNOS)上已过时,这些系统现在使用 getrusage()。可能需要包含 sys/times.h

HAS_TM_TM_GMTOFF

如果定义了此符号,则表示 C 程序的 struct tm 结构体包含 tm_gmtoff 字段。

HAS_TM_TM_ZONE

如果定义了此符号,则表示 C 程序的 struct tm 结构体包含 tm_zone 字段。

HAS_TZNAME

如果定义了此符号,则表示 tzname[] 数组可用于访问时区名称。

HAS_USLEEP

如果定义了此符号,则表示 usleep 函数可用,允许进程以亚秒精度休眠。

HAS_USLEEP_PROTO

如果定义了此符号,则表示系统提供了 usleep() 函数的原型。否则,程序需要自行提供原型。一个好的猜测是

extern int usleep(useconds_t);
I_TIME

此符号始终定义,并指示 C 程序应包含 time.h 头文件。

    #ifdef I_TIME
        #include <time.h>
    #endif
I_UTIME

如果定义了此符号,则指示 C 程序应包含 utime.h 头文件。

    #ifdef I_UTIME
        #include <utime.h>
    #endif
LOCALTIME_MAX

此符号包含系统函数 localtime () 接受的 time_t 偏移量的最大值,默认值为 0

LOCALTIME_MIN

此符号包含系统函数 localtime () 接受的 time_t 偏移量的最小值,默认值为 0

LOCALTIME_R_NEEDS_TZSET

许多 libc 的 localtime_r 实现不调用 tzset,这使得它们与 localtime() 不同,并且在没有显式调用 tzset 的情况下,使用 $ENV{TZ} 进行时区更改变得不可能。此符号使我们在 localtime_r 之前调用 tzset

LOCALTIME_R_PROTO

此符号编码 localtime_r 的原型。如果 d_localtime_r 未定义,则为零;如果 d_localtime_r 已定义,则为 reentr.h 中的 REENTRANT_PROTO_T_ABC 宏之一。

L_R_TZSET

如果 localtime_r() 需要 tzset,则在此定义中定义它

mini_mktime

struct tm 值进行规范化,不使用 mktime() 的本地时间语义(以及开销)。

    void  mini_mktime(struct tm *ptm)
my_strftime

strftime(),但使用不同的 API,因此返回值是指向格式化结果的指针(必须安排由调用者释放)。这允许该函数根据需要增加缓冲区大小,因此调用者不必担心这一点。

失败时返回 NULL。

请注意,此函数实际上忽略了 yday 和 wday,因为 mini_mktime() 会覆盖它们。

另请注意,它始终在程序的底层 LC_TIME 本地化中执行,提供基于该本地化的结果。

    char *  my_strftime(const char *fmt, int sec, int min, int hour,
                        int mday, int mon, int year, int wday,
                        int yday, int isdst)
switch_to_global_locale

此函数将调用线程的本地化状态复制到程序的全局本地化中,并将线程转换为使用该全局本地化。

它的目的是使 Perl 可以安全地与访问全局本地化的 C 库一起使用,这些库无法转换为不访问它。实际上,这意味着调用 setlocale(3) 的库(在非 Windows 系统上)。(为了可移植性,最好在 Windows 上也使用它。)

使用它的一个缺点是它会禁用 Perl 提供的服务,这些服务可以隐藏代码中的本地化问题。您最有可能错过的服务是浮点数中的基数字符(小数点)。在调用此函数后执行的代码不再能仅仅假设此字符对于当前情况是正确的。

要返回到 Perl 控制并重新启动问题预防服务,请调用 "sync_locale"。在切换生效期间执行的任何纯 Perl 代码的行为都是未定义的。

全局区域设置和每个线程的区域设置是独立的。只要只有一个线程转换为全局区域设置,一切都能正常运行。但如果有多个线程转换,它们很容易相互干扰,并且很可能发生竞争条件。在 Visual Studio 15 之前的 Windows 系统上(微软在该版本修复了一个 bug),即使只有一个线程被转换为全局区域设置,也可能发生竞争条件,但前提是您使用以下操作

POSIX::localeconv
I18N::Langinfo,项目 CRNCYSTRTHOUSEP
"Perl_langinfo" in perlapi,项目 CRNCYSTRTHOUSEP

第一个问题无法修复(除非升级到更高版本的 Visual Studio),但可以通过让 Perl 更改其计算这些值的算法来解决后两个问题,使用 Windows API 函数(可能是 GetNumberFormatGetCurrencyFormat);欢迎提供补丁。

XS 代码永远不应该调用普通的 setlocale,而应该转换为调用 Perl_setlocale(它是系统 setlocale 的直接替代)或使用 perlcall 中给出的方法来调用 POSIX::setlocale。无论哪种方式,都会透明地正确处理单线程和多线程、支持 POSIX 2008 或不支持的所有情况。

    void  switch_to_global_locale()
sync_locale

此函数将程序全局区域设置的状态复制到调用线程,并将该线程转换为使用每个线程的区域设置(如果尚未转换,并且平台支持它们)。如果不在 use locale 的词法范围内,则 LC_NUMERIC 区域设置将切换到标准状态(使用 C 区域设置的约定)。

Perl 现在将认为它控制着区域设置。

由于无线程的 Perl 只有一个全局区域设置,因此此函数在没有线程的情况下是无操作的。

此函数旨在与执行区域设置操作的 C 库一起使用。它允许 Perl 适应使用它们。在返回到 Perl 空间之前调用此函数,以便它知道 C 代码将事物留在了什么状态。

XS 代码不应该自行操作区域设置。相反,可以在任何时候使用 Perl_setlocale 来查询或更改区域设置(尽管在没有多线程安全区域设置操作的多线程系统上更改区域设置是不友好的且危险的。(参见 "perllocale 中的多线程操作")。

应避免使用 libc setlocale(3) 函数。然而,某些从 XS 调用的非 Perl 库确实会调用它,并且它们的行為可能无法更改。只要只涉及一个线程,此函数以及 "switch_to_global_locale" 可以用来在这种情况下获得无缝的行為。

如果库有选项可以关闭其区域设置操作,那么这样做比使用此机制更可取。Gtk 就是这样的库。

返回值是一个布尔值:如果调用时的全局区域设置对调用者有效,则为 TRUE;如果使用的是每个线程的区域设置,则为 FALSE。

    bool  sync_locale()

类型定义名称

DB_Hash_t

此符号包含 db.h 头文件中的前缀结构元素的类型。在旧版本的 DB 中,它是 int,而在新版本中它是 size_t

DB_Prefix_t

此符号包含 db.h 头文件中的前缀结构元素的类型。在旧版本的 DB 中,它是 int,而在新版本中它是 u_int32_t

Direntry_t

此符号根据 dirent 是否可用而设置为 'struct direct' 或 'struct dirent'。您应该使用此伪类型来便携地声明您的目录条目。

Fpos_t

此符号保存用于在 libc 中声明文件位置的类型。它可以是 fpos_t、long、uint 等。可能需要包含 sys/types.h 来获取任何类型定义的信息。

Free_t

此变量包含 free() 的返回值类型。它通常是 void,但偶尔是 int。

Gid_t

此符号保存 getgid() 的返回值类型,以及 setrgid() 及相关函数的参数类型。通常,它是内核中组 ID 的类型。它可以是 int、ushort、gid_t 等。可能需要包含 sys/types.h 以获取任何 typedef 的信息。

Gid_t_f

此符号定义用于打印 Gid_t 的格式字符串。

Gid_t_sign

此符号保存 Gid_t 的符号性。1 表示无符号,-1 表示有符号。

Gid_t_size

此符号保存 Gid_t 的大小(以字节为单位)。

Groups_t

此符号保存用于 getgroups()setgroups() 的第二个参数的类型。通常,这与 gidtype (gid_t) 相同,但有时并非如此。它可以是 int、ushort、gid_t 等。可能需要包含 sys/types.h 以获取任何 typedef 的信息。这仅在您有 getgroups()setgroups() 时才需要。

Malloc_t

此符号是 malloc 和 realloc 返回的指针类型。

Mmap_t

此符号保存 mmap() 系统调用的返回值类型(同时也是第一个参数的类型)。通常设置为 'void *' 或 'caddr_t'。

Mode_t

此符号保存用于声明系统调用文件模式的类型。它通常是 mode_t,但可能是 int 或 unsigned short。可能需要包含 sys/types.h 以获取任何 typedef 的信息。

Netdb_hlen_t

此符号保存用于 gethostbyaddr() 的第二个参数的类型。

Netdb_host_t

此符号保存用于 gethostbyaddr() 的第一个参数的类型。

Netdb_name_t

此符号保存用于 gethostbyname() 的参数的类型。

Netdb_net_t

此符号保存用于 getnetbyaddr() 的第一个参数的类型。

Off_t

此符号保存用于声明内核中偏移量的类型。它可以是 int、long、off_t 等。可能需要包含 sys/types.h 以获取任何 typedef 的信息。

Off_t_size

此符号保存Off_t使用的字节数。

Pid_t

此符号保存用于在内核中声明进程 ID 的类型。它可以是 int、uint、pid_t 等。可能需要包含 sys/types.h 以获取任何类型定义的信息。

Rand_seed_t

此符号定义随机种子函数参数的类型。

Select_fd_set_t

此符号保存用于 select 的第二个、第三个和第四个参数的类型。通常,如果定义了 HAS_FD_SET,则为 'fd_set *',否则为 'int *'。当然,只有在您有 select() 时,这才是有用的。

Shmat_t

此符号保存 shmat() 系统调用的返回值类型。通常设置为 'void *' 或 'char *'。

Signal_t

此符号的值为 "void" 或 "int",对应于信号处理程序的适当返回值类型。因此,您可以使用 "Signal_t (*handler)()" 声明信号处理程序,并使用 "Signal_t handler(sig)" 定义处理程序。

Size_t

此符号保存用于声明字符串函数长度参数的类型。它通常是 size_t,但可能是 unsigned long、int 等。可能需要包含 sys/types.h 以获取任何类型定义的信息。

Size_t_size

此符号保存 Size_t 的大小(以字节为单位)。

Sock_size_t

此符号保存用于各种套接字调用的大小参数的类型(仅基本类型,不包括指向该类型的指针)。

SSize_t

此符号保存用于返回字节数或错误条件的函数的类型。它必须是带符号类型。它通常是 ssize_t,但可能是 long 或 int 等。可能需要包含 sys/types.hunistd.h 以获取任何类型定义的信息。我们将选择一种类型,使得 sizeof(SSize_t) == sizeof(Size_t)

Time_t

此符号保存 time() 返回的类型。它可以是 long,或者在 BSD 站点上是 time_t(在这种情况下,应包含 sys/types.h)。

Uid_t

此符号保存用于在内核中声明用户 ID 的类型。它可以是 int、ushort、uid_t 等。可能需要包含 sys/types.h 以获取任何类型定义的信息。

Uid_t_f

此符号定义用于打印 Uid_t 的格式字符串。

Uid_t_sign

此符号保存 Uid_t 的符号。1 表示无符号,-1 表示有符号。

Uid_t_size

此符号保存 Uid_t 的大小(以字节为单位)。

Unicode 支持

"perlguts 中的 Unicode 支持" 对此 API 进行了介绍。

另请参阅 "字符分类""字符大小写转换""字符串处理"。此部分之外的各种函数也专门用于 Unicode。在此文档中搜索字符串 "utf8"。

BOM_UTF8

这是一个宏,它计算为一个字符串常量,该常量包含定义 Unicode 字节顺序标记 (U+FEFF) 的 UTF-8 字节,用于编译 perl 的平台。这使代码能够使用一个助记符来表示此字符,该助记符在 ASCII 和 EBCDIC 平台上都能正常工作。 sizeof(BOM_UTF8) - 1 可用于获取其长度(以字节为单位)。

bytes_cmp_utf8

比较 bblen 中的字符序列(存储为八位字节)与 uulen 中的字符序列(存储为 UTF-8)。如果它们相等,则返回 0;如果第一个字符串小于第二个字符串,则返回 -1 或 -2;如果第一个字符串大于第二个字符串,则返回 +1 或 +2。

如果较短的字符串与较长字符串的开头相同,则返回 -1 或 +1。如果字符串中的字符之间存在差异,则返回 -2 或 +2。

    int  bytes_cmp_utf8(const U8 *b, STRLEN blen, const U8 *u,
                        STRLEN ulen)
bytes_from_utf8

注意:bytes_from_utf8 处于实验阶段,可能会在未经通知的情况下更改或删除。

将长度为 *lenp 的潜在 UTF-8 编码字符串 s 转换为本机字节编码。在输入时,布尔值 *is_utf8p 表示 s 是否实际上是 UTF-8 编码的。

"utf8_to_bytes" 不同,但与 "bytes_to_utf8" 相似,它不会破坏输入字符串。

如果 *is_utf8p 为 0,或者字符串中存在无法用本机字节编码表示的代码点,则不执行任何操作。在这种情况下,*is_utf8p*lenp 保持不变,返回值为原始 s

否则,*is_utf8p 将设置为 0,返回值为指向新创建的字符串的指针,该字符串包含 s 的降级副本,其长度在 *lenp 中返回并更新。新字符串以 NUL 结尾。调用者负责安排此字符串使用的内存被释放。

成功返回后,可以通过在调用之前保存*lenp的值,然后从调用后的*lenp值中减去它来计算字符串中的变体数量。

    U8 *  bytes_from_utf8(const U8 *s, STRLEN *lenp, bool *is_utf8p)
bytes_to_utf8

注意:bytes_to_utf8实验性的,可能会在没有通知的情况下更改或删除。

将长度为*lenp字节的字符串s从本机编码转换为 UTF-8。返回指向新创建字符串的指针,并将*lenp设置为反映新的字节长度。调用者负责安排此字符串使用的内存被释放。

成功返回后,可以通过在调用之前保存*lenp的值,然后从调用后的*lenp值中减去它来计算字符串中的变体数量。

字符串末尾将写入一个NUL字符。

如果您想从除本机(Latin1 或 EBCDIC)以外的编码转换为 UTF-8,请参阅"sv_recode_to_utf8"()。

    U8 *  bytes_to_utf8(const U8 *s, STRLEN *lenp)
DO_UTF8

返回一个布尔值,表示sv中的 PV 是否被视为以 UTF-8 编码。

您应该在调用SvPV()或其变体之后使用它,以防任何对字符串重载的调用更新内部 UTF-8 编码标志。

    bool  DO_UTF8(SV* sv)
foldEQ_utf8

如果字符串s1s2(其中一个或两个都可能在 UTF-8 中)的开头部分在不区分大小写的情况下相同,则返回 true;否则返回 false。比较字符串的深度由其他输入参数决定。

如果u1为 true,则字符串s1被假定为以 UTF-8 编码的 Unicode;否则,它被假定为以本机 8 位编码。u2相对于s2也是如此。

如果字节长度l1不为零,则它表示在s1中检查折叠相等的深度。换句话说,s1+l1将用作目标。扫描将不被视为匹配,除非达到目标,并且扫描不会继续超过该目标。l2相对于s2也是如此。

如果pe1不为NULL,并且它指向的指针不为NULL,则该指针被视为s1中最大点的 1 字节之后的结束指针,扫描在任何情况下都不会继续超过该点。(此例程假设 UTF-8 编码的输入字符串没有格式错误;格式错误的输入会导致它读取超过pe1)。这意味着如果同时指定了l1pe1,并且pe1小于s1+l1,则匹配将永远不会成功,因为它永远无法达到其目标(实际上是断言)。pe2相对于s2也是如此。

s1s2 中至少有一个必须有目标(l1l2 中至少有一个必须非零),如果两者都有,则两者都必须达到才能成功匹配。此外,如果一个字符的折叠是多个字符,则所有字符都必须匹配(有关“折叠”的定义,请参见下面的 tr21 参考资料)。

成功匹配后,如果 pe1NULL,则它将被设置为指向 s1 中匹配部分之后的下一个字符的开头。pe2s2 也是如此。

对于不区分大小写,使用 Unicode 的“大小写折叠”而不是将字符都转换为大写或小写,请参见 https://www.unicode.org/reports/tr21/(大小写映射)。

    I32  foldEQ_utf8(const char *s1, char **pe1, UV l1, bool u1,
                     const char *s2, char **pe2, UV l2, bool u2)
is_ascii_string

这是一个命名误导的 "is_utf8_invariant_string" 的同义词。在类似 ASCII 的平台上,这个名字并不误导:ASCII 范围内的字符正是 UTF-8 不变字符。但 EBCDIC 机器拥有比 ASCII 字符更多的不变字符,因此 is_utf8_invariant_string 是首选。

    bool  is_ascii_string(const U8 * const s, STRLEN len)
isC9_STRICT_UTF8_CHAR

如果从 s 开始的字符串的前几个字节(不超过 e - 1)是格式良好的 UTF-8,并且表示某个 Unicode 非代理代码点,则评估为非零;否则评估为 0。如果非零,则该值表示从 s 开始的构成代码点表示的字节数。e 之前的任何字节,但超出构成 s 中第一个代码点的字节,都不会被检查。

最大的可接受代码点是 Unicode 最大值 0x10FFFF。这与 "isSTRICT_UTF8_CHAR" 唯一的区别在于它接受非字符代码点。这对应于 Unicode 修订 #9,该修订指出非字符代码点在开放式交换中只是被劝阻,而不是完全禁止。请参见 "perlunicode 中的非字符代码点"

使用 "isUTF8_CHAR" 检查 Perl 的扩展 UTF-8;使用 "isUTF8_CHAR_flags" 获取更自定义的定义。

使用 "is_c9strict_utf8_string""is_c9strict_utf8_string_loc""is_c9strict_utf8_string_loclen" 检查整个字符串。

    Size_t  isC9_STRICT_UTF8_CHAR(const U8 * const s0,
                                  const U8 * const e)
is_c9strict_utf8_string

如果字符串 s 的前 len 个字节构成符合 Unicode 修订 #9 的有效 UTF-8 编码字符串,则返回 TRUE;否则返回 FALSE。如果 len 为 0,则将使用 strlen(s) 计算(这意味着如果您使用此选项,则 s 不能包含嵌入的 NUL 字符,并且必须具有终止的 NUL 字节)。请注意,所有字符都是 ASCII 构成“有效 UTF-8 字符串”。

此函数对于包含任何超过 Unicode 最大值 0x10FFFF 的代码点或代理代码点的字符串返回 FALSE,但根据 勘误 #9 接受非字符代码点。

另请参阅 "is_utf8_invariant_string""is_utf8_invariant_string_loc""is_utf8_string""is_utf8_string_flags""is_utf8_string_loc""is_utf8_string_loc_flags""is_utf8_string_loclen""is_utf8_string_loclen_flags""is_utf8_fixed_width_buf_flags""is_utf8_fixed_width_buf_loc_flags""is_utf8_fixed_width_buf_loclen_flags""is_strict_utf8_string""is_strict_utf8_string_loc""is_strict_utf8_string_loclen""is_c9strict_utf8_string_loc""is_c9strict_utf8_string_loclen"

    bool  is_c9strict_utf8_string(const U8 *s, STRLEN len)
is_c9strict_utf8_string_loc

类似于 "is_c9strict_utf8_string",但将失败的位置(在“utf8ness 失败”的情况下)或位置 s+len(在“utf8ness 成功”的情况下)存储在 ep 指针中。

另请参阅 "is_c9strict_utf8_string_loclen"

    bool  is_c9strict_utf8_string_loc(const U8 *s, STRLEN len,
                                      const U8 **ep)
is_c9strict_utf8_string_loclen

类似于 "is_c9strict_utf8_string",但将失败的位置(在“utf8ness 失败”的情况下)或位置 s+len(在“utf8ness 成功”的情况下)存储在 ep 指针中,并将 UTF-8 编码字符的数量存储在 el 指针中。

另请参阅 "is_c9strict_utf8_string_loc"

    bool  is_c9strict_utf8_string_loclen(const U8 *s, STRLEN len,
                                         const U8 **ep, STRLEN *el)
is_invariant_string

这是一个命名有点误导的 "is_utf8_invariant_string" 的同义词。is_utf8_invariant_string 是首选,因为它指示了字符串在什么条件下是不变的。

    bool  is_invariant_string(const U8 * const s, STRLEN len)
isSTRICT_UTF8_CHAR

如果从s开始的字符串的前几个字节,在不超过e - 1的情况下,是格式良好的 UTF-8,并且表示所有应用程序之间可以互操作的 Unicode 代码点,则评估为非零值;否则评估为 0。如果非零,则该值表示从s开始的多少个字节构成了代码点的表示。在e之前但超出形成s中第一个代码点所需的字节将不会被检查。

最大的可接受代码点是 Unicode 最大值 0x10FFFF,并且不能是代理代码点或非字符代码点。因此,这排除了 Perl 扩展 UTF-8 中的任何代码点。

这用于有效地确定s中的接下来的几个字节是否为单个字符的合法 Unicode 可接受 UTF-8。

使用"isC9_STRICT_UTF8_CHAR"来使用Unicode 修正案 #9中定义的可允许代码点;使用"isUTF8_CHAR"来检查 Perl 的扩展 UTF-8;使用"isUTF8_CHAR_flags"来进行更自定义的定义。

使用"is_strict_utf8_string""is_strict_utf8_string_loc""is_strict_utf8_string_loclen"来检查整个字符串。

    Size_t  isSTRICT_UTF8_CHAR(const U8 * const s0,
                               const U8 * const e)
is_strict_utf8_string

如果字符串s的前len个字节形成了有效的 UTF-8 编码字符串,并且可以被使用 Unicode 规则的任何应用程序完全互操作,则返回 TRUE;否则返回 FALSE。如果len为 0,则将使用strlen(s)计算(这意味着如果您使用此选项,则s不能包含嵌入的NUL字符,并且必须具有终止的NUL字节)。请注意,所有字符都是 ASCII 构成“有效的 UTF-8 字符串”。

此函数对于包含任何超过 Unicode 最大值 0x10FFFF 的代码点、代理代码点或非字符代码点的字符串返回 FALSE。

另请参阅 "is_utf8_invariant_string""is_utf8_invariant_string_loc""is_utf8_string""is_utf8_string_flags""is_utf8_string_loc""is_utf8_string_loc_flags""is_utf8_string_loclen""is_utf8_string_loclen_flags""is_utf8_fixed_width_buf_flags""is_utf8_fixed_width_buf_loc_flags""is_utf8_fixed_width_buf_loclen_flags""is_strict_utf8_string_loc""is_strict_utf8_string_loclen""is_c9strict_utf8_string""is_c9strict_utf8_string_loc""is_c9strict_utf8_string_loclen"

    bool  is_strict_utf8_string(const U8 *s, STRLEN len)
is_strict_utf8_string_loc

类似于 "is_strict_utf8_string",但将失败位置(在“utf8ness 失败”的情况下)或位置 s+len(在“utf8ness 成功”的情况下)存储在 ep 指针中。

另请参阅 "is_strict_utf8_string_loclen"

    bool  is_strict_utf8_string_loc(const U8 *s, STRLEN len,
                                    const U8 **ep)
is_strict_utf8_string_loclen

类似于 "is_strict_utf8_string",但将失败位置(在“utf8ness 失败”的情况下)或位置 s+len(在“utf8ness 成功”的情况下)存储在 ep 指针中,并将 UTF-8 编码字符的数量存储在 el 指针中。

另请参阅 "is_strict_utf8_string_loc"

    bool  is_strict_utf8_string_loclen(const U8 *s, STRLEN len,
                                       const U8 **ep, STRLEN *el)
isUTF8_CHAR

如果从 s 开始的字符串的前几个字节(不超过 e - 1)是格式良好的 UTF-8(由 Perl 扩展),表示某个代码点,则评估为非零;否则评估为 0。如果为非零,则该值表示从 s 开始的构成代码点表示的字节数。在 e 之前但超出构成 s 中第一个代码点的字节的任何剩余字节都不会被检查。

代码点可以是本机上 IV 中可以容纳的任何代码点,使用 Perl 对官方 UTF-8 的扩展来表示高于 Unicode 最大值 0x10FFFF 的代码点。这意味着此宏用于有效地确定 s 中的接下来的几个字节是否为单个字符的合法 UTF-8。

使用 "isSTRICT_UTF8_CHAR" 将可接受的代码点限制为 Unicode 定义的那些完全可跨应用程序互换的代码点;使用 "isC9_STRICT_UTF8_CHAR" 使用 Unicode 修订 #9 对允许代码点的定义;使用 "isUTF8_CHAR_flags" 获取更自定义的定义。

使用 "is_utf8_string""is_utf8_string_loc""is_utf8_string_loclen" 检查整个字符串。

还要注意,UTF-8 “不变”字符(即非 EBCDIC 机器上的 ASCII)是有效的 UTF-8 字符。

    Size_t  isUTF8_CHAR(const U8 * const s0, const U8 * const e)
is_utf8_char_buf

这与宏 "perlapi 中的 isUTF8_CHAR" 相同。

    STRLEN  is_utf8_char_buf(const U8 *buf, const U8 *buf_end)
isUTF8_CHAR_flags

如果从 s 开始的字符串的前几个字节(不超过 e - 1)是符合 Perl 扩展的 UTF-8 规范的,并且表示某个代码点,并且满足 flags 中指定的限制,则该函数返回非零值;否则返回 0。如果返回非零值,则该值表示从 s 开始的构成代码点表示的字节数。在 e 之前但超出构成 s 中第一个代码点的字节数的任何字节都不会被检查。

如果 flags 为 0,则该函数与 "isUTF8_CHAR" 的结果相同;如果 flagsUTF8_DISALLOW_ILLEGAL_INTERCHANGE,则该函数与 "isSTRICT_UTF8_CHAR" 的结果相同;如果 flagsUTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE,则该函数与 "isC9_STRICT_UTF8_CHAR" 的结果相同。否则,flags 可以是 "utf8n_to_uvchr" 所理解的任何 UTF8_DISALLOW_foo 标志的组合,含义相同。

这三个替代宏用于最常见的验证;它们可能比这个更通用的宏运行得更快,因为它们可以内联到您的代码中。

使用 "is_utf8_string_flags""is_utf8_string_loc_flags""is_utf8_string_loclen_flags" 来检查整个字符串。

    Size_t  isUTF8_CHAR_flags(const U8 * const s0, const U8 * const e,
                              const U32 flags)
is_utf8_fixed_width_buf_flags

如果从 s 开始长度为 len 的定长缓冲区完全是有效的 UTF-8,并且满足 flags 中指定的限制,则返回 TRUE;否则返回 FALSE。

如果 flags 为 0,则任何符合 Perl 扩展的 UTF-8 规范的字符都将被接受,没有任何限制。如果缓冲区的最后几个字节没有构成一个完整的代码点,则该函数仍然会返回 TRUE,前提是 "is_utf8_valid_partial_char_flags" 对它们返回 TRUE。

如果 flags 不为零,则它可以是 "utf8n_to_uvchr" 所接受的任何 UTF8_DISALLOW_foo 标志的组合,含义相同。

该函数与 "is_utf8_string_flags" 的区别在于,如果字符串的最后几个字节没有构成一个完整的代码点,则后者会返回 FALSE。

    bool  is_utf8_fixed_width_buf_flags(const U8 * const s,
                                        STRLEN len, const U32 flags)
is_utf8_fixed_width_buf_loc_flags

"is_utf8_fixed_width_buf_flags" 相似,但将失败的位置存储在 ep 指针中。如果该函数返回 TRUE,则 *ep 将指向缓冲区末尾的任何部分字符的开头;如果没有部分字符,则 *ep 将包含 s+len

另请参阅 "is_utf8_fixed_width_buf_loclen_flags"

    bool  is_utf8_fixed_width_buf_loc_flags(const U8 * const s,
                                            STRLEN len, const U8 **ep,
                                            const U32 flags)
is_utf8_fixed_width_buf_loclen_flags

类似于 "is_utf8_fixed_width_buf_loc_flags",但将 el 指针中找到的完整有效字符数存储起来。

    bool  is_utf8_fixed_width_buf_loclen_flags(const U8 * const s,
                                               STRLEN len,
                                               const U8 **ep,
                                               STRLEN *el,
                                               const U32 flags)
is_utf8_invariant_string

如果字符串 s 的前 len 个字节与字符串的 UTF-8 编码(或 EBCDIC 机器上的 UTF-EBCDIC 编码)无关,则返回 TRUE;否则返回 FALSE。也就是说,如果它们是 UTF-8 不变的,则返回 TRUE。在 ASCII 类机器上,所有 ASCII 字符,并且只有 ASCII 字符符合此定义。在 EBCDIC 机器上,ASCII 范围内的字符是不变的,但 C1 控制字符也是如此。

如果 len 为 0,则将使用 strlen(s) 计算(这意味着如果您使用此选项,则 s 不能包含嵌入的 NUL 字符,并且必须具有终止的 NUL 字节)。

另请参阅 "is_utf8_string""is_utf8_string_flags""is_utf8_string_loc""is_utf8_string_loc_flags""is_utf8_string_loclen""is_utf8_string_loclen_flags""is_utf8_fixed_width_buf_flags""is_utf8_fixed_width_buf_loc_flags""is_utf8_fixed_width_buf_loclen_flags""is_strict_utf8_string""is_strict_utf8_string_loc""is_strict_utf8_string_loclen""is_c9strict_utf8_string""is_c9strict_utf8_string_loc""is_c9strict_utf8_string_loclen"

    bool  is_utf8_invariant_string(const U8 * const s, STRLEN len)
is_utf8_invariant_string_loc

类似于 "is_utf8_invariant_string",但在失败时,将第一个 UTF-8 变体字符的位置存储在 ep 指针中;如果所有字符都是 UTF-8 不变的,则此函数不会更改 *ep 的内容。

    bool  is_utf8_invariant_string_loc(const U8 * const s, STRLEN len,
                                       const U8 **ep)
is_utf8_string

如果字符串 s 的前 len 个字节构成一个有效的 Perl 扩展 UTF-8 字符串,则返回 TRUE;否则返回 FALSE。如果 len 为 0,则将使用 strlen(s) 计算(这意味着如果您使用此选项,则 s 不能包含嵌入的 NUL 字符,并且必须具有终止的 NUL 字节)。请注意,所有字符都是 ASCII 构成“有效的 UTF-8 字符串”。

此函数认为 Perl 的扩展 UTF-8 是有效的。这意味着 Unicode 以上的代码点、代理和非字符代码点被此函数视为有效。使用 "is_strict_utf8_string""is_c9strict_utf8_string""is_utf8_string_flags" 来限制哪些代码点被视为有效。

另请参阅 "is_utf8_invariant_string""is_utf8_invariant_string_loc""is_utf8_string_loc""is_utf8_string_loclen""is_utf8_fixed_width_buf_flags""is_utf8_fixed_width_buf_loc_flags""is_utf8_fixed_width_buf_loclen_flags",

    bool  is_utf8_string(const U8 *s, STRLEN len)
is_utf8_string_flags

如果字符串 s 的前 len 个字节构成一个有效的 UTF-8 字符串,则返回 TRUE,该字符串受 flags 强制执行的限制;否则返回 FALSE。如果 len 为 0,则将使用 strlen(s) 计算(这意味着如果您使用此选项,则 s 不能包含嵌入的 NUL 字符,并且必须具有终止的 NUL 字节)。请注意,所有字符都是 ASCII 构成“有效的 UTF-8 字符串”。

如果 flags 为 0,则结果与 "is_utf8_string" 相同;如果 flagsUTF8_DISALLOW_ILLEGAL_INTERCHANGE,则结果与 "is_strict_utf8_string" 相同;如果 flagsUTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE,则结果与 "is_c9strict_utf8_string" 相同。否则,flags 可以是 "utf8n_to_uvchr" 所理解的任何 UTF8_DISALLOW_foo 标志的组合,含义相同。

另请参阅 "is_utf8_invariant_string""is_utf8_invariant_string_loc""is_utf8_string""is_utf8_string_loc""is_utf8_string_loc_flags""is_utf8_string_loclen""is_utf8_string_loclen_flags""is_utf8_fixed_width_buf_flags""is_utf8_fixed_width_buf_loc_flags""is_utf8_fixed_width_buf_loclen_flags""is_strict_utf8_string""is_strict_utf8_string_loc""is_strict_utf8_string_loclen""is_c9strict_utf8_string""is_c9strict_utf8_string_loc""is_c9strict_utf8_string_loclen"

    bool  is_utf8_string_flags(const U8 *s, STRLEN len,
                               const U32 flags)
is_utf8_string_loc

类似于 "is_utf8_string",但将失败位置(在“utf8ness 失败”的情况下)或位置 s+len(在“utf8ness 成功”的情况下)存储在 ep 指针中。

另请参阅 "is_utf8_string_loclen"

    bool  is_utf8_string_loc(const U8 *s, const STRLEN len,
                             const U8 **ep)
is_utf8_string_loc_flags

类似于 "is_utf8_string_flags",但将失败位置(在“utf8ness 失败”的情况下)或位置 s+len(在“utf8ness 成功”的情况下)存储在 ep 指针中。

另请参阅 "is_utf8_string_loclen_flags"

    bool  is_utf8_string_loc_flags(const U8 *s, STRLEN len,
                                   const U8 **ep, const U32 flags)
is_utf8_string_loclen

类似于 "is_utf8_string",但将失败位置(在“utf8ness 失败”的情况下)或位置 s+len(在“utf8ness 成功”的情况下)存储在 ep 指针中,并将 UTF-8 编码字符的数量存储在 el 指针中。

另请参阅 "is_utf8_string_loc"

    bool  is_utf8_string_loclen(const U8 *s, STRLEN len,
                                const U8 **ep, STRLEN *el)
is_utf8_string_loclen_flags

类似于 "is_utf8_string_flags",但将失败位置(在“utf8ness 失败”的情况下)或位置 s+len(在“utf8ness 成功”的情况下)存储在 ep 指针中,并将 UTF-8 编码字符的数量存储在 el 指针中。

另请参阅 "is_utf8_string_loc_flags"

    bool  is_utf8_string_loclen_flags(const U8 *s, STRLEN len,
                                      const U8 **ep, STRLEN *el,
                                      const U32 flags)
is_utf8_valid_partial_char

如果从 s 开始的字节序列,不超过 e - 1,是 Perl 扩展的 UTF-8 编码的一个或多个代码点的编码,则返回 0。否则,如果存在至少一个非空字节序列,当追加到序列 s(从位置 e 开始)时,会导致整个序列成为某个代码点的良好格式的 UTF-8,则返回 1;否则返回 0。

换句话说,如果 s 指向一个部分 UTF-8 编码的代码点,则返回 TRUE。

当一个固定长度的缓冲区被测试是否为良好格式的 UTF-8,但其中的最后几个字节不构成一个完整的字符时,这很有用;也就是说,它在最终代码点的 UTF-8 表示的中间某个地方被分割了。(可以假设,当缓冲区用下一块数据刷新时,新的第一个字节将完成部分代码点。)此函数用于验证当前缓冲区中的最后几个字节实际上是某个代码点的合法开头,以便如果它们不是,则可以在不必等待下一次读取的情况下发出信号。

    bool  is_utf8_valid_partial_char(const U8 * const s0,
                                     const U8 * const e)
is_utf8_valid_partial_char_flags

"is_utf8_valid_partial_char" 相似,它返回一个布尔值,指示输入是否为有效的 UTF-8 编码的部分字符,但它接受一个额外的参数 flags,它可以进一步限制哪些代码点被认为是有效的。

如果 flags 为 0,则此函数的行为与 "is_utf8_valid_partial_char" 相同。否则,flags 可以是 "utf8n_to_uvchr" 接受的 UTF8_DISALLOW_foo 标志的任何组合。如果存在任何字节序列可以以形成非禁止字符的方式完成输入部分字符,则该函数返回 TRUE;否则返回 FALSE。非字符代码点无法根据部分字符输入来确定。但许多其他可能的排除类型可以从前一两个字节中确定。

    bool  is_utf8_valid_partial_char_flags(const U8 * const s0,
                                           const U8 * const e,
                                           const U32 flags)
LATIN1_TO_NATIVE

返回由 ch 给出的输入 Latin-1 代码点的本机等效值(包括 ASCII 和控制字符)。因此,在 EBCDIC 平台上,LATIN1_TO_NATIVE(66) 返回 194。这些分别代表它们各自平台上的字符 "B"。在 ASCII 平台上,不需要转换,因此此宏扩展为其输入,不会给实现添加任何时间或空间需求。

要转换可能大于字符所能容纳的代码点,请使用 "UNI_TO_NATIVE"

    U8  LATIN1_TO_NATIVE(U8 ch)
NATIVE_TO_LATIN1

返回由 ch 给出的输入本地代码点的 Latin-1(包括 ASCII 和控制字符)等效项。因此,在 EBCDIC 平台上,NATIVE_TO_LATIN1(193) 返回 65。这些分别代表其各自平台上的字符 "A"。在 ASCII 平台上,不需要转换,因此此宏扩展到仅其输入,不会为实现添加任何时间或空间要求。

对于可能大于字符所能容纳的代码点的转换,请使用 "NATIVE_TO_UNI".

    U8  NATIVE_TO_LATIN1(U8 ch)
NATIVE_TO_UNI

返回由 ch 给出的输入本地代码点的 Unicode 等效项。因此,在 EBCDIC 平台上,NATIVE_TO_UNI(195) 返回 67。这些分别代表其各自平台上的字符 "C"。在 ASCII 平台上,不需要转换,因此此宏扩展到仅其输入,不会为实现添加任何时间或空间要求。

    UV  NATIVE_TO_UNI(UV ch)
pv_uni_display

将 UTF-8 编码字符串 spv 的可显示版本构建到标量 dsv 中,长度为 len,可显示版本最多为 pvlim 字节长(如果更长,则其余部分将被截断,并且将追加 "...")。

flags 参数可以设置 UNI_DISPLAY_ISPRINT 以将 isPRINT() 可显示的字符显示为自身,UNI_DISPLAY_BACKSLASH 以将 \\[nrfta\\] 显示为反斜杠版本(如 "\n")(对于 "\\"UNI_DISPLAY_BACKSLASHUNI_DISPLAY_ISPRINT 更可取)。UNI_DISPLAY_QQ(及其别名 UNI_DISPLAY_REGEX)同时打开了 UNI_DISPLAY_BACKSLASHUNI_DISPLAY_ISPRINT

此外,现在有 UNI_DISPLAY_BACKSPACE,它允许 \b 表示退格键,但前提是 UNI_DISPLAY_BACKSLASH 也已设置。

返回指向 dsv 的 PV 的指针。

另请参见 "sv_uni_display".

    char *  pv_uni_display(SV *dsv, const U8 *spv, STRLEN len,
                           STRLEN pvlim, UV flags)
REPLACEMENT_CHARACTER_UTF8

这是一个宏,它计算为定义 Unicode 替换字符 (U+FFFD) 的 UTF-8 字节的字符串常量,用于编译 perl 的平台。这允许代码使用在 ASCII 和 EBCDIC 平台上都可用的助记符来表示此字符。 sizeof(REPLACEMENT_CHARACTER_UTF8) - 1 可用于获取其以字节为单位的长度。

sv_cat_decode

encoding 假设为一个 Encode 对象,ssv 的 PV 假设为该编码中的八位字节,并且解码输入从 (PV + *offset) 指向的位置开始。dsv 将与从 ssv 解码的 UTF-8 字符串连接。当字符串 tstr 出现在解码输出中或输入在 ssv 的 PV 上结束时,解码将终止。offset 指向的值将被修改为 ssv 上的最后一个输入位置。

如果找到终止符,则返回 TRUE,否则返回 FALSE。

    bool  sv_cat_decode(SV *dsv, SV *encoding, SV *ssv, int *offset,
                        char *tstr, int tlen)
sv_recode_to_utf8

encoding 假设为 Encode 对象,在进入时,sv 的 PV 假设为该编码中的字节,并且 sv 将被转换为 Unicode(和 UTF-8)。

如果 sv 已经是 UTF-8(或者它不是 POK),或者如果 encoding 不是引用,则不会对 sv 进行任何操作。如果 encoding 不是 Encode::XS 编码对象,则会发生不好的事情。(参见 encodingEncode。)

返回 sv 的 PV。

    char *  sv_recode_to_utf8(SV *sv, SV *encoding)
sv_uni_display

为标量 dsv 构建标量 sv 的可显示版本,可显示版本最多为 pvlim 字节长(如果更长,则其余部分将被截断,并且将附加 "...")。

flags 参数与 "pv_uni_display"() 中的相同。

返回指向 dsv 的 PV 的指针。

    char *  sv_uni_display(SV *dsv, SV *ssv, STRLEN pvlim, UV flags)
UNICODE_IS_NONCHAR

返回一个布尔值,表示 uv 是否是 Unicode 非字符代码点之一。

    bool  UNICODE_IS_NONCHAR(const UV uv)
UNICODE_IS_REPLACEMENT

返回一个布尔值,表示 uv 是否是 Unicode 替换字符。

    bool  UNICODE_IS_REPLACEMENT(const UV uv)
UNICODE_IS_SUPER

返回一个布尔值,表示 uv 是否高于 U+10FFFF 的最大合法 Unicode 代码点。

    bool  UNICODE_IS_SUPER(const UV uv)
UNICODE_IS_SURROGATE

返回一个布尔值,表示 uv 是否是 Unicode 代理代码点之一。

    bool  UNICODE_IS_SURROGATE(const UV uv)
UNICODE_REPLACEMENT

计算结果为 0xFFFD,即 Unicode 替换字符的代码点。

UNI_TO_NATIVE

返回由 ch 给出的输入 Unicode 代码点的本机等效项。因此,在 EBCDIC 平台上,UNI_TO_NATIVE(68) 返回 196。这些分别代表其各自平台上的字符 "D"。在 ASCII 平台上,不需要进行转换,因此此宏扩展为仅其输入,不会为实现添加任何时间或空间要求。

    UV  UNI_TO_NATIVE(UV ch)
UTF8_CHK_SKIP

这是 "UTF8SKIP" 的更安全版本,但仍然不如 "UTF8_SAFE_SKIP" 安全。此版本不会盲目地假设 s 指向的输入字符串是格式良好的,而是验证在 s 中下一个字符的预期结束之前是否没有 NUL 终止符。UTF8_CHK_SKIP 返回的长度在任何此类 NUL 之前停止。

Perl 倾向于在 SV 中字符串的末尾添加 NUL,作为一种保险策略,因此使用此宏可能会防止意外读取超出输入缓冲区的末尾,即使它是格式错误的 UTF-8。

此宏旨在用于 XS 模块,其中输入可能是格式错误的,并且无法重构以使用更安全的 "UTF8_SAFE_SKIP",例如在与 C 库交互时。

    STRLEN  UTF8_CHK_SKIP(char* s)
utf8_distance

返回 UTF-8 指针 ab 之间的 UTF-8 字符数。

警告:仅当您 *知道* 指针指向同一个 UTF-8 缓冲区内部时才使用。

    IV  utf8_distance(const U8 *a, const U8 *b)
utf8_hop

返回 UTF-8 指针 s,该指针被 off 个字符位移,可以向前(如果 off 为正)或向后(如果为负)。s 不需要指向字符的起始字节。如果不是,则 off 的一个计数将被用于到达下一个字符的开头(对于向前跳跃)和当前字符的开头(对于向后跳跃)。

警告:优先使用 "utf8_hop_safe"

除非您 知道 offs 指向的 UTF-8 数据内 并且 在进入时 s 与字符的第一个字节对齐或紧接在字符的最后一个字节之后,否则不要使用此函数。

    U8 *  utf8_hop(const U8 *s, SSize_t off)
utf8_hop_back

返回 UTF-8 指针 s,该指针最多被 off 个字符位移,向后。s 不需要指向字符的起始字节。如果不是,则 off 的一个计数将被用于到达该开头。

off 必须是非正数。

s 必须在 start 之后或等于 start

向后移动时,它不会移动到 start 之前。

即使字符串不是有效的 "UTF-8",也不会超过此限制。

    U8 *  utf8_hop_back(const U8 *s, SSize_t off, const U8 *start)
utf8_hop_forward

返回 UTF-8 指针 s,该指针最多被 off 个字符位移,向前。s 不需要指向字符的起始字节。如果不是,则 off 的一个计数将被用于到达下一个字符的开头。

off 必须是非负数。

s 必须在 end 之前或等于 end

向前移动时,它不会移动到 end 以外。

即使字符串不是有效的 "UTF-8",也不会超过此限制。

    U8 *  utf8_hop_forward(const U8 *s, SSize_t off, const U8 *end)
utf8_hop_safe

返回 UTF-8 指针 s 向前或向后移动最多 off 个字符后的位置。s 不需要指向字符的起始字节。如果不是,向前跳跃时将使用 off 的一个计数来到达下一个字符的开头,而对于负数则到达当前字符的开头。

向后移动时,它不会移动到 start 之前。

向前移动时,它不会移动到 end 以外。

即使字符串不是有效的“UTF-8”,也不会超过这些限制。

    U8 *  utf8_hop_safe(const U8 *s, SSize_t off, const U8 *start,
                        const U8 *end)
UTF8_IS_INVARIANT

如果字节 c 在 UTF-8 编码和未编码时表示相同的字符,则评估为 1;否则评估为 0。UTF-8 不变字符在转换为/从 UTF-8 转换时可以按原样复制,从而节省时间。

尽管有这个名字,但如果 c 来自的输入字符串不是 UTF-8 编码,这个宏也会给出正确的结果。

请参阅 "UVCHR_IS_INVARIANT" 以检查 UV 是否不变。

    bool  UTF8_IS_INVARIANT(char c)
UTF8_IS_NONCHAR

如果从 s 开始的字符串的前几个字节,并且不超过 e - 1,是格式良好的 UTF-8,并且表示 Unicode 非字符代码点之一,则评估为非零;否则评估为 0。如果为非零,则该值表示从 s 开始的多少个字节构成了代码点的表示。

    bool  UTF8_IS_NONCHAR(const U8 *s, const U8 *e)
UTF8_IS_REPLACEMENT

如果从 s 开始的字符串的前几个字节,并且不超过 e - 1,是格式良好的 UTF-8,并且表示 Unicode 替换字符,则评估为非零;否则评估为 0。如果为非零,则该值表示从 s 开始的多少个字节构成了代码点的表示。

    bool  UTF8_IS_REPLACEMENT(const U8 *s, const U8 *e)
UTF8_IS_SUPER

回想一下,Perl 识别 UTF-8 的扩展,它可以编码比 Unicode 定义的代码点更大的代码点,即 0..0x10FFFF。

如果从 s 开始的字符串的前几个字节,并且不超过 e - 1,来自此 UTF-8 扩展,则此宏评估为非零;否则评估为 0。如果为非零,则返回值表示从 s 开始的多少个字节构成了代码点的表示。

如果字节不是格式良好的扩展 UTF-8,或者它们表示的代码点无法在当前平台上的 UV 中容纳,则返回 0。因此,此宏在 64 位字机器上运行时可能与在 32 位字大小的机器上运行时给出不同的结果。

请注意,在 Perl 中,代码点大于当前机器上 IV 的大小是违法的;在 Unicode 中,任何与该宏匹配的代码点都是违法的。

    bool  UTF8_IS_SUPER(const U8 *s, const U8 *e)
UTF8_IS_SURROGATE

如果从 s 开始的字符串的前几个字节(不超过 e - 1)是格式良好的 UTF-8,并且表示 Unicode 代理代码点之一,则评估为非零;否则评估为 0。如果非零,则该值表示从 s 开始的代码点表示形式包含多少个字节。

    bool  UTF8_IS_SURROGATE(const U8 *s, const U8 *e)
utf8_length

返回从 s 开始到 e 前一个字节结束的 UTF-8 编码字节序列中的字符数。如果 <s> 和 <e> 指向同一个位置,则返回 0,不会发出任何警告。

如果 e < s 或扫描会超出 e,则会发出 UTF8 警告并返回有效字符数。

    STRLEN  utf8_length(const U8 *s0, const U8 *e)
UTF8_MAXBYTES

单个 UTF-8 编码字符的最大宽度(以字节为单位)。

注意:严格来说,Perl 的 UTF-8 不应该被称为 UTF-8,因为 UTF-8 是 Unicode 的编码,而 Unicode 的上限 0x10FFFF 可以用 4 个字节表示。但是,Perl 将 UTF-8 视为一种以二进制格式编码非负整数的方法,即使这些整数超过了 Unicode。

UTF8_MAXBYTES_CASE

单个 Unicode 字符可以转换为大写/小写/标题/折叠的最大 UTF-8 字节数。

utf8ness_t

此 typedef 用于几个返回 PV 字符串的核心函数,以指示这些字符串的 UTF-8 性质。

(如果您编写一个新函数,您可能应该将 PV 返回到一个 SV 中,并正确设置 SV 的 UTF-8 标志,而不是使用这种机制。)

此 typedef 可能的值为

UTF8NESS_YES

这意味着该字符串绝对应该被视为 UTF-8 编码字符序列。

大多数需要处理此 typedef 的代码应该采用以下形式

if (utf8ness_flag == UTF8NESS_YES) {
    treat as utf8;  // like turning on an SV UTF-8 flag
}
UTF8NESS_NO

这意味着该字符串绝对应该被视为字节序列,而不是 UTF-8 编码。

UTF8NESS_IMMATERIAL

这意味着将字符串视为字节或 UTF-8 字符是等效的;您可以选择任何一种方式。当字符串完全由在 UTF-8 编码中具有相同表示的字符组成时,就会发生这种情况。

UTF8NESS_UNKNOWN

这意味着不知道如何处理字符串。任何核心函数都不会将此值返回给非核心调用者。相反,它由调用者用于将变量初始化为非合法值。典型的调用将类似于

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;
}

枚举值之间存在以下关系

0 <= 枚举值 <= UTF8NESS_IMMATERIAL

字符串可以在代码中被视为非 UTF-8

UTF8NESS_IMMATERIAL <= <枚举值

字符串可以在代码中被视为以 UTF-8 编码

utf8n_to_uvchr

此函数仅应在非常特殊的情况下使用。大多数代码应该使用 "utf8_to_uvchr_buf"() 而不是直接调用它。

底层 UTF-8 解码例程。返回字符串 s 中第一个字符的本机代码点值,该字符串假定为 UTF-8(或 UTF-EBCDIC)编码,并且不超过 curlen 字节;*retlen(如果 retlen 不为 NULL)将设置为该字符的长度(以字节为单位)。

flags 的值决定了当 s 不指向格式良好的 UTF-8 字符时的行为。如果 flags 为 0,则遇到格式错误会导致返回零,并且 *retlen 被设置为 (s + *retlen) 是 s 中可能开始非格式错误字符的下一个位置。此外,如果 UTF-8 警告尚未在词法上禁用,则会发出警告。一些 UTF-8 输入序列可能包含多个格式错误。此函数尝试在每次调用中找到所有可能的格式错误,因此可以针对同一序列发出多个警告。

可以在 flags 中设置各种 ALLOW 标志以允许(并且不警告)单个类型的格式错误,例如序列过长(即,当存在可以表达相同代码点的更短序列时;过长序列在 UTF-8 标准中明确禁止,因为存在潜在的安全问题)。另一个格式错误示例是字符的第一个字节不是合法的第一个字节。有关此类标志的列表,请参见 utf8.h。即使允许,此函数通常在遇到格式错误时也会返回 Unicode 替换字符。utf8.h 中有标志可以覆盖过长格式错误的这种行为,但不要这样做,除非出于非常特殊的目的。

UTF8_CHECK_ONLY 标志会覆盖在发现未允许的(由其他标志允许)格式错误时的行为。如果设置了此标志,则例程假设调用者将发出警告,并且此函数将静默地将 retlen 设置为 -1(强制转换为 STRLEN)并返回零。

请注意,此 API 需要区分成功解码 NUL 字符和错误返回(除非设置了 UTF8_CHECK_ONLY 标志),因为在这两种情况下,都会返回 0,并且根据畸形情况,retlen 可能被设置为 1。为了区分,在返回 0 时,请查看 s 的第一个字节是否也为 0。如果是,则输入为 NUL;如果不是,则输入有错误。或者您可以使用 "utf8n_to_uvchr_error"

某些代码点被认为是有问题的。这些是 Unicode 代理项、Unicode 非字符和超过 Unicode 最大值 0x10FFFF 的代码点。默认情况下,这些被视为常规代码点,但在某些情况下需要对它们进行特殊处理,可以使用 flags 参数指定。如果 flags 包含 UTF8_DISALLOW_ILLEGAL_INTERCHANGE,则所有三类都被视为畸形,并按此处理。标志 UTF8_DISALLOW_SURROGATEUTF8_DISALLOW_NONCHARUTF8_DISALLOW_SUPER(表示超过合法 Unicode 最大值)可以分别设置以禁止这些类别。UTF8_DISALLOW_ILLEGAL_INTERCHANGE 将允许的输入限制为 Unicode 传统定义的严格 UTF-8。使用 UTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE 来使用 Unicode 修正案 #9 给出的严格性定义。传统严格性和 C9 严格性之间的区别在于,后者不禁止非字符代码点。(但是,它们仍然不被鼓励。)有关更多讨论,请参见 "perlunicode 中的非字符代码点"

标志 UTF8_WARN_ILLEGAL_INTERCHANGEUTF8_WARN_ILLEGAL_C9_INTERCHANGEUTF8_WARN_SURROGATEUTF8_WARN_NONCHARUTF8_WARN_SUPER 将导致对各自类别发出警告消息,但否则代码点被视为有效(不是畸形)。要使类别既被视为畸形又发出警告,请同时指定 WARN 和 DISALLOW 标志。(但请注意,如果词法上禁用或同时指定 UTF8_CHECK_ONLY,则不会发出警告。)

极高的代码点从未在任何标准中指定,需要对 UTF-8 进行扩展才能表达,Perl 实现了这种扩展。其他语言编写的程序可能无法读取包含这些代码点的文件;Perl 也无法理解使用不同扩展编写的文件。出于这些原因,有一组单独的标志可以警告和/或禁止这些极高的代码点,即使接受其他高于 Unicode 的代码点。它们是 UTF8_WARN_PERL_EXTENDEDUTF8_DISALLOW_PERL_EXTENDED 标志。有关更多信息,请参见 "UTF8_GOT_PERL_EXTENDED"。当然,UTF8_DISALLOW_SUPER 会将所有高于 Unicode 的代码点(包括这些代码点)视为畸形。(请注意,Unicode 标准认为任何高于 0x10FFFF 的代码点都是非法的,但早于它的标准允许使用高达 0x7FFF_FFFF (2**31 -1) 的代码点。)

UTF8_WARN_PERL_EXTENDED 的一个略带误导性的同义词 UTF8_WARN_ABOVE_31_BIT 被保留以保持向后兼容性。类似地,UTF8_DISALLOW_ABOVE_31_BIT 可以代替更准确的 UTF8_DISALLOW_PERL_EXTENDED 使用。这些名称具有误导性,因为这些标志可以应用于实际上适合 31 位的代码点。这种情况发生在 EBCDIC 平台上,有时也发生在存在 过长畸形 的情况下。新的名称准确地描述了所有情况下的情况。

所有其他与 Unicode 字符相对应的代码点,包括私有使用代码点和尚未分配的代码点,永远不会被视为畸形,也不会发出警告。

    UV  utf8n_to_uvchr(const U8 *s, STRLEN curlen, STRLEN *retlen,
                       const U32 flags)
utf8n_to_uvchr_error

此函数仅应在非常特殊的情况下使用。大多数代码应该使用 "utf8_to_uvchr_buf"() 而不是直接调用它。

此函数适用于需要知道错误发生时确切畸形情况的代码。如果您还需要知道生成的警告消息,请改用 "utf8n_to_uvchr_msgs"()。

它类似于 "utf8n_to_uvchr",但它在所有其他参数之后接受一个额外的参数 errors。如果此参数为 0,则此函数的行为与 "utf8n_to_uvchr" 相同。否则,errors 应该指向一个 U32 变量,此函数会将该变量设置为指示找到的任何错误。返回后,如果 *errors 为 0,则没有找到错误。否则,*errors 是下面列表中描述的位的按位或。如果找到畸形,即使输入 flags 参数指示允许给定的畸形,也会设置其中一些位;这些例外情况已在注释中说明。

UTF8_GOT_PERL_EXTENDED

输入序列不是标准 UTF-8,而是 Perl 扩展。仅当输入 flags 参数包含 UTF8_DISALLOW_PERL_EXTENDEDUTF8_WARN_PERL_EXTENDED 标志时,才会设置此位。

大于 0x7FFF_FFFF (2**31 - 1) 的码点从未在任何标准中指定,因此必须使用某种扩展来表示它们。Perl 使用对 UTF-8 的自然扩展来表示高达 2**36-1 的码点,并发明了另一种扩展来表示更高的码点,以便任何适合 64 位字的码点都可以表示。使用这些扩展的文本可能无法移植到非 Perl 代码。我们将这两种扩展统称为 Perl 扩展 UTF-8。还存在其他人发明的与 Perl 不兼容的扩展。

在 Perl v5.24 及更高版本的 EBCDIC 平台上,用于表示极高码点的 Perl 扩展在 0x3FFF_FFFF (2**30 -1) 处开始生效,这比 ASCII 平台低。在此之前,2**31 及更高的码点根本无法表示,并且使用了一种不同的、不兼容的方法来表示 2**30 到 2**31 - 1 之间的码点。

在 ASCII 和 EBCDIC 平台上,如果使用 Perl 扩展 UTF-8,则会设置 UTF8_GOT_PERL_EXTENDED

在早期的 Perl 版本中,此位名为 UTF8_GOT_ABOVE_31_BIT,您仍然可以出于向后兼容性使用它。这个名字具有误导性,因为当码点实际上适合 31 位时,此标志可能会被设置。这发生在 EBCDIC 平台上,有时也会发生在 超长畸形 也存在的情况下。新名称准确地描述了所有情况。

UTF8_GOT_CONTINUATION

输入序列格式错误,因为第一个字节是 UTF-8 延续字节。

UTF8_GOT_EMPTY

输入 curlen 参数为 0。

UTF8_GOT_LONG

输入序列格式错误,因为存在其他序列计算结果为相同的码点,但该序列比此序列短。

在 Unicode 3.1 之前,程序可以接受这种畸形,但后来发现这会导致安全问题。

UTF8_GOT_NONCHAR

输入 UTF-8 序列表示的码点是 Unicode 非字符码点。仅当输入 flags 参数包含 UTF8_DISALLOW_NONCHARUTF8_WARN_NONCHAR 标志时,才会设置此位。

UTF8_GOT_NON_CONTINUATION

输入序列格式错误,因为在仅应出现延续类型字节的位置找到了非延续类型字节。另请参见 "UTF8_GOT_SHORT"

UTF8_GOT_OVERFLOW

输入序列格式错误,因为它对应于当前平台上 IV 中可用位数无法表示的代码点。

UTF8_GOT_SHORT

输入序列格式错误,因为 curlen 小于完整序列所需的长度。换句话说,输入是部分字符序列。

UTF8_GOT_SHORTUTF8_GOT_NON_CONTINUATION 都表示序列过短。区别在于 UTF8_GOT_NON_CONTINUATION 始终表示存在错误,而 UTF8_GOT_SHORT 表示查看了不完整的序列。如果不存在其他标志,则表示该序列在它所包含的范围内是有效的。根据应用程序的不同,这可能意味着以下三种情况之一:

  • 传递的 curlen 长度参数过小,导致函数无法检查所有必要的字节。

  • 正在查看的缓冲区基于读取数据,并且到目前为止接收到的数据在字符中间停止,因此下次读取将读取该字符的剩余部分。(由调用者决定如何处理分割的字节。)

  • 这是一个真正的错误,并且部分序列是我们所能得到的全部。

UTF8_GOT_SUPER

输入序列格式错误,因为它对应于非 Unicode 代码点;也就是说,它高于合法的 Unicode 最大值。仅当输入 flags 参数包含 UTF8_DISALLOW_SUPERUTF8_WARN_SUPER 标志时,才会设置此位。

UTF8_GOT_SURROGATE

输入序列格式错误,因为它对应于 -Unicode UTF-16 代理代码点。仅当输入 flags 参数包含 UTF8_DISALLOW_SURROGATEUTF8_WARN_SURROGATE 标志时,才会设置此位。

要进行自己的错误处理,请使用 UTF8_CHECK_ONLY 标志调用此函数以抑制任何警告,然后检查 *errors 返回值。

    UV  utf8n_to_uvchr_error(const U8 *s, STRLEN curlen,
                             STRLEN *retlen, const U32 flags,
                             U32 *errors)
utf8n_to_uvchr_msgs

此函数仅应在非常特殊的情况下使用。大多数代码应该使用 "utf8_to_uvchr_buf"() 而不是直接调用它。

此函数适用于需要了解错误发生时确切的格式错误,并希望将相应的警告和/或错误消息返回给调用者而不是显示的代码。将返回所有本来会在启用所有词法警告的情况下显示的消息。

它与 "utf8n_to_uvchr_error" 相似,但它在所有其他参数之后接受一个额外的参数 msgs。如果此参数为 0,则此函数的行为与 "utf8n_to_uvchr_error" 相同。否则,msgs 应该指向一个 AV * 变量,在此函数中,此函数将创建一个新的 AV 来包含任何适当的消息。数组的元素按顺序排列,以便第一个将显示的消息位于第 0 个元素中,依此类推。每个元素都是一个哈希,包含三个键值对,如下所示:

text

消息文本,以 SVpv 格式表示。

warn_categories

警告类别(或多个类别),打包成 SVuv 格式。

flag

与该消息关联的单个标志位,以 SVuv 格式表示。该位对应于 *errors 返回值中的某个位,例如 UTF8_GOT_LONG

需要注意的是,将此参数指定为非空值会导致该函数原本会生成的任何警告被抑制,并将其放入 *msgs 中。调用者可以在选择如何处理返回的消息时检查词法警告状态(或不检查)。

如果传递了标志 UTF8_CHECK_ONLY,则不会生成任何警告,因此不会创建 AV。

当然,调用者负责释放任何返回的 AV。

    UV  utf8n_to_uvchr_msgs(const U8 *s, STRLEN curlen,
                            STRLEN *retlen, const U32 flags,
                            U32 *errors, AV **msgs)
UTF8_SAFE_SKIP

如果 s >= e,则返回 0;否则返回由 s 指向的第一个字节的 UTF-8 编码字符的字节数。但它永远不会返回超出 e 的值。在 DEBUGGING 版本中,它断言 s <= e

    STRLEN  UTF8_SAFE_SKIP(char* s, char* e)
UTF8SKIP

返回由 s 指向的第一个(可能是唯一的)字节的非畸形的 UTF-8 编码字符的字节数。

如果存在畸形输入的可能性,请改用

"UTF8_SAFE_SKIP",如果您知道由 s 指向的缓冲区的最大结束指针;或者
"UTF8_CHK_SKIP",如果您不知道它。

最好重构您的代码,以便传递结束指针,以便您在调用此函数时知道它实际上是什么,但如果不可能,"UTF8_CHK_SKIP" 可以最大程度地减少访问输入缓冲区末尾的可能性。

    STRLEN  UTF8SKIP(char* s)
UTF8_SKIP

这是 "UTF8SKIP" 的同义词。

    STRLEN  UTF8_SKIP(char* s)
utf8_to_bytes

注意:utf8_to_bytes 处于实验性阶段,可能会在未经通知的情况下更改或删除。

将长度为 *lenp 的字符串 "s" 从 UTF-8 转换为本地字节编码。与 "bytes_to_utf8" 不同,它会覆盖原始字符串,并将 *lenp 更新为包含新长度。如果失败(使 "s" 保持不变)则返回零,并将 *lenp 设置为 -1。

成功返回后,可以通过在调用之前保存*lenp的值,然后从调用后的*lenp值中减去它来计算字符串中的变体数量。

如果您需要字符串的副本,请参阅 "bytes_from_utf8"

    U8 *  utf8_to_bytes(U8 *s, STRLEN *lenp)
utf8_to_uvchr

已弃用! 计划从 Perl 的未来版本中删除 utf8_to_uvchr。不要在新的代码中使用它;从现有代码中删除它。

返回字符串 s 中第一个字符的本机代码点,该字符串假定为 UTF-8 编码;retlen 将设置为该字符的字节长度。

一些(但不是全部)UTF-8 畸形会被检测到,事实上,一些畸形输入可能会导致读取超出输入缓冲区的末尾,这就是该函数被弃用的原因。请使用 "utf8_to_uvchr_buf" 代替。

如果 s 指向检测到的畸形之一,并且启用了 UTF8 警告,则返回零,并且 *retlen 被设置为(如果 retlen 不为 NULL) -1。如果这些警告被关闭,则计算出的值(如果定义良好,否则为 Unicode 替换字符)将被静默返回,并且 *retlen 被设置为(如果 retlen 不为 NULL)以便 (s + *retlen) 是 s 中下一个可能开始非畸形字符的位置。有关何时返回替换字符的详细信息,请参阅 "utf8n_to_uvchr"

    UV  utf8_to_uvchr(const U8 *s, STRLEN *retlen)
utf8_to_uvchr_buf

返回字符串 s 中第一个字符的本机代码点,该字符串假定为 UTF-8 编码;send 指向 s 的末尾之外的 1。*retlen 将设置为该字符的字节长度。

如果 s 不指向一个格式良好的 UTF-8 字符,并且启用了 UTF8 警告,则返回零,并且 *retlen 被设置为(如果 retlen 不为 NULL) -1。如果这些警告被关闭,则计算出的值(如果定义良好,否则为 Unicode 替换字符)将被静默返回,并且 *retlen 被设置为(如果 retlen 不为 NULL)以便 (s + *retlen) 是 s 中下一个可能开始非畸形字符的位置。有关何时返回替换字符的详细信息,请参阅 "utf8n_to_uvchr"

    UV  utf8_to_uvchr_buf(const U8 *s, const U8 *send, STRLEN *retlen)
UVCHR_IS_INVARIANT

如果代码点 cp 的表示形式无论是否以 UTF-8 编码都相同,则评估为 1;否则评估为 0。UTF-8 不变字符在转换为/从 UTF-8 转换时可以按原样复制,从而节省时间。cp 是 Unicode(如果大于 255);否则是平台本地的。

    bool  UVCHR_IS_INVARIANT(UV cp)
UVCHR_SKIP

返回以 UTF-8 编码表示代码点 cp 所需的字节数。cp 是本机(ASCII 或 EBCDIC)代码点(如果小于 255);否则是 Unicode 代码点。

    STRLEN  UVCHR_SKIP(UV cp)
uvchr_to_utf8_flags

将本机代码点 uv 的 UTF-8 表示形式添加到字符串 d 的末尾;d 应该至少有 UVCHR_SKIP(uv)+1(最多 UTF8_MAXBYTES+1)个空闲字节可用。返回值是指向新字符末尾后的字节的指针。换句话说,

d = uvchr_to_utf8_flags(d, uv, flags);

或者,在大多数情况下,

d = uvchr_to_utf8_flags(d, uv, 0);

这是 Unicode 意识的表达方式

*(d++) = uv;

如果 flags 为 0,则此函数接受 0..IV_MAX 之间的任何代码点作为输入。IV_MAX 在 32 位字中通常为 0x7FFF_FFFF。

指定 flags 可以进一步限制允许和不警告的内容,如下所示

如果 uv 是 Unicode 代理代码点,并且设置了 UNICODE_WARN_SURROGATE,则该函数将发出警告,前提是启用了 UTF8 警告。如果设置了 UNICODE_DISALLOW_SURROGATE,则该函数将失败并返回 NULL。如果两个标志都设置,则该函数将发出警告并返回 NULL。

类似地,UNICODE_WARN_NONCHARUNICODE_DISALLOW_NONCHAR 标志影响函数如何处理 Unicode 非字符。

同样,UNICODE_WARN_SUPERUNICODE_DISALLOW_SUPER 标志影响对超过 Unicode 最大值 0x10FFFF 的代码点的处理。除了 Perl 之外的语言可能无法接受包含这些代码点的文件。

标志 UNICODE_WARN_ILLEGAL_INTERCHANGE 选择以上三个 WARN 标志;UNICODE_DISALLOW_ILLEGAL_INTERCHANGE 选择以上三个 DISALLOW 标志。UNICODE_DISALLOW_ILLEGAL_INTERCHANGE 将允许的输入限制为 Unicode 传统定义的严格 UTF-8。类似地,UNICODE_WARN_ILLEGAL_C9_INTERCHANGEUNICODE_DISALLOW_ILLEGAL_C9_INTERCHANGE 是选择以上 Unicode 和代理标志的快捷方式,但不选择非字符标志,如 Unicode 修订 #9 中所定义。请参阅 "perlunicode 中的非字符代码点"

极高的代码点从未在任何标准中指定,需要对 UTF-8 进行扩展才能表达,Perl 实现了这一点。其他语言编写的程序可能无法读取包含这些代码点的文件;Perl 也无法理解使用不同扩展编写的文件。出于这些原因,有一组单独的标志可以警告和/或禁止这些极高的代码点,即使其他高于 Unicode 的代码点被接受。它们是 UNICODE_WARN_PERL_EXTENDEDUNICODE_DISALLOW_PERL_EXTENDED 标志。有关更多信息,请参见 "UTF8_GOT_PERL_EXTENDED"。当然,UNICODE_DISALLOW_SUPER 会将所有高于 Unicode 的代码点(包括这些代码点)视为格式错误。(请注意,Unicode 标准认为任何高于 0x10FFFF 的代码点都是非法的,但有一些早于它的标准允许使用高达 0x7FFF_FFFF (2**31 -1) 的代码点。)

为了向后兼容,保留了 UNICODE_WARN_PERL_EXTENDED 的一个略微误导的同义词:UNICODE_WARN_ABOVE_31_BIT。类似地,UNICODE_DISALLOW_ABOVE_31_BIT 可以代替更准确的 UNICODE_DISALLOW_PERL_EXTENDED 使用。这些名称具有误导性,因为在 EBCDIC 平台上,这些标志可能适用于实际上适合 31 位的代码点。新的名称准确地描述了所有情况下的情况。

    U8 *  uvchr_to_utf8_flags(U8 *d, UV uv, UV flags)
uvchr_to_utf8_flags_msgs

此函数仅应在非常特殊的情况下使用。

大多数代码应该使用 "uvchr_to_utf8_flags"() 而不是直接调用此函数。

此函数适用于希望将任何警告和/或错误消息返回给调用者而不是显示的代码。将返回所有本应在启用所有词法警告时显示的消息。

它与 "uvchr_to_utf8_flags" 相同,但它在所有其他参数之后接受一个额外的参数 msgs。如果此参数为 0,则此函数的行为与 "uvchr_to_utf8_flags" 相同。否则,msgs 应该指向一个 HV * 变量,此函数将在其中创建一个新的 HV 来包含任何适当的消息。哈希有三个键值对,如下所示

text

消息文本,以 SVpv 格式表示。

warn_categories

警告类别(或多个类别),打包成 SVuv 格式。

flag

与此消息关联的单个标志位,位于 SVuv 中。该位对应于 *errors 返回值中的某个位,例如 UNICODE_GOT_SURROGATE

需要注意的是,将此参数指定为非空值会导致该函数原本会生成的任何警告被抑制,并将其放入 *msgs 中。调用者可以在选择如何处理返回的消息时检查词法警告状态(或不检查)。

当然,调用者负责释放任何返回的 HV。

    U8 *  uvchr_to_utf8_flags_msgs(U8 *d, UV uv, UV flags, HV **msgs)
uvchr_to_utf8

将本机代码点 uv 的 UTF-8 表示形式添加到字符串 d 的末尾;d 应该至少有 UVCHR_SKIP(uv)+1(最多 UTF8_MAXBYTES+1)个空闲字节可用。返回值是指向新字符末尾后的字节的指针。换句话说,

d = uvchr_to_utf8(d, uv);

是推荐的宽原生字符感知方式,用于表示

*(d++) = uv;

此函数接受 0..IV_MAX 之间的任何代码点作为输入。IV_MAX 通常在 32 位字中为 0x7FFF_FFFF。

可以使用 "uvchr_to_utf8_flags" 禁止或警告非 Unicode 代码点,或可能存在问题的代码点。

    U8 *  uvchr_to_utf8(U8 *d, UV uv)

实用函数

C_ARRAY_END

返回指向输入 C 数组最后一个元素之后的元素的指针。

    void *  C_ARRAY_END(void *a)
C_ARRAY_LENGTH

返回输入 C 数组中的元素数量(因此您希望您的基于零的索引小于但不等于)。

    STRLEN  C_ARRAY_LENGTH(void *a)
getcwd_sv

用当前工作目录填充 sv

    int  getcwd_sv(SV *sv)
IN_PERL_COMPILETIME

如果此宏是在程序的编译阶段被调用,则返回 1;否则返回 0;

    bool  IN_PERL_COMPILETIME
IN_PERL_RUNTIME

如果此宏是在程序的执行阶段被调用,则返回 1;否则返回 0;

    bool  IN_PERL_RUNTIME
IS_SAFE_SYSCALL

"is_safe_syscall" 相同。

    bool  IS_SAFE_SYSCALL(NN const char *pv, STRLEN len,
                          NN const char *what, NN const char *op_name)
is_safe_syscall

测试给定的 pv(长度为 len)是否包含任何内部 NUL 字符。如果包含,则将 errno 设置为 ENOENT,可选地使用 syscalls 类别发出警告,并返回 FALSE。

如果名称安全,则返回 TRUE。

whatop_name 用于任何警告。

IS_SAFE_SYSCALL() 宏使用。

    bool  is_safe_syscall(const char *pv, STRLEN len,
                          const char *what, const char *op_name)
my_setenv

C 库 setenv(3) 的包装器。不要使用后者,因为 perl 版本具有理想的安全措施

    void  my_setenv(const char *nam, const char *val)
newPADxVOP

构造、检查并返回包含垫偏移量的操作。type 是操作码,应该是 OP_PADSVOP_PADAVOP_PADHVOP_PADCV 之一。返回的操作将通过 padix 参数设置 op_targ 字段。

这在嵌套函数调用中构造大型 optree 时很方便,因为它避免了需要直接存储垫操作以将 op_targ 字段作为副作用设置。例如

o = op_append_elem(OP_LINESEQ, o,
    newPADxVOP(OP_PADSV, 0, padix));
    OP *  newPADxVOP(I32 type, I32 flags, PADOFFSET padix)
phase_name

返回给定阶段的名称,以 NUL 结尾的字符串形式。

例如,要打印包含当前解释器阶段的堆栈跟踪,您可能需要执行以下操作

const char* phase_name = phase_name(PL_phase);
mess("This is weird. (Perl phase: %s)", phase_name);
    const char * const  phase_name(enum perl_phase)
Poison

PoisonWith(0xEF) 用于捕获对已释放内存的访问。

    void  Poison(void* dest, int nitems, type)
PoisonFree

PoisonWith(0xEF) 用于捕获对已释放内存的访问。

    void  PoisonFree(void* dest, int nitems, type)
PoisonNew

PoisonWith(0xAB) 用于捕获对已分配但未初始化的内存的访问。

    void  PoisonNew(void* dest, int nitems, type)
PoisonWith

用字节模式(一个字节重复多次)填充内存,该模式有望捕获对未初始化内存的访问尝试。

    void  PoisonWith(void* dest, int nitems, type, U8 byte)
StructCopy

这是一个与体系结构无关的宏,用于将一个结构复制到另一个结构。

    void  StructCopy(type *src, type *dest, type)
sv_destroyable

虚拟例程,在没有共享模块存在时报告对象可以被销毁。它忽略其单个 SV 参数,并返回“true”。存在是为了避免测试 NULL 函数指针,并且因为它可能在某些严格级别下发出警告。

    bool  sv_destroyable(SV *sv)
sv_nosharing

虚拟例程,在没有共享模块存在时“共享” SV。或者“锁定”它。或者“解锁”它。换句话说,忽略其单个 SV 参数。存在是为了避免测试 NULL 函数指针,并且因为它可能在某些严格级别下发出警告。

    void  sv_nosharing(SV *sv)

版本控制

new_version

根据传入的 SV 返回一个新的版本对象

SV *sv = new_version(SV *ver);

不改变传入的 ver SV。如果您想升级 SV,请参阅“upg_version”。

    SV *  new_version(SV *ver)
PERL_REVISION

已弃用! 计划从 Perl 的未来版本中删除 PERL_REVISION。不要在新的代码中使用它;从现有代码中删除它。

当前正在编译或执行的 perl 解释器的主要版本号。从 1993 年到 2020 年,它一直是 5

相反,请使用其中一个版本比较宏。请参阅 "PERL_VERSION_EQ"

PERL_SUBVERSION

已弃用! 计划从 Perl 的未来版本中删除 PERL_SUBVERSION。不要在新的代码中使用它;从现有代码中删除它。

当前正在编译或执行的 perl 解释器的微版本号。在稳定版本中,它提供维护更新的点版本号。在开发版本中,它提供开发周期中各个时间点的快照标签。

相反,请使用其中一个版本比较宏。请参阅 "PERL_VERSION_EQ"

PERL_VERSION

已弃用! 计划在未来的 Perl 版本中移除 PERL_VERSION。不要在新的代码中使用它;从现有代码中移除它。

正在编译或执行的 perl 解释器的次要版本号。从 1993 年到 2020 年,这个数字范围从 0 到 33。

相反,请使用其中一个版本比较宏。请参阅 "PERL_VERSION_EQ"

PERL_VERSION_EQ
PERL_VERSION_GE
PERL_VERSION_GT
PERL_VERSION_LE
PERL_VERSION_LT
PERL_VERSION_NE

返回当前正在编译的 perl 是否与参数给出的 perl 具有指定的关联关系。例如,

#if PERL_VERSION_GT(5,24,2)
  code that will only be compiled on perls after v5.24.2
#else
  fallback code
#endif

请注意,这可用于在编译时做出决策

您可以使用特殊值 '*' 来表示最后一个数字的所有可能值。因此,

#if PERL_VERSION_EQ(5,31,'*')

表示 5.31 系列中的所有 perl。而

#if PERL_VERSION_NE(5,24,'*')

表示除 5.24 之外的所有 perl。而

#if PERL_VERSION_LE(5,9,'*')

实际上是

#if PERL_VERSION_LT(5,10,0)

这意味着在将现有的已弃用的 PERL_VERSION 转换为使用此宏时,您不必过多考虑

#if PERL_VERSION <= 9

变为

#if PERL_VERSION_LE(5,9,'*')
    bool  PERL_VERSION_EQ(const U8 major, const U8 minor,
                          const U8 patch)
prescan_version

验证给定字符串是否可以解析为版本对象,但不实际执行解析。可以使用严格或宽松的验证规则。可以选择设置一些提示变量,以便在标记化时为解析代码节省一些时间。

    const char *  prescan_version(const char *s, bool strict,
                                  const char **errstr, bool *sqv,
                                  int *ssaw_decimal, int *swidth,
                                  bool *salpha)
scan_version

返回解析后的版本字符串后的下一个字符的指针,并将传递的 SV 升级为 RV。

函数必须使用已存在的 SV 调用,例如

sv = newSV(0);
s = scan_version(s, SV *sv, bool qv);

对字符串进行一些预处理,以确保它具有版本字符串的正确特征。如果字符串包含下划线(表示这是一个 alpha 版本),则标记该对象。布尔值 qv 表示即使版本字符串没有多个小数点,也应该将其解释为具有多个小数点。

    const char *  scan_version(const char *s, SV *rv, bool qv)
upg_version

将提供的 SV 就地升级为版本对象。

SV *sv = upg_version(SV *sv, bool qv);

返回升级后的 SV 的指针。如果您想强制将此 SV 解释为“扩展”版本,请设置布尔值 qv。

    SV *  upg_version(SV *ver, bool qv)
vcmp

版本对象感知比较。两个操作数都必须已经转换为版本对象。

    int  vcmp(SV *lhv, SV *rhv)
vnormal

接受一个版本对象并返回规范化的字符串表示形式。调用方式如下

sv = vnormal(rv);

注意:您可以直接传递对象或传递 RV 中包含的 SV。

返回的 SV 的引用计数为 1。

    SV *  vnormal(SV *vs)
vnumify

接受一个版本对象并返回规范化的浮点表示形式。调用方式如下

sv = vnumify(rv);

注意:您可以直接传递对象或传递 RV 中包含的 SV。

返回的 SV 的引用计数为 1。

    SV *  vnumify(SV *vs)
vstringify

为了最大程度地与早期版本的 Perl 保持兼容性,此函数将返回浮点表示法或多个点表示法,具体取决于原始版本是否包含 1 个或多个点。

返回的 SV 的引用计数为 1。

    SV *  vstringify(SV *vs)
vverify

验证 SV 是否包含版本对象的有效内部结构。它可以传递版本对象 (RV) 或哈希本身 (HV)。如果结构有效,则返回 HV。如果结构无效,则返回 NULL。

SV *hv = vverify(sv);

请注意,它只确认最基本的结构(以免与可能包含其他哈希条目的派生类混淆)

  • SV 是一个 HV 或对 HV 的引用

  • 哈希包含一个“version”键

  • “version”键的值为对 AV 的引用

    SV *  vverify(SV *vs)

警告和死亡

在所有这些调用中,U32 wn 参数是警告类别常量。您可以在 "warnings 中的类别层次结构" 中查看当前可用的类别,只需将名称中的所有字母大写并以 WARN_ 为前缀即可。例如,perl 程序中使用的类别 void 在 XS 代码中使用时变为 WARN_VOID,并传递给以下调用之一。

ckWARN
ckWARN2
ckWARN3
ckWARN4

这些返回一个布尔值,表示是否为任何警告类别参数启用了警告:ww1、....

如果任何类别默认情况下都已启用,即使不在 use warnings 的范围内,也请使用 "ckWARN_d" 宏。

类别必须完全独立,一个类别不能从另一个类别继承。

    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)
ckWARN_d
ckWARN2_d
ckWARN3_d
ckWARN4_d

类似于 "ckWARN",但仅当警告类别默认启用,即使不在 use warnings 的范围内时使用。

    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)
ck_warner
ck_warner_d

如果 err 给出的警告类别均未启用,则不执行任何操作;否则,使用传入的参数调用 "warner""warner_nocontext"

err 必须是 "packWARN"packWARN2packWARN3packWARN4 宏之一,这些宏填充了适当数量的警告类别。

两种形式的区别仅在于,如果任何类别的警告默认启用,则应使用 ck_warner_d

注意:ck_warner 必须显式调用为 Perl_ck_warner,并带有 aTHX_ 参数。

注意:ck_warner_d 必须显式调用为 Perl_ck_warner_d,并带有 aTHX_ 参数。

    void  Perl_ck_warner(pTHX_ U32 err, const char *pat, ...)
CLEAR_ERRSV

清除 $@ 的内容,将其设置为空字符串。

这将用一个新的 SV 替换任何只读 SV,并删除任何魔法。

    void  CLEAR_ERRSV()
croak
croak_nocontext

这些是 Perl die 函数的 XS 接口。

它们接受一个 sprintf 风格的格式模式和参数列表,这些参数用于生成字符串消息。如果消息不以换行符结尾,则它将扩展为包含代码中当前位置的指示,如 "mess_sv" 所述。

错误消息将用作异常,默认情况下将控制权返回到最近的封闭 eval,但会受到 $SIG{__DIE__} 处理程序的修改。无论如何,这些 croak 函数都不会正常返回。

出于历史原因,如果 pat 为空,则 ERRSV$@)的内容将用作错误消息或对象,而不是从参数构建错误消息。如果您想抛出一个非字符串对象,或者自己在一个 SV 中构建一个错误消息,最好使用 "croak_sv" 函数,它不涉及覆盖 ERRSV

这两个形式的区别仅在于 croak_nocontext 不接受线程上下文 (aTHX) 参数。它通常是首选,因为它比普通的 Perl_croak 占用更少的代码字节,而且当你即将抛出异常时,时间很少是关键资源。

注意:croak 必须显式地调用为 Perl_croak,并带有一个 aTHX_ 参数。

    void  Perl_croak     (pTHX_ const char *pat, ...)
    void  croak_nocontext(const char *pat, ...)
croak_no_modify

它封装了一个常见的死亡原因,生成比使用通用 Perl_croak 更简洁的对象代码。它与 Perl_croak(aTHX_ "%s", PL_no_modify) 完全等效(它扩展为类似于“尝试修改只读值”的内容)。

在异常代码路径上使用的代码越少,CPU 缓存压力就越小。

    void  croak_no_modify()
croak_sv

这是 Perl 的 die 函数的 XS 接口。

baseex 是错误消息或对象。如果它是一个引用,它将按原样使用。否则它将用作字符串,如果它不以换行符结尾,它将被扩展为一些指示代码中当前位置的信息,如 "mess_sv" 所述。

错误消息或对象将用作异常,默认情况下将控制权返回到最近的封闭 eval,但会受到 $SIG{__DIE__} 处理程序的修改。无论如何,croak_sv 函数永远不会正常返回。

要使用简单的字符串消息死亡,"croak" 函数可能更方便。

    void  croak_sv(SV *baseex)
die
die_nocontext

它们的行为与 "croak" 相同,除了返回类型。它们应该只在需要 OP * 返回类型的地方使用。它们永远不会真正返回。

这两个形式的区别仅在于 die_nocontext 不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

注意:die 必须显式地调用为 Perl_die,并带有一个 aTHX_ 参数。

    OP *  Perl_die     (pTHX_ const char *pat, ...)
    OP *  die_nocontext(const char *pat, ...)
die_sv

此函数的行为与 "croak_sv" 相同,除了返回值类型。它应该只在需要 OP * 返回类型的地方使用。该函数实际上永远不会返回。

    OP *  die_sv(SV *baseex)
ERRSV

返回 $@ 的 SV,如果需要则创建它。

    SV *  ERRSV
packWARN
packWARN2
packWARN3
packWARN4

这些宏用于将警告类别打包到单个 U32 中,以传递给接受警告类别参数的宏和函数。要打包的类别数量由名称给出,并传递相应的类别参数数量。

    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)
SANE_ERRSV

清理 ERRSV,以便我们可以安全地设置它。

这将用一个新的可写副本替换任何只读 SV,并删除任何魔法。

    void  SANE_ERRSV()
vcroak

这是 Perl 的 die 函数的 XS 接口。

patargs 是一个 sprintf 风格的格式模式和封装的参数列表。这些用于生成字符串消息。如果消息没有以换行符结尾,则它将扩展一些代码中当前位置的指示,如 "mess_sv" 所述。

错误消息将用作异常,默认情况下将控制权返回到最近的封闭 eval,但会受到 $SIG{__DIE__} 处理程序的修改。在任何情况下,croak 函数都不会正常返回。

出于历史原因,如果 pat 为空,则 ERRSV ($@) 的内容将用作错误消息或对象,而不是从参数构建错误消息。如果您想抛出一个非字符串对象,或在 SV 中自己构建一个错误消息,最好使用 "croak_sv" 函数,它不涉及覆盖 ERRSV

    void  vcroak(const char *pat, va_list *args)
vwarn

这是 Perl 的 warn 函数的 XS 接口。

这类似于 "warn",但 args 是一个封装的参数列表。

"vcroak" 不同,pat 不允许为空。

    void  vwarn(const char *pat, va_list *args)
vwarner

这类似于 "warner",但 args 是一个封装的参数列表。

    void  vwarner(U32 err, const char *pat, va_list *args)
warn
warn_nocontext

这些是 Perl warn 函数的 XS 接口。

它们接受一个 sprintf 风格的格式模式和参数列表,这些参数用于生成字符串消息。如果消息不以换行符结尾,则它将扩展为包含代码中当前位置的指示,如 "mess_sv" 所述。

错误消息或对象默认情况下将写入标准错误,但这会受到 $SIG{__WARN__} 处理程序的修改。

"croak" 不同,pat 不允许为空。

两种形式的区别仅在于 warn_nocontext 不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

注意:warn 必须显式调用为 Perl_warn,并带有 aTHX_ 参数。

    void  Perl_warn     (pTHX_ const char *pat, ...)
    void  warn_nocontext(const char *pat, ...)
warner
warner_nocontext

这些使用 sprintf 风格的格式模式 pat 和参数列表,输出指定类别(或类别)的警告。

err 必须是 "packWARN"packWARN2packWARN3packWARN4 宏之一,这些宏填充了适当数量的警告类别。如果它们指定的任何警告类别是致命的,则会抛出致命异常。

无论如何,都会通过模式和参数生成消息。如果消息没有以换行符结尾,则会用一些指示代码中当前位置的信息扩展它,如 "mess_sv" 所述。

错误消息或对象默认情况下将写入标准错误,但这会受到 $SIG{__WARN__} 处理程序的修改。

pat 不允许为空。

两种形式的区别仅在于 warner_nocontext 不接受线程上下文 (aTHX) 参数,因此在调用者没有线程上下文的情况下使用。

这些函数与同名 "warn" 函数不同,后者用于 XS 代码无条件地显示警告,而这些函数用于可能正在编译 perl 程序的代码,并进行额外的检查以查看警告是否应该致命。

注意:warner 必须显式地调用为 Perl_warner,并带有一个 aTHX_ 参数。

    void  Perl_warner     (pTHX_ U32 err, const char *pat, ...)
    void  warner_nocontext(U32 err, const char *pat, ...)
warn_sv

这是 Perl 的 warn 函数的 XS 接口。

baseex 是错误消息或对象。如果它是一个引用,它将按原样使用。否则它将用作字符串,如果它不以换行符结尾,它将被扩展为一些指示代码中当前位置的信息,如 "mess_sv" 所述。

错误消息或对象默认情况下将写入标准错误,但这会受到 $SIG{__WARN__} 处理程序的修改。

要使用简单的字符串消息发出警告,"warn" 函数可能更方便。

    void  warn_sv(SV *baseex)

XS

xsubpp 将 XS 代码编译成 C。参见 "perlutil 中的 xsubpp"

aMY_CXT

perlxs 中描述。

_aMY_CXT

perlxs 中描述。

aMY_CXT_

perlxs 中描述。

ax

xsubpp 设置的变量,用于指示堆栈基址偏移量,由 STXSprePUSHXSRETURN 宏使用。dMARK 宏必须在设置 MARK 变量之前调用。

    I32  ax
CLASS

xsubpp 设置的变量,用于指示 C++ XS 构造函数的类名。这始终是一个 char*。参见 "THIS"

    char*  CLASS
dAX

设置 ax 变量。这通常由 xsubpp 通过调用 dXSARGS 自动处理。

    dAX;
dAXMARK

设置 ax 变量和堆栈标记变量 mark。这通常由 xsubpp 通过调用 dXSARGS 自动处理。

    dAXMARK;
dITEMS

设置 items 变量。这通常由 xsubpp 通过调用 dXSARGS 自动处理。

    dITEMS;
dMY_CXT

perlxs 中描述。

dMY_CXT_SV

现在是一个占位符,不声明任何内容

    dMY_CXT_SV;
dUNDERBAR

设置 UNDERBAR 宏所需的任何变量。它用于定义 padoff_du,但目前是一个空操作。但是,强烈建议仍然使用它来确保过去和将来的兼容性。

    dUNDERBAR;
dXSARGS

为 XSUB 设置堆栈和标记指针,调用 dSPdMARK。通过调用 dAXdITEMS 设置 axitems 变量。这通常由 xsubpp 自动处理。

    dXSARGS;
dXSI32

为具有别名的 XSUB 设置 ix 变量。这通常由 xsubpp 自动处理。

    dXSI32;
items

xsubpp 设置的变量,用于指示堆栈上的项目数量。请参阅 "perlxs 中的可变长度参数列表"

    I32  items
ix

xsubpp 设置的变量,用于指示用于调用 XSUB 的别名。请参阅 "perlxs 中的 ALIAS: 关键字"

    I32  ix
MY_CXT

perlxs 中描述。

MY_CXT_CLONE

perlxs 中描述。

MY_CXT_INIT

perlxs 中描述。

pMY_CXT

perlxs 中描述。

_pMY_CXT

perlxs 中描述。

pMY_CXT_

perlxs 中描述。

RETVAL

xsubpp 设置的变量,用于保存 XSUB 的返回值。这始终是 XSUB 的正确类型。请参阅 "perlxs 中的 RETVAL 变量"

    type  RETVAL
ST

用于访问 XSUB 堆栈上的元素。

    SV*  ST(int ix)
START_MY_CXT

perlxs 中描述。

THIS

xsubpp 设置的变量,用于指定 C++ XSUB 中的对象。这始终是 C++ 对象的正确类型。请参阅 "CLASS""perlxs 中使用 XS 与 C++"

    type  THIS
UNDERBAR

对应于 $_ 变量的 SV*。即使作用域中存在词法 $_,它也能正常工作。

XS

用于声明 XSUB 及其 C 参数列表的宏。这由 xsubpp 处理。它与使用更明确的 XS_EXTERNAL 宏相同;后者更可取。

XS_EXTERNAL

用于显式导出符号来声明 XSUB 及其 C 参数列表的宏。

XS_INTERNAL

用于声明 XSUB 及其 C 参数列表而不导出符号的宏。这由 xsubpp 处理,通常比不必要地导出 XSUB 符号更可取。

XSPROTO

"XS_INTERNAL""XS_EXTERNAL" 用于声明函数原型的宏。您可能不应该直接使用它。

未记录的元素

以下函数已被标记为公共 API 的一部分,但目前未记录。请自行承担风险使用它们,因为接口可能会发生变化。本文档中未列出的函数不打算供公众使用,在任何情况下都不应使用。

如果您觉得需要使用其中一个函数,请先发送电子邮件至 [email protected]。可能存在函数未记录的充分理由,应将其从此列表中删除;或者可能只是没有人有时间记录它。在后一种情况下,您将被要求提交一个补丁来记录该函数。一旦您的补丁被接受,它将表明该接口是稳定的(除非明确标记为其他情况)并且您可以使用它。

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     

接下来是标记为 API 的实验性元素。使用这些元素比使用普通的未记录元素风险更大。它们被列在这里是因为它们应该被列在某个地方(这样它们的存在就不会丢失),而这里是最适合它们的地方。

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             

最后是已弃用的未记录 API 元素。不要在新的代码中使用任何这些元素;从现有代码中删除所有这些元素的所有出现。

目前没有此类项目。

作者

直到 1997 年 5 月,这份文档由 Jeff Okamoto <[email protected]> 维护。现在它作为 Perl 本身的一部分进行维护。

在 Dean Roehrich、Malcolm Beattie、Andreas Koenig、Paul Hudson、Ilya Zakharevich、Paul Marquess、Neil Bowers、Matthew Green、Tim Bunce、Spider Boardman、Ulrich Pfeifer、Stephen McCamant 和 Gurusamy Sarathy 的大量帮助和建议下。

API 列表最初由 Dean Roehrich <[email protected]> 创建。

由 Benjamin Stuhl 更新,以从源代码中的注释自动生成。

另请参阅

config.h, perlapio, perlcall, perlclib, perlembed, perlfilter, perlguts, perlhacktips, perlintern, perlinterp, perliol, perlmroapi, perlreapi, perlreguts, perlxs