+HashList *CtxList = NULL;
+
+static CtxType CtxCounter = CTX_NONE;
+
+CtxType CTX_STRBUF = CTX_NONE;
+CtxType CTX_STRBUFARR = CTX_NONE;
+CtxType CTX_LONGVECTOR = CTX_NONE;
+
+CtxType CTX_ITERATE = CTX_NONE;
+CtxType CTX_TAB = CTX_NONE;
+
+void HFreeContextType(void *pCtx)
+{
+ CtxTypeStruct *FreeStruct = (CtxTypeStruct *) pCtx;
+ FreeStrBuf(&FreeStruct->Name);
+ free(FreeStruct);
+}
+void PutContextType(const char *name, long len, CtxType TheCtx)
+{
+ CtxTypeStruct *NewStruct;
+
+ NewStruct = (CtxTypeStruct*) malloc(sizeof(CtxTypeStruct));
+ NewStruct->Name = NewStrBufPlain(name, len);
+ NewStruct->Type = TheCtx;
+
+ Put(CtxList, IKEY(NewStruct->Type), NewStruct, HFreeContextType);
+}
+void RegisterContextType(const char *name, long len, CtxType *TheCtx)
+{
+ if (*TheCtx != CTX_NONE)
+ return;
+
+ *TheCtx = ++CtxCounter;
+ PutContextType(name, len, *TheCtx);
+}
+
+CtxTypeStruct *GetContextType(CtxType Type)
+{
+ void *pv = NULL;
+ GetHash(CtxList, IKEY(Type), &pv);
+ return pv;
+}
+
+const char *UnknownContext = "CTX_UNKNOWN";
+
+const char *ContextName(CtxType ContextType)
+{
+ CtxTypeStruct *pCtx;
+
+ pCtx = GetContextType(ContextType);
+
+ if (pCtx != NULL)
+ return ChrPtr(pCtx->Name);
+ else
+ return UnknownContext;
+}
+
+void StackDynamicContext(WCTemplputParams *Super,
+ WCTemplputParams *Sub,
+ void *Context,
+ CtxType ContextType,
+ int nArgs,
+ WCTemplateToken *Tokens,
+ WCConditionalFunc ExitCtx,
+ long ExitCTXID)
+{
+ memset(Sub, 0, sizeof(WCTemplputParams));
+
+ if (Super != NULL) {
+ Sub->Sub = Super->Sub;
+ Super->Sub = Sub;
+ }
+ if (Sub->Sub != NULL)
+ Sub->Sub->Super = Sub;
+ Sub->Super = Super;
+
+ Sub->Context = Context;
+ Sub->Filter.ContextType = ContextType;
+ Sub->nArgs = nArgs;
+ Sub->Tokens = Tokens;
+ Sub->ExitCtx = ExitCtx;
+ Sub->ExitCTXID = ExitCTXID;
+}
+
+void UnStackContext(WCTemplputParams *Sub)
+{
+ if (Sub->Super != NULL)
+ {
+ Sub->Super->Sub = Sub->Sub;
+ }
+ if (Sub->Sub != NULL)
+ {
+ Sub->Sub->Super = Sub->Super;
+ }
+}
+void UnStackDynamicContext(StrBuf *Target, WCTemplputParams **TPP)
+{
+ WCTemplputParams *TP = *TPP;
+ WCTemplputParams *Super = TP->Super;
+ TP->ExitCtx(Target, TP);
+ *TPP = Super;
+}
+
+void *GetContextPayload(WCTemplputParams *TP, CtxType ContextType)
+{
+ WCTemplputParams *whichTP = TP;