From 2f1c296e40e5696c014407334a4e714966809b0d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Wed, 14 Jan 2009 23:46:21 +0000 Subject: [PATCH] * add 'control context'; which will carry information from control elements into their own template replacers * abstract context checking * make ITERATE:xxx own template callbacks instead of using SVPUT and friends * replace conditionals in templates leaning on ITERATE:xxx by their native new implementations --- webcit/auth.c | 2 +- webcit/downloads.c | 2 +- webcit/graphics.c | 2 +- webcit/messages.c | 10 +- webcit/msg_renderers.c | 22 +- webcit/netconf.c | 2 +- webcit/notes.c | 2 +- webcit/roomops.c | 6 +- webcit/static/t/json_floor.html | 2 +- webcit/static/t/json_room.html | 3 +- webcit/static/t/section_files_onefile.html | 4 +- webcit/subst.c | 250 +++++++++++++++------ webcit/subst.h | 19 +- webcit/useredit.c | 4 +- 14 files changed, 233 insertions(+), 97 deletions(-) diff --git a/webcit/auth.c b/webcit/auth.c index 364a2c367..082321604 100644 --- a/webcit/auth.c +++ b/webcit/auth.c @@ -793,7 +793,7 @@ void display_changepw(void) Buf = NewStrBufPlain(_("Change your password"), -1); memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_STRBUF; + SubTP.Filter.ContextType = CTX_STRBUF; SubTP.Context = Buf; DoTemplate(HKEY("beginbox"), NULL, &SubTP); diff --git a/webcit/downloads.c b/webcit/downloads.c index b26666744..24276dc98 100644 --- a/webcit/downloads.c +++ b/webcit/downloads.c @@ -210,7 +210,7 @@ HashList* LoadFileList(StrBuf *Target, WCTemplputParams *TP) } Put(Files, SKEY(Entry->Filename), Entry, FreeFiles); } - SubTP.ContextType = CTX_FILELIST; + SubTP.Filter.ContextType = CTX_FILELIST; SortIt = RetrieveSort(&SubTP, NULL, 0, HKEY("fileunsorted"), 0); if (SortIt != NULL) SortByPayload(Files, SortIt); diff --git a/webcit/graphics.c b/webcit/graphics.c index ba879dc35..361c19752 100644 --- a/webcit/graphics.c +++ b/webcit/graphics.c @@ -28,7 +28,7 @@ void display_graphics_upload(char *description, char *filename, char *uplurl) Buf = NewStrBufPlain(_("Image upload"), -1); memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_STRBUF; + SubTP.Filter.ContextType = CTX_STRBUF; SubTP.Context = Buf; DoTemplate(HKEY("beginbox"), NULL, &SubTP); diff --git a/webcit/messages.c b/webcit/messages.c index 242262945..015e36187 100644 --- a/webcit/messages.c +++ b/webcit/messages.c @@ -235,7 +235,7 @@ int read_message(StrBuf *Target, const char *tmpl, long tmpllen, long msgnum, in } DeleteHashPos(&it); memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_MAILSUM; + SubTP.Filter.ContextType = CTX_MAILSUM; SubTP.Context = Msg; DoTemplate(tmpl, tmpllen, Target, &SubTP); @@ -511,7 +511,7 @@ long DrawMessageDropdown(StrBuf *Selector, long maxmsgs, long startmsg, int nMes WCTemplputParams SubTP; memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_LONGVECTOR; + SubTP.Filter.ContextType = CTX_LONGVECTOR; SubTP.Context = &vector; TmpBuf = NewStrBuf(); At = GetNewHashPos(WCC->summ, nMessages); @@ -761,7 +761,7 @@ void readloop(long oper) if (sortit) { CompareFunc SortIt; memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_NONE; + SubTP.Filter.ContextType = CTX_NONE; SubTP.Context = NULL; SortIt = RetrieveSort(&SubTP, NULL, 0, HKEY("date"), defaultsortorder); @@ -800,7 +800,7 @@ void readloop(long oper) } memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_STRBUF; + SubTP.Filter.ContextType = CTX_STRBUF; SubTP.Context = MessageDropdown; DoTemplate(HKEY("msg_listselector_top"), BBViewToolBar, &SubTP); StrBufAppendBuf(WCC->WBuf, BBViewToolBar, 0); @@ -890,7 +890,7 @@ void readloop(long oper) displayed_msgs = NULL; } memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_STRBUF; + SubTP.Filter.ContextType = CTX_STRBUF; SubTP.Context = MessageDropdown; DoTemplate(HKEY("msg_listselector_bottom"), BBViewToolBar, &SubTP); StrBufAppendBuf(WCC->WBuf, BBViewToolBar, 0); diff --git a/webcit/msg_renderers.c b/webcit/msg_renderers.c index 22eace1db..d3b896f60 100644 --- a/webcit/msg_renderers.c +++ b/webcit/msg_renderers.c @@ -410,25 +410,29 @@ int Conditional_ROOM_DISPLAY_MSG(StrBuf *Target, WCTemplputParams *TP) { wcsubst *subst; wcsession *WCC = WC; - GetHash(WCC->vars, HKEY("ITERATE:N"), (void *)&subst); - num_inset = subst->lvalue; - if ((num_inset >= WC->startmsg) && (WCC->num_displayed <= WCC->maxmsgs)) { - WCC->num_displayed = WCC->num_displayed+1; - return 1; /* Pass GO, collect $200 */ - } + if (GetHash(WCC->vars, HKEY("ITERATE:N"), (void *)&subst) && + (subst != NULL)) { + num_inset = subst->lvalue; + if ((num_inset >= WC->startmsg) && (WCC->num_displayed <= WCC->maxmsgs)) { + WCC->num_displayed = WCC->num_displayed+1; + return 1; /* Pass GO, collect $200 */ + } + } return 0; } int Conditional_MAIL_SUMM_LASTMSG(StrBuf *Target, WCTemplputParams *TP) { wcsubst *nsubst; - long is_last_n; + long is_last_n = 0; - GetHash(WC->vars, HKEY("ITERATE:LASTN"), (void *)&nsubst); - is_last_n = nsubst->lvalue; + if (GetHash(WC->vars, HKEY("ITERATE:LASTN"), (void *)&nsubst) && + (nsubst != NULL)) { + is_last_n = nsubst->lvalue; /* //GetHash(WC->vars, HKEY("ITERATE:N"), (void *)&n_dsubst); //num_inset = n_dsubst->lvalue; */ /* Is the num_displayed higher than maxmsgs? OR last in iterator */ + } return ((WC->num_displayed > WC->maxmsgs) || (is_last_n == 1)); } void examine_time(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) diff --git a/webcit/netconf.c b/webcit/netconf.c index 5f9087228..c8add9311 100644 --- a/webcit/netconf.c +++ b/webcit/netconf.c @@ -206,7 +206,7 @@ void display_edit_node(void) memset(&SubTP, 0, sizeof(WCTemplputParams)); SVPutBuf("ITERATE:KEY", Index, 1); - SubTP.ContextType = CTX_NODECONF; + SubTP.Filter.ContextType = CTX_NODECONF; SubTP.Context = vNode; begin_burst(); Tmpl = sbstr("template"); diff --git a/webcit/notes.c b/webcit/notes.c index d55fd2f81..9e00be85f 100644 --- a/webcit/notes.c +++ b/webcit/notes.c @@ -342,7 +342,7 @@ void display_note(message_summary *Msg, int unread) { WCTemplputParams TP; memset(&TP, 0, sizeof(WCTemplputParams)); - TP.ContextType = CTX_VNOTE; + TP.Filter.ContextType = CTX_VNOTE; v = vnote_new_from_msg(Msg->msgnum); if (v) { // display_vnote_div(v); diff --git a/webcit/roomops.c b/webcit/roomops.c index c2b6ad9da..c180b529d 100644 --- a/webcit/roomops.c +++ b/webcit/roomops.c @@ -278,7 +278,7 @@ void zapped_list(void) output_headers(1, 1, 1, 0, 0, 0); memset(&SubTP, 0, sizeof(WCTemplputParams)); Buf = NewStrBufPlain(_("Zapped (forgotten) rooms"), -1); - SubTP.ContextType = CTX_STRBUF; + SubTP.Filter.ContextType = CTX_STRBUF; SubTP.Context = Buf; DoTemplate(HKEY("beginbox"), NULL, &SubTP); @@ -2705,7 +2705,7 @@ void display_private(char *rname, int req_pass) Buf = NewStrBufPlain(_("Go to a hidden room"), -1); memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_STRBUF; + SubTP.Filter.ContextType = CTX_STRBUF; SubTP.Context = Buf; DoTemplate(HKEY("beginbox"), NULL, &SubTP); @@ -3222,7 +3222,7 @@ void do_rooms_view(struct folder *fold, int max_folders, int num_floors) { Buf = NewStrBufPlain(floor_name, -1); memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_STRBUF; + SubTP.Filter.ContextType = CTX_STRBUF; SubTP.Context = Buf; DoTemplate(HKEY("beginbox"), NULL, &SubTP); diff --git a/webcit/static/t/json_floor.html b/webcit/static/t/json_floor.html index 2c0790150..50d9853eb 100644 --- a/webcit/static/t/json_floor.html +++ b/webcit/static/t/json_floor.html @@ -1 +1 @@ -[, "", ] , \ No newline at end of file +[, "", ] , diff --git a/webcit/static/t/json_room.html b/webcit/static/t/json_room.html index 424501547..4ac6ff3ba 100644 --- a/webcit/static/t/json_room.html +++ b/webcit/static/t/json_room.html @@ -1,2 +1 @@ -["", , , ,, , , ] , \ No newline at end of file +["", , , ,, , , ] , diff --git a/webcit/static/t/section_files_onefile.html b/webcit/static/t/section_files_onefile.html index 76d052135..3beb8d4dd 100644 --- a/webcit/static/t/section_files_onefile.html +++ b/webcit/static/t/section_files_onefile.html @@ -1,4 +1,4 @@ - + @@ -13,7 +13,7 @@ - +
diff --git a/webcit/subst.c b/webcit/subst.c index 215527a61..3a52342de 100644 --- a/webcit/subst.c +++ b/webcit/subst.c @@ -51,9 +51,8 @@ typedef struct _WCTemplate { } WCTemplate; typedef struct _HashHandler { - int nMinArgs; - int nMaxArgs; - int ContextRequired; + ContextFilter Filter; + WCHandlerFunc HandlerFunc; }HashHandler; @@ -70,6 +69,28 @@ typedef struct _SortStruct { long ContextType; }SortStruct; +const char *CtxNames[] = { + "Context NONE", + "Context SITECFG", + "Context SESSION", + "Context INETCFG", + "Context VNOTE", + "Context WHO", + "Context PREF", + "Context NODECONF", + "Context USERLIST", + "Context MAILSUM", + "Context MIME_ATACH", + "Context FILELIST", + "Context STRBUF", + "Context LONGVECTOR", + "Context ROOMS", + "Context FLOORS", + "Context ITERATE" +}; + + + void DestroySortStruct(void *vSort) { SortStruct *Sort = (SortStruct*) vSort; @@ -135,13 +156,76 @@ void RegisterNS(const char *NSName, HashHandler *NewHandler; NewHandler = (HashHandler*) malloc(sizeof(HashHandler)); - NewHandler->nMinArgs = nMinArgs; - NewHandler->nMaxArgs = nMaxArgs; + NewHandler->Filter.nMinArgs = nMinArgs; + NewHandler->Filter.nMaxArgs = nMaxArgs; + NewHandler->Filter.ContextType = ContextRequired; + NewHandler->Filter.ControlContextType = CTX_NONE; + NewHandler->HandlerFunc = HandlerFunc; - NewHandler->ContextRequired = ContextRequired; Put(GlobalNS, NSName, len, NewHandler, NULL); } +void RegisterControlNS(const char *NSName, + long len, + int nMinArgs, + int nMaxArgs, + WCHandlerFunc HandlerFunc, + int ControlContextRequired) +{ + HashHandler *NewHandler; + + NewHandler = (HashHandler*) malloc(sizeof(HashHandler)); + NewHandler->Filter.nMinArgs = nMinArgs; + NewHandler->Filter.nMaxArgs = nMaxArgs; + NewHandler->Filter.ContextType = CTX_NONE; + NewHandler->Filter.ControlContextType = ControlContextRequired; + NewHandler->HandlerFunc = HandlerFunc; + Put(GlobalNS, NSName, len, NewHandler, NULL); +} + + + +int CheckContext(StrBuf *Target, ContextFilter *Need, WCTemplputParams *TP, const char *ErrType) +{ + if ((Need->ContextType != CTX_NONE) && + (Need->ContextType != TP->Filter.ContextType)) { + LogTemplateError( + Target, ErrType, ERR_PARM1, TP, + " WARNING: requires Context: [%s], have [%s]!", + CtxNames[Need->ContextType], + CtxNames[TP->Filter.ContextType]); + return 0; + } + + if ((Need->ControlContextType != CTX_NONE) && + (Need->ControlContextType != TP->Filter.ControlContextType)) { + LogTemplateError( + Target, ErrType, ERR_PARM1, TP, + " WARNING: requires Control Context: [%s], have [%s]!", + CtxNames[Need->ControlContextType], + CtxNames[TP->Filter.ControlContextType]); + 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", + TP->Tokens->nParameters, + Need->nMaxArgs); + return 0; + + } + return 1; +} + void FreeToken(WCTemplateToken **Token) { int i; @@ -573,7 +657,7 @@ void GetTemplateTokenString(WCTemplputParams *TP, case TYPE_SUBTEMPLATE: memset(&SubTP, 0, sizeof(WCTemplputParams *)); SubTP.Context = TP->Context; - SubTP.ContextType = TP->ContextType; + SubTP.Filter.ContextType = TP->Filter.ContextType; Buf = NewStrBuf(); DoTemplate(TKEY(N), Buf, &SubTP); *Value = ChrPtr(Buf); @@ -1000,8 +1084,8 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf, if (GetHash(GlobalNS, NewToken->pName, NewToken->NameEnd, &vVar)) { HashHandler *Handler; Handler = (HashHandler*) vVar; - if ((NewToken->nParameters < Handler->nMinArgs) || - (NewToken->nParameters > Handler->nMaxArgs)) { + if ((NewToken->nParameters < Handler->Filter.nMinArgs) || + (NewToken->nParameters > Handler->Filter.nMaxArgs)) { LogTemplateError( NULL, "Token", ERR_NAME, &TP, "doesn't work with %ld params", @@ -1286,6 +1370,7 @@ int EvaluateToken(StrBuf *Target, int state, WCTemplputParams *TP) long AppendMeLen; HashHandler *Handler; void *vVar; + /* much output, since pName is not terminated... lprintf(1,"Doing token: %s\n",Token->pName); */ @@ -1325,43 +1410,21 @@ int EvaluateToken(StrBuf *Target, int state, WCTemplputParams *TP) break; case SV_SUBTEMPL: if (TP->Tokens->nParameters == 1) - DoTemplate(TKEY(0), NULL, TP); + DoTemplate(TKEY(0), Target, TP); break; case SV_PREEVALUATED: Handler = (HashHandler*) TP->Tokens->PreEval; - if ((Handler->ContextRequired != CTX_NONE) && - (Handler->ContextRequired != TP->ContextType)) { - LogTemplateError( - Target, "Token", ERR_NAME, TP, - "requires context of type %ld, have %ld", - Handler->ContextRequired, - TP->ContextType); + if (!CheckContext(Target, &Handler->Filter, TP, "Token")) { return -1; - } Handler->HandlerFunc(Target, TP); break; default: if (GetHash(GlobalNS, TP->Tokens->pName, TP->Tokens->NameEnd, &vVar)) { Handler = (HashHandler*) vVar; - if ((Handler->ContextRequired != CTX_NONE) && - (Handler->ContextRequired != TP->ContextType)) { - LogTemplateError( - Target, "Token", ERR_NAME, TP, - "requires context of type %ld, have %ld", - Handler->ContextRequired, - TP->ContextType); + if (!CheckContext(Target, &Handler->Filter, TP, "Token")) { return -1; } - else if ((TP->Tokens->nParameters < Handler->nMinArgs) || - (TP->Tokens->nParameters > Handler->nMaxArgs)) { - LogTemplateError( - Target, "Token", ERR_NAME, TP, - "doesn't work with %ld params need > %ld < %ld", - TP->Tokens->nParameters, - Handler->nMaxArgs, - Handler->nMinArgs); - } else { Handler->HandlerFunc(Target, TP); } @@ -1385,7 +1448,7 @@ void ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, void *Context, int Contex WCTemplputParams TP; TP.Context = Context; - TP.ContextType = ContextType; + TP.Filter.ContextType = ContextType; if (LoadTemplates != 0) { if (LoadTemplates > 1) @@ -1489,7 +1552,7 @@ void DoTemplate(const char *templatename, long len, StrBuf *Target, WCTemplputPa } if (vTmpl == NULL) return; - ProcessTemplate(vTmpl, Target, TP->Context, TP->ContextType); + ProcessTemplate(vTmpl, Target, TP->Context, TP->Filter.ContextType); } /*----------------------------------------------------------------------------- @@ -1528,6 +1591,15 @@ void RegisterITERATOR(const char *Name, long len, Put(Iterators, Name, len, It, NULL); } +typedef struct _iteratestruct { + int GroupChange; + int oddeven; + const char *Key; + long KeyLen; + int n; + int LastN; +}IterateStruct; + void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) { void *vIt; @@ -1538,15 +1610,13 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) void *vSortBy; int DetectGroupChange = 0; int nMembersUsed; - int nMembersCounted = 0; - long len; - const char *Key; void *vContext; void *vLastContext = NULL; StrBuf *SubBuf; - int oddeven = 0; WCTemplputParams SubTP; + IterateStruct Status; + memset(&Status, 0, sizeof(IterateStruct)); memcpy (&SubTP, &TP, sizeof(WCTemplputParams)); if (!GetHash(Iterators, TKEY(0), &vIt)) { @@ -1566,12 +1636,12 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) } if ((It->XPectContextType != CTX_NONE) && - (It->XPectContextType != TP->ContextType)) { + (It->XPectContextType != TP->Filter.ContextType)) { LogTemplateError( Target, "Iterator", ERR_PARM1, TP, "requires context of type %ld, have %ld", It->XPectContextType, - TP->ContextType); + TP->Filter.ContextType); return ; } @@ -1602,20 +1672,15 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) } nMembersUsed = GetCount(List); SubBuf = NewStrBuf(); - SubTP.ContextType = It->ContextType; + SubTP.Filter.ContextType = It->ContextType; + SubTP.Filter.ControlContextType = CTX_ITERATE; + SubTP.ControlContext = &Status; it = GetNewHashPos(List, 0); - while (GetNextHashPos(List, it, &len, &Key, &vContext)) { - if (DetectGroupChange && nMembersCounted > 0) { - if (SortBy->GroupChange(vContext, vLastContext)) - svputlong("ITERATE:ISGROUPCHANGE", 1); - else - svputlong("ITERATE:ISGROUPCHANGE", 0); + while (GetNextHashPos(List, it, &Status.KeyLen, &Status.Key, &vContext)) { + if (DetectGroupChange && Status.n > 0) { + Status.GroupChange = (SortBy->GroupChange(vContext, vLastContext))? 1:0; } - svprintf(HKEY("ITERATE:ODDEVEN"), WCS_STRING, "%s", - (oddeven) ? "odd" : "even"); - svprintf(HKEY("ITERATE:KEY"), WCS_STRING, "%s", Key); - svputlong("ITERATE:N", nMembersCounted); - svputlong("ITERATE:LASTN", ++nMembersCounted == nMembersUsed); + Status.LastN = ++Status.LastN == nMembersUsed; SubTP.Context = vContext; if (It->DoSubTemplate != NULL) It->DoSubTemplate(SubBuf, &SubTP); @@ -1623,7 +1688,7 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) StrBufAppendBuf(Target, SubBuf, 0); FlushStrBuf(SubBuf); - oddeven = ~ oddeven; + Status.oddeven = ! Status.oddeven; vLastContext = vContext; } FreeStrBuf(&SubBuf); @@ -1633,6 +1698,43 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP) } +int conditional_ITERATE_ISGROUPCHANGE(StrBuf *Target, WCTemplputParams *TP) +{ + IterateStruct *Ctx = CCTX; + return Ctx->GroupChange; +} + +void tmplput_ITERATE_ODDEVEN(StrBuf *Target, WCTemplputParams *TP) +{ + IterateStruct *Ctx = CCTX; + if (Ctx->oddeven) + StrBufAppendBufPlain(Target, HKEY("odd"), 0); + else + StrBufAppendBufPlain(Target, HKEY("even"), 0); +} + + +void tmplput_ITERATE_KEY(StrBuf *Target, WCTemplputParams *TP) +{ + IterateStruct *Ctx = CCTX; + + StrBufAppendBufPlain(Target, Ctx->Key, Ctx->KeyLen, 0); +} + + +void tmplput_ITERATE_LASTN(StrBuf *Target, WCTemplputParams *TP) +{ + IterateStruct *Ctx = CCTX; + StrBufAppendPrintf(Target, "%d", Ctx->n); +} + +int conditional_ITERATE_LASTN(StrBuf *Target, WCTemplputParams *TP) +{ + IterateStruct *Ctx = CCTX; + return Ctx->LastN; +} + + /*----------------------------------------------------------------------------- * Conditionals @@ -1674,12 +1776,8 @@ int ConditionalVar(StrBuf *Target, WCTemplputParams *TP) if (!GetHash(WC->vars, TKEY(2), &vsubst)) return 0; subst = (wcsubst*) vsubst; - if ((subst->ContextRequired != CTX_NONE) && - (subst->ContextRequired != TP->ContextType)) { - LogTemplateError( - Target, "ConditionalVar", ERR_PARM1, TP, - " WARNING: Conditional requires Context: [%ld], have [%ld]!", - subst->ContextRequired, CTX); + + if (!CheckContext(Target, &subst->Filter, TP, "Conditional")) { return -1; } @@ -1706,7 +1804,6 @@ int ConditionalVar(StrBuf *Target, WCTemplputParams *TP) return 0; } - void RegisterConditional(const char *Name, long len, int nParams, WCConditionalFunc CondF, @@ -1716,7 +1813,22 @@ void RegisterConditional(const char *Name, long len, Cond->PlainName = Name; Cond->nParams = nParams; Cond->CondF = CondF; - Cond->ContextRequired = ContextRequired; + Cond->Filter.ContextType = ContextRequired; + Cond->Filter.ControlContextType = CTX_NONE; + Put(Conditionals, Name, len, Cond, NULL); +} + +void RegisterControlConditional(const char *Name, long len, + int nParams, + WCConditionalFunc CondF, + int ControlContextRequired) +{ + ConditionalStruct *Cond = (ConditionalStruct*)malloc(sizeof(ConditionalStruct)); + Cond->PlainName = Name; + Cond->nParams = nParams; + Cond->CondF = CondF; + Cond->Filter.ContextType = CTX_NONE; + Cond->Filter.ControlContextType = ControlContextRequired; Put(Conditionals, Name, len, Cond, NULL); } @@ -1763,7 +1875,7 @@ void tmpl_do_boxed(StrBuf *Target, WCTemplputParams *TP) } memcpy (&SubTP, TP, sizeof(WCTemplputParams)); SubTP.Context = Headline; - SubTP.ContextType = CTX_STRBUF; + SubTP.Filter.ContextType = CTX_STRBUF; DoTemplate(HKEY("beginbox"), Target, &SubTP); DoTemplate(TKEY(0), Target, TP); DoTemplate(HKEY("endbox"), Target, TP); @@ -2175,6 +2287,16 @@ InitModule_SUBST RegisterConditional(HKEY("COND:SUBST"), 3, ConditionalVar, CTX_NONE); RegisterConditional(HKEY("COND:CONTEXTSTR"), 3, ConditionalContextStr, CTX_STRBUF); RegisterConditional(HKEY("COND:LONGVECTOR"), 4, ConditionalLongVector, CTX_LONGVECTOR); + + RegisterControlConditional(HKEY("COND:ITERATE:ISGROUPCHANGE"), 2, + conditional_ITERATE_ISGROUPCHANGE, + CTX_ITERATE); + RegisterControlConditional(HKEY("COND:ITERATE:LASTN"), 2, + conditional_ITERATE_LASTN, + CTX_ITERATE); + RegisterControlNS(HKEY("ITERATE:ODDEVEN"), 0, 0, tmplput_ITERATE_ODDEVEN, CTX_ITERATE); + RegisterControlNS(HKEY("ITERATE:KEY"), 0, 0, tmplput_ITERATE_KEY, CTX_ITERATE); + RegisterControlNS(HKEY("ITERATE:N"), 0, 0, tmplput_ITERATE_LASTN, CTX_ITERATE); } /*@}*/ diff --git a/webcit/subst.h b/webcit/subst.h index 4a488404e..b39ba22dd 100644 --- a/webcit/subst.h +++ b/webcit/subst.h @@ -30,6 +30,14 @@ enum { WCS_LONG /* its an integer */ }; +typedef struct _contexts { + int ContextType; /* do we require a context type? */ + int ControlContextType; + int nMinArgs; + int nMaxArgs; +} ContextFilter; + + typedef struct WCTemplateToken WCTemplateToken; typedef struct WCTemplputParams WCTemplputParams; typedef void (*WCHandlerFunc)(StrBuf *Target, WCTemplputParams *TP); @@ -67,25 +75,27 @@ struct WCTemplateToken { * \brief Dynamic content for variable substitution in templates */ typedef struct _wcsubst { + ContextFilter Filter; int wcs_type; /* which type of Substitution are we */ char wcs_key[32]; /* copy of our hashkey for debugging */ StrBuf *wcs_value; /* if we're a string, keep it here */ long lvalue; /* type long? keep data here */ - int ContextRequired; /* do we require a context type? */ WCHandlerFunc wcs_function; /* funcion hook ???*/ } wcsubst; struct WCTemplputParams { + ContextFilter Filter; + void *Context; + void *ControlContext; int nArgs; WCTemplateToken *Tokens; - void *Context; - int ContextType; }; extern WCTemplputParams NoCtx; #define CTX TP->Context +#define CCTX TP->ControlContext @@ -105,6 +115,7 @@ extern WCTemplputParams NoCtx; #define CTX_LONGVECTOR 13 #define CTX_ROOMS 14 #define CTX_FLOORS 15 +#define CTX_ITERATE 16 void RegisterNS(const char *NSName, long len, int nMinArgs, @@ -115,9 +126,9 @@ void RegisterNS(const char *NSName, long len, typedef int (*WCConditionalFunc)(StrBuf *Target, WCTemplputParams *TP); typedef struct _ConditionalStruct { + ContextFilter Filter; const char *PlainName; int nParams; - int ContextRequired; WCConditionalFunc CondF; } ConditionalStruct; void RegisterConditional(const char *Name, long len, diff --git a/webcit/useredit.c b/webcit/useredit.c index 37320a55d..42cac326b 100644 --- a/webcit/useredit.c +++ b/webcit/useredit.c @@ -267,7 +267,7 @@ HashList *iterate_load_userlist(StrBuf *Target, WCTemplputParams *TP) Put(Hash, nnn, nUsed, ul, DeleteUserListEntry); } FreeStrBuf(&Buf); - SubTP.ContextType = CTX_USERLIST; + SubTP.Filter.ContextType = CTX_USERLIST; SortIt = RetrieveSort(&SubTP, HKEY("USER"), HKEY("user:uid"), 0); if (SortIt != NULL) SortByPayload(Hash, SortIt); @@ -529,7 +529,7 @@ void display_edituser(char *supplied_username, int is_new) { else { WCTemplputParams SubTP; memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_USERLIST; + SubTP.Filter.ContextType = CTX_USERLIST; SubTP.Context = UL; output_headers(1, 0, 0, 0, 1, 0); DoTemplate(HKEY("userlist_detailview"), NULL, &SubTP); -- 2.30.2