X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fsubst.c;h=4e08db7ace058e6464fdd11db346d417f143a139;hb=f5c1330914acc193f96892efc191a32ee537dfb5;hp=766790bb67147b3edca140b88fbbdfa51c5a024e;hpb=09d536b383a20aad105bc181a05027a4964bf624;p=citadel.git diff --git a/webcit/subst.c b/webcit/subst.c index 766790bb6..4e08db7ac 100644 --- a/webcit/subst.c +++ b/webcit/subst.c @@ -1,6 +1,3 @@ -/* - * $Id$ - */ #include "sysdep.h" @@ -34,7 +31,7 @@ HashList *Defines; int DumpTemplateI18NStrings = 0; int LoadTemplates = 0; -int dbg_bactrace_template_errors = 0; +int dbg_backtrace_template_errors = 0; WCTemplputParams NoCtx; StrBuf *I18nDump = NULL; @@ -112,6 +109,7 @@ const char *CtxNames[] = { "Context ITERATE", "Context ICAL", "Context DavNamespace", + "Context TAB", "Context UNKNOWN" }; @@ -149,19 +147,13 @@ void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplpu va_end(arg_ptr); switch (ErrorPos) { - default: case ERR_NAME: /* the main token name... */ Err = (TP->Tokens!= NULL)? TP->Tokens->pName:""; break; - case ERR_PARM1: - Err = ((TP->Tokens!= NULL) && - (TP->Tokens->nParameters > 0))? - TP->Tokens->Params[0]->Start : ""; - break; - case ERR_PARM2: + default: Err = ((TP->Tokens!= NULL) && - (TP->Tokens->nParameters > 1))? - TP->Tokens->Params[1]->Start : ""; + (TP->Tokens->nParameters > ErrorPos - 1))? + TP->Tokens->Params[ErrorPos - 1]->Start : ""; break; } if (TP->Tokens != NULL) @@ -243,7 +235,7 @@ void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplpu FreeStrBuf(&Info); FreeStrBuf(&Error); /* - if (dbg_bactrace_template_errors) + if (dbg_backtrace_template_errors) wc_backtrace(); */ } @@ -278,7 +270,7 @@ void LogError (StrBuf *Target, const char *Type, const char *Format, ...) FreeStrBuf(&Info); FreeStrBuf(&Error); /* - if (dbg_bactrace_template_errors) + if (dbg_backtrace_template_errors) wc_backtrace(); */ } @@ -400,338 +392,6 @@ void FreeWCTemplate(void *vFreeMe) } -/* - * debugging function to print array to log - */ -void VarPrintTransition(void *vVar1, void *vVar2, int odd){} - -/* - * debugging function to print array to log - */ -void VarPrintEntry(const char *Key, void *vSubst, int odd) -{ - wcsubst *ptr; - lprintf(1,"Subst[%s] : ", Key); - ptr = (wcsubst*) vSubst; - - switch(ptr->wcs_type) { - case WCS_STRING: - lprintf(1, " -> %s\n", ChrPtr(ptr->wcs_value)); - break; - case WCS_SERVCMD: - lprintf(1, " -> Server [%s]\n", ChrPtr(ptr->wcs_value)); - break; - case WCS_FUNCTION: - lprintf(1, " -> function at [%0xd]\n", ptr->wcs_function); - break; - default: - lprintf(1," WARNING: invalid type: [%ld]!\n", ptr->wcs_type); - } -} - - - -/* - * Clear out the list of substitution variables local to this session - */ -void clear_substs(wcsession *wc) { - - if (wc->vars != NULL) { - DeleteHash(&wc->vars); - } -} - -/* - * Clear out the list of substitution variables local to this session - */ -void clear_local_substs(void) { - clear_substs (WC); -} - -int NeedNewBuf(type) -{ - switch(type) { - case WCS_STRING: - case WCS_SERVCMD: - case WCS_STRBUF: - return 1; - case WCS_FUNCTION: - case WCS_STRBUF_REF: - case WCS_LONG: - default: - return 0; - } -} - -void FlushPayload(wcsubst *ptr, int reusestrbuf, int type) -{ - int NeedNew = NeedNewBuf(type); - switch(ptr->wcs_type) { - case WCS_STRING: - case WCS_SERVCMD: - case WCS_STRBUF: - if (reusestrbuf && NeedNew) { - FlushStrBuf(ptr->wcs_value); - } - else { - - FreeStrBuf(&ptr->wcs_value); - ptr->wcs_value = NULL; - } - break; - case WCS_FUNCTION: - ptr->wcs_function = NULL; - if (reusestrbuf && NeedNew) - ptr->wcs_value = NewStrBuf(); - break; - case WCS_STRBUF_REF: - ptr->wcs_value = NULL; - if (reusestrbuf && NeedNew) - ptr->wcs_value = NewStrBuf(); - break; - case WCS_LONG: - ptr->lvalue = 0; - if (reusestrbuf && NeedNew) - ptr->wcs_value = NewStrBuf(); - break; - default: - if (reusestrbuf && NeedNew) - ptr->wcs_value = NewStrBuf(); - break; - } -} - - -/* - * destructor; kill one entry. - */ -void deletevar(void *data) -{ - wcsubst *ptr = (wcsubst*)data; - FlushPayload(ptr, 0, ptr->wcs_type); - free(ptr); -} - - -wcsubst *NewSubstVar(const char *keyname, int keylen, int type) -{ - wcsubst* ptr; - wcsession *WCC = WC; - - ptr = (wcsubst *) malloc(sizeof(wcsubst)); - memset(ptr, 0, sizeof(wcsubst)); - - ptr->wcs_type = type; - safestrncpy(ptr->wcs_key, keyname, sizeof ptr->wcs_key); - Put(WCC->vars, keyname, keylen, ptr, deletevar); - - switch(ptr->wcs_type) { - case WCS_STRING: - case WCS_SERVCMD: - ptr->wcs_value = NewStrBuf(); - break; - case WCS_STRBUF: - case WCS_FUNCTION: - case WCS_STRBUF_REF: - case WCS_LONG: - default: - break; - } - return ptr; -} - - -/* - * Add a substitution variable (local to this session) (strlen version...) - * keyname the replacementstring to substitute - * keytype the kind of the key - * format the format string ala printf - * ... the arguments to substitute in the formatstring - */ -void SVPRINTF(char *keyname, int keytype, const char *format,...) -{ - va_list arg_ptr; - void *vPtr; - wcsubst *ptr = NULL; - size_t keylen; - wcsession *WCC = WC; - - keylen = strlen(keyname); - /* - * First look if we're doing a replacement of - * an existing key - */ - /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/ - if (GetHash(WCC->vars, keyname, keylen, &vPtr)) { - ptr = (wcsubst*)vPtr; - FlushPayload(ptr, keytype, keytype); - ptr->wcs_type = keytype; - } - else /** Otherwise allocate a new one */ - { - ptr = NewSubstVar(keyname, keylen, keytype); - } - - /* Format the string */ - va_start(arg_ptr, format); - StrBufVAppendPrintf(ptr->wcs_value, format, arg_ptr); - va_end(arg_ptr); -} - -/* - * Add a substitution variable (local to this session) - * keyname the replacementstring to substitute - * keytype the kind of the key - * format the format string ala printf - * ... the arguments to substitute in the formatstring - */ -void svprintf(char *keyname, size_t keylen, int keytype, const char *format,...) -{ - va_list arg_ptr; - void *vPtr; - wcsubst *ptr = NULL; - wcsession *WCC = WC; - - /* - * First look if we're doing a replacement of - * an existing key - */ - /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/ - if (GetHash(WCC->vars, keyname, keylen, &vPtr)) { - ptr = (wcsubst*)vPtr; - FlushPayload(ptr, 1, keytype); - ptr->wcs_type = keytype; - } - else /** Otherwise allocate a new one */ - { - ptr = NewSubstVar(keyname, keylen, keytype); - } - - /** Format the string and save it */ - va_start(arg_ptr, format); - StrBufVAppendPrintf(ptr->wcs_value, format, arg_ptr); - va_end(arg_ptr); -} - -/* - * Add a substitution variable (local to this session) - * keyname the replacementstring to substitute - * keytype the kind of the key - * format the format string ala printf - * ... the arguments to substitute in the formatstring - */ -void SVPut(char *keyname, size_t keylen, int keytype, char *Data) -{ - void *vPtr; - wcsubst *ptr = NULL; - wcsession *WCC = WC; - - - /* - * First look if we're doing a replacement of - * an existing key - */ - /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/ - if (GetHash(WCC->vars, keyname, keylen, &vPtr)) { - ptr = (wcsubst*)vPtr; - FlushPayload(ptr, 1, keytype); - ptr->wcs_type = keytype; - } - else /** Otherwise allocate a new one */ - { - ptr = NewSubstVar(keyname, keylen, keytype); - } - StrBufAppendBufPlain(ptr->wcs_value, Data, -1, 0); -} - -/** - * \brief Add a substitution variable (local to this session) - * \param keyname the replacementstring to substitute - * \param keytype the kind of the key - * \param format the format string ala printf - * \param ... the arguments to substitute in the formatstring - */ -void SVPutLong(char *keyname, size_t keylen, long Data) -{ - void *vPtr; - wcsubst *ptr = NULL; - wcsession *WCC = WC; - - - /** - * First look if we're doing a replacement of - * an existing key - */ - /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/ - if (GetHash(WCC->vars, keyname, keylen, &vPtr)) { - ptr = (wcsubst*)vPtr; - FlushPayload(ptr, 1, WCS_LONG); - ptr->wcs_type = WCS_LONG; - } - else /** Otherwise allocate a new one */ - { - ptr = NewSubstVar(keyname, keylen, WCS_LONG); - } - ptr->lvalue = Data; -} - -/** - * \brief Add a substitution variable (local to this session) that does a callback - * \param keyname the keystring to substitute - * \param fcn_ptr the function callback to give the substitution string - */ -void SVCallback(char *keyname, size_t keylen, WCHandlerFunc fcn_ptr) -{ - wcsubst *ptr; - void *vPtr; - wcsession *WCC = WC; - - /** - * First look if we're doing a replacement of - * an existing key - */ - /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/ - if (GetHash(WCC->vars, keyname, keylen, &vPtr)) { - ptr = (wcsubst*)vPtr; - FlushPayload(ptr, 1, WCS_FUNCTION); - ptr->wcs_type = WCS_FUNCTION; - } - else /** Otherwise allocate a new one */ - { - ptr = NewSubstVar(keyname, keylen, WCS_FUNCTION); - } - - ptr->wcs_function = fcn_ptr; -} -inline void SVCALLBACK(char *keyname, WCHandlerFunc fcn_ptr) -{ - SVCallback(keyname, strlen(keyname), fcn_ptr); -} - - - -void SVPUTBuf(const char *keyname, int keylen, const StrBuf *Buf, int ref) -{ - wcsubst *ptr; - void *vPtr; - wcsession *WCC = WC; - - /** - * First look if we're doing a replacement of - * an existing key - */ - /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/ - if (GetHash(WCC->vars, keyname, keylen, &vPtr)) { - ptr = (wcsubst*)vPtr; - FlushPayload(ptr, 0, (ref)?WCS_STRBUF_REF:WCS_STRBUF); - ptr->wcs_type = (ref)?WCS_STRBUF_REF:WCS_STRBUF; - } - else /** Otherwise allocate a new one */ - { - ptr = NewSubstVar(keyname, keylen, (ref)?WCS_STRBUF_REF:WCS_STRBUF); - } - ptr->wcs_value = (StrBuf*)Buf; -} /** * \brief back end for print_value_of() ... does a server command @@ -868,7 +528,7 @@ void GetTemplateTokenString(StrBuf *Target, *Value = ChrPtr(Buf); *len = StrLength(Buf); /* we can't free it here, so we put it into the subst so its discarded later on. */ - SVPUTBuf(TKEY(N), Buf, 0); + ///SVPUTBuf(TKEY(N), Buf, 0); break; default: @@ -949,129 +609,6 @@ long GetTemplateTokenNumber(StrBuf *Target, WCTemplputParams *TP, int N, long df } - -/** - * \brief Print the value of a variable - * \param keyname get a key to print - */ -void print_value_of(StrBuf *Target, WCTemplputParams *TP) - -{ - wcsession *WCC = WC; - wcsubst *ptr; - void *vVar; - - /*if (WCC->vars != NULL) PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/ - /* TODO: depricated! */ - if (TP->Tokens->pName[0] == '=') { - DoTemplate(TP->Tokens->pName+1, TP->Tokens->NameEnd - 1, NULL, &NoCtx); - } -/*/////TODO: if param[1] == "U" -> urlescape -/// X -> escputs */ - /** Page-local variables */ - if ((WCC->vars!= NULL) && GetHash(WCC->vars, TP->Tokens->pName, TP->Tokens->NameEnd, &vVar)) { - ptr = (wcsubst*) vVar; - switch(ptr->wcs_type) { - case WCS_STRING: - StrBufAppendBuf(Target, ptr->wcs_value, 0); - break; - case WCS_SERVCMD: - pvo_do_cmd(Target, ptr->wcs_value); - break; - case WCS_FUNCTION: - (*ptr->wcs_function) (Target, TP); - break; - case WCS_STRBUF: - case WCS_STRBUF_REF: - StrBufAppendBuf(Target, ptr->wcs_value, 0); - break; - case WCS_LONG: - StrBufAppendPrintf(Target, "%ld", ptr->lvalue); - break; - default: - LogTemplateError( - Target, "Subst", ERR_NAME, TP, - "WARNING: invalid value in SV-Hash at %s!", TP->Tokens->pName); - } - } - else { - LogTemplateError( - Target, "Token", ERR_NAME, TP, - "didn't find Handler \"%s\"", TP->Tokens->pName); - wc_backtrace(); - } -} - -int CompareSubstToToken(TemplateParam *ParamToCompare, TemplateParam *ParamToLookup) -{ - wcsession *WCC = WC; - wcsubst *ptr; - void *vVar; - - if ((WCC->vars!= NULL) && GetHash(WCC->vars, ParamToLookup->Start, - ParamToLookup->len, &vVar)) { - ptr = (wcsubst*) vVar; - switch(ptr->wcs_type) { - case WCS_STRING: - case WCS_STRBUF: - case WCS_STRBUF_REF: - if (ParamToCompare->Type == TYPE_STR) - return ((ParamToCompare->len == StrLength(ptr->wcs_value)) && - (strcmp(ParamToCompare->Start, ChrPtr(ptr->wcs_value)) == 0)); - else - return ParamToCompare->lvalue == StrTol(ptr->wcs_value); - break; - case WCS_SERVCMD: - return 1; - break; - case WCS_FUNCTION: - return 1; - case WCS_LONG: - if (ParamToCompare->Type == TYPE_STR) - return 0; - else - return ParamToCompare->lvalue == ptr->lvalue; - break; - default: - lprintf(1,"WARNING: invalid value in SV-Hash at %s!\n", - ParamToLookup->Start); - } - } - return 0; -} - -int CompareSubstToStrBuf(StrBuf *Compare, TemplateParam *ParamToLookup) -{ - wcsession *WCC = WC; - wcsubst *ptr; - void *vVar; - - if ((WCC->vars!= NULL) && GetHash(WCC->vars, ParamToLookup->Start, - ParamToLookup->len, &vVar)) { - ptr = (wcsubst*) vVar; - switch(ptr->wcs_type) { - case WCS_STRING: - case WCS_STRBUF: - case WCS_STRBUF_REF: - return ((StrLength(Compare) == StrLength(ptr->wcs_value)) && - (strcmp(ChrPtr(Compare), ChrPtr(ptr->wcs_value)) == 0)); - case WCS_SERVCMD: - return 1; - break; - case WCS_FUNCTION: - return 1; - case WCS_LONG: - return StrTol(Compare) == ptr->lvalue; - default: - lprintf(1,"WARNING: invalid value in SV-Hash at %s!\n", - ParamToLookup->Start); - } - } - return 0; -} - - - /** * \brief puts string into the template and computes which escape methon we should use * \param Source the string we should put into the template @@ -1144,12 +681,13 @@ void PutNewToken(WCTemplate *Template, WCTemplateToken *NewToken) Template->Tokens[(Template->nTokensUsed)++] = NewToken; } -TemplateParam *GetNextParameter(StrBuf *Buf, - const char **pCh, - const char *pe, - WCTemplateToken *Tokens, - WCTemplate *pTmpl, - WCTemplputParams *TP) +int GetNextParameter(StrBuf *Buf, + const char **pCh, + const char *pe, + WCTemplateToken *Tokens, + WCTemplate *pTmpl, + WCTemplputParams *TP, + TemplateParam **pParm) { const char *pch = *pCh; const char *pchs, *pche; @@ -1157,7 +695,7 @@ TemplateParam *GetNextParameter(StrBuf *Buf, char quote = '\0'; int ParamBrace = 0; - Parm = (TemplateParam *) malloc(sizeof(TemplateParam)); + *pParm = Parm = (TemplateParam *) malloc(sizeof(TemplateParam)); memset(Parm, 0, sizeof(TemplateParam)); Parm->Type = TYPE_STR; @@ -1236,7 +774,8 @@ TemplateParam *GetNextParameter(StrBuf *Buf, *pCh); pch ++; free(Parm); - return NULL; + *pParm = NULL; + return 0; } else { StrBufPeek(Buf, pch, -1, '\0'); @@ -1279,7 +818,8 @@ TemplateParam *GetNextParameter(StrBuf *Buf, *pCh); */ free(Parm); - return NULL; + *pParm = NULL; + return 0; } } while ((*pch == ' ' )|| @@ -1306,9 +846,84 @@ TemplateParam *GetNextParameter(StrBuf *Buf, Parm->lvalue = *PVal; } - else + else if (strchr(Parm->Start, '|') != NULL) + { + const char *Pos; + StrBuf *pToken; + StrBuf *Match; + + Parm->MaskBy = eOR; + pToken = NewStrBufPlain (Parm->Start, Parm->len); + Match = NewStrBufPlain (NULL, Parm->len); + Pos = ChrPtr(pToken); + + while ((Pos != NULL) && (Pos != StrBufNOTNULL)) + { + StrBufExtract_NextToken(Match, pToken, &Pos, '|'); + StrBufTrim(Match); + if (StrLength (Match) > 0) + { + if (GetHash(Defines, SKEY(Match), &vPVal) && + (vPVal != NULL)) + { + long *PVal; + PVal = (long*) vPVal; + + Parm->lvalue |= *PVal; + } + else { + LogTemplateError(NULL, "Define", + Tokens->nParameters, + TP, + "%s isn't known!!", + ChrPtr(Match)); + + } + } + } + } + else if (strchr(Parm->Start, '&') != NULL) { - LogTemplateError(NULL, "Define", ERR_PARM1, TP, + const char *Pos; + StrBuf *pToken; + StrBuf *Match; + + Parm->MaskBy = eAND; + pToken = NewStrBufPlain (Parm->Start, Parm->len); + Match = NewStrBufPlain (NULL, Parm->len); + Pos = ChrPtr(pToken); + + while ((Pos != NULL) && (Pos != StrBufNOTNULL)) + { + StrBufExtract_NextToken(Match, pToken, &Pos, '&'); + StrBufTrim(Match); + if (StrLength (Match) > 0) + { + if (GetHash(Defines, SKEY(Match), &vPVal) && + (vPVal != NULL)) + { + long *PVal; + PVal = (long*) vPVal; + + Parm->lvalue |= *PVal; + } + else { + LogTemplateError(NULL, "Define", + Tokens->nParameters, + TP, + "%s isn't known!!", + ChrPtr(Match)); + + } + } + } + } + else { + + + LogTemplateError(NULL, "Define", + Tokens->nParameters, + TP, "%s isn't known!!", Parm->Start); }} @@ -1318,14 +933,16 @@ TemplateParam *GetNextParameter(StrBuf *Buf, /* well, we don't check the mobile stuff here... */ if (!GetHash(LocalTemplateCache, Parm->Start, Parm->len, &vTmpl) && !GetHash(TemplateCache, Parm->Start, Parm->len, &vTmpl)) { - LogTemplateError( - NULL, "SubTemplate", ERR_PARM1, TP, - "referenced here doesn't exist"); + LogTemplateError(NULL, + "SubTemplate", + Tokens->nParameters, + TP, + "referenced here doesn't exist"); }} break; } *pCh = pch; - return Parm; + return 1; } WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf, @@ -1337,7 +954,6 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf, { void *vVar; const char *pch; - TemplateParam *Param; WCTemplateToken *NewToken; WCTemplputParams TP; @@ -1374,8 +990,15 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf, "Warning, Non welformed Token; missing right parenthesis"); } while (pch < pTokenEnd - 1) { - Param = GetNextParameter(Buf, &pch, pTokenEnd - 1, NewToken, pTmpl, &TP); - if (Param != NULL) { + NewToken->nParameters++; + if (GetNextParameter(Buf, + &pch, + pTokenEnd - 1, + NewToken, + pTmpl, + &TP, + &NewToken->Params[NewToken->nParameters - 1])) + { NewToken->HaveParameters = 1; if (NewToken->nParameters > MAXPARAM) { LogTemplateError( @@ -1383,11 +1006,9 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf, "only [%d] Params allowed in Tokens", MAXPARAM); - free(Param); FreeToken(&NewToken); return NULL; } - NewToken->Params[NewToken->nParameters++] = Param; } else break; } @@ -1950,7 +1571,9 @@ int EvaluateToken(StrBuf *Target, int state, WCTemplputParams *TP) } } else { - print_value_of(Target, TP); + LogTemplateError( + Target, "Token UNKNOWN", ERR_NAME, TP, + "You've specified a token that isn't known to webcit.!"); } } return 0; @@ -2087,6 +1710,24 @@ const StrBuf *DoTemplate(const char *templatename, long len, StrBuf *Target, WCT } + +void tmplput_Comment(StrBuf *Target, WCTemplputParams *TP) +{ + if (LoadTemplates != 0) + { + StrBuf *Comment; + const char *pch; + long len; + + GetTemplateTokenString(Target, TP, 0, &pch, &len); + Comment = NewStrBufPlain(pch, len); + StrBufAppendBufPlain(Target, HKEY(""), 0); + FreeStrBuf(&Comment); + } +} + /*----------------------------------------------------------------------------- * Iterators */ @@ -2141,6 +1782,7 @@ int preeval_iterate(WCTemplateToken *Token) WCTemplputParams *TP; void *vTmpl; void *vIt; + HashIterator *It; memset(&TPP, 0, sizeof(WCTemplputParams)); TP = &TPP; @@ -2164,6 +1806,16 @@ int preeval_iterate(WCTemplateToken *Token) "referenced here doesn't exist"); } Token->Preeval2 = vIt; + It = (HashIterator *) vIt; + + if (TP->Tokens->nParameters < It->AdditionalParams + 2) { + LogTemplateError( + NULL, "Iterator", ERR_PARM1, TP, + "doesn't work with %d params", + TP->Tokens->nParameters); + } + + return 1; } @@ -2200,7 +1852,7 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) LogTemplateError( Target, "Iterator", ERR_PARM1, TP, "doesn't work with %d params", - TP->Tokens->nParameters); + TP->Tokens->nParameters - 1); return; } @@ -2208,9 +1860,9 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) (It->XPectContextType != TP->Filter.ContextType)) { LogTemplateError( Target, "Iterator", ERR_PARM1, TP, - "requires context of type %d, have %d", - It->XPectContextType, - TP->Filter.ContextType); + "requires context of type %s, have %s", + ContextName(It->XPectContextType), + ContextName(TP->Filter.ContextType)); return ; } @@ -2358,38 +2010,6 @@ int EvaluateConditional(StrBuf *Target, int Neg, int state, WCTemplputParams *TP return 0; } -int ConditionalVar(StrBuf *Target, WCTemplputParams *TP) -{ - void *vsubst; - wcsubst *subst; - - if (!GetHash(WC->vars, TKEY(2), &vsubst)) - return 0; - subst = (wcsubst*) vsubst; - - switch(subst->wcs_type) { - case WCS_FUNCTION: - return (subst->wcs_function!=NULL); - case WCS_SERVCMD: - lprintf(1, " -> Server [%s]\n", subst->wcs_value);/* TODO */ - return 1; - case WCS_STRING: - case WCS_STRBUF: - case WCS_STRBUF_REF: - if (TP->Tokens->nParameters < 4) - return 1; - return (strcmp(TP->Tokens->Params[3]->Start, ChrPtr(subst->wcs_value)) == 0); - case WCS_LONG: - if (TP->Tokens->nParameters < 4) - return (subst->lvalue != 0); - return (subst->lvalue == TP->Tokens->Params[3]->lvalue); - default: - lprintf(1," WARNING: invalid type: [%ld]!\n", subst->wcs_type); - return -1; - } - return 0; -} - void RegisterConditional(const char *Name, long len, int nParams, WCConditionalFunc CondF, @@ -2556,6 +2176,12 @@ void tmpl_do_boxed(StrBuf *Target, WCTemplputParams *TP) /*----------------------------------------------------------------------------- * Tabbed-API */ + +typedef struct _tab_struct { + long CurrentTab; + StrBuf *TabTitle; +} tab_struct; + int preeval_do_tabbed(WCTemplateToken *Token) { WCTemplputParams TPP; @@ -2623,6 +2249,11 @@ void tmpl_do_tabbed(StrBuf *Target, WCTemplputParams *TP) { StrBuf **TabNames; int i, ntabs, nTabs; + tab_struct TS; + WCTemplputParams SubTP; + + memset(&TS, 0, sizeof(tab_struct)); + memcpy (&SubTP, &TP, sizeof(WCTemplputParams)); nTabs = ntabs = TP->Tokens->nParameters / 2; TabNames = (StrBuf **) malloc(ntabs * sizeof(StrBuf*)); @@ -2649,17 +2280,35 @@ void tmpl_do_tabbed(StrBuf *Target, WCTemplputParams *TP) nTabs --; } } + memcpy (&SubTP, TP, sizeof(WCTemplputParams)); + SubTP.Filter.ControlContextType = CTX_TAB; + SubTP.ControlContext = &TS; StrTabbedDialog(Target, nTabs, TabNames); for (i = 0; i < ntabs; i++) { - StrBeginTab(Target, i, nTabs); - DoTemplate(TKEY(i * 2 + 1), Target, TP); + memset(&TS, 0, sizeof(tab_struct)); + TS.CurrentTab = i; + TS.TabTitle = TabNames[i]; + StrBeginTab(Target, i, nTabs, TabNames); + DoTemplate(TKEY(i * 2 + 1), Target, &SubTP); StrEndTab(Target, i, nTabs); } for (i = 0; i < ntabs; i++) FreeStrBuf(&TabNames[i]); } +void tmplput_TAB_N(StrBuf *Target, WCTemplputParams *TP) +{ + tab_struct *Ctx = CCTX; + + StrBufAppendPrintf(Target, "%d", Ctx->CurrentTab); +} + +void tmplput_TAB_TITLE(StrBuf *Target, WCTemplputParams *TP) +{ + tab_struct *Ctx = CCTX; + StrBufAppendTemplate(Target, TP, Ctx->TabTitle, 0); +} /*----------------------------------------------------------------------------- * Sorting-API @@ -3030,22 +2679,27 @@ InitModule_SUBST (void) { memset(&NoCtx, 0, sizeof(WCTemplputParams)); + RegisterNamespace("--", 0, 2, tmplput_Comment, NULL, CTX_NONE); RegisterNamespace("SORT:ICON", 1, 2, tmplput_SORT_ICON, NULL, CTX_NONE); RegisterNamespace("SORT:ORDER", 1, 2, tmplput_SORT_ORDER, NULL, CTX_NONE); RegisterNamespace("SORT:NEXT", 1, 2, tmplput_SORT_NEXT, NULL, CTX_NONE); RegisterNamespace("CONTEXTSTR", 0, 1, tmplput_ContextString, NULL, CTX_STRBUF); - RegisterNamespace("CONTEXTSTRARR", 1, 2, tmplput_ContextStringArray, NULL, CTX_STRBUF); + RegisterNamespace("CONTEXTSTRARR", 1, 2, tmplput_ContextStringArray, NULL, CTX_STRBUFARR); RegisterNamespace("ITERATE", 2, 100, tmpl_iterate_subtmpl, preeval_iterate, CTX_NONE); RegisterNamespace("DOBOXED", 1, 2, tmpl_do_boxed, NULL, CTX_NONE); RegisterNamespace("DOTABBED", 2, 100, tmpl_do_tabbed, preeval_do_tabbed, CTX_NONE); + RegisterControlNS(HKEY("TAB:N"), 0, 0, tmplput_TAB_N, CTX_TAB); + RegisterControlNS(HKEY("TAB:SUBJECT"), 0, 1, tmplput_TAB_TITLE, CTX_TAB); + + RegisterNamespace("LONGVECTOR", 1, 1, tmplput_long_vector, NULL, CTX_LONGVECTOR); - RegisterConditional(HKEY("COND:SUBST"), 3, ConditionalVar, CTX_NONE); RegisterConditional(HKEY("COND:CONTEXTSTR"), 3, ConditionalContextStr, CTX_STRBUF); RegisterConditional(HKEY("COND:CONTEXTSTRARR"), 4, ConditionalContextStrinArray, CTX_STRBUFARR); RegisterConditional(HKEY("COND:LONGVECTOR"), 4, ConditionalLongVector, CTX_LONGVECTOR); + RegisterControlConditional(HKEY("COND:ITERATE:ISGROUPCHANGE"), 2, conditional_ITERATE_ISGROUPCHANGE, CTX_ITERATE); @@ -3119,14 +2773,13 @@ void SessionAttachModule_SUBST (wcsession *sess) { - sess->vars = NewHash(1,NULL); } void SessionDetachModule_SUBST (wcsession *sess) { - DeleteHash(&sess->vars); + FreeStrBuf(&sess->WFBuf); } void