libctemplate——源码分析

时间:2021-07-05 05:33:04

前言

在阅读此文章前,建议先阅读我之前写的《libctemplate——C语言模块引擎简介及使用》,以便对这个库有一个初步的认识。通过对库的代码阅读,对库有了一定的认识,提练一些重要的知识点,以作记录。

原理

1、通过一系列接口函数建立字典树,属于MVC中的C,即controllor部分;接口在头文件中,主要包括

// 添加简单的变量,键值对
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);

2、调用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)把文件一次性读入缓存中

(2)解析缓存,转换为各种类型的标签(tagnode),组成一棵标签树

(3)从标签树根开始,输出各个标签的内容;需要输出标签中的变量值时就查找字典树。

显示view(标签)

libctemplate允许在模板文件(html)中使用的一些特定标签,这些特定的标签如tag_kind枚举类型定义。具体意义见注释。

 typedef enum {
tag_text = 0x001, /* text sequence */
tag_var = 0x002, /* TMPL_VAR */
tag_if = 0x004, /* TMPL_IF */
tag_elsif = 0x008, /* TMPL_ELSIF */
tag_else = 0x010, /* <TMPL_ELSE> */
tag_endif = 0x020, /* </TMPL_IF> */
tag_include = 0x040, /* TMPL_INCLUDE */
tag_loop = 0x080, /* TMPL_LOOP */
tag_break = 0x100, /* TMPL_BREAK */
tag_cont = 0x200, /* TMPL_CONTINUE */
tag_endloop = 0x400 /* </TMPL_LOOP> */
} tag_kind;

模型model(字典)

 struct TMPL_var {
TMPL_var *next; /* next simple variable on list */
const char *name;
char value[]; /* value and name stored here */
};
 struct TMPL_varlist {
TMPL_varlist *next; /* next variable list on a list */
TMPL_var *var; /* list of my simple variables */
TMPL_loop *loop; /* list of my loop variables */
TMPL_loop *parent; /* my parent loop variable (if any) */
};
 struct TMPL_loop {
TMPL_loop *next; /* next loop variable on a list */
const char *name; /* my name */
TMPL_varlist *varlist; /* list of my variable lists */
TMPL_varlist *tail; /* tail of "varlist" */
TMPL_varlist *parent; /* my parent variable list */
};

简单键值对插入

以一个简单的例子作为说明。

 // 插入姓名和年龄,所有键与值用字符串表示,以0表示结束
TMPL_varlist *mainList = ;
personList = TMPL_add_var(, "Name", "lucy", "Age", "", );
函数TMPL_add_var原型如下所示,从原型可以看出,是可变参数的
TMPL_varlist* TMPL_add_var(TMPL_varlist *varlist, ...)

执行此函数操作后,会建成一个链表,所结成的结构如下所示

libctemplate——源码分析