簡體   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