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 * __LEVEL - level of nested loop (root == 0)
74 * __SIZE - number of iterations
75 * __ODD - true for odd iteraion
76 * __EVEN - true for even iteraion
82 ******************************************************************************
84 ******************************************************************************
85 * - setTemplateValueInt
86 * setTemplateValueString
87 * setTemplateValueTime
88 * setTemplateValueBool
89 * setTemplateValueDouble
90 * setTemplateValueUndefined
91 * Sets varibale's value
93 * Add one iteration to the pointed loop. Local variable in loop should
94 * pointed with predecence loop's mark(s) separated by dot. Example:
103 * addTemplateRow("outerLoop");
104 * setTemplateValueBool("outerLoop.var1");
105 * addTemplateRow("innerLoop");
106 * setTemplateValueBool("outerLoop.innerLoop.var2");
107 * - addTemplateNestedLoop
108 * returnTemplateNestedLoop
109 * Manage self-nested loops ( ie tree-like structures ).
110 * Loop's template should contains one <@ SELF @> pointer.
112 * Examplaes of usage are in data/template.html used for test.
114 ******************************************************************************
115 * Memory management *
116 ******************************************************************************
117 * Unfortunatly, I'm too lazy to unify memory usage by several pieces
118 * in library. So, library uses mixed plain malloc and memory context
119 * concepts (tmalloc.h).
120 * To work with library it's needed to allocate persistent memory context
121 * for initTemplate().
122 * To work with template it's needed to get template's instance by
123 * newTemplateInstance() call with separated memory context. In any time
124 * that memory context can be reseted or freeed and it will be enough
125 * to free template's instance.
127 ******************************************************************************/
129 #ifndef __TEMPLATE_H__
130 #define __TEMPLATE_H__
132 #include <sys/types.h>
138 typedef enum TemplateNodeType {
139 /* node tree types */
152 /* value's types of variables */
153 valueInt = 200, /* smallest of any values type */
161 #define TND_HTMLESCAPE (0x0001)
162 #define TND_URLESCAPE (0x0002)
163 #define TND_GLOBAL (0x0004)
165 #define TND___FIRST (0x0008)
166 #define TND___LAST (0x0010)
167 #define TND___COUNTER (0x0020)
168 #define TND___SIZE (0x0040)
169 #define TND___ODD (0x0080)
170 #define TND___EVEN (0x0100)
171 #define TND___LEVEL (0x0200)
173 #define TND_DEFINED (0x0400)
175 #define TND__SPECIALMASK (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN | TND___LEVEL)
177 typedef struct TemplateData *Template;
179 typedef struct TemplateInstanceData *TemplateInstance;
181 typedef struct TemplateNodeData *TemplateNode;
183 typedef struct VariableValueData * VariableValue;
184 typedef struct VariableValueData {
185 TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */
193 VariableValue ptrValue; /* special value to handle loop variables,
194 points to members of loopValues */
199 typedef struct executeFunctionDescData *executeFunctionDesc;
200 typedef struct executeFunctionDescData {
202 int nargs; /* -1 - variable number */
203 VariableValue (*execFn)(TemplateInstance, int, VariableValue*);
204 } executeFunctionDescData;
206 typedef struct LoopInstanceData * LoopInstance;
208 typedef struct LoopRowData *LoopRow;
210 typedef struct LoopRowData {
212 LoopInstance nestedInstance;
214 VariableValueData varvals[1];
216 #define LRDHDRSZ (offsetof(LoopRowData, varvals))
218 typedef struct LoopInstanceData {
220 LoopInstance upperInstance;
222 LoopInstance nextCell;
225 /* GList *rowValues; */ /*list of LoopRow */
228 typedef struct LoopTemplateInstanceData *LoopTemplateInstance;
229 typedef struct LoopTemplateInstanceData {
230 TemplateNodeType type; /* LoopData */
231 TemplateNode loopNode;
233 LoopInstance currentInstance;
234 LoopInstance headList;
235 LoopInstance tailList;
236 /*GList *listInstance;*/
237 } LoopTemplateInstanceData;
241 typedef struct TemplateNodeData {
242 TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */
255 Offset varValueOffset;
256 /* VariableValue value; */
262 VariableValue *argsValue;
265 executeFunctionDesc function;
266 GList *argsNode; /* list of arguments nodes */
270 VariableValueData value;
274 TemplateNode expressionNode;
286 LoopRow savedRowData;
287 GList *childrenLoopAfterSelf;
294 TemplateNode bodyNode;
295 TemplateNode selfNode; /* pointer to self-nested plase to insert */
296 GList *childrenLoop; /* to reset loop's instance */
297 GList *listVarValues; /* list of loop variables */
298 Offset loopDataOffset;
303 TemplateNode expressionNode;
305 TemplateNode elseNode;
315 typedef void (*outFn)(char *, int);
317 typedef char* (*urlEscapeFn)(char *, int * /* in/out */);
318 typedef char* (*htmlEscapeFn)(char *, int * /* in/out */);
320 typedef struct TemplateData {
322 MemoryContext *templateContext;
325 urlEscapeFn urlEscape;
326 htmlEscapeFn htmlEscape;
327 executeFunctionDesc functions;
329 Offset templateInstanceSize;
330 char *templateInstance;
333 typedef struct TemplateInstanceData {
335 MemoryContext *templateContext;
336 char instanceData[1];
337 } TemplateInstanceData;
339 int parseTemplateFile(Template tmpl, char* filename ); /* return non-zero if error */
340 int initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, char *basedir, char *filename );
341 void freeTemplate( Template tmpl );
342 TemplateInstance newTemplateInstance(Template tmpl, MemoryContext *mc);
343 int printTemplate( TemplateInstance tmpl );
346 #define TVAR_NOTFOUND (1)
347 #define TVAR_FORBIDDEN (2)
348 #define TVAR_NOROW (3)
349 #define TVAR_LOOPMARK (4)
351 int setTemplateValueInt( TemplateInstance tmpl, char * key, int64_t val );
352 int setTemplateValueString( TemplateInstance tmpl, char * key, char * val );
353 int setTemplateValueTime( TemplateInstance tmpl, char * key, time_t val );
354 int setTemplateValueBool( TemplateInstance tmpl, char * key, int val );
355 int setTemplateValueUndefined( TemplateInstance tmpl, char * key );
356 int setTemplateValueDouble( TemplateInstance tmpl, char * key, double val );
357 int addTemplateRow( TemplateInstance tmpl, char * key );
358 int addTemplateNestedLoop( TemplateInstance tmpl, char * key);
359 int returnTemplateNestedLoop( TemplateInstance tmpl, char * key);
360 void dumpTemplate( Template tmpl );