terminfo 参数化字符串中的“%l”编码
`%l` encoding in terminfo parameterized strings
我正在用 C++ 为参数化字符串(用于指定终端的某些终端功能)实现解析器。然后我在 terminfo 的 man page 上遇到了这个 % encoding
:
%l push strlen(pop)
所以,我的问题是,每当我们将任何东西压入堆栈时,都会遇到以下 % encodings
:
%p[1-9] push ith parm
%’c’ push char constant c
%{nn} push decimal constant nn
%l push strlen(pop)
%+ %− %* %/ %m (arithmetic): push(pop integer2 op pop integer1)
%& %| %^ (bit operations): push(pop integer2 op pop integer1)
%= %> %< (logical operations): push(pop integer2 op pop integer1)
%A %O (logical operations): and, or
%! %~ (unary operations): push(op pop)
并且每当遇到这些并计算它们的结果并且当结果将要被压入堆栈时,然后一个整数(包括布尔结果的 0 或 1)或一个字符将被压入堆栈 ,那么 %l encoding
是指以下任何一项还是 none:
从堆栈中弹出一个值,然后if a character push 1 onto stack
和if an integer push #digits_in_that_integer onto the stack
。
(因为 %l
是使用 strlen
在 manpages 中编写的)从堆栈中弹出一个字符串(要弹出一个字符串:继续弹出直到堆栈空),然后将弹出字符串的长度推回堆栈。
所以,我的问题是 %l push strlen(pop)
是什么意思,它指的是哪个长度?
奖金问题:在 terminfo 的参数化字符串(在上面提到的第二个要点中)的情况下,弹出字符串的方法是否正确?
编辑:正如 Thomas Dickey 所指出的,现在我指的是 this man page of terminfo。
尽管页面标题为 "Linux Manpages Online",但参考的手册页是 Solaris (SVr4),已被X/Open诅咒。两者都没有提供必要的细节; ncurses的解释填写详情:
- SVr4(和 X/Open,在没有增加清晰度的情况下重复了该信息)说
tparm
的参数是 "long"。但是一些参数必须是字符串(即 char*
),以支持标签功能。
- 在首次记录
tparm
时,long
似乎大到足以容纳一个指针(即 char*
、一个 字符串 ), <stdarg.h>
不是常见的做法。关于 "big enough" 的假设不一定正确(请参阅 20-year-old 64-Bit Programming Models: Why LP64? 中的讨论),但这是对 tparm
. 的假设
- 对于您最感兴趣的平台,假设您有 LP64(或 LP32)。
- 当您调用
tparm
时,ncurses 会分析功能字符串以确定特定参数是否将被解释为字符串(是否匹配 %l
或 %s
),并且每当使用该参数时,它都会提供字符串。
- ncurses 使用堆栈进行一系列操作(参考Parameterized Strings in the
terminfo
manual page)。
实际上,ncurses 在能力字符串上使用了两次遍历:
- 在第一遍中(参见 source-code 中的
_nc_tparm_analyze
),它遍历字符串以查看哪个参数将被压入堆栈,当它看到 %l
或 %s
,将数组 p_is_s[]
中的位置标记为字符串。
- 然后在第二遍中,ncurses 使用
_nc_tparm_internal
(shared by varargs- and a fixed-length argument list functions tiparm
and tparm
, respectively). Using the array, it knows whether to handle a zero-parameter as a numeric zero, or an empty string. Referring to the source-code,如果要求弹出一个 string 给定数字的地方(或者如果堆栈上没有任何内容), ncurses 返回一个空字符串。
所有这些都依赖于对 tparm
的正确调用,因为没有可移植的方法来确定传递给 到 函数的参数数量,实际上也没有确定它们的参数数量类型。与 printf
不同,编译器没有帮助。但是如果参数列表匹配能力字符串,ncurses 将(可能...)匹配它。 SVr4 curses 不会这样做(参见示例 tparm.c
on illumos-gate)。
在给定的示例中,%p1%l
- ncurses 期望 string 被压入堆栈,例如,使用
%p1
(指代能力之后 tparm
的第一个参数字符串)和
- ncurses 从堆栈中弹出字符串值,
- 调用
strlen
获取它的长度并且
- 将该长度(作为数字)压入堆栈。
堆栈上的那个数字可以用于计算,例如
%p1%l%{1}%+
将其加 1(将结果压入堆栈),或者通过 %d
,等等
要输出一个字符串和它的长度,同样假设字符串是第一个参数,那么你可以像这样在能力字符串中多次引用它
%p1%l%d:%p1%s
输出字符串的长度、冒号(:
)分隔符和字符串本身。 tparm
的 "output" 当然是另一个字符串,打算使用 putp
或 tputs
打印,因为它可能嵌入了 padding information (see Output Functions in the terminfo function manual page).
为terminfo定义的操作来自SVr4,它于1988年正式宣布,但实际上花了几年时间才成为现实。没有为字符串连接或子字符串定义操作;应用程序必须自己做这类事情。什么 terminfo does 是参数化数字,并且(不完全是事后的想法)提供在适当的地方插入字符串。
我正在用 C++ 为参数化字符串(用于指定终端的某些终端功能)实现解析器。然后我在 terminfo 的 man page 上遇到了这个 % encoding
:
%l push strlen(pop)
所以,我的问题是,每当我们将任何东西压入堆栈时,都会遇到以下 % encodings
:
%p[1-9] push ith parm
%’c’ push char constant c
%{nn} push decimal constant nn
%l push strlen(pop)
%+ %− %* %/ %m (arithmetic): push(pop integer2 op pop integer1)
%& %| %^ (bit operations): push(pop integer2 op pop integer1)
%= %> %< (logical operations): push(pop integer2 op pop integer1)
%A %O (logical operations): and, or
%! %~ (unary operations): push(op pop)
并且每当遇到这些并计算它们的结果并且当结果将要被压入堆栈时,然后一个整数(包括布尔结果的 0 或 1)或一个字符将被压入堆栈 ,那么 %l encoding
是指以下任何一项还是 none:
从堆栈中弹出一个值,然后
if a character push 1 onto stack
和if an integer push #digits_in_that_integer onto the stack
。(因为
%l
是使用strlen
在 manpages 中编写的)从堆栈中弹出一个字符串(要弹出一个字符串:继续弹出直到堆栈空),然后将弹出字符串的长度推回堆栈。
所以,我的问题是 %l push strlen(pop)
是什么意思,它指的是哪个长度?
奖金问题:在 terminfo 的参数化字符串(在上面提到的第二个要点中)的情况下,弹出字符串的方法是否正确?
编辑:正如 Thomas Dickey 所指出的,现在我指的是 this man page of terminfo。
尽管页面标题为 "Linux Manpages Online",但参考的手册页是 Solaris (SVr4),已被X/Open诅咒。两者都没有提供必要的细节; ncurses的解释填写详情:
- SVr4(和 X/Open,在没有增加清晰度的情况下重复了该信息)说
tparm
的参数是 "long"。但是一些参数必须是字符串(即char*
),以支持标签功能。 - 在首次记录
tparm
时,long
似乎大到足以容纳一个指针(即char*
、一个 字符串 ),<stdarg.h>
不是常见的做法。关于 "big enough" 的假设不一定正确(请参阅 20-year-old 64-Bit Programming Models: Why LP64? 中的讨论),但这是对tparm
. 的假设
- 对于您最感兴趣的平台,假设您有 LP64(或 LP32)。
- 当您调用
tparm
时,ncurses 会分析功能字符串以确定特定参数是否将被解释为字符串(是否匹配%l
或%s
),并且每当使用该参数时,它都会提供字符串。 - ncurses 使用堆栈进行一系列操作(参考Parameterized Strings in the
terminfo
manual page)。
实际上,ncurses 在能力字符串上使用了两次遍历:
- 在第一遍中(参见 source-code 中的
_nc_tparm_analyze
),它遍历字符串以查看哪个参数将被压入堆栈,当它看到%l
或%s
,将数组p_is_s[]
中的位置标记为字符串。 - 然后在第二遍中,ncurses 使用
_nc_tparm_internal
(shared by varargs- and a fixed-length argument list functionstiparm
andtparm
, respectively). Using the array, it knows whether to handle a zero-parameter as a numeric zero, or an empty string. Referring to the source-code,如果要求弹出一个 string 给定数字的地方(或者如果堆栈上没有任何内容), ncurses 返回一个空字符串。
所有这些都依赖于对 tparm
的正确调用,因为没有可移植的方法来确定传递给 到 函数的参数数量,实际上也没有确定它们的参数数量类型。与 printf
不同,编译器没有帮助。但是如果参数列表匹配能力字符串,ncurses 将(可能...)匹配它。 SVr4 curses 不会这样做(参见示例 tparm.c
on illumos-gate)。
在给定的示例中,%p1%l
- ncurses 期望 string 被压入堆栈,例如,使用
%p1
(指代能力之后tparm
的第一个参数字符串)和 - ncurses 从堆栈中弹出字符串值,
- 调用
strlen
获取它的长度并且 - 将该长度(作为数字)压入堆栈。
堆栈上的那个数字可以用于计算,例如
%p1%l%{1}%+
将其加 1(将结果压入堆栈),或者通过 %d
,等等
要输出一个字符串和它的长度,同样假设字符串是第一个参数,那么你可以像这样在能力字符串中多次引用它
%p1%l%d:%p1%s
输出字符串的长度、冒号(:
)分隔符和字符串本身。 tparm
的 "output" 当然是另一个字符串,打算使用 putp
或 tputs
打印,因为它可能嵌入了 padding information (see Output Functions in the terminfo function manual page).
为terminfo定义的操作来自SVr4,它于1988年正式宣布,但实际上花了几年时间才成为现实。没有为字符串连接或子字符串定义操作;应用程序必须自己做这类事情。什么 terminfo does 是参数化数字,并且(不完全是事后的想法)提供在适当的地方插入字符串。