命令存儲結構
對於上圖中略去的cmd_elemnt,它代表了一條命令,具體展開如下:
每條命令按上圖存儲,命令被分拆爲tokens,存儲在vector中
如此,形成了zebra命令模式的基本框架:所有命令被分類到不同模式下。這裏的模式即上面圖中的
節點cmd_node,而命令則相當於cmd_element,可見,命令被放到了不同的node下。注意,上圖中的虛
箭頭並不代表鏈表,只是代表元素的先後順序,實際上它們是以數組存儲的。
Zebra中命令的總結點(或根結點)是cmdvec,它包含了所有的cmd_node,而cmd_node包含了所有
的cmd_element。
初始化時首先加載所有的命令,形成上圖中的整體層次結構,然後對每個cmd_node下的命令執
行qsort,按命令的字符序重排,主要是爲了查找加速。
命令分析
命令的執行只要查找cmdvec就可以了,下面着重於zebra命令的tab自動補齊,及打印所有可用命令
接收tab鍵,自動補齊命令,執行函數: vty_complete_command()
Zebra的調用結構:
整個流程的主體是cmd_complete_command(),它調用了cmd_filter_by_completion()匹配已輸入字符 串,返回匹配結果,結果分爲 了10種
no_match |
extend_match |
Ipv4_prefix_match |
Ipv4_match |
Ipv6_prefix_match |
Ipv6_match |
range_match |
vararg_match |
partly_match |
exact_match |
大部分是zebra支持的變量的匹配類型,partly_match表示只是部分匹配,exact_match表示一個
token的完全匹配,no_match表示不 匹配,這三個狀態是我們所關心的。
例子: 輸入’configure’,輸入tab補齊,返回’configure(空格)’
輸入’configure(空格)’,輸入tab補齊,返回’configure(空格)terminal’
輸入’c’,輸入tab補齊,返回’co’
輸入’terminal(空格)’,輸入tab補齊,返回’terminal(空格)’ ‘length monitor no’
上面就是補齊的基本情況了(爲了標註空格,上面的空格都以中文寫出)
1. 對於輸入的命令字符串分拆成token後存儲爲vector,程序中則是(以’configure ter’爲例):
2. 假設vline有n個token,則對於vline的前n-1個token與每個命令的對應token比較,如果不是 exact_match,則返回
3. 對於vline的第n個token,匹配每個命令的第n個token前幾位是否爲’ter’,並記錄下
所有匹配的token,生成匹配向量matchvec:
4. 結果回送給終端,在輸出完匹配結果後,再輸出一個空格,即上例的實際輸出結果爲:
‘configure terminal ’(注意:最後多了個空格)
空格的作用:補上空格的意義在於,如果檢測輸入命令的最後一個字符是空格,則在命令向
量vline最後補上’/0’,如輸入’configure ’,則生成vline如下圖:
在匹配vline的第二個token時,由於是空字符,所以它與所有的字符都相匹配,達到自動補齊下 一個可選token的作用
接收?,顯示所有命令,執行函數: vty_describe_command()
對zebra命令模式有所分析後,下面小試牛刀,寫個函數測試框架(Function Test Frame),目的在於提供接口函數的測試的代碼框架,輕鬆實現自動補齊、函數解釋、函數運行等,方便測試人員與接口使用者迅速瞭解函數
數據結構
基本存儲結構爲vector
命令存儲結構
在函數測試中,不存在節點的概念,因此刪除了節點,cmd_element直接掛載在根節點cmdvec下,如下圖所示(而命令的結構則無需變化):
終端I/O
由於輸入字符並不以回車符結束,也可能是tab鍵或方向鍵,因此不能使用stdio中的I/O函數(都會緩衝)[爲什麼設置setvbuf也沒有用???],通過修改終端的屬性termios,實現windows下的getch()函數,該函數沒有緩衝
特殊字符處理
輸入回車: 執行用戶輸入的命令
輸入tab鍵:若用戶未輸入任何內容,則輸出所有可用命令;
若用戶已輸入字符,則輸出匹配後命令
輸入?鍵: 用戶輸入命令,再輸入問號,查看該命令的詳細註釋
輸入方向上鍵:用前一條輸入的命令作爲此次輸入
輸入方向下鍵:用後一條輸入的命令作爲此次輸入
由於許多按鍵的值是多個字符構成,如方向上鍵是27 91 65,且不同按鍵組成的字符數也不相同,所以未對所有按鍵處理,如輸入F1~F12會有異常
測試函數使用
·在cmd.h中,添加測試函數
·在ftf_main.c中,加載測試函數
·在Makefile中,加入接口文件
編譯,執行即可
代碼結構
例子
鍵入tab鍵:
鍵入pa後,鍵入tab:
鍵入命令後,鍵入?:
鍵入方向上鍵:
鍵入方向下鍵:
執行:
相關代碼下載鏈接:http://download.csdn.net/detail/qy532846454/4266019