Add simple template library
[tedtools.git] / template.h
diff --git a/template.h b/template.h
new file mode 100644 (file)
index 0000000..9b45bea
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2008 Teodor Sigaev <teodor@sigaev.ru>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *        notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *        notice, this list of conditions and the following disclaimer in the
+ *        documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *        may be used to endorse or promote products derived from this software
+ *        without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ *                                  SYNTAX                                    *
+ ******************************************************************************
+ * <% [^]VARNAME[, "FORMAT"] [||"DEFAULTVALUE"] [|(h|u)]%>
+ *    - '^' mark means global variable.
+ *    - 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@>
+ * <@ELSE@>
+ * <@ENDIF@>
+ *
+ * <@LOOP MARKNAME@>
+ *
+ * <@ENDLOOP@>
+ *
+ * <& FILENAME &>
+ *
+ * <# comment #>
+ *
+ ******************************************************************************/
+
+#ifndef __TEMPLATE_H__
+#define __TEMPLATE_H__
+
+#include <sys/types.h>
+#include <time.h>
+#include "glist.h"
+#include "sfxstr.h"
+
+typedef        enum TemplateNodeType {
+       /* node tree types */
+       TextNode = 100,
+       VariableNode,
+       IncludeNode,
+       LoopNode,
+       ConditionNode,
+       CollectionNode,
+
+       /* value's types of variables */
+       valueInt = 200, /* smallest of any values type */
+       valueString,
+       valueTime,
+       valueBool,
+       valueDouble,
+       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__SPECIALMASK       (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN)
+struct  TemplateNodeData;
+typedef struct TemplateNodeData *TemplateNode;
+
+typedef struct VariableValueData * VariableValue;
+typedef struct VariableValueData {
+       TemplateNodeType        type; /* should be first, see resetTemplate/freeTemplate */
+       int                                     flags;
+       union {
+               int                             intValue;
+               char                    *stringValue;
+               time_t                  timeValue;
+               int                             boolValue;
+               double                  doubleValue;
+               VariableValue   ptrValue; /* special value to handle loop variables,
+                                                                        points to members of loopValues */
+       } value;
+} VariableValueData;
+
+typedef struct LoopInstanceData * LoopInstance;
+typedef struct LoopInstanceData {
+       int                             nrow;
+       GList                   *rowValues;
+} LoopInstanceData;
+
+typedef struct  TemplateNodeData {
+       TemplateNodeType        type; /* should be first, see resetTemplate/freeTemplate */
+
+       union {
+               /* TextNode */
+               struct {
+                       char    *value;
+                       int             valueLength;
+               } text;
+
+               /* VariableNode */
+               struct {
+                       char                    *varName;
+                       int                             varNameLength;
+                       VariableValue   value;
+                       int                             flags;
+                       char                    *formatValue;
+                       char                    *defaultValue;
+               } variable;
+
+               /* IncludeNode */
+               char    *includeFile;
+
+               /* LoopNode */
+               struct {
+                       char                    *varName;
+                       int                     varNameLength;
+                       TemplateNode    bodyNode;
+                       int                             counter;
+                       GList                   *childrenLoop;  /* to reset instance  */
+                       GList                   *listVarValues; /* list of loop variables */
+                       GList                   *listInstance;
+               } loop;
+
+               /* ConditionNode */
+               struct {
+                       int                     flags;
+                       char                    *varName;
+                       int                     varNameLength;
+                       VariableValue   value;
+                       TemplateNode    ifNode;
+                       TemplateNode    elseNode;
+               } condition;
+
+               /* CollectionNode */
+               GList   *children;
+       } nodeData;
+       
+} TemplateNodeData;
+
+/* prints result */
+typedef void  (*outFn)(char *, int);
+
+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;
+} 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 );
+void freeTemplate( Template tmpl );
+void resetTemplate( Template tmpl );
+int printTemplate( Template tmpl );
+
+#define TVAR_OK                        (0)
+#define TVAR_NOTFOUND  (1)
+#define TVAR_FORBIDDEN (2)
+#define TVAR_NOROW             (3)
+#define TVAR_LOOPMARK  (4)
+
+int setTemplateValueInt( Template tmpl, char * key, int val );
+int setTemplateValueString( Template tmpl, char * key, char * val );
+int setTemplateValueTime( Template tmpl, char * key, time_t val );
+int setTemplateValueBool( Template tmpl, char * key, int val );
+int setTemplateValueUndefined( Template tmpl, char * key );
+int setTemplateValueDouble( Template tmpl, char * key, double val );
+int addTemplateRow( Template tmpl, char * key );
+
+void dumpTemplate( Template tmpl );
+#endif