2017-07-29 58 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)。我添加了一個權威的鏈接到我的答案。 –