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");
105 * - addTemplateNestedLoop
106 * returnTemplateNestedLoop
107 * Manage self-nested loops ( ie tree-like structures ).
108 * Loop's template should contains one <@ SELF @> pointer.
110 * Examplaes of usage are in data/template.html used for test.
112 ******************************************************************************
113 * Memory management *
114 ******************************************************************************
115 * Unfortunatly, I'm too lazy to unify memory usage by several pieces
116 * in library. So, library uses mixed plain malloc and memory context
117 * concepts (tmalloc.h).
118 * To work with library it's needed to allocate persistent memory context
119 * for initTemplate().
120 * To work with template it's needed to get template's instance by
121 * newTemplateInstance() call with separated memory context. In any time
122 * that memory context can be reseted or freeed and it will be enough
123 * to free template's instance.
125 ******************************************************************************/
127 #ifndef __TEMPLATE_H__
128 #define __TEMPLATE_H__
130 #include <sys/types.h>
136 typedef enum TemplateNodeType {
137 /* node tree types */
150 /* value's types of variables */
151 valueInt = 200, /* smallest of any values type */
159 #define TND_HTMLESCAPE (0x0001)
160 #define TND_URLESCAPE (0x0002)
161 #define TND_GLOBAL (0x0004)
163 #define TND___FIRST (0x0008)
164 #define TND___LAST (0x0010)
165 #define TND___COUNTER (0x0020)
166 #define TND___SIZE (0x0040)
167 #define TND___ODD (0x0080)
168 #define TND___EVEN (0x0100)
170 #define TND_DEFINED (0x0200)
172 #define TND__SPECIALMASK (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN)
174 typedef struct TemplateData *Template;
176 typedef struct TemplateInstanceData *TemplateInstance;
178 typedef struct TemplateNodeData *TemplateNode;
180 typedef struct VariableValueData * VariableValue;
181 typedef struct VariableValueData {
182 TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */
190 VariableValue ptrValue; /* special value to handle loop variables,
191 points to members of loopValues */
196 typedef struct executeFunctionDescData *executeFunctionDesc;
197 typedef struct executeFunctionDescData {
199 int nargs; /* -1 - variable number */
200 VariableValue (*execFn)(TemplateInstance, int, VariableValue*);
201 } executeFunctionDescData;
203 typedef struct LoopInstanceData * LoopInstance;
205 typedef struct LoopRowData *LoopRow;
207 typedef struct LoopRowData {
209 LoopInstance nestedInstance;
211 VariableValueData varvals[1];
213 #define LRDHDRSZ (offsetof(LoopRowData, varvals))
215 typedef struct LoopInstanceData {
217 LoopInstance upperInstance;
219 LoopInstance nextCell;
222 /* GList *rowValues; */ /*list of LoopRow */
225 typedef struct LoopTemplateInstanceData *LoopTemplateInstance;
226 typedef struct LoopTemplateInstanceData {
227 TemplateNodeType type; /* LoopData */
228 TemplateNode loopNode;
230 LoopInstance currentInstance;
231 LoopInstance headList;
232 LoopInstance tailList;
233 /*GList *listInstance;*/
234 } LoopTemplateInstanceData;
238 typedef struct TemplateNodeData {
239 TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */
252 Offset varValueOffset;
253 /* VariableValue value; */
259 VariableValue *argsValue;
262 executeFunctionDesc function;
263 GList *argsNode; /* list of arguments nodes */
267 VariableValueData value;
271 TemplateNode expressionNode;
283 LoopRow savedRowData;
284 GList *childrenLoopAfterSelf;
291 TemplateNode bodyNode;
292 TemplateNode selfNode; /* pointer to self-nested plase to insert */
293 GList *childrenLoop; /* to reset loop's instance */
294 GList *listVarValues; /* list of loop variables */
295 Offset loopDataOffset;
300 TemplateNode expressionNode;
302 TemplateNode elseNode;
312 typedef void (*outFn)(char *, int);
314 typedef char* (*urlEscapeFn)(char *, int * /* in/out */);
315 typedef char* (*htmlEscapeFn)(char *, int * /* in/out */);
317 typedef struct TemplateData {
319 MemoryContext *templateContext;
322 urlEscapeFn urlEscape;
323 htmlEscapeFn htmlEscape;
324 executeFunctionDesc functions;
326 Offset templateInstanceSize;
327 char *templateInstance;
330 typedef struct TemplateInstanceData {
332 MemoryContext *templateContext;
333 char instanceData[1];
334 } TemplateInstanceData;
336 int parseTemplateFile(Template tmpl, char* filename ); /* return non-zero if error */
337 int initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, char *basedir, char *filename );
338 void freeTemplate( Template tmpl );
339 TemplateInstance newTemplateInstance(Template tmpl, MemoryContext *mc);
340 int printTemplate( TemplateInstance tmpl );
343 #define TVAR_NOTFOUND (1)
344 #define TVAR_FORBIDDEN (2)
345 #define TVAR_NOROW (3)
346 #define TVAR_LOOPMARK (4)
348 int setTemplateValueInt( TemplateInstance tmpl, char * key, int val );
349 int setTemplateValueString( TemplateInstance tmpl, char * key, char * val );
350 int setTemplateValueTime( TemplateInstance tmpl, char * key, time_t val );
351 int setTemplateValueBool( TemplateInstance tmpl, char * key, int val );
352 int setTemplateValueUndefined( TemplateInstance tmpl, char * key );
353 int setTemplateValueDouble( TemplateInstance tmpl, char * key, double val );
354 int addTemplateRow( TemplateInstance tmpl, char * key );
355 int addTemplateNestedLoop( TemplateInstance tmpl, char * key);
356 int returnTemplateNestedLoop( TemplateInstance tmpl, char * key);
357 void dumpTemplate( Template tmpl );