X-Git-Url: http://sigaev.ru/git/gitweb.cgi?p=tedtools.git;a=blobdiff_plain;f=template.h;h=97e9070c0413ec535629741868843017b250ade7;hp=9061e30da980e7cfbf5cd582bfee402754362e89;hb=HEAD;hpb=1562fc9176be457277437d8154279957fe1e394e diff --git a/template.h b/template.h index 9061e30..97e9070 100644 --- a/template.h +++ b/template.h @@ -33,12 +33,13 @@ ****************************************************************************** * SYNTAX * ****************************************************************************** - * <% EXPRESSION , "FORMAT"] [# "DEFAULTVALUE"] [|(h|u)]%> + * <% 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 EXPRESSION @> - * <@ELSE@> + * [<@ ELSE IF EXPRESSION | ELSIF EXPRESSION @>] + * [ <@ELSE@> ] * <@ENDIF@> * * Expression is classical with support following: @@ -63,11 +64,13 @@ * C-level. * * <@LOOP MARKNAME@> + * [ <@ SELF @> ] * <@ENDLOOP@> * Loop has predefined variables: * __FIRST - true for first iteration * __LAST - true for last iteration * __COUNTER - iteration's number + * __LEVEL - level of nested loop (root == 0) * __SIZE - number of iterations * __ODD - true for odd iteraion * __EVEN - true for even iteraion @@ -101,6 +104,12 @@ * setTemplateValueBool("outerLoop.var1"); * addTemplateRow("innerLoop"); * setTemplateValueBool("outerLoop.innerLoop.var2"); + * - addTemplateNestedLoop + * returnTemplateNestedLoop + * Manage self-nested loops ( ie tree-like structures ). + * Loop's template should contains one <@ SELF @> pointer. + * + * Examplaes of usage are in data/template.html used for test. * ****************************************************************************** * Memory management * @@ -108,10 +117,12 @@ * Unfortunatly, I'm too lazy to unify memory usage by several pieces * in library. So, library uses mixed plain malloc and memory context * concepts (tmalloc.h). - * To work with library it's needed to allocate persitent memory context - * for initTemplate() call and temprorary memory context for usual work. - * after printTemplate is called it's needed to call resetTemplate() and - * then resetMemoryContext() for second context. + * To work with library it's needed to allocate persistent memory context + * for initTemplate(). + * To work with template it's needed to get template's instance by + * newTemplateInstance() call with separated memory context. In any time + * that memory context can be reseted or freeed and it will be enough + * to free template's instance. * ******************************************************************************/ @@ -135,6 +146,8 @@ typedef enum TemplateNodeType { ExpressionNode, PrintNode, ConstNode, + NestNode, + LoopData, /* value's types of variables */ valueInt = 200, /* smallest of any values type */ @@ -155,13 +168,16 @@ typedef enum TemplateNodeType { #define TND___SIZE (0x0040) #define TND___ODD (0x0080) #define TND___EVEN (0x0100) +#define TND___LEVEL (0x0200) -#define TND_DEFINED (0x0200) +#define TND_DEFINED (0x0400) -#define TND__SPECIALMASK (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN) +#define TND__SPECIALMASK (TND___FIRST | TND___LAST | TND___COUNTER | TND___SIZE | TND___ODD | TND___EVEN | TND___LEVEL) typedef struct TemplateData *Template; +typedef struct TemplateInstanceData *TemplateInstance; + typedef struct TemplateNodeData *TemplateNode; typedef struct VariableValueData * VariableValue; @@ -169,7 +185,7 @@ typedef struct VariableValueData { TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */ int flags; union { - int intValue; + int64_t intValue; char *stringValue; time_t timeValue; int boolValue; @@ -184,15 +200,44 @@ typedef struct executeFunctionDescData *executeFunctionDesc; typedef struct executeFunctionDescData { char *name; int nargs; /* -1 - variable number */ - VariableValue (*execFn)(Template, int, VariableValue*); + VariableValue (*execFn)(TemplateInstance, int, VariableValue*); } executeFunctionDescData; typedef struct LoopInstanceData * LoopInstance; + +typedef struct LoopRowData *LoopRow; + +typedef struct LoopRowData { + TemplateNode loop; + LoopInstance nestedInstance; + LoopRow nextCell; + VariableValueData varvals[1]; +} LoopRowData; +#define LRDHDRSZ (offsetof(LoopRowData, varvals)) + typedef struct LoopInstanceData { int nrow; - GList *rowValues; + LoopInstance upperInstance; + + LoopInstance nextCell; + LoopRow headList; + LoopRow tailList; + /* GList *rowValues; */ /*list of LoopRow */ } LoopInstanceData; +typedef struct LoopTemplateInstanceData *LoopTemplateInstance; +typedef struct LoopTemplateInstanceData { + TemplateNodeType type; /* LoopData */ + TemplateNode loopNode; + LoopRow lastRow; + LoopInstance currentInstance; + LoopInstance headList; + LoopInstance tailList; + /*GList *listInstance;*/ +} LoopTemplateInstanceData; + +typedef long Offset; + typedef struct TemplateNodeData { TemplateNodeType type; /* should be first, see resetTemplate/freeTemplate */ @@ -207,7 +252,8 @@ typedef struct TemplateNodeData { struct { char *varName; int varNameLength; - VariableValue value; + Offset varValueOffset; + /* VariableValue value; */ int flags; } variable; @@ -234,14 +280,22 @@ typedef struct TemplateNodeData { /* IncludeNode */ char *includeFile; + /* NestNode */ + struct { + TemplateNode loop; + LoopRow savedRowData; + GList *childrenLoopAfterSelf; + } nest; + /* LoopNode */ struct { char *varName; int varNameLength; TemplateNode bodyNode; + TemplateNode selfNode; /* pointer to self-nested plase to insert */ GList *childrenLoop; /* to reset loop's instance */ GList *listVarValues; /* list of loop variables */ - GList *listInstance; + Offset loopDataOffset; } loop; /* ConditionNode */ @@ -271,13 +325,22 @@ typedef struct TemplateData { urlEscapeFn urlEscape; htmlEscapeFn htmlEscape; executeFunctionDesc functions; + + Offset templateInstanceSize; + char *templateInstance; } TemplateData; +typedef struct TemplateInstanceData { + Template tmpl; + MemoryContext *templateContext; + char instanceData[1]; +} TemplateInstanceData; + int parseTemplateFile(Template tmpl, char* filename ); /* return non-zero if error */ int initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, char *basedir, char *filename ); void freeTemplate( Template tmpl ); -void resetTemplate( Template tmpl ); -int printTemplate( Template tmpl ); +TemplateInstance newTemplateInstance(Template tmpl, MemoryContext *mc); +int printTemplate( TemplateInstance tmpl ); #define TVAR_OK (0) #define TVAR_NOTFOUND (1) @@ -285,13 +348,14 @@ int printTemplate( Template tmpl ); #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 ); - +int setTemplateValueInt( TemplateInstance tmpl, char * key, int64_t val ); +int setTemplateValueString( TemplateInstance tmpl, char * key, char * val ); +int setTemplateValueTime( TemplateInstance tmpl, char * key, time_t val ); +int setTemplateValueBool( TemplateInstance tmpl, char * key, int val ); +int setTemplateValueUndefined( TemplateInstance tmpl, char * key ); +int setTemplateValueDouble( TemplateInstance tmpl, char * key, double val ); +int addTemplateRow( TemplateInstance tmpl, char * key ); +int addTemplateNestedLoop( TemplateInstance tmpl, char * key); +int returnTemplateNestedLoop( TemplateInstance tmpl, char * key); void dumpTemplate( Template tmpl ); #endif