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"
41 * [<@ ELSE IF EXPRESSION | ELSIF EXPRESSION @>]
45 * Expression is classical with support following:
47 * variable defined from C-code. Mark '^' means global
48 * variable, not local in loop.
49 * - expression (+|-|*|/|%) expression
50 * ariphmetic operations
51 * - expression ( || | && ) expression
53 * logical OR, AND and NOT
54 * - expression ( < | <= | == | >= | > | != | <> ) expression
56 * - LENGTH(expression)
57 * computes length of string
58 * - DEFINED(expression)
59 * returns true if expression is defined
60 * - expression ? expression : expression
62 * - USERDEFINEDFUNCTION( [expression[,expression[...]]] )
63 * User defined function call. Function should be defined at
69 * Loop has predefined variables:
70 * __FIRST - true for first iteration
71 * __LAST - true for last iteration
72 * __COUNTER - iteration's number
73 * __SIZE - number of iterations
74 * __ODD - true for odd iteraion
75 * __EVEN - true for even iteraion
81 ******************************************************************************
83 ******************************************************************************
84 * - setTemplateValueInt
85 * setTemplateValueString
86 * setTemplateValueTime
87 * setTemplateValueBool
88 * setTemplateValueDouble
89 * setTemplateValueUndefined
90 * Sets varibale's value
92 * Add one iteration to the pointed loop. Local variable in loop should
93 * pointed with predecence loop's mark(s) separated by dot. Example:
102 * addTemplateRow("outerLoop");
103 * setTemplateValueBool("outerLoop.var1");
104 * addTemplateRow("innerLoop");
105 * setTemplateValueBool("outerLoop.innerLoop.var2");
106 * - addTemplateNestedLoop
107 * returnTemplateNestedLoop
108 * Manage self-nested loops ( ie tree-like structures ).
109 * Loop's template should contains one <@ SELF @> pointer.
111 * Examplaes of usage are in data/template.html used for test.
113 ******************************************************************************
114 * Memory management *
115 ******************************************************************************
116 * Unfortunatly, I'm too lazy to unify memory usage by several pieces
117 * in library. So, library uses mixed plain malloc and memory context
118 * concepts (tmalloc.h).
119 * To work with library it's needed to allocate persistent memory context
120 * for initTemplate().
121 * To work with template it's needed to get template's instance by
122 * newTemplateInstance() call with separated memory context. In any time
123 * that memory context can be reseted or freeed and it will be enough
124 * to free template's instance.
126 ******************************************************************************/
128 #ifndef __TEMPLATE_H__
129 #define __TEMPLATE_H__
131 #include <sys/types.h>
137 typedef enum TemplateNodeType {
138 /* node tree types */
151 /* value's types of variables */
152 valueInt = 200, /* smallest of any values type */
160 #define TND_HTMLESCAPE (0x0001)
161 #define TND_URLESCAPE (0x0002)
162 #define TND_GLOBAL (0x0004)
164 #define TND___FIRST (0x0008)
165 #define TND___LAST (0x0010)
166 #define TND___COUNTER (0x0020)
167 #define TND___SIZE (0x0040)
168 #define TND___ODD (0x0080)
169 #define TND___EVEN (0x0100)
171 #define TND_DEFINED (0x0200)
173 #define TND__SPECIALMASK (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN)
175 typedef struct TemplateData *Template;
177 typedef struct TemplateInstanceData *TemplateInstance;
179 typedef struct TemplateNodeData *TemplateNode;
181 typedef struct VariableValueData * VariableValue;
182 typedef struct VariableValueData {
183 TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */
191 VariableValue ptrValue; /* special value to handle loop variables,
192 points to members of loopValues */
197 typedef struct executeFunctionDescData *executeFunctionDesc;
198 typedef struct executeFunctionDescData {
200 int nargs; /* -1 - variable number */
201 VariableValue (*execFn)(TemplateInstance, int, VariableValue*);
202 } executeFunctionDescData;
204 typedef struct LoopInstanceData * LoopInstance;
206 typedef struct LoopRowData *LoopRow;
208 typedef struct LoopRowData {
210 LoopInstance nestedInstance;
212 VariableValueData varvals[1];
214 #define LRDHDRSZ (offsetof(LoopRowData, varvals))
216 typedef struct LoopInstanceData {
218 LoopInstance upperInstance;
220 LoopInstance nextCell;
223 /* GList *rowValues; */ /*list of LoopRow */
226 typedef struct LoopTemplateInstanceData *LoopTemplateInstance;
227 typedef struct LoopTemplateInstanceData {
228 TemplateNodeType type; /* LoopData */
229 TemplateNode loopNode;
231 LoopInstance currentInstance;
232 LoopInstance headList;
233 LoopInstance tailList;
234 /*GList *listInstance;*/
235 } LoopTemplateInstanceData;
239 typedef struct TemplateNodeData {
240 TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */
253 Offset varValueOffset;
254 /* VariableValue value; */
260 VariableValue *argsValue;
263 executeFunctionDesc function;
264 GList *argsNode; /* list of arguments nodes */
268 VariableValueData value;
272 TemplateNode expressionNode;
284 LoopRow savedRowData;
285 GList *childrenLoopAfterSelf;
292 TemplateNode bodyNode;
293 TemplateNode selfNode; /* pointer to self-nested plase to insert */
294 GList *childrenLoop; /* to reset loop's instance */
295 GList *listVarValues; /* list of loop variables */
296 Offset loopDataOffset;
301 TemplateNode expressionNode;
303 TemplateNode elseNode;
313 typedef void (*outFn)(char *, int);
315 typedef char* (*urlEscapeFn)(char *, int * /* in/out */);
316 typedef char* (*htmlEscapeFn)(char *, int * /* in/out */);
318 typedef struct TemplateData {
320 MemoryContext *templateContext;
323 urlEscapeFn urlEscape;
324 htmlEscapeFn htmlEscape;
325 executeFunctionDesc functions;
327 Offset templateInstanceSize;
328 char *templateInstance;
331 typedef struct TemplateInstanceData {
333 MemoryContext *templateContext;
334 char instanceData[1];
335 } TemplateInstanceData;
337 int parseTemplateFile(Template tmpl, char* filename ); /* return non-zero if error */
338 int initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, char *basedir, char *filename );
339 void freeTemplate( Template tmpl );
340 TemplateInstance newTemplateInstance(Template tmpl, MemoryContext *mc);
341 int printTemplate( TemplateInstance tmpl );
344 #define TVAR_NOTFOUND (1)
345 #define TVAR_FORBIDDEN (2)
346 #define TVAR_NOROW (3)
347 #define TVAR_LOOPMARK (4)
349 int setTemplateValueInt( TemplateInstance tmpl, char * key, int val );
350 int setTemplateValueString( TemplateInstance tmpl, char * key, char * val );
351 int setTemplateValueTime( TemplateInstance tmpl, char * key, time_t val );
352 int setTemplateValueBool( TemplateInstance tmpl, char * key, int val );
353 int setTemplateValueUndefined( TemplateInstance tmpl, char * key );
354 int setTemplateValueDouble( TemplateInstance tmpl, char * key, double val );
355 int addTemplateRow( TemplateInstance tmpl, char * key );
356 int addTemplateNestedLoop( TemplateInstance tmpl, char * key);
357 int returnTemplateNestedLoop( TemplateInstance tmpl, char * key);
358 void dumpTemplate( Template tmpl );