X-Git-Url: http://sigaev.ru/git/gitweb.cgi?a=blobdiff_plain;f=template.c;fp=template.c;h=b20fb894c287526773fe2ef0a7a2e1060635e3d0;hb=9029e8cc9a52539819e1a07f4ccddbc75c3b8c2c;hp=73d9cc43941324f4980fd6db2e71d6724c4a265a;hpb=1f3fc08a819bb5e9b56712198ec7cf47a214cec3;p=tedtools.git diff --git a/template.c b/template.c index 73d9cc4..b20fb89 100644 --- a/template.c +++ b/template.c @@ -34,6 +34,39 @@ #include "tlog.h" #include "template.h" +/* + * Simple list implementation + */ +#define TListPush(l,c) do { \ + (c)->nextCell = NULL; \ + if ( (l)->tailList == NULL ) { \ + (l)->headList = (l)->tailList = (c); \ + } else { \ + (l)->tailList->nextCell = (c); \ + (l)->tailList = (c); \ + } \ +} while(0) + +#define TListUnShift(l,c) do { \ + (c)->nextCell = (l)->headList; \ + if ( (l)->headList == NULL ) { \ + (l)->headList = (l)->tailList = (c); \ + } else { \ + (l)->headList = (c); \ + } \ +} while(0) + +#define TListShift(l,c) do { \ + (c) = (l)->headList; \ + if ( (c) != NULL ) { \ + (l)->headList = (c)->nextCell; \ + if ( (l)->headList == NULL ) \ + (l)->tailList = NULL; \ + } \ +} while(0) + +#define TListIsEmpty(l) ( (l)->headList == NULL ) + /* * Default operations and functions */ @@ -69,7 +102,7 @@ isVariable(VariableValue value) { } static VariableValue -makeBoolValue(Template tmpl, int v) { +makeBoolValue(TemplateInstance tmpl, int v) { VariableValue outvalue = mcalloc(tmpl->templateContext, sizeof(VariableValueData)); outvalue->type = valueBool; @@ -79,7 +112,7 @@ makeBoolValue(Template tmpl, int v) { } static VariableValue -copyValue(Template tmpl, VariableValue in) { +copyValue(TemplateInstance tmpl, VariableValue in) { VariableValue out= mcalloc(tmpl->templateContext, sizeof(VariableValueData)); if (in) @@ -92,7 +125,7 @@ copyValue(Template tmpl, VariableValue in) { } static VariableValue -isDefinedFn(Template tmpl, int n, VariableValue *vals) { +isDefinedFn(TemplateInstance tmpl, int n, VariableValue *vals) { return makeBoolValue(tmpl, vals[0]->flags & TND_DEFINED ); } @@ -113,7 +146,7 @@ strmblen(char *str) { } static VariableValue -LengthFn(Template tmpl, int n, VariableValue *vals) { +LengthFn(TemplateInstance tmpl, int n, VariableValue *vals) { VariableValue outvalue = NULL; outvalue = copyValue( tmpl, NULL ); @@ -130,27 +163,27 @@ LengthFn(Template tmpl, int n, VariableValue *vals) { } static VariableValue -NotFn(Template tmpl, int n, VariableValue *vals) { +NotFn(TemplateInstance tmpl, int n, VariableValue *vals) { return makeBoolValue(tmpl, !isVariable(vals[0])); } static VariableValue -AndFn(Template tmpl, int n, VariableValue *vals) { +AndFn(TemplateInstance tmpl, int n, VariableValue *vals) { return makeBoolValue(tmpl, isVariable(vals[0]) && isVariable(vals[1]) ); } static VariableValue -OrFn(Template tmpl, int n, VariableValue *vals) { +OrFn(TemplateInstance tmpl, int n, VariableValue *vals) { return makeBoolValue(tmpl, isVariable(vals[0]) || isVariable(vals[1]) ); } static VariableValue -CondFn(Template tmpl, int n, VariableValue *vals) { +CondFn(TemplateInstance tmpl, int n, VariableValue *vals) { return isVariable(vals[0]) ? vals[1] : vals[2]; } static VariableValue -ModFn(Template tmpl, int n, VariableValue *vals) { +ModFn(TemplateInstance tmpl, int n, VariableValue *vals) { VariableValue outvalue = copyValue( tmpl, NULL ); outvalue->type = valueInt; @@ -167,7 +200,7 @@ ModFn(Template tmpl, int n, VariableValue *vals) { } static VariableValue -UnaryMinesFn(Template tmpl, int n, VariableValue *vals) { +UnaryMinesFn(TemplateInstance tmpl, int n, VariableValue *vals) { VariableValue outvalue = copyValue( tmpl, vals[0] ); if (outvalue->type == valueInt) @@ -204,25 +237,25 @@ UnaryMinesFn(Template tmpl, int n, VariableValue *vals) { } static VariableValue -PlusFn(Template tmpl, int n, VariableValue *vals) { +PlusFn(TemplateInstance tmpl, int n, VariableValue *vals) { ARIPHACT(+) return outvalue; } static VariableValue -MinesFn(Template tmpl, int n, VariableValue *vals) { +MinesFn(TemplateInstance tmpl, int n, VariableValue *vals) { ARIPHACT(-) return outvalue; } static VariableValue -MulFn(Template tmpl, int n, VariableValue *vals) { +MulFn(TemplateInstance tmpl, int n, VariableValue *vals) { ARIPHACT(*) return outvalue; } static VariableValue -DivFn(Template tmpl, int n, VariableValue *vals) { +DivFn(TemplateInstance tmpl, int n, VariableValue *vals) { ARIPHACT(/) return outvalue; } @@ -249,37 +282,37 @@ DivFn(Template tmpl, int n, VariableValue *vals) { } static VariableValue -LtFn(Template tmpl, int n, VariableValue *vals) { +LtFn(TemplateInstance tmpl, int n, VariableValue *vals) { CMPACT(<) return outvalue; } static VariableValue -LeFn(Template tmpl, int n, VariableValue *vals) { +LeFn(TemplateInstance tmpl, int n, VariableValue *vals) { CMPACT(<=) return outvalue; } static VariableValue -EqFn(Template tmpl, int n, VariableValue *vals) { +EqFn(TemplateInstance tmpl, int n, VariableValue *vals) { CMPACT(==) return outvalue; } static VariableValue -GeFn(Template tmpl, int n, VariableValue *vals) { +GeFn(TemplateInstance tmpl, int n, VariableValue *vals) { CMPACT(>=) return outvalue; } static VariableValue -GtFn(Template tmpl, int n, VariableValue *vals) { +GtFn(TemplateInstance tmpl, int n, VariableValue *vals) { CMPACT(>) return outvalue; } static VariableValue -NeFn(Template tmpl, int n, VariableValue *vals) { +NeFn(TemplateInstance tmpl, int n, VariableValue *vals) { CMPACT(!=) return outvalue; } @@ -366,12 +399,14 @@ findIncludes(ParseState *state, TemplateNode *node) { *node = tmp.tree; break; case LoopNode: + state->tmpl->templateInstanceSize += sizeof( LoopTemplateInstanceData ); if ( findIncludes(state, &( (*node)->nodeData.loop.bodyNode )) != 0 ) return 1; break; case ConditionNode: if ( findIncludes(state, &( (*node)->nodeData.condition.ifNode )) != 0 || - findIncludes(state, &( (*node)->nodeData.condition.elseNode )) != 0 ) + findIncludes(state, &( (*node)->nodeData.condition.elseNode )) != 0 || + findIncludes(state, &( (*node)->nodeData.condition.expressionNode )) != 0 ) return 1; break; case CollectionNode: @@ -384,10 +419,23 @@ findIncludes(ParseState *state, TemplateNode *node) { GLCELL_DATA(cell) = chld; } break; - case ExpressionNode: /* any expression node can not include files */ + case VariableNode: + state->tmpl->templateInstanceSize += sizeof( VariableValueData ); + break; + case ExpressionNode: + GListForeach(cell, (*node)->nodeData.expression.argsNode) { + TemplateNode chld = (TemplateNode)GLCELL_DATA(cell); + + if ( findIncludes(state, &chld) != 0 ) + return 1; + GLCELL_DATA(cell) = chld; + } + break; case PrintNode: + if ( findIncludes(state, &( (*node)->nodeData.print.expressionNode )) ) + return 1; + break; case ConstNode: - case VariableNode: case TextNode: case NestNode: break; @@ -470,40 +518,47 @@ checkSpecialVariable(int flags, char *varName) { return flags; } -static VariableValue +static Offset findVariable( Template tmpl, TemplateNode loopParentNode, int flags, char *varName, int varNameLength ) { - VariableValue *pvarval; + Offset *pOffset; - if ( (pvarval = SFSFindData(&tmpl->variables, varName, varNameLength)) == NULL ) { - VariableValue pdata = mc0alloc(tmpl->templateContext, sizeof(VariableValueData)); + if ( (pOffset = SFSFindData(&tmpl->variables, varName, varNameLength)) == NULL ) { + Offset offset = tmpl->templateInstanceSize; + VariableValue pdata = (VariableValue)(tmpl->templateInstance + tmpl->templateInstanceSize); SFSDataIO in; in.key = varName; in.keylen = varNameLength; - in.data = &pdata; + in.data = &offset; + + tmpl->templateInstanceSize += sizeof(VariableValueData); SFSAdd(&tmpl->variables, &in); + pdata->flags = 0; + if ( loopParentNode && (flags & TND_GLOBAL) == 0 ) { /* - * copy special flags to support new inform loopParentNode + * copy special flags to support loopParentNode */ pdata->flags |= flags & TND__SPECIALMASK; pdata->type = valuePointer; + pdata->value.ptrValue = NULL; loopParentNode->nodeData.loop.listVarValues = - GListPush( loopParentNode->nodeData.loop.listVarValues, pdata ); + GListPush( loopParentNode->nodeData.loop.listVarValues, (void*)offset ); } - return pdata; + return offset; } - return *pvarval; + return *pOffset; } static int addLoop(Template tmpl, TemplateNode node, TemplateNode loopParentNode) { - SFSDataIO in; + SFSDataIO in; + LoopTemplateInstance lti; if ( SFSFindData(&tmpl->variables, node->nodeData.loop.varName, node->nodeData.loop.varNameLength) != NULL ) { tlog(TL_CRIT,"Loop marked '%s' is already defined", node->nodeData.loop.varName); @@ -512,10 +567,18 @@ addLoop(Template tmpl, TemplateNode node, TemplateNode loopParentNode) { in.key = node->nodeData.loop.varName; in.keylen = node->nodeData.loop.varNameLength; - in.data = &node; + in.data = &tmpl->templateInstanceSize; SFSAdd(&tmpl->variables, &in); + node->nodeData.loop.loopDataOffset = tmpl->templateInstanceSize; + lti = (LoopTemplateInstance)(tmpl->templateInstance + tmpl->templateInstanceSize); + memset(lti, 0, sizeof( LoopTemplateInstanceData )); + lti->type = LoopData; + lti->loopNode = node; + + tmpl->templateInstanceSize += sizeof( LoopTemplateInstanceData ); + if ( loopParentNode ) { loopParentNode->nodeData.loop.childrenLoop = GListPush( loopParentNode->nodeData.loop.childrenLoop, node ); @@ -603,7 +666,7 @@ compileTree( Template tmpl, TemplateNode node, TemplateNode loopParentNode ) { node->nodeData.variable.varName, &node->nodeData.variable.varNameLength); - node->nodeData.variable.value = findVariable( tmpl, loopParentNode, + node->nodeData.variable.varValueOffset = findVariable( tmpl, loopParentNode, node->nodeData.variable.flags, node->nodeData.variable.varName, node->nodeData.variable.varNameLength ); @@ -647,7 +710,7 @@ initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, c memset(tmpl, 0, sizeof(TemplateData)); tmpl->templateContext = mc; - SFSInit_dp(&tmpl->variables, sizeof(void*), NULL); + SFSInit_dp(&tmpl->variables, sizeof(Offset), NULL); if ( functions ) { executeFunctionDesc ptr = functions; @@ -667,6 +730,9 @@ initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, c if ( (err=recursiveReadTemplate(&state, NULL, filename))!=0 ) return err; + + tmpl->templateInstance = mcalloc( tmpl->templateContext, tmpl->templateInstanceSize ); + tmpl->templateInstanceSize = 0; if ( (err=compileTree( tmpl, tmpl->tree, NULL ))!=0 ) return err; @@ -674,41 +740,9 @@ initTemplate( Template tmpl, MemoryContext *mc, executeFunctionDesc functions, c } /* - * Reset/cleanup + * cleanup */ -void -resetTemplate( Template tmpl ) { - SFSDataIO out; - GListCell *cell; - - SFSIteratorStart( &tmpl->variables ); - - while( SFSIterate( &tmpl->variables, &out ) ) { - VariableValue varval = *(VariableValue*) out.data; - - if ( varval->type >= valueInt ) - varval->flags &= ~TND_DEFINED; - else if ( varval->type == LoopNode ) { - TemplateNode node = (TemplateNode) varval; - - GListForeach( cell, node->nodeData.loop.listVarValues ) { - varval = (VariableValue) GLCELL_DATA(cell); - - if ( varval->type == valuePointer ) - varval->value.ptrValue = NULL; - } - - GListForeach( cell, node->nodeData.loop.listInstance ) { - LoopInstance instance = GLCELL_DATA(cell); - - GListFree(instance->rowValues ); - } - GListTruncate( node->nodeData.loop.listInstance, 0 ); - } - } -} - static void freeNode( TemplateNode node ) { GListCell *cell; @@ -721,13 +755,6 @@ freeNode( TemplateNode node ) { freeNode( node->nodeData.loop.bodyNode ); /* selfNode is somewhere inside bodyNode */ GListFree( node->nodeData.loop.childrenLoop ); GListFree( node->nodeData.loop.listVarValues ); - - GListForeach( cell, node->nodeData.loop.listInstance ) { - LoopInstance instance = GLCELL_DATA(cell); - - GListFree(instance->rowValues ); - } - GListFree( node->nodeData.loop.listInstance ); break; case CollectionNode: GListForeach( cell, node->nodeData.children ) @@ -769,135 +796,174 @@ freeTemplate( Template tmpl ) { * Set value routines */ +TemplateInstance +newTemplateInstance(Template tmpl, MemoryContext *mc) { + TemplateInstance ti; + + if (mc == NULL) + mc = tmpl->templateContext; + + ti = mcalloc(mc, sizeof(TemplateInstanceData) + tmpl->templateInstanceSize); + ti->tmpl = tmpl; + ti->templateContext = mc; + memcpy( ti->instanceData, tmpl->templateInstance, tmpl->templateInstanceSize); + + return ti; +} + static void -newLoopInstance( Template tmpl, TemplateNode node ) { - LoopInstance upper = NULL; +newLoopInstance( TemplateInstance tmpl, TemplateNode node ) { + LoopInstance upper = NULL; + LoopTemplateInstance loopData = (LoopTemplateInstance) + (tmpl->instanceData + node->nodeData.loop.loopDataOffset); - if ( node->nodeData.loop.currentInstance ) - upper = node->nodeData.loop.currentInstance->upperInstance; + if ( loopData->currentInstance ) + upper = loopData->currentInstance->upperInstance; - node->nodeData.loop.currentInstance = + loopData->currentInstance = mc0alloc(tmpl->templateContext, sizeof(LoopInstanceData) ); - node->nodeData.loop.currentInstance->upperInstance = upper; + loopData->currentInstance->upperInstance = upper; - node->nodeData.loop.listInstance = GListPush( - node->nodeData.loop.listInstance, - node->nodeData.loop.currentInstance ); + TListPush( loopData, loopData->currentInstance ); - node->nodeData.loop.lastRow = NULL; + loopData->lastRow = NULL; } int -addTemplateRow( Template tmpl, char * key) { - TemplateNode *pnode, node; +addTemplateRow( TemplateInstance tmpl, char * key) { + Offset *pOffset; + TemplateNode node; + LoopTemplateInstance loopData; char *lkey = strlower(mcstrdup(tmpl->templateContext, key)); GListCell *cell; int i=0, nvar; LoopRow rowData; - pnode = SFSFindData(&tmpl->variables, lkey, 0); + pOffset = SFSFindData(&tmpl->tmpl->variables, lkey, 0); mcfree(lkey); - if ( pnode == NULL ) + if ( pOffset == NULL ) return TVAR_NOTFOUND; - node = *pnode; + loopData = (LoopTemplateInstance)(tmpl->instanceData + *pOffset); - if ( node->type != LoopNode ) + if ( loopData->type != LoopData ) return TVAR_FORBIDDEN; + node = loopData->loopNode; + + tassert( *pOffset == node->nodeData.loop.loopDataOffset ); nvar = GLIST_LENGTH( node->nodeData.loop.listVarValues ); if ( nvar == 0 ) /* loop without vars can not be looped */ return TVAR_NOROW; - if ( GLIST_LENGTH(node->nodeData.loop.listInstance) == 0 ) + if ( TListIsEmpty(loopData) ) newLoopInstance(tmpl, node); GListForeach( cell, node->nodeData.loop.childrenLoop ) newLoopInstance( tmpl, GLCELL_DATA(cell) ); - node->nodeData.loop.lastRow = rowData = mcalloc( tmpl->templateContext, LRDHDRSZ + sizeof(VariableValueData) * nvar ); + loopData->lastRow = rowData = mcalloc( tmpl->templateContext, LRDHDRSZ + sizeof(VariableValueData) * nvar ); rowData->loop = node; rowData->nestedInstance = NULL; GListForeach( cell, node->nodeData.loop.listVarValues ) { - VariableValue vv = GLCELL_DATA(cell); + VariableValue vv = (VariableValue) (tmpl->instanceData + ((Offset)GLCELL_DATA(cell))); vv->value.ptrValue = rowData->varvals + i; rowData->varvals[i].flags = 0; i++; } - node->nodeData.loop.currentInstance->nrow++; - node->nodeData.loop.currentInstance->rowValues = - GListPush( node->nodeData.loop.currentInstance->rowValues, rowData ); + loopData->currentInstance->nrow++; + TListPush( loopData->currentInstance, rowData ); return TVAR_OK; } int -addTemplateNestedLoop( Template tmpl, char * key) { - TemplateNode *pnode, node; +addTemplateNestedLoop( TemplateInstance tmpl, char * key) { + Offset *pOffset; + TemplateNode node; + LoopTemplateInstance loopData; char *lkey = strlower(mcstrdup(tmpl->templateContext, key)); GListCell *cell; - pnode = SFSFindData(&tmpl->variables, lkey, 0); + pOffset = SFSFindData(&tmpl->tmpl->variables, lkey, 0); mcfree(lkey); - if ( pnode == NULL ) + if ( pOffset == NULL ) return TVAR_NOTFOUND; - node = *pnode; + loopData = (LoopTemplateInstance)(tmpl->instanceData + *pOffset); - if ( node->type != LoopNode || node->nodeData.loop.selfNode == 0 ) + if ( loopData->type != LoopData ) return TVAR_FORBIDDEN; + node = loopData->loopNode; - if ( GLIST_LENGTH(node->nodeData.loop.listInstance) == 0 || node->nodeData.loop.lastRow == NULL ) + if ( node->nodeData.loop.selfNode == NULL ) + return TVAR_FORBIDDEN; + + if ( TListIsEmpty(loopData) || loopData->lastRow == NULL ) return TVAR_NOROW; - GListForeach( cell, node->nodeData.loop.childrenLoop ) - ((TemplateNode)GLCELL_DATA(cell))->nodeData.loop.lastRow = NULL; + GListForeach( cell, node->nodeData.loop.childrenLoop ) { + LoopTemplateInstance childData = (LoopTemplateInstance) + (tmpl->instanceData + ((TemplateNode)GLCELL_DATA(cell))->nodeData.loop.loopDataOffset); + + childData->lastRow = NULL; + } - node->nodeData.loop.lastRow->nestedInstance = + loopData->lastRow->nestedInstance = mc0alloc(tmpl->templateContext, sizeof(LoopInstanceData) ); - node->nodeData.loop.lastRow->nestedInstance->upperInstance = - node->nodeData.loop.currentInstance; - node->nodeData.loop.currentInstance = - node->nodeData.loop.lastRow->nestedInstance; - node->nodeData.loop.lastRow = NULL; + loopData->lastRow->nestedInstance->upperInstance = + loopData->currentInstance; + loopData->currentInstance = + loopData->lastRow->nestedInstance; + loopData->lastRow = NULL; return TVAR_OK; } int -returnTemplateNestedLoop( Template tmpl, char * key) { - TemplateNode *pnode, node; +returnTemplateNestedLoop( TemplateInstance tmpl, char * key) { + Offset *pOffset; + TemplateNode node; + LoopTemplateInstance loopData; char *lkey = strlower(mcstrdup(tmpl->templateContext, key)); GListCell *cell; - pnode = SFSFindData(&tmpl->variables, lkey, 0); + pOffset = SFSFindData(&tmpl->tmpl->variables, lkey, 0); mcfree(lkey); - if ( pnode == NULL ) + if ( pOffset == NULL ) return TVAR_NOTFOUND; - node = *pnode; + loopData = (LoopTemplateInstance)(tmpl->instanceData + *pOffset); - if ( node->type != LoopNode || node->nodeData.loop.selfNode == 0 ) + if ( loopData->type != LoopData ) return TVAR_FORBIDDEN; + node = loopData->loopNode; - if ( GLIST_LENGTH(node->nodeData.loop.listInstance) == 0 ) + if ( node->nodeData.loop.selfNode == NULL ) + return TVAR_FORBIDDEN; + + if ( TListIsEmpty(loopData) ) return TVAR_NOROW; - if ( node->nodeData.loop.currentInstance == NULL ) + if ( loopData->currentInstance == NULL ) return TVAR_NOROW; - GListForeach( cell, node->nodeData.loop.childrenLoop ) - ((TemplateNode)GLCELL_DATA(cell))->nodeData.loop.lastRow = NULL; + GListForeach( cell, node->nodeData.loop.childrenLoop ) { + LoopTemplateInstance childData = (LoopTemplateInstance) + (tmpl->instanceData + ((TemplateNode)GLCELL_DATA(cell))->nodeData.loop.loopDataOffset); + + childData->lastRow = NULL; + } - node->nodeData.loop.currentInstance = node->nodeData.loop.currentInstance->upperInstance; - node->nodeData.loop.lastRow = NULL; + loopData->currentInstance = loopData->currentInstance->upperInstance; + loopData->lastRow = NULL; return TVAR_OK; @@ -906,17 +972,18 @@ returnTemplateNestedLoop( Template tmpl, char * key) { static VariableValueData storage; static int -setTemplateValue( Template tmpl, char *key) { - VariableValue *pvarval, varval; +setTemplateValue( TemplateInstance tmpl, char *key) { + Offset *pOffset; + VariableValue varval; char *lkey = strlower(mcstrdup(tmpl->templateContext, key)); - pvarval = SFSFindData(&tmpl->variables, lkey, 0); + pOffset = SFSFindData(&tmpl->tmpl->variables, lkey, 0); mcfree(lkey); - if ( pvarval == NULL ) + if ( pOffset == NULL ) return TVAR_NOTFOUND; - varval = *pvarval; + varval = (VariableValue)(tmpl->instanceData + *pOffset); if ( varval->type != 0 && varval->type < valueInt ) { return TVAR_LOOPMARK; @@ -946,7 +1013,7 @@ setTemplateValue( Template tmpl, char *key) { int -setTemplateValueInt( Template tmpl, char * key, int val ) { +setTemplateValueInt( TemplateInstance tmpl, char * key, int val ) { storage.flags = TND_DEFINED; storage.type = valueInt; storage.value.intValue = val; @@ -954,7 +1021,7 @@ setTemplateValueInt( Template tmpl, char * key, int val ) { } int -setTemplateValueString( Template tmpl, char * key, char * val ) { +setTemplateValueString( TemplateInstance tmpl, char * key, char * val ) { storage.flags = TND_DEFINED; storage.type = valueString; storage.value.stringValue = val; @@ -962,7 +1029,7 @@ setTemplateValueString( Template tmpl, char * key, char * val ) { } int -setTemplateValueTime( Template tmpl, char * key, time_t val ) { +setTemplateValueTime( TemplateInstance tmpl, char * key, time_t val ) { storage.flags = TND_DEFINED; storage.type = valueTime; storage.value.timeValue = val; @@ -970,7 +1037,7 @@ setTemplateValueTime( Template tmpl, char * key, time_t val ) { } int -setTemplateValueBool( Template tmpl, char * key, int val ) { +setTemplateValueBool( TemplateInstance tmpl, char * key, int val ) { storage.flags = TND_DEFINED; storage.type = valueBool; storage.value.boolValue = val; @@ -978,7 +1045,7 @@ setTemplateValueBool( Template tmpl, char * key, int val ) { } int -setTemplateValueDouble( Template tmpl, char * key, double val ) { +setTemplateValueDouble( TemplateInstance tmpl, char * key, double val ) { storage.flags = TND_DEFINED; storage.type = valueDouble; storage.value.boolValue = val; @@ -986,7 +1053,7 @@ setTemplateValueDouble( Template tmpl, char * key, double val ) { } int -setTemplateValueUndefined( Template tmpl, char * key ) { +setTemplateValueUndefined( TemplateInstance tmpl, char * key ) { storage.flags = 0; return setTemplateValue( tmpl, key ); } @@ -996,7 +1063,7 @@ setTemplateValueUndefined( Template tmpl, char * key ) { */ static char * -printVal( Template tmpl, VariableValue value, int *len, char *format ) { +printVal( TemplateInstance tmpl, VariableValue value, int *len, char *format ) { int printedlen; char *res; @@ -1065,7 +1132,7 @@ printVal( Template tmpl, VariableValue value, int *len, char *format ) { static VariableValue -executeExpression( Template tmpl, TemplateNode node ) { +executeExpression( TemplateInstance tmpl, TemplateNode node ) { VariableValue outvalue = NULL; GListCell *cell; int i = 0; @@ -1076,10 +1143,12 @@ executeExpression( Template tmpl, TemplateNode node ) { outvalue = &node->nodeData.value; break; case VariableNode: - if ( node->nodeData.variable.value->type == valuePointer ) - outvalue = node->nodeData.variable.value->value.ptrValue; - else - outvalue = node->nodeData.variable.value; + outvalue = (VariableValue)(tmpl->instanceData + node->nodeData.variable.varValueOffset); + + tassert( (outvalue->flags & TND_DEFINED) == 0 || (outvalue->type >= valueInt && outvalue->type <= valuePointer) ); + + if ( outvalue->type == valuePointer ) + outvalue = outvalue->value.ptrValue; break; case ExpressionNode: GListForeach(cell, node->nodeData.expression.argsNode) @@ -1110,7 +1179,7 @@ executeExpression( Template tmpl, TemplateNode node ) { } static void -printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { +printNode( TemplateInstance tmpl, TemplateNode node, LoopInstance loopInstance ) { GListCell *cell; VariableValue value; int i; @@ -1121,18 +1190,17 @@ printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { switch (node->type) { case LoopNode: { + LoopTemplateInstance loopData = (LoopTemplateInstance) + (tmpl->instanceData + node->nodeData.loop.loopDataOffset); GListCell *cell; LoopInstance instance; if ( loopInstance ) { instance = loopInstance; } else { - cell = GListShift( node->nodeData.loop.listInstance ); - if ( cell == NULL ) + TListShift( loopData, instance ); + if ( instance == NULL ) return; - - instance = GLCELL_DATA(cell); - GListFreeCell( node->nodeData.loop.listInstance, cell ); } for(i=0; inrow;i++) { @@ -1140,12 +1208,10 @@ printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { int j = 0; VariableValue realValue; - cell = GListShift( instance->rowValues ); - rowData = GLCELL_DATA(cell); - GListFreeCell( instance->rowValues, cell ); + TListShift( instance, rowData ); GListForeach( cell, node->nodeData.loop.listVarValues ) { - value = (VariableValue)GLCELL_DATA(cell); + value = (VariableValue) (tmpl->instanceData + ((Offset)GLCELL_DATA(cell))); tassert( value->type == valuePointer ); realValue = value->value.ptrValue = rowData->varvals+j; @@ -1194,8 +1260,6 @@ printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { printNode( tmpl, node->nodeData.loop.bodyNode, NULL ); } - - GListFree( instance->rowValues ); } break; case NestNode: @@ -1213,14 +1277,13 @@ printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { i=0; GListForeach( cell, node->nodeData.nest.childrenLoopAfterSelf) { TemplateNode chld = GLCELL_DATA(cell); - GListCell *cellInstance = GListShift( chld->nodeData.loop.listInstance ); + LoopTemplateInstance loopData = (LoopTemplateInstance) + (tmpl->instanceData + chld->nodeData.loop.loopDataOffset); + LoopInstance cellInstance; - if ( cellInstance == NULL ) - savedChildrenInstance[i++] = NULL; - else { - savedChildrenInstance[i++] = GLCELL_DATA(cellInstance); - GListFreeCell( chld->nodeData.loop.listInstance, cellInstance ); - } + TListShift( loopData, cellInstance ); + + savedChildrenInstance[i++] = cellInstance; } } @@ -1231,7 +1294,8 @@ printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { */ i=0; GListForeach( cell, node->nodeData.nest.loop->nodeData.loop.listVarValues ) { - ((VariableValue)GLCELL_DATA(cell))->value.ptrValue = savedRowData->varvals + i; + value = (VariableValue) (tmpl->instanceData + ((Offset)GLCELL_DATA(cell))); + value->value.ptrValue = savedRowData->varvals + i; i++; } @@ -1239,9 +1303,11 @@ printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { i=0; GListForeach( cell, node->nodeData.nest.childrenLoopAfterSelf) { TemplateNode chld = GLCELL_DATA(cell); + LoopTemplateInstance loopData = (LoopTemplateInstance) + (tmpl->instanceData + chld->nodeData.loop.loopDataOffset); if ( savedChildrenInstance[i] ) - GListUnshift( chld->nodeData.loop.listInstance, savedChildrenInstance[i]); + TListUnShift( loopData, savedChildrenInstance[i] ); i++; } } @@ -1268,22 +1334,22 @@ printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { res = printVal(tmpl, value, &len, node->nodeData.print.formatValue); - if ( (node->nodeData.variable.flags & TND_HTMLESCAPE) && tmpl->htmlEscape ) - res = tmpl->htmlEscape(res, &len); - if ( (node->nodeData.variable.flags & TND_URLESCAPE) && tmpl->urlEscape ) - res = tmpl->urlEscape(res, &len); + if ( (node->nodeData.variable.flags & TND_HTMLESCAPE) && tmpl->tmpl->htmlEscape ) + res = tmpl->tmpl->htmlEscape(res, &len); + if ( (node->nodeData.variable.flags & TND_URLESCAPE) && tmpl->tmpl->urlEscape ) + res = tmpl->tmpl->urlEscape(res, &len); if ( res && len>0 ) { - tmpl->printString( res, len ); + tmpl->tmpl->printString( res, len ); mcfree(res); } } else if ( node->nodeData.print.defaultValue ) { - tmpl->printString( node->nodeData.print.defaultValue, + tmpl->tmpl->printString( node->nodeData.print.defaultValue, strlen( node->nodeData.print.defaultValue ) ); } break; case TextNode: - tmpl->printString( node->nodeData.text.value, node->nodeData.text.valueLength ); + tmpl->tmpl->printString( node->nodeData.text.value, node->nodeData.text.valueLength ); break; case IncludeNode: case VariableNode: @@ -1298,11 +1364,11 @@ printNode( Template tmpl, TemplateNode node, LoopInstance loopInstance ) { } int -printTemplate( Template tmpl ) { - if (!tmpl->printString) +printTemplate( TemplateInstance tmpl ) { + if (!tmpl->tmpl->printString) return 1; - printNode(tmpl, tmpl->tree, NULL); + printNode(tmpl, tmpl->tmpl->tree, NULL); return 0; }