X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fsubst.c;h=7964ab4c2795f3481421da790a0acee9f743b687;hb=c19da2c87226fee57abdab376d09475cccb11fe5;hp=e9955a05d51060d1291a569e91ae522a5fbd012b;hpb=b39d860713ddd390339211be8d398c4d4b6680ba;p=citadel.git
diff --git a/webcit/subst.c b/webcit/subst.c
index e9955a05d..7964ab4c2 100644
--- a/webcit/subst.c
+++ b/webcit/subst.c
@@ -43,6 +43,7 @@ const char EmptyStr[]="";
#define SV_PREEVALUATED 6
+
/*
* Dynamic content for variable substitution in templates
*/
@@ -163,6 +164,8 @@ void StackDynamicContext(WCTemplputParams *Super,
Sub->Sub = Super->Sub;
Super->Sub = Sub;
}
+ if (Sub->Sub != NULL)
+ Sub->Sub->Super = Sub;
Sub->Super = Super;
Sub->Context = Context;
@@ -179,6 +182,10 @@ void UnStackContext(WCTemplputParams *Sub)
{
Sub->Super->Sub = Sub->Sub;
}
+ if (Sub->Sub != NULL)
+ {
+ Sub->Sub->Super = Sub->Super;
+ }
}
void UnStackDynamicContext(StrBuf *Target, WCTemplputParams **TPP)
{
@@ -237,7 +244,7 @@ void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplpu
}
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),
@@ -247,7 +254,7 @@ void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplpu
}
else
{
- syslog(1, "%s: %s;\n",
+ syslog(LOG_WARNING, "%s: %s;\n",
Type,
ChrPtr(Error));
}
@@ -311,13 +318,10 @@ void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplpu
FreeStrBuf(&Error);
/*
if (dbg_backtrace_template_errors)
- wc_backtrace();
+ wc_backtrace(LOG_DEBUG);
*/
}
-
-
-
void LogError (StrBuf *Target, const char *Type, const char *Format, ...)
{
wcsession *WCC;
@@ -332,7 +336,7 @@ void LogError (StrBuf *Target, const char *Type, const char *Format, ...)
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();
@@ -346,7 +350,7 @@ void LogError (StrBuf *Target, const char *Type, const char *Format, ...)
FreeStrBuf(&Error);
/*
if (dbg_backtrace_template_errors)
- wc_backtrace();
+ wc_backtrace(LOG_DEBUG);
*/
}
@@ -392,7 +396,7 @@ int CheckContext(StrBuf *Target, ContextFilter *Need, WCTemplputParams *TP, cons
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));
@@ -482,7 +486,6 @@ void GetTemplateTokenString(StrBuf *Target,
long *len)
{
StrBuf *Buf;
-/// WCTemplputParams SubTP;
if (N >= TP->Tokens->nParameters) {
LogTemplateError(Target,
@@ -587,7 +590,7 @@ long GetTemplateTokenNumber(StrBuf *Target, WCTemplputParams *TP, int N, long df
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;
}
@@ -676,6 +679,7 @@ void StrBufAppendTemplate(StrBuf *Target,
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;
@@ -692,10 +696,10 @@ void StrBufAppendTemplate(StrBuf *Target,
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;
@@ -755,7 +759,7 @@ void StrBufAppendTemplateStr(StrBuf *Target,
break;
*/
default:
- StrBufAppendBufPlain(Target, Source, 0, 0);
+ StrBufAppendBufPlain(Target, Source, -1, 0);
}
}
@@ -883,7 +887,7 @@ int GetNextParameter(StrBuf *Buf,
}
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,
@@ -897,8 +901,8 @@ int GetNextParameter(StrBuf *Buf,
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)
);
}
@@ -929,7 +933,7 @@ int GetNextParameter(StrBuf *Buf,
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,
@@ -1200,10 +1204,10 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf,
}
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;
@@ -1397,13 +1401,13 @@ 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;
}
@@ -1411,7 +1415,7 @@ void *load_template(StrBuf *Target, WCTemplate *NewTemplate)
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
\n",
+ syslog(LOG_WARNING, "ERROR: reading template '%s' - %s
\n",
ChrPtr(NewTemplate->FileName), strerror(errno));
return NULL;
}
@@ -1522,8 +1526,13 @@ int LoadTemplateDir(const StrBuf *DirName, HashList *big, const StrBuf *BaseKey)
{
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
@@ -1536,7 +1545,6 @@ int LoadTemplateDir(const StrBuf *DirName, HashList *big, const StrBuf *BaseKey)
#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;
@@ -1558,7 +1566,7 @@ int LoadTemplateDir(const StrBuf *DirName, HashList *big, const StrBuf *BaseKey)
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);
}
}
@@ -1586,7 +1594,7 @@ int LoadTemplateDir(const StrBuf *DirName, HashList *big, const StrBuf *BaseKey)
LoadTemplateDir(SubDirectory, big, SubKey);
break;
- case DT_LNK: /* TODO: check whether its a file or a directory */
+ case DT_LNK:
case DT_REG:
@@ -1611,7 +1619,7 @@ int LoadTemplateDir(const StrBuf *DirName, HashList *big, const StrBuf *BaseKey)
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;
@@ -1706,7 +1714,7 @@ int EvaluateToken(StrBuf *Target, int state, WCTemplputParams **TPP)
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) {
@@ -1716,21 +1724,21 @@ int EvaluateToken(StrBuf *Target, int state, WCTemplputParams **TPP)
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)) {
@@ -1765,7 +1773,7 @@ int EvaluateToken(StrBuf *Target, int state, WCTemplputParams **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;
@@ -1773,7 +1781,7 @@ int EvaluateToken(StrBuf *Target, int state, WCTemplputParams **TPP)
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);
@@ -1801,6 +1809,8 @@ const StrBuf *ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, WCTemplputParams
WCTemplputParams TP;
WCTemplputParams *TPtr = &TP;
+ memset(TPtr, 0, sizeof(WCTemplputParams));
+
memcpy(&TP.Filter, &CallingTP->Filter, sizeof(ContextFilter));
TP.Context = CallingTP->Context;
@@ -1809,7 +1819,7 @@ const StrBuf *ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, WCTemplputParams
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) {
@@ -1835,7 +1845,7 @@ const StrBuf *ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, WCTemplputParams
done = 1;
}
else {
- int TokenRc;
+ int TokenRc = 0;
StrBufAppendBufPlain(
Target, pData,
@@ -1844,7 +1854,19 @@ const StrBuf *ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, WCTemplputParams
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 */
@@ -1860,15 +1882,19 @@ const StrBuf *ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, WCTemplputParams
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;
@@ -1881,6 +1907,8 @@ const StrBuf *ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, WCTemplputParams
}
+
+StrBuf *textPlainType;
/**
* \brief Display a variable-substituted template
* \param templatename template file to load
@@ -1905,25 +1933,30 @@ const StrBuf *DoTemplate(const char *templatename, long len, StrBuf *Target, WCT
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, "
\nCan't to load a template with empty name!\n"); - 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, "
\ndidn't find Template [%s] %ld %ld\n", - 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); } @@ -1958,6 +1991,7 @@ typedef struct _HashIterator { RetrieveHashlistFunc GetHash; HashDestructorFunc Destructor; SubTemplFunc DoSubTemplate; + FilterByParamFunc Filter; } HashIterator; void RegisterITERATOR(const char *Name, long len, @@ -1966,6 +2000,7 @@ void RegisterITERATOR(const char *Name, long len, RetrieveHashlistFunc GetHash, SubTemplFunc DoSubTempl, HashDestructorFunc Destructor, + FilterByParamFunc Filter, CtxType ContextType, CtxType XPectContextType, int Flags) @@ -1979,6 +2014,7 @@ void RegisterITERATOR(const char *Name, long len, It->GetHash = GetHash; It->DoSubTemplate = DoSubTempl; It->Destructor = Destructor; + It->Filter = Filter; It->ContextType = ContextType; It->XPectContextType = XPectContextType; It->Flags = Flags; @@ -2132,6 +2168,13 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) } 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); } @@ -2220,7 +2263,7 @@ int EvaluateConditional(StrBuf *Target, int Neg, int state, WCTemplputParams **T 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; @@ -2228,7 +2271,7 @@ int EvaluateConditional(StrBuf *Target, int Neg, int state, WCTemplputParams **T LogTemplateError( Target, "Conditional", ERR_PARM1, TP, "unknown!"); - return 1; + return 0; } if (!CheckContext(Target, &Cond->Filter, TP, "Conditional")) { @@ -2238,13 +2281,14 @@ int EvaluateConditional(StrBuf *Target, int Neg, int state, WCTemplputParams **T 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; @@ -2505,9 +2549,6 @@ void tmpl_do_tabbed(StrBuf *Target, WCTemplputParams *TP) } 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)); @@ -2563,7 +2604,7 @@ void RegisterSortFunc(const char *name, long len, 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); } @@ -2612,7 +2653,7 @@ CompareFunc RetrieveSort(WCTemplputParams *TP, LogTemplateError( NULL, "Sorting", ERR_PARM1, TP, "Illegal default sort: [%s]", Default); - wc_backtrace(); + wc_backtrace(LOG_WARNING); } } SortBy = (SortStruct*)vSortBy; @@ -2857,7 +2898,7 @@ void dbg_print_longvector(long *LongVector) StrBufAppendPrintf(Buf, "%d: %ld]\n", i, LongVector[i]); } - syslog(1, "%s", ChrPtr(Buf)); + syslog(LOG_DEBUG, "%s", ChrPtr(Buf)); FreeStrBuf(&Buf); } @@ -2954,9 +2995,9 @@ void 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); @@ -2982,9 +3023,11 @@ void ServerShutdownModule_SUBST (void) { + FreeStrBuf(&textPlainType); + DeleteHash(&TemplateCache); DeleteHash(&LocalTemplateCache); - + DeleteHash(&GlobalNS); DeleteHash(&Iterators); DeleteHash(&Conditionals);