Add expressions
[tedtools.git] / template.h
index 72a57e5..0e12052 100644 (file)
 /******************************************************************************
  *                                  SYNTAX                                    *
  ******************************************************************************
- * <% [^]VARNAME[, "FORMAT"] [||"DEFAULTVALUE"] [|(h|u)]%>
- *    - '^' mark means global variable.
+ * <% EXPRESSION , "FORMAT"] [# "DEFAULTVALUE"] [|(h|u)]%>
  *    - format value should be as in strftime for time value and printf
  *      for all other. Currently, bool values have only "true"/"false"
  *      string values
- * <@IF [NOT] [DEFINED] [^]VARNAME@>
+ * <@IF EXPRESSION @>
  * <@ELSE@>
  * <@ENDIF@>
  *
- * <@LOOP MARKNAME@>
+ * Expression is classical with support following:
+ *    -  ['^'] VARNAME     
+ *             variable defined from C-code. Mark '^' means global 
+ *       variable, not local in loop.
+ *    -  expression (+|-|*|/|%) expression
+ *              ariphmetic operations
+ *    -  expression ( || | && ) expression
+ *              ! expression
+ *       logical OR, AND and NOT
+ *    - expression ( < | <= | == | >= | > | != | <> ) expression 
+ *             compare expression
+ *    - LENGTH(expression)
+ *      computes length of string
+ *    - DEFINED(expression)
+ *      returns true if expression is defined
+ *       - expression ? expression : expression
+ *    - ( expression )
+ *    - USERDEFINEDFUNCTION( [expression[,expression[...]]] )
+ *      User defined function call. Function should be defined at 
+ *      C-level.
  *
+ * <@LOOP MARKNAME@>
  * <@ENDLOOP@>
+ * Loop has predefined variables:
+ *    __FIRST   - true for first iteration
+ *    __LAST    - true for last iteration
+ *    __COUNTER - iteration's number
+ *    __SIZE    - number of iterations
+ *    __ODD     - true for odd iteraion
+ *    __EVEN    - true for even iteraion
  *
  * <& FILENAME &>
  *
  * <# comment #>
  *
+ ******************************************************************************
+ *                                C-Interface
+ ******************************************************************************
+ * - setTemplateValueInt
+ *   setTemplateValueString
+ *   setTemplateValueTime
+ *   setTemplateValueBool
+ *   setTemplateValueDouble
+ *   setTemplateValueUndefined
+ *   Sets varibale's value
+ * - addTemplateRow
+ *   Add one iteration to the pointed loop. Local variable in loop should 
+ *   pointed with predecence loop's mark(s) separated by dot. Example:
+ *      HTML:
+ *   <@Loop outerLoop@>
+ *             <% var1 %>
+ *     <@Loop innerLoop@>
+ *                     <% var2 %>
+ *             <@endloop@>
+ *      <@endloop@>
+ *     C:
+ *     addTemplateRow("outerLoop");
+ *  setTemplateValueBool("outerLoop.var1");
+ *     addTemplateRow("innerLoop");
+ *  setTemplateValueBool("outerLoop.innerLoop.var2");
+ * 
  ******************************************************************************/
 
 #ifndef __TEMPLATE_H__
@@ -66,6 +118,9 @@ typedef      enum TemplateNodeType {
        LoopNode,
        ConditionNode,
        CollectionNode,
+       ExpressionNode,
+       PrintNode,
+       ConstNode,
 
        /* value's types of variables */
        valueInt = 200, /* smallest of any values type */
@@ -76,20 +131,23 @@ typedef    enum TemplateNodeType {
        valuePointer
 } TemplateNodeType;
 
-#define        TND_DEFINED                     (0x0001)
-#define        TND_NOT                         (0x0002)
-#define        TND_HTMLESCAPE          (0x0004)
-#define        TND_URLESCAPE           (0x0008)
-#define TND_GLOBAL                     (0x0010)
-#define TND___FIRST                    (0x0020)
-#define TND___LAST                     (0x0040)
-#define TND___COUNTER          (0x0080)
-#define TND___SIZE                     (0x0100)
-#define TND___ODD                      (0x0200)
-#define TND___EVEN                     (0x0400)
+#define        TND_HTMLESCAPE          (0x0001)
+#define        TND_URLESCAPE           (0x0002)
+#define TND_GLOBAL                     (0x0004)
+
+#define TND___FIRST                    (0x0008)
+#define TND___LAST                     (0x0010)
+#define TND___COUNTER          (0x0020)
+#define TND___SIZE                     (0x0040)
+#define TND___ODD                      (0x0080)
+#define TND___EVEN                     (0x0100)
+
+#define TND_DEFINED                    (0x0200)
 
 #define TND__SPECIALMASK       (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN)
-struct  TemplateNodeData;
+
+typedef struct TemplateData *Template;
+
 typedef struct TemplateNodeData *TemplateNode;
 
 typedef struct VariableValueData * VariableValue;
@@ -107,6 +165,14 @@ typedef struct VariableValueData {
        } value;
 } VariableValueData;
 
+
+typedef struct executeFunctionDescData *executeFunctionDesc;
+typedef struct executeFunctionDescData {
+       char                    *name;
+       int                             nargs; /* -1 - variable number */
+       VariableValue   (*execFn)(Template, int, VariableValue*);
+} executeFunctionDescData;
+
 typedef struct LoopInstanceData * LoopInstance;
 typedef struct LoopInstanceData {
        int                             nrow;
@@ -129,10 +195,29 @@ typedef struct  TemplateNodeData {
                        int                             varNameLength;
                        VariableValue   value;
                        int                             flags;
-                       char                    *formatValue;
-                       char                    *defaultValue;
                } variable;
 
+               /* ExpressionNode */
+               struct {
+                       VariableValue           *argsValue;
+                       int                                     nargs;
+                       char                            *functionName;
+                       executeFunctionDesc     function;
+                       GList                           *argsNode; /* list of nodes after parsing 
+                                                                                               but before compile */   
+               } expression;
+
+               /* ConstNode */
+               VariableValueData               value;
+
+               /* PrintNode */
+               struct {
+                       TemplateNode    expressionNode;
+                       char                    *formatValue;
+                       char                    *defaultValue;
+                       int                             flags;
+               } print; 
+
                /* IncludeNode */
                char    *includeFile;
 
@@ -149,10 +234,7 @@ typedef struct  TemplateNodeData {
 
                /* ConditionNode */
                struct {
-                       int                     flags;
-                       char                    *varName;
-                       int                     varNameLength;
-                       VariableValue   value;
+                       TemplateNode    expressionNode;
                        TemplateNode    ifNode;
                        TemplateNode    elseNode;
                } condition;
@@ -170,18 +252,17 @@ typedef char*     (*urlEscapeFn)(char *, int * /* in/out */);
 typedef char*  (*htmlEscapeFn)(char *, int * /* in/out */);
 
 typedef struct TemplateData {
-       TemplateNode    tree;
-       MemoryContext   *templateContext;
-       SFSTree                 variables;
-       outFn                   printString;
-       urlEscapeFn             urlEscape;
-       htmlEscapeFn    htmlEscape;
+       TemplateNode            tree;
+       MemoryContext           *templateContext;
+       SFSTree                         variables;
+       outFn                           printString;
+       urlEscapeFn                     urlEscape;
+       htmlEscapeFn            htmlEscape;
+       executeFunctionDesc functions;
 } TemplateData;
 
-typedef struct TemplateData *Template;
-
 int parseTemplateFile(Template tmpl, char* filename );  /* return non-zero if error */
-int initTemplate( Template tmpl, MemoryContext *mc, char *basedir, char *filename );
+int initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, char *basedir, char *filename );
 void freeTemplate( Template tmpl );
 void resetTemplate( Template tmpl );
 int printTemplate( Template tmpl );