+/*
+ * 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