繁体   English   中英

terminfo参数化字符串中的`%l`编码

[英]`%l` encoding in terminfo parameterized strings

我在C ++中为参数化的字符串(用于指定终端的某些终端功能)实现一个解析器。 然后我在terminfo的手册页上遇到了这种% 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)

并且每当遇到这些错误并计算它们的结果以及将结果推入堆栈时, 则将整数(对于bool结果包括0或1)或一个字符都将推入堆栈 ,然后执行%l encoding表示以下任何一项或全部都不是:

  • 从堆栈中弹出一个值, if a character push 1 onto stackif an integer push #digits_in_that_integer onto the stack

  • (因为%l是使用strlen手册页中编写的),从堆栈中弹出一个字符串(以弹出字符串:一直弹出直到堆栈为空),然后将弹出的字符串的长度推回堆栈中。

所以,我的问题是%l push strlen(pop)是什么意思,它在说什么长度?

额外的问题:在terminfo的参数化字符串(在上述第二个要点中)的情况下,弹出字符串的方法正确吗?

编辑:正如Thomas Dickey指出的那样,现在我指的是terminfo的手册页

尽管页面标题为“ Linux在线联机手册 ,但所指的手册页是Solaris(SVr4),它已被X / Open Curses淘汰。 没有给出必要的细节; ncurses的解释填写了以下详细信息:

  • SVr4(和X / Open,在不增加清晰度的情况下重新提供信息)表示tparm的参数很长。 但是某些参数必须是字符串(即char* )才能支持标签功能。
  • 在首次记录tparm时, long似乎足够大以容纳指针(即char*string ),并且<stdarg.h>并不常见。 关于“足够大”的假设不一定正确(请参阅20年历史的64位编程模型中的讨论:为什么选择LP64? ),但这是对tparm所做的假设。
  • 对于您最感兴趣的平台,假定您具有LP64(或LP32)。
  • 当您调用tparm ,ncurses会分析功能字符串,以确定某个特定参数是否将被解释为字符串(无论它与%l还是%s匹配),并且无论何时使用该参数,它都会提供该字符串。
  • ncurses使用堆栈进行一系列操作(请参阅terminfo手册页中的参数化字符串 )。

实际上,ncurses在功能字符串上使用两次传递:

  1. 在第一遍中(请参见源代码中的_nc_tparm_analyze ),它逐步遍历字符串以查看将哪个参数压入堆栈,并在看到%l%s时将其在数组p_is_s[]中的位置标记为一个字符串。
  2. 然后在第二遍中,ncurses使用_nc_tparm_internal (分别由varargs-和定长参数列表函数tiparmtparm )。 使用数组,它知道是将零参数处理为数字零还是将空字符串处理。 参考源代码 ,如果要求弹出一个给出了数字的字符串 (或者堆栈上没有剩余内容),则ncurses传回一个空字符串。

所有这些都依赖于对tparm的正确调用,因为没有可移植的方法来确定传递函数的参数的数量,也不能确定它们的类型 printf不同,编译器没有帮助。 但是,如果参数列表与功能字符串匹配,则ncurses将(可能...)与之匹配。 SVr4 curses不会这样做(例如,请参见illumos-gate上的tparm.c )。

在给定的示例中, %p1%l

  • ncurses期望将字符串压入堆栈,例如,使用%p1 (以引用功能字符串之后的tparm的第一个参数),并且
  • ncurses将字符串值弹出堆栈,
  • 调用strlen以获取其长度,
  • 将长度(作为数字)压入堆栈。

堆栈中的该数字可用于计算,例如,

%p1%l%{1}%+

向其添加1(将结果推入堆栈),或通过使用%d格式化数字等方式使用 (堆栈中什么都没有)。

要输出一个字符串及其长度,再次假设该字符串是第一个参数,那么您可以在功能字符串中多次引用它,如下所示

%p1%l%d:%p1%s

以输出字符串的长度,冒号( : )分离器和字符串本身。 所述的“输出” tparm当然另一个字符串,意在使用被打印的putptputs ,因为它可以具有嵌入填充信息(参见输出功能的terminfo函数手册页 )。

为terminfo定义的操作来自SVr4,该SVr4于1988年正式宣布,尽管实际上它花了几年时间才成为现实。 没有为字符串连接或子字符串定义任何操作; 应用程序必须自己做这种事情。 terminfo的作用是对数字进行参数化,并且(不完全是事后的想法)可以在适当的位置插入字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM