libctemplate——源碼分析

前言

在閱讀此文章前,建議先閱讀我以前寫的《libctemplate——C語言模塊引擎簡介及使用》,以便對這個庫有一個初步的認識。經過對庫的代碼閱讀,對庫有了必定的認識,提練一些重要的知識點,以做記錄。html

 

原理

一、經過一系列接口函數創建字典樹,屬於MVC中的C,即controllor部分;接口在頭文件中,主要包括node

// 添加簡單的變量,鍵值對
TMPL_varlist *TMPL_add_var(TMPL_varlist *varlist, ...);

// 添加一個循環列表中值列表中
TMPL_varlist *TMPL_add_loop(TMPL_varlist *varlist, const char *name, TMPL_loop *loop);

// 在循環列表中添加值列表
TMPL_loop *TMPL_add_varlist(TMPL_loop *loop, TMPL_varlist *varlist);

 

二、調用TMPL_write接口,把字典中的值替換模板中的變量,並輸出緩存

// 通常使用,只須要提供filename,varlist,out
int TMPL_write(const char *filename, const char *tmplstr,
    const TMPL_fmtlist *fmtlist, const TMPL_varlist *varlist,
    FILE *out, FILE *errout);

這個函數內部,又分幾步完成函數

(1)把文件一次性讀入緩存中oop

(2)解析緩存,轉換爲各類類型的標籤(tagnode),組成一棵標籤樹spa

(3)從標籤樹根開始,輸出各個標籤的內容;須要輸出標籤中的變量值時就查找字典樹。code

 

顯示view(標籤)

libctemplate容許在模板文件(html)中使用的一些特定標籤,這些特定的標籤如tag_kind枚舉類型定義。具體意義見註釋。htm

 1 typedef enum {
 2     tag_text    = 0x001,   /* text sequence */
 3     tag_var     = 0x002,   /* TMPL_VAR      */
 4     tag_if      = 0x004,   /* TMPL_IF       */
 5     tag_elsif   = 0x008,   /* TMPL_ELSIF    */
 6     tag_else    = 0x010,   /* <TMPL_ELSE>   */
 7     tag_endif   = 0x020,   /* </TMPL_IF>    */
 8     tag_include = 0x040,   /* TMPL_INCLUDE  */
 9     tag_loop    = 0x080,   /* TMPL_LOOP     */
10     tag_break   = 0x100,   /* TMPL_BREAK    */
11     tag_cont    = 0x200,   /* TMPL_CONTINUE */
12     tag_endloop = 0x400    /* </TMPL_LOOP>  */
13 } tag_kind;

 

模型model(字典)

1 struct TMPL_var {
2     TMPL_var *next;     /* next simple variable on list */
3     const char *name;
4     char value[1];      /* value and name stored here */
5 };

 

1 struct TMPL_varlist {
2     TMPL_varlist *next;  /* next variable list on a list */
3     TMPL_var   *var;     /* list of my simple variables */
4     TMPL_loop  *loop;    /* list of my loop variables */
5     TMPL_loop  *parent;  /* my parent loop variable (if any) */
6 };

 

1 struct TMPL_loop {
2     TMPL_loop *next;       /* next loop variable on a list */
3     const char *name;      /* my name */
4     TMPL_varlist *varlist; /* list of my variable lists */
5     TMPL_varlist *tail;    /* tail of "varlist" */
6     TMPL_varlist *parent;  /* my parent variable list */
7 };

 

簡單鍵值對插入

以一個簡單的例子做爲說明。blog

1 // 插入姓名和年齡,全部鍵與值用字符串表示,以0表示結束
2 TMPL_varlist *mainList = 0;
3 personList = TMPL_add_var(0, "Name", "lucy", "Age", "16", 0);
函數TMPL_add_var原型以下所示,從原型能夠看出,是可變參數的
TMPL_varlist* TMPL_add_var(TMPL_varlist *varlist, ...)

執行此函數操做後,會建成一個鏈表,所結成的結構以下所示接口

 

相關文章
相關標籤/搜索