2 * Copyright (c) 2008 Teodor Sigaev <teodor@sigaev.ru>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 /******************************************************************************
31 * Html template library *
32 ******************************************************************************
33 ******************************************************************************
35 ******************************************************************************
36 * <% EXPRESSION , "FORMAT"] [# "DEFAULTVALUE"] [|(h|u)]%>
37 * - format value should be as in strftime for time value and printf
38 * for all other. Currently, bool values have only "true"/"false"
44 * Expression is classical with support following:
46 * variable defined from C-code. Mark '^' means global
47 * variable, not local in loop.
48 * - expression (+|-|*|/|%) expression
49 * ariphmetic operations
50 * - expression ( || | && ) expression
52 * logical OR, AND and NOT
53 * - expression ( < | <= | == | >= | > | != | <> ) expression
55 * - LENGTH(expression)
56 * computes length of string
57 * - DEFINED(expression)
58 * returns true if expression is defined
59 * - expression ? expression : expression
61 * - USERDEFINEDFUNCTION( [expression[,expression[...]]] )
62 * User defined function call. Function should be defined at
68 * Loop has predefined variables:
69 * __FIRST - true for first iteration
70 * __LAST - true for last iteration
71 * __COUNTER - iteration's number
72 * __SIZE - number of iterations
73 * __ODD - true for odd iteraion
74 * __EVEN - true for even iteraion
80 ******************************************************************************
82 ******************************************************************************
83 * - setTemplateValueInt
84 * setTemplateValueString
85 * setTemplateValueTime
86 * setTemplateValueBool
87 * setTemplateValueDouble
88 * setTemplateValueUndefined
89 * Sets varibale's value
91 * Add one iteration to the pointed loop. Local variable in loop should
92 * pointed with predecence loop's mark(s) separated by dot. Example:
101 * addTemplateRow("outerLoop");
102 * setTemplateValueBool("outerLoop.var1");
103 * addTemplateRow("innerLoop");
104 * setTemplateValueBool("outerLoop.innerLoop.var2");
106 ******************************************************************************
107 * Memory management *
108 ******************************************************************************
109 * Unfortunatly, I'm too lazy to unify memory usage by several pieces
110 * in library. So, library uses mixed plain malloc and memory context
111 * concepts (tmalloc.h).
112 * To work with library it's needed to allocate persitent memory context
113 * for initTemplate() call and temprorary memory context for usual work.
114 * after printTemplate is called it's needed to call resetTemplate() and
115 * then resetMemoryContext() for second context.
117 ******************************************************************************/
119 #ifndef __TEMPLATE_H__
120 #define __TEMPLATE_H__
122 #include <sys/types.h>
128 typedef enum TemplateNodeType {
129 /* node tree types */
141 /* value's types of variables */
142 valueInt = 200, /* smallest of any values type */
150 #define TND_HTMLESCAPE (0x0001)
151 #define TND_URLESCAPE (0x0002)
152 #define TND_GLOBAL (0x0004)
154 #define TND___FIRST (0x0008)
155 #define TND___LAST (0x0010)
156 #define TND___COUNTER (0x0020)
157 #define TND___SIZE (0x0040)
158 #define TND___ODD (0x0080)
159 #define TND___EVEN (0x0100)
161 #define TND_DEFINED (0x0200)
163 #define TND__SPECIALMASK (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN)
165 typedef struct TemplateData *Template;
167 typedef struct TemplateNodeData *TemplateNode;
169 typedef struct VariableValueData * VariableValue;
170 typedef struct VariableValueData {
171 TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */
179 VariableValue ptrValue; /* special value to handle loop variables,
180 points to members of loopValues */
185 typedef struct executeFunctionDescData *executeFunctionDesc;
186 typedef struct executeFunctionDescData {
188 int nargs; /* -1 - variable number */
189 VariableValue (*execFn)(Template, int, VariableValue*);
190 } executeFunctionDescData;
192 typedef struct LoopInstanceData * LoopInstance;
194 typedef struct LoopRowData *LoopRow;
196 typedef struct LoopRowData {
198 LoopInstance nestedInstance;
199 VariableValueData varvals[1];
201 #define LRDHDRSZ (offsetof(LoopRowData, varvals))
203 typedef struct LoopInstanceData {
205 LoopInstance upperInstance;
206 GList *rowValues; /*list of LoopRow */
209 typedef struct TemplateNodeData {
210 TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */
229 VariableValue *argsValue;
232 executeFunctionDesc function;
233 GList *argsNode; /* list of arguments nodes */
237 VariableValueData value;
241 TemplateNode expressionNode;
253 LoopRow savedRowData;
254 GList *childrenLoopAfterSelf;
261 TemplateNode bodyNode;
262 TemplateNode selfNode;
263 GList *childrenLoop; /* to reset loop's instance */
264 GList *listVarValues; /* list of loop variables */
271 +->row->nestedinstance
274 LoopInstance currentInstance;
279 TemplateNode expressionNode;
281 TemplateNode elseNode;
291 typedef void (*outFn)(char *, int);
293 typedef char* (*urlEscapeFn)(char *, int * /* in/out */);
294 typedef char* (*htmlEscapeFn)(char *, int * /* in/out */);
296 typedef struct TemplateData {
298 MemoryContext *templateContext;
301 urlEscapeFn urlEscape;
302 htmlEscapeFn htmlEscape;
303 executeFunctionDesc functions;
306 int parseTemplateFile(Template tmpl, char* filename ); /* return non-zero if error */
307 int initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, char *basedir, char *filename );
308 void freeTemplate( Template tmpl );
309 void resetTemplate( Template tmpl );
310 int printTemplate( Template tmpl );
313 #define TVAR_NOTFOUND (1)
314 #define TVAR_FORBIDDEN (2)
315 #define TVAR_NOROW (3)
316 #define TVAR_LOOPMARK (4)
318 int setTemplateValueInt( Template tmpl, char * key, int val );
319 int setTemplateValueString( Template tmpl, char * key, char * val );
320 int setTemplateValueTime( Template tmpl, char * key, time_t val );
321 int setTemplateValueBool( Template tmpl, char * key, int val );
322 int setTemplateValueUndefined( Template tmpl, char * key );
323 int setTemplateValueDouble( Template tmpl, char * key, double val );
324 int addTemplateRow( Template tmpl, char * key );
325 int addTemplateNestedLoop( Template tmpl, char * key);
326 int returnTemplateNestedLoop( Template tmpl, char * key);
327 void dumpTemplate( Template tmpl );