2017-07-29 20 views
1

我正在C++中为参数化字符串(用于指定终端的某些终端功能)实施解析器。那时,我发现这个% encoding传来的terminfo的man page在terminfo参数化字符串中'%1'编码

        %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的bool结果)或一个字符将被推入堆栈,然后是%l encoding意味着任何或没有下述的:

  • 弹出从堆栈和if a character push 1 onto stackif 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

回答

2

尽管页面标题“在线Linux的联机手册”,手动页面称为是的Solaris(SVR4),其通过在X/Open诅咒废弃。既没有提供必要的细节, ncurses的解释填补了细节:

  • SVR4(和X/Open,即反刍信息不增加清晰度)说,对于tparm的参数是‘长’。但是一些参数必须是字符串(即,char*),以支持标签功能。
  • 在这个tparm年首次记载的时间,long似乎大到足以容纳一个指针(即char*,一个)和<stdarg.h>不是常见的做法。关于“足够大”的假设不一定是正确的(参见20年前的64-Bit Programming Models: Why LP64?中的讨论),但它是为tparm作出的假设。
  • 对于您最感兴趣的平台,假设您使用LP64(或LP32)。
  • 当你调用tparm,ncurses的分析能力字符串来确定一个特定的参数是否将被解释为一个字符串(无论它与%l%s相匹配),并且只要使用该参数,它提供的字符串。
  • ncurses使用堆栈进行一系列操作(请参阅terminfo manual page中的Parameterized Strings)。

实际上,ncurses的使用两个越过能力字符串:

  1. 在第一遍(见以源代码_nc_tparm_analyze),它的步骤通过串以查看哪些参数将被压入堆栈,当它看到一个%l%s时,将该阵列中的位置标记为字符串p_is_s[]
  2. 然后在第二遍中,ncurses使用_nc_tparm_internal(分别由varargs和固定长度参数列表函数tiparmtparm共享)。使用该数组,它知道是否将零参数作为数字零或空字符串处理。参照source-code,如果要求弹出一个字符串,其中给出了一个数字(或者如果堆栈中没有东西),ncurses会传回一个空字符串。

所有这一切都依赖于正确的呼叫tparm,因为没有可移植的方法来确定的传递函数参数的个数,也不是真正的自己类型。与printf不同,编译器没有任何帮助。但是,如果参数列表匹配能力字符串,ncurses将(可能...)匹配它。 SVr4诅咒不会这样做(例如,请参阅tparm.c on illumos-gate)。

在给定示例,%p1%l

  • ncurses的期望一个被压入堆栈,例如,使用%p1(指的tparm第一参数的能力串之后),和
  • ncurses的持久性有机污染物的字符串值出栈,
  • 调用strlen得到它的长度和
  • 推动该长度(作为棕黄色)到堆叠上。

在栈上,这个数字可以在计算中使用,例如,

%p1%l%{1}%+ 

1添加到它(推动的结果到堆栈),或者只是用在(无通过格式化编号%d

要输出字符串及其长度,再假设该字符串是第一个参数,那么你可以参考它不止一次在能力字符串这样

%p1%l%d:%p1%s 

输出字符串的长度,冒号(:)分隔符和字符串本身。 tparm的“输出”当然是另一个字符串,打算使用putptputs打印,因为它可能嵌入了padding信息(请参阅terminfo function manual page中的Output Functions)。

为terminfo定义的操作来自于SVr4,它在1988年正式宣布,但实际上它花了几年的时间才成为现实。没有为字符串连接或子字符串定义操作;应用程序必须为自己做这样的事情。什么terminfo 确实是参数化的数字,和(不完全是一个事后)提供插入字符串在适当的地方。

+0

感谢您的回答,现在我指的是[此手册页](https://linux.die.net/man/5/terminfo),如果您想详细阐述__ncurses分析功能字符串以确定一个特定的参数是否将被解释为一个字符串(不管它是否与%1或%s匹配),并且每当使用该参数时,它将为字符串_提供一个示例,谢谢:) – tkhurana96

+0

实际上,这个手册页](https://linux.die.net/man/5/terminfo)是一个如何不格式化一个手册页的例子,我在这里详细讨论了[here](http:// invisible-island。净/脚本/ man2html.html)。我添加了一个权威的链接到我的答案。 –