Add expressions
[tedtools.git] / template.h
1 /*
2  * Copyright (c) 2008 Teodor Sigaev <teodor@sigaev.ru>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
16  *
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.
28  */
29
30 /******************************************************************************
31  *                                  SYNTAX                                    *
32  ******************************************************************************
33  * <% EXPRESSION , "FORMAT"] [# "DEFAULTVALUE"] [|(h|u)]%>
34  *    - format value should be as in strftime for time value and printf
35  *      for all other. Currently, bool values have only "true"/"false"
36  *      string values
37  * <@IF EXPRESSION @>
38  * <@ELSE@>
39  * <@ENDIF@>
40  *
41  * Expression is classical with support following:
42  *    -  ['^'] VARNAME     
43  *              variable defined from C-code. Mark '^' means global 
44  *       variable, not local in loop.
45  *    -  expression (+|-|*|/|%) expression
46  *               ariphmetic operations
47  *    -  expression ( || | && ) expression
48  *               ! expression
49  *       logical OR, AND and NOT
50  *    - expression ( < | <= | == | >= | > | != | <> ) expression 
51  *              compare expression
52  *    - LENGTH(expression)
53  *      computes length of string
54  *    - DEFINED(expression)
55  *      returns true if expression is defined
56  *        - expression ? expression : expression
57  *    - ( expression )
58  *    - USERDEFINEDFUNCTION( [expression[,expression[...]]] )
59  *      User defined function call. Function should be defined at 
60  *      C-level.
61  *
62  * <@LOOP MARKNAME@>
63  * <@ENDLOOP@>
64  * Loop has predefined variables:
65  *    __FIRST   - true for first iteration
66  *    __LAST    - true for last iteration
67  *    __COUNTER - iteration's number
68  *    __SIZE    - number of iterations
69  *    __ODD     - true for odd iteraion
70  *    __EVEN    - true for even iteraion
71  *
72  * <& FILENAME &>
73  *
74  * <# comment #>
75  *
76  ******************************************************************************
77  *                                C-Interface
78  ******************************************************************************
79  * - setTemplateValueInt
80  *   setTemplateValueString
81  *   setTemplateValueTime
82  *   setTemplateValueBool
83  *   setTemplateValueDouble
84  *   setTemplateValueUndefined
85  *   Sets varibale's value
86  * - addTemplateRow
87  *   Add one iteration to the pointed loop. Local variable in loop should 
88  *   pointed with predecence loop's mark(s) separated by dot. Example:
89  *       HTML:
90  *   <@Loop outerLoop@>
91  *              <% var1 %>
92  *      <@Loop innerLoop@>
93  *                      <% var2 %>
94  *              <@endloop@>
95  *       <@endloop@>
96  *      C:
97  *      addTemplateRow("outerLoop");
98  *  setTemplateValueBool("outerLoop.var1");
99  *      addTemplateRow("innerLoop");
100  *  setTemplateValueBool("outerLoop.innerLoop.var2");
101  * 
102  ******************************************************************************/
103
104 #ifndef __TEMPLATE_H__
105 #define __TEMPLATE_H__
106
107 #include <sys/types.h>
108 #include <time.h>
109 #include "glist.h"
110 #include "sfxstr.h"
111 #include "tmalloc.h"
112
113 typedef enum TemplateNodeType {
114         /* node tree types */
115         TextNode = 100,
116         VariableNode,
117         IncludeNode,
118         LoopNode,
119         ConditionNode,
120         CollectionNode,
121         ExpressionNode,
122         PrintNode,
123         ConstNode,
124
125         /* value's types of variables */
126         valueInt = 200, /* smallest of any values type */
127         valueString,
128         valueTime,
129         valueBool,
130         valueDouble,
131         valuePointer
132 } TemplateNodeType;
133
134 #define TND_HTMLESCAPE          (0x0001)
135 #define TND_URLESCAPE           (0x0002)
136 #define TND_GLOBAL                      (0x0004)
137
138 #define TND___FIRST                     (0x0008)
139 #define TND___LAST                      (0x0010)
140 #define TND___COUNTER           (0x0020)
141 #define TND___SIZE                      (0x0040)
142 #define TND___ODD                       (0x0080)
143 #define TND___EVEN                      (0x0100)
144
145 #define TND_DEFINED                     (0x0200)
146
147 #define TND__SPECIALMASK        (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN)
148
149 typedef struct TemplateData *Template;
150
151 typedef struct TemplateNodeData *TemplateNode;
152
153 typedef struct VariableValueData * VariableValue;
154 typedef struct VariableValueData {
155         TemplateNodeType        type; /* should be first, see resetTemplate/freeTemplate */
156         int                                     flags;
157         union {
158                 int                             intValue;
159                 char                    *stringValue;
160                 time_t                  timeValue;
161                 int                             boolValue;
162                 double                  doubleValue;
163                 VariableValue   ptrValue; /* special value to handle loop variables,
164                                                                          points to members of loopValues */
165         } value;
166 } VariableValueData;
167
168
169 typedef struct executeFunctionDescData *executeFunctionDesc;
170 typedef struct executeFunctionDescData {
171         char                    *name;
172         int                             nargs; /* -1 - variable number */
173         VariableValue   (*execFn)(Template, int, VariableValue*);
174 } executeFunctionDescData;
175
176 typedef struct LoopInstanceData * LoopInstance;
177 typedef struct LoopInstanceData {
178         int                             nrow;
179         GList                   *rowValues;
180 } LoopInstanceData;
181
182 typedef struct  TemplateNodeData {
183         TemplateNodeType        type; /* should be first, see resetTemplate/freeTemplate */
184
185         union {
186                 /* TextNode */
187                 struct {
188                         char    *value;
189                         int             valueLength;
190                 } text;
191
192                 /* VariableNode */
193                 struct {
194                         char                    *varName;
195                         int                             varNameLength;
196                         VariableValue   value;
197                         int                             flags;
198                 } variable;
199
200                 /* ExpressionNode */
201                 struct {
202                         VariableValue           *argsValue;
203                         int                                     nargs;
204                         char                            *functionName;
205                         executeFunctionDesc     function;
206                         GList                           *argsNode; /* list of nodes after parsing 
207                                                                                                 but before compile */   
208                 } expression;
209
210                 /* ConstNode */
211                 VariableValueData               value;
212
213                 /* PrintNode */
214                 struct {
215                         TemplateNode    expressionNode;
216                         char                    *formatValue;
217                         char                    *defaultValue;
218                         int                             flags;
219                 } print; 
220
221                 /* IncludeNode */
222                 char    *includeFile;
223
224                 /* LoopNode */
225                 struct {
226                         char                    *varName;
227                         int                     varNameLength;
228                         TemplateNode    bodyNode;
229                         int                             counter;
230                         GList                   *childrenLoop;  /* to reset instance  */
231                         GList                   *listVarValues; /* list of loop variables */
232                         GList                   *listInstance;
233                 } loop;
234
235                 /* ConditionNode */
236                 struct {
237                         TemplateNode    expressionNode;
238                         TemplateNode    ifNode;
239                         TemplateNode    elseNode;
240                 } condition;
241
242                 /* CollectionNode */
243                 GList   *children;
244         } nodeData;
245         
246 } TemplateNodeData;
247
248 /* prints result */
249 typedef void  (*outFn)(char *, int);
250
251 typedef char*   (*urlEscapeFn)(char *, int * /* in/out */);
252 typedef char*   (*htmlEscapeFn)(char *, int * /* in/out */);
253
254 typedef struct TemplateData {
255         TemplateNode            tree;
256         MemoryContext           *templateContext;
257         SFSTree                         variables;
258         outFn                           printString;
259         urlEscapeFn                     urlEscape;
260         htmlEscapeFn            htmlEscape;
261         executeFunctionDesc functions;
262 } TemplateData;
263
264 int parseTemplateFile(Template tmpl, char* filename );  /* return non-zero if error */
265 int initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, char *basedir, char *filename );
266 void freeTemplate( Template tmpl );
267 void resetTemplate( Template tmpl );
268 int printTemplate( Template tmpl );
269
270 #define TVAR_OK                 (0)
271 #define TVAR_NOTFOUND   (1)
272 #define TVAR_FORBIDDEN  (2)
273 #define TVAR_NOROW              (3)
274 #define TVAR_LOOPMARK   (4)
275
276 int setTemplateValueInt( Template tmpl, char * key, int val );
277 int setTemplateValueString( Template tmpl, char * key, char * val );
278 int setTemplateValueTime( Template tmpl, char * key, time_t val );
279 int setTemplateValueBool( Template tmpl, char * key, int val );
280 int setTemplateValueUndefined( Template tmpl, char * key );
281 int setTemplateValueDouble( Template tmpl, char * key, double val );
282 int addTemplateRow( Template tmpl, char * key );
283
284 void dumpTemplate( Template tmpl );
285 #endif