-#include "sysdep.h"
-
+// Spaghetti, technical debt, and an unmaintainable big mess.
+// No one knows how this works. This is why we started over with WebCit-NG.
+#include "sysdep.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
-
#include <unistd.h>
#include <stdio.h>
#include <stdarg.h>
#define SV_PREEVALUATED 6
+
/*
* Dynamic content for variable substitution in templates
*/
Sub->Sub = Super->Sub;
Super->Sub = Sub;
}
+ if (Sub->Sub != NULL)
+ Sub->Sub->Super = Sub;
Sub->Super = Super;
Sub->Context = Context;
{
Sub->Super->Sub = Sub->Sub;
}
+ if (Sub->Sub != NULL)
+ {
+ Sub->Sub->Super = Sub->Super;
+ }
}
void UnStackDynamicContext(StrBuf *Target, WCTemplputParams **TPP)
{
void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplputParams *TP, const char *Format, ...)
{
- wcsession *WCC;
StrBuf *Error;
StrBuf *Info;
va_list arg_ptr;
}
if (TP->Tokens != NULL)
{
- syslog(1, "%s [%s] (in '%s' line %ld); %s; [%s]\n",
+ syslog(LOG_WARNING, "%s [%s] (in '%s' line %ld); %s; [%s]\n",
Type,
Err,
ChrPtr(TP->Tokens->FileName),
}
else
{
- syslog(1, "%s: %s;\n",
+ syslog(LOG_WARNING, "%s: %s;\n",
Type,
ChrPtr(Error));
}
- WCC = WC;
- if (WCC == NULL) {
+ if (WC == NULL) {
FreeStrBuf(&Info);
FreeStrBuf(&Error);
return;
}
- if (WCC->WFBuf == NULL) WCC->WFBuf = NewStrBuf();
+ if (WC->WFBuf == NULL) WC->WFBuf = NewStrBuf();
if (TP->Tokens != NULL)
{
/* deprecated:
ChrPtr(TP->Tokens->FlatToken));
- SerializeJson(WCC->WFBuf, WildFireException(SKEY(TP->Tokens->FileName),
+ SerializeJson(WC->WFBuf, WildFireException(SKEY(TP->Tokens->FileName),
TP->Tokens->Line,
Info,
1), 1);
-/*
- SerializeJson(Header, WildFireMessage(SKEY(TP->Tokens->FileName),
- TP->Tokens->Line,
- Error,
- eERROR), 1);
-*/
-
}
- else
- {
- /* deprecated.
- StrBufAppendPrintf(
- Target,
- "<pre>\n%s: %s\n</pre>\n",
- Type,
- ChrPtr(Error));
- */
+ else {
StrBufPrintf(Info, "%s [%s] %s; [%s]",
Type,
Err,
ChrPtr(Error),
ChrPtr(TP->Tokens->FlatToken));
- SerializeJson(WCC->WFBuf, WildFireException(HKEY(__FILE__), __LINE__, Info, 1), 1);
+ SerializeJson(WC->WFBuf, WildFireException(HKEY(__FILE__), __LINE__, Info, 1), 1);
}
FreeStrBuf(&Info);
FreeStrBuf(&Error);
-/*
- if (dbg_backtrace_template_errors)
- wc_backtrace();
-*/
}
-
-
-void LogError (StrBuf *Target, const char *Type, const char *Format, ...)
-{
- wcsession *WCC;
+void LogError (StrBuf *Target, const char *Type, const char *Format, ...) {
StrBuf *Error;
StrBuf *Info;
va_list arg_ptr;
StrBufVAppendPrintf(Error, Format, arg_ptr);
va_end(arg_ptr);
- syslog(1, "%s", ChrPtr(Error));
+ syslog(LOG_WARNING, "%s", ChrPtr(Error));
- WCC = WC;
- if (WCC->WFBuf == NULL) WCC->WFBuf = NewStrBuf();
+ if (WC->WFBuf == NULL) WC->WFBuf = NewStrBuf();
- SerializeJson(WCC->WFBuf, WildFireException(Type, strlen(Type),
+ SerializeJson(WC->WFBuf, WildFireException(Type, strlen(Type),
0,
Info,
1), 1);
FreeStrBuf(&Info);
FreeStrBuf(&Error);
-/*
- if (dbg_backtrace_template_errors)
- wc_backtrace();
-*/
}
return 1;
LogTemplateError(
- Target, ErrType, ERR_PARM1, TP,
+ Target, ErrType, ERR_NAME, TP,
" WARNING: requires Context: [%s], have [%s]!",
ContextName(Need->ContextType),
ContextName(TP->Filter.ContextType));
return 0;
}
-/*
- if (TP->Tokens->nParameters < Need->nMinArgs) {
- LogTemplateError(Target, ErrType, ERR_NAME, TP,
- "needs at least %ld params, have %ld",
- Need->nMinArgs,
- TP->Tokens->nParameters);
- return 0;
-
- }
- else if (TP->Tokens->nParameters > Need->nMaxArgs) {
- LogTemplateError(Target, ErrType, ERR_NAME, TP,
- "just needs %ld params, you gave %ld",
- Need->nMaxArgs,
- TP->Tokens->nParameters);
- return 0;
-
- }
-*/
return 1;
}
-void FreeToken(WCTemplateToken **Token)
-{
+void FreeToken(WCTemplateToken **Token) {
int i;
FreeStrBuf(&(*Token)->FlatToken);
if ((*Token)->HaveParameters)
}
-
-void FreeWCTemplate(void *vFreeMe)
-{
+void FreeWCTemplate(void *vFreeMe) {
int i;
WCTemplate *FreeMe = (WCTemplate*)vFreeMe;
}
}
-void GetTemplateTokenString(StrBuf *Target,
- WCTemplputParams *TP,
- int N,
- const char **Value,
- long *len)
-{
+void GetTemplateTokenString(StrBuf *Target, WCTemplputParams *TP, int N, const char **Value, long *len) {
StrBuf *Buf;
-/// WCTemplputParams SubTP;
if (N >= TP->Tokens->nParameters) {
LogTemplateError(Target,
}
}
-long GetTemplateTokenNumber(StrBuf *Target, WCTemplputParams *TP, int N, long dflt)
-{
+long GetTemplateTokenNumber(StrBuf *Target, WCTemplputParams *TP, int N, long dflt) {
long Ret;
if (N >= TP->Tokens->nParameters) {
LogTemplateError(Target,
"TokenParameter", N, TP,
"invalid token %d. this shouldn't have come till here.\n", N);
- wc_backtrace();
+ wc_backtrace(LOG_DEBUG);
return 0;
}
char EscapeAs = ' ';
if ((FormatTypeIndex < TP->Tokens->nParameters) &&
+ (TP->Tokens->Params[FormatTypeIndex] != NULL) &&
(TP->Tokens->Params[FormatTypeIndex]->Type == TYPE_STR) &&
(TP->Tokens->Params[FormatTypeIndex]->len >= 1)) {
pFmt = TP->Tokens->Params[FormatTypeIndex]->Start;
break;
case 'J':
StrECMAEscAppend(Target, Source, NULL);
- break;
+ break;
case 'K':
StrHtmlEcmaEscAppend(Target, Source, NULL, 0, 0);
- break;
+ break;
case 'U':
StrBufUrlescAppend(Target, Source, NULL);
break;
break;
*/
default:
- StrBufAppendBufPlain(Target, Source, 0, 0);
+ StrBufAppendBufPlain(Target, Source, -1, 0);
}
}
}
pche = pch;
if (*pch != quote) {
- syslog(1, "Error (in '%s' line %ld); "
+ syslog(LOG_WARNING, "Error (in '%s' line %ld); "
"evaluating template param [%s] in Token [%s]\n",
ChrPtr(pTmpl->FileName),
Tokens->Line,
else {
StrBufPeek(Buf, pch, -1, '\0');
if (LoadTemplates > 1) {
- syslog(1,
- "DBG: got param [%s] %d %d\n",
+ syslog(LOG_DEBUG,
+ "DBG: got param [%s] "SIZE_T_FMT" "SIZE_T_FMT"\n",
pchs, pche - pchs, strlen(pchs)
);
}
else {
Parm->lvalue = 0;
/* TODO whUT?
- syslog(1, "Error (in '%s' line %ld); "
+ syslog(LOG_DEBUG, "Error (in '%s' line %ld); "
"evaluating long template param [%s] in Token [%s]\n",
ChrPtr(pTmpl->FileName),
Tokens->Line,
}
break;
case SV_GETTEXT:
- if (NewToken->nParameters !=1) {
+ if ((NewToken->nParameters < 1) || (NewToken->nParameters > 2)) {
LogTemplateError(
NULL, "Gettext", ERR_NAME, &TP,
- "requires exactly 1 parameter, you gave %d params",
+ "requires 1 or 2 parameter, you gave %d params",
NewToken->nParameters);
NewToken->Flags = 0;
break;
-/**
- * \brief Display a variable-substituted template
- * \param templatename template file to load
+/*
+ * Display a variable-substituted template
+ * templatename template file to load
*/
-void *prepare_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
-{
+void *prepare_template(StrBuf *filename, StrBuf *Key, HashList *PutThere) {
WCTemplate *NewTemplate;
NewTemplate = (WCTemplate *) malloc(sizeof(WCTemplate));
return NewTemplate;
}
-/**
- * \brief Display a variable-substituted template
- * \param templatename template file to load
+/*
+ * Display a variable-substituted template
+ * templatename template file to load
*/
-void *duplicate_template(WCTemplate *OldTemplate)
-{
+void *duplicate_template(WCTemplate *OldTemplate) {
WCTemplate *NewTemplate;
NewTemplate = (WCTemplate *) malloc(sizeof(WCTemplate));
}
-void SanityCheckTemplate(StrBuf *Target, WCTemplate *CheckMe)
-{
+void SanityCheckTemplate(StrBuf *Target, WCTemplate *CheckMe) {
int i = 0;
int j;
int FoundConditionalEnd;
- for (i = 0; i < CheckMe->nTokensUsed; i++)
- {
- switch(CheckMe->Tokens[i]->Flags)
- {
+ for (i = 0; i < CheckMe->nTokensUsed; i++) {
+ switch(CheckMe->Tokens[i]->Flags) {
case SV_CONDITIONAL:
case SV_NEG_CONDITIONAL:
FoundConditionalEnd = 0;
}
}
-/**
- * \brief Display a variable-substituted template
- * \param templatename template file to load
+/*
+ * Display a variable-substituted template
+ * templatename template file to load
*/
void *load_template(StrBuf *Target, WCTemplate *NewTemplate)
{
fd = open(ChrPtr(NewTemplate->FileName), O_RDONLY);
if (fd <= 0) {
- syslog(1, "ERROR: could not open template '%s' - %s\n",
+ syslog(LOG_WARNING, "ERROR: could not open template '%s' - %s\n",
ChrPtr(NewTemplate->FileName), strerror(errno));
return NULL;
}
if (fstat(fd, &statbuf) == -1) {
- syslog(1, "ERROR: could not stat template '%s' - %s\n",
+ syslog(LOG_WARNING, "ERROR: could not stat template '%s' - %s\n",
ChrPtr(NewTemplate->FileName), strerror(errno));
return NULL;
}
NewTemplate->Data = NewStrBufPlain(NULL, statbuf.st_size + 1);
if (StrBufReadBLOB(NewTemplate->Data, &fd, 1, statbuf.st_size, &Err) < 0) {
close(fd);
- syslog(1, "ERROR: reading template '%s' - %s<br>\n",
+ syslog(LOG_WARNING, "ERROR: reading template '%s' - %s<br>\n",
ChrPtr(NewTemplate->FileName), strerror(errno));
return NULL;
}
{
char *MinorPtr;
-#ifdef _DIRENT_HAVE_D_NAMELEN
- d_namelen = filedir_entry->d_namelen;
+#ifdef _DIRENT_HAVE_D_NAMLEN
+ d_namelen = filedir_entry->d_namlen;
+#else
+ d_namelen = strlen(filedir_entry->d_name);
+#endif
+
+#ifdef _DIRENT_HAVE_D_TYPE
d_type = filedir_entry->d_type;
#else
#define IFTODT(mode) (((mode) & 0170000) >> 12)
#define DTTOIF(dirtype) ((dirtype) << 12)
#endif
- d_namelen = strlen(filedir_entry->d_name);
d_type = DT_UNKNOWN;
#endif
d_without_ext = d_namelen;
char path[PATH_MAX];
snprintf(path, PATH_MAX, "%s/%s",
ChrPtr(DirName), filedir_entry->d_name);
- if (stat(path, &s) == 0) {
+ if (lstat(path, &s) == 0) {
d_type = IFTODT(s.st_mode);
}
}
LoadTemplateDir(SubDirectory, big, SubKey);
break;
- case DT_LNK: /* TODO: check whether its a file or a directory */
+ case DT_LNK:
case DT_REG:
StrBufAppendBufPlain(Key, filedir_entry->d_name, MinorPtr - filedir_entry->d_name, 0);
if (LoadTemplates >= 1)
- syslog(1, "%s %s\n", ChrPtr(FileName), ChrPtr(Key));
+ syslog(LOG_DEBUG, "%s %s\n", ChrPtr(FileName), ChrPtr(Key));
prepare_template(FileName, Key, big);
default:
break;
WCTemplputParams *TP = *TPP;
/* much output, since pName is not terminated...
- syslog(1,"Doing token: %s\n",Token->pName);
+ syslog(LOG_DEBUG,"Doing token: %s\n",Token->pName);
*/
switch (TP->Tokens->Flags) {
case SV_CONDITIONAL: /** Forward conditional evaluation */
Handler = (HashHandler*) TP->Tokens->PreEval;
if (!CheckContext(Target, &Handler->Filter, TP, "Conditional")) {
- return -1;
+ return 0;
}
return EvaluateConditional(Target, 1, state, TPP);
break;
case SV_NEG_CONDITIONAL: /** Reverse conditional evaluation */
Handler = (HashHandler*) TP->Tokens->PreEval;
if (!CheckContext(Target, &Handler->Filter, TP, "Conditional")) {
- return -1;
+ return 0;
}
return EvaluateConditional(Target, 0, state, TPP);
break;
case SV_CUST_STR_CONDITIONAL: /** Conditional put custom strings from params */
Handler = (HashHandler*) TP->Tokens->PreEval;
if (!CheckContext(Target, &Handler->Filter, TP, "Conditional")) {
- return -1;
+ return 0;
}
if (TP->Tokens->nParameters >= 6) {
if (EvaluateConditional(Target, 0, state, TPP)) {
case SV_PREEVALUATED:
Handler = (HashHandler*) TP->Tokens->PreEval;
if (!CheckContext(Target, &Handler->Filter, TP, "Token")) {
- return -1;
+ return 0;
}
Handler->HandlerFunc(Target, TP);
break;
if (GetHash(GlobalNS, TP->Tokens->pName, TP->Tokens->NameEnd, &vVar)) {
Handler = (HashHandler*) vVar;
if (!CheckContext(Target, &Handler->Filter, TP, "Token")) {
- return -1;
+ return 0;
}
else {
Handler->HandlerFunc(Target, TP);
WCTemplputParams TP;
WCTemplputParams *TPtr = &TP;
+ memset(TPtr, 0, sizeof(WCTemplputParams));
+
memcpy(&TP.Filter, &CallingTP->Filter, sizeof(ContextFilter));
TP.Context = CallingTP->Context;
if (LoadTemplates != 0) {
if (LoadTemplates > 1)
- syslog(1, "DBG: ----- loading: [%s] ------ \n",
+ syslog(LOG_DEBUG, "DBG: ----- loading: [%s] ------ \n",
ChrPtr(Tmpl->FileName));
pTmpl = duplicate_template(Tmpl);
if(load_template(Target, pTmpl) == NULL) {
done = 1;
}
else {
- int TokenRc;
+ int TokenRc = 0;
StrBufAppendBufPlain(
Target, pData,
TPtr->nArgs = pTmpl->Tokens[i]->nParameters;
TokenRc = EvaluateToken(Target, TokenRc, &TPtr);
- if (TokenRc != 0) state = eSkipTilEnd;
+ if (TokenRc > 0)
+ {
+ state = eSkipTilEnd;
+ }
+ else if (TokenRc < 0)
+ {
+ if ((TPtr != &TP) &&
+ (TPtr->ExitCTXID == -TokenRc))
+ {
+ UnStackDynamicContext(Target, &TPtr);
+ }
+ TokenRc = 0;
+ }
while ((state != eNext) && (i+1 < pTmpl->nTokensUsed)) {
/* condition told us to skip till its end condition */
pTmpl->Tokens[i]->Flags,
TokenRc,
&TPtr);
- if (rc == TokenRc)
+ if (-rc == TokenRc)
{
TokenRc = 0;
state = eNext;
- if (TPtr != &TP)
+ if ((TPtr != &TP) &&
+ (TPtr->ExitCTXID == - rc))
+ {
UnStackDynamicContext(Target, &TPtr);
+ }
}
}
}
+
pData = pTmpl->Tokens[i++]->pTokenEnd + 1;
if (i > pTmpl->nTokensUsed)
done = 1;
}
+
+StrBuf *textPlainType;
/**
* \brief Display a variable-substituted template
* \param templatename template file to load
if (len == 0)
{
- syslog(1, "Can't to load a template with empty name!\n");
+ syslog(LOG_WARNING, "Can't to load a template with empty name!\n");
StrBufAppendPrintf(Target, "<pre>\nCan't to load a template with empty name!\n</pre>");
- return NULL;
+ return textPlainType;
}
if (!GetHash(StaticLocal, templatename, len, &vTmpl) &&
!GetHash(Static, templatename, len, &vTmpl)) {
- syslog(1, "didn't find Template [%s] %ld %ld\n", templatename, len , (long)strlen(templatename));
+ StrBuf *escapedString = NewStrBufPlain(NULL, len);
+
+ StrHtmlEcmaEscAppend(escapedString, NULL, templatename, 1, 1);
+ syslog(LOG_WARNING, "didn't find Template [%s] %ld %ld\n", ChrPtr(escapedString), len , (long)strlen(templatename));
StrBufAppendPrintf(Target, "<pre>\ndidn't find Template [%s] %ld %ld\n</pre>",
- templatename, len,
+ ChrPtr(escapedString), len,
(long)strlen(templatename));
+ WC->isFailure = 1;
#if 0
dbg_PrintHash(Static, PrintTemplate, NULL);
PrintHash(Static, VarPrintTransition, PrintTemplate);
#endif
- return NULL;
+ FreeStrBuf(&escapedString);
+ return textPlainType;
}
if (vTmpl == NULL)
- return NULL;
+ return textPlainType;
return ProcessTemplate(vTmpl, Target, TP);
}
RetrieveHashlistFunc GetHash;
HashDestructorFunc Destructor;
SubTemplFunc DoSubTemplate;
+ FilterByParamFunc Filter;
} HashIterator;
void RegisterITERATOR(const char *Name, long len,
RetrieveHashlistFunc GetHash,
SubTemplFunc DoSubTempl,
HashDestructorFunc Destructor,
+ FilterByParamFunc Filter,
CtxType ContextType,
CtxType XPectContextType,
int Flags)
It->GetHash = GetHash;
It->DoSubTemplate = DoSubTempl;
It->Destructor = Destructor;
+ It->Filter = Filter;
It->ContextType = ContextType;
It->XPectContextType = XPectContextType;
It->Flags = Flags;
/** Ok, its us, lets see in which direction we should sort... */
(havebstr("SortOrder"))) {
int SortOrder;
- SortOrder = LBSTR("SortOrder");
+ SortOrder = lbstr("SortOrder");
if (SortOrder != 0)
DetectGroupChange = 1;
}
}
while (GetNextHashPos(List, it, &Status.KeyLen, &Status.Key, &vContext)) {
if ((Status.n >= StartAt) && (Status.n <= StopAt)) {
+
+ if ((It->Filter != NULL) &&
+ !It->Filter(Status.Key, Status.KeyLen, vContext, Target, TP))
+ {
+ continue;
+ }
+
if (DetectGroupChange && Status.n > 0) {
Status.GroupChange = SortBy->GroupChange(vContext, vLastContext);
}
StrBufAppendBufPlain(Target, Ctx->Key, Ctx->KeyLen, 0);
}
+void tmplput_ITERATE_N_DIV(StrBuf *Target, WCTemplputParams *TP)
+{
+ IterateStruct *Ctx = CTX(CTX_ITERATE);
+ long div;
+ long divisor = GetTemplateTokenNumber(Target, TP, 0, 1);
+///TODO divisor == 0 -> log error exit
+ div = Ctx->n / divisor;
+ StrBufAppendPrintf(Target, "%ld", div);
+}
-void tmplput_ITERATE_LASTN(StrBuf *Target, WCTemplputParams *TP)
+void tmplput_ITERATE_N(StrBuf *Target, WCTemplputParams *TP)
{
IterateStruct *Ctx = CTX(CTX_ITERATE);
StrBufAppendPrintf(Target, "%d", Ctx->n);
return Ctx->LastN;
}
+int conditional_ITERATE_ISMOD(StrBuf *Target, WCTemplputParams *TP)
+{
+ IterateStruct *Ctx = CTX(CTX_ITERATE);
+
+ long divisor = GetTemplateTokenNumber(Target, TP, 2, 1);
+ long expectRemainder = GetTemplateTokenNumber(Target, TP, 3, 0);
+
+ return Ctx->n % divisor == expectRemainder;
+}
+
/*-----------------------------------------------------------------------------
if ((TP->Tokens->Params[0]->len == 1) &&
(TP->Tokens->Params[0]->Start[0] == 'X'))
{
- return (state != 0)?TP->Tokens->Params[1]->lvalue:0;
+ return - (TP->Tokens->Params[1]->lvalue);
}
Cond = (ConditionalStruct *) TP->Tokens->PreEval;
LogTemplateError(
Target, "Conditional", ERR_PARM1, TP,
"unknown!");
- return 1;
+ return 0;
}
if (!CheckContext(Target, &Cond->Filter, TP, "Conditional")) {
res = Cond->CondF(Target, TP);
if (res == Neg)
rc = TP->Tokens->Params[1]->lvalue;
+
if (LoadTemplates > 5)
- syslog(1, "<%s> : %d %d==%d\n",
+ syslog(LOG_DEBUG, "<%s> : %d %d==%d\n",
ChrPtr(TP->Tokens->FlatToken),
rc, res, Neg);
+
if (TP->Sub != NULL)
{
-//// *XC = Cond->CondExitCtx;
*TPP = TP->Sub;
}
return rc;
}
StackContext (TP, &SubTP, &TS, CTX_TAB, 0, NULL);
{
-//// TODO jetzt memcpy (&SubTP, TP, sizeof(WCTemplputParams));
-// SubTP.Filter.ControlContextType = ;
-
StrTabbedDialog(Target, nTabs, TabNames);
for (i = 0; i < ntabs; i++) {
memset(&TS, 0, sizeof(tab_struct));
NewSort->GroupChange = GroupChange;
NewSort->ContextType = ContextType;
if (ContextType == CTX_NONE) {
- syslog(1, "sorting requires a context. CTX_NONE won't make it.\n");
+ syslog(LOG_WARNING, "sorting requires a context. CTX_NONE won't make it.\n");
exit(1);
}
LogTemplateError(
NULL, "Sorting", ERR_PARM1, TP,
"Illegal default sort: [%s]", Default);
- wc_backtrace();
+ wc_backtrace(LOG_WARNING);
}
}
SortBy = (SortStruct*)vSortBy;
/** Ok, its us, lets see in which direction we should sort... */
if (havebstr("SortOrder")) {
- SortOrder = LBSTR("SortOrder");
+ SortOrder = lbstr("SortOrder");
}
else { /** Try to fallback to our remembered values... */
StrBuf *Buf = NULL;
/** Ok, its us, lets see in which direction we should sort... */
if (havebstr("SortOrder")) {
- *SortOrder = LBSTR("SortOrder");
+ *SortOrder = lbstr("SortOrder");
}
else { /** Try to fallback to our remembered values... */
if ((*Param)->PrefPrepend == NULL) {
StrBufAppendPrintf(Buf, "%d: %ld]\n", i, LongVector[i]);
}
- syslog(1, "%s", ChrPtr(Buf));
+ syslog(LOG_DEBUG, "%s", ChrPtr(Buf));
FreeStrBuf(&Buf);
}
RegisterConditional("COND:ITERATE:FIRSTN", 2,
conditional_ITERATE_FIRSTN,
CTX_ITERATE);
+ RegisterConditional("COND:ITERATE:ISMOD", 3,
+ conditional_ITERATE_ISMOD,
+ CTX_ITERATE);
RegisterNamespace("ITERATE:ODDEVEN", 0, 0, tmplput_ITERATE_ODDEVEN, NULL, CTX_ITERATE);
RegisterNamespace("ITERATE:KEY", 0, 0, tmplput_ITERATE_KEY, NULL, CTX_ITERATE);
- RegisterNamespace("ITERATE:N", 0, 0, tmplput_ITERATE_LASTN, NULL, CTX_ITERATE);
+ RegisterNamespace("ITERATE:N", 0, 0, tmplput_ITERATE_N, NULL, CTX_ITERATE);
+ RegisterNamespace("ITERATE:N:DIV", 1, 1, tmplput_ITERATE_N_DIV, NULL, CTX_ITERATE);
RegisterNamespace("CURRENTFILE", 0, 1, tmplput_CURRENT_FILE, NULL, CTX_NONE);
RegisterNamespace("DEF:STR", 1, 1, tmplput_DefStr, NULL, CTX_NONE);
RegisterNamespace("DEF:VAL", 1, 1, tmplput_DefVal, NULL, CTX_NONE);
ServerStartModule_SUBST
(void)
{
+ textPlainType = NewStrBufPlain(HKEY("text/plain"));
LocalTemplateCache = NewHash(1, NULL);
TemplateCache = NewHash(1, NULL);
-
GlobalNS = NewHash(1, NULL);
Iterators = NewHash(1, NULL);
Conditionals = NewHash(1, NULL);
ServerShutdownModule_SUBST
(void)
{
+ FreeStrBuf(&textPlainType);
+
DeleteHash(&TemplateCache);
DeleteHash(&LocalTemplateCache);
-
+
DeleteHash(&GlobalNS);
DeleteHash(&Iterators);
DeleteHash(&Conditionals);