HashList *GlobalNS;
HashList *Iterators;
HashList *Conditionals;
+HashList *SortHash;
int LoadTemplates = 0;
}HashHandler;
void *load_template(StrBuf *filename, StrBuf *Key, HashList *PutThere);
+int EvaluateConditional(StrBuf *Target, WCTemplateToken *Tokens, WCTemplate *pTmpl, void *Context, int Neg, int state, int ContextType);
void RegisterNS(const char *NSName,
long len,
}
}
-
-/**
- * \brief puts string into the template and computes which escape methon we should use
- * \param Source the string we should put into the template
- * \param FormatTypeIndex where should we look for escape types if?
- */
-void StrBufAppendTemplate(StrBuf *Target,
- int nArgs,
- WCTemplateToken *Tokens,
- void *Context, int ContextType,
- const StrBuf *Source, int FormatTypeIndex)
-{
- struct wcsession *WCC;
- StrBuf *Buf;
- char EscapeAs = ' ';
-
- if ((FormatTypeIndex < Tokens->nParameters) &&
- (Tokens->Params[FormatTypeIndex]->Type == TYPE_STR) &&
- (Tokens->Params[FormatTypeIndex]->len == 1)) {
- EscapeAs = *Tokens->Params[FormatTypeIndex]->Start;
- }
-
- switch(EscapeAs)
- {
- case 'H':
- WCC = WC;
- Buf = NewStrBufPlain(NULL, StrLength(Source));
- StrBuf_RFC822_to_Utf8(Buf,
- Source,
- (WCC!=NULL)? WCC->DefaultCharset : NULL,
- NULL);
- StrEscAppend(Target, Buf, NULL, 0, 0);
- FreeStrBuf(&Buf);
- break;
- case 'X':
- StrEscAppend(Target, Source, NULL, 0, 0);
- break;
- default:
- StrBufAppendBuf(Target, Source, 0);
- }
-}
-
-
void GetTemplateTokenString(WCTemplateToken *Tokens,
int N,
const char **Value,
}
+
+/**
+ * \brief puts string into the template and computes which escape methon we should use
+ * \param Source the string we should put into the template
+ * \param FormatTypeIndex where should we look for escape types if?
+ */
+void StrBufAppendTemplate(StrBuf *Target,
+ int nArgs,
+ WCTemplateToken *Tokens,
+ void *Context, int ContextType,
+ const StrBuf *Source, int FormatTypeIndex)
+{
+ struct wcsession *WCC;
+ StrBuf *Buf;
+ char EscapeAs = ' ';
+
+ if ((FormatTypeIndex < Tokens->nParameters) &&
+ (Tokens->Params[FormatTypeIndex]->Type == TYPE_STR) &&
+ (Tokens->Params[FormatTypeIndex]->len == 1)) {
+ EscapeAs = *Tokens->Params[FormatTypeIndex]->Start;
+ }
+
+ switch(EscapeAs)
+ {
+ case 'H':
+ WCC = WC;
+ Buf = NewStrBufPlain(NULL, StrLength(Source));
+ StrBuf_RFC822_to_Utf8(Buf,
+ Source,
+ (WCC!=NULL)? WCC->DefaultCharset : NULL,
+ NULL);
+ StrEscAppend(Target, Buf, NULL, 0, 0);
+ FreeStrBuf(&Buf);
+ break;
+ case 'X':
+ StrEscAppend(Target, Source, NULL, 0, 0);
+ break;
+ default:
+ StrBufAppendBuf(Target, Source, 0);
+ }
+}
+
+
void PutNewToken(WCTemplate *Template, WCTemplateToken *NewToken)
{
if (Template->nTokensUsed + 1 >= Template->TokenSpace) {
-int EvaluateConditional(StrBuf *Target, WCTemplateToken *Tokens, WCTemplate *pTmpl, void *Context, int Neg, int state, int ContextType)
-{
- ConditionalStruct *Cond;
- if ((Tokens->Params[0]->len == 1) &&
- (Tokens->Params[0]->Start[0] == 'X'))
- return (state != 0)?Tokens->Params[1]->lvalue:0;
-
- Cond = (ConditionalStruct *) Tokens->PreEval;
- if (Cond == NULL) {
- lprintf(1, "Conditional [%s] (in '%s' line %ld); unknown![%s]\n",
- Tokens->Params[0]->Start,
- ChrPtr(pTmpl->FileName),
- Tokens->Line,
- ChrPtr(Tokens->FlatToken));
- return 1;
- }
- if (Tokens->nParameters < Cond->nParams) {
- lprintf(1, "Conditional [%s] (in '%s' line %ld); needs %ld Params![%s]\n",
- Tokens->Params[0]->Start,
- ChrPtr(pTmpl->FileName),
- Tokens->Line,
- Cond->nParams,
- ChrPtr(Tokens->FlatToken));
- StrBufAppendPrintf(
- Target,
- "<pre>\nConditional [%s] (in '%s' line %ld); needs %ld Params!\n[%s]\n</pre>\n",
- Tokens->Params[0]->Start,
- ChrPtr(pTmpl->FileName),
- Tokens->Line,
- Cond->nParams,
- ChrPtr(Tokens->FlatToken));
- return 0;
- }
- if (Cond->CondF(Tokens, Context, ContextType) == Neg)
- return Tokens->Params[1]->lvalue;
- return 0;
+/**
+ * \brief Display a variable-substituted template
+ * \param templatename template file to load
+ */
+void *prepare_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
+{
+ WCTemplate *NewTemplate;
+ NewTemplate = (WCTemplate *) malloc(sizeof(WCTemplate));
+ NewTemplate->Data = NULL;
+ NewTemplate->FileName = NewStrBufDup(filename);
+ NewTemplate->nTokensUsed = 0;
+ NewTemplate->TokenSpace = 0;
+ NewTemplate->Tokens = NULL;
+
+ Put(PutThere, ChrPtr(Key), StrLength(Key), NewTemplate, FreeWCTemplate);
+ return NewTemplate;
}
/**
- * \brief executes one token
- * \param Target buffer to append to
- * \param Token da to process.
- * \param Template we're iterating
- * \param Context Contextpoointer to pass in
- * \param state are we in conditional state?
- * \param ContextType what type of information does context giv us?
+ * \brief Display a variable-substituted template
+ * \param templatename template file to load
*/
-int EvaluateToken(StrBuf *Target, WCTemplateToken *Tokens, WCTemplate *pTmpl, void *Context, int state, int ContextType)
+void *load_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
{
- HashHandler *Handler;
- void *vVar;
-// much output, since pName is not terminated...
-// lprintf(1,"Doing token: %s\n",Token->pName);
+ int fd;
+ struct stat statbuf;
+ const char *pS, *pE, *pch, *Err;
+ long Line;
+ int pos;
+ WCTemplate *NewTemplate;
- switch (Tokens->Flags) {
- case SV_GETTEXT:
- TmplGettext(Target, Tokens->nParameters, Tokens);
- break;
- case SV_CONDITIONAL: /** Forward conditional evaluation */
- return EvaluateConditional(Target, Tokens, pTmpl, Context, 1, state, ContextType);
- break;
- case SV_NEG_CONDITIONAL: /** Reverse conditional evaluation */
- return EvaluateConditional(Target, Tokens, pTmpl, Context, 0, state, ContextType);
- break;
- case SV_CUST_STR_CONDITIONAL: /** Conditional put custom strings from params */
- if (Tokens->nParameters >= 6) {
- if (EvaluateConditional(Target, Tokens, pTmpl, Context, 0, state, ContextType))
- StrBufAppendBufPlain(Target,
- Tokens->Params[5]->Start,
- Tokens->Params[5]->len,
- 0);
- else
- StrBufAppendBufPlain(Target,
- Tokens->Params[4]->Start,
- Tokens->Params[4]->len,
- 0);
+ fd = open(ChrPtr(filename), O_RDONLY);
+ if (fd <= 0) {
+ lprintf(1, "ERROR: could not open template '%s' - %s\n",
+ ChrPtr(filename), strerror(errno));
+ return NULL;
+ }
+
+ if (fstat(fd, &statbuf) == -1) {
+ lprintf(1, "ERROR: could not stat template '%s' - %s\n",
+ ChrPtr(filename), strerror(errno));
+ return NULL;
+ }
+
+ NewTemplate = (WCTemplate *) malloc(sizeof(WCTemplate));
+ NewTemplate->Data = NewStrBufPlain(NULL, statbuf.st_size);
+ NewTemplate->FileName = NewStrBufDup(filename);
+ NewTemplate->nTokensUsed = 0;
+ NewTemplate->TokenSpace = 0;
+ NewTemplate->Tokens = NULL;
+ if (StrBufReadBLOB(NewTemplate->Data, &fd, 1, statbuf.st_size, &Err) < 0) {
+ close(fd);
+ FreeWCTemplate(NewTemplate);
+ lprintf(1, "ERROR: reading template '%s' - %s<br />\n",
+ ChrPtr(filename), strerror(errno));
+ return NULL;
+ }
+ close(fd);
+
+ Line = 0;
+ pS = pch = ChrPtr(NewTemplate->Data);
+ pE = pS + StrLength(NewTemplate->Data);
+ while (pch < pE) {
+ const char *pts, *pte;
+ int InQuotes = 0;
+ int InDoubleQuotes = 0;
+
+ /** Find one <? > */
+ pos = (-1);
+ for (; pch < pE; pch ++) {
+ if ((*pch=='<')&&(*(pch + 1)=='?'))
+ break;
+ if (*pch=='\n') Line ++;
}
- else {
- lprintf(1, "Conditional [%s] (in '%s' line %ld); needs at least 6 Params![%s]\n",
- Tokens->Params[0]->Start,
- ChrPtr(pTmpl->FileName),
- Tokens->Line,
- ChrPtr(Tokens->FlatToken));
- StrBufAppendPrintf(
- Target,
- "<pre>\nConditional [%s] (in '%s' line %ld); needs 6 Params!\n[%s]\n</pre>\n",
- Tokens->Params[0]->Start,
- ChrPtr(pTmpl->FileName),
- Tokens->Line,
- ChrPtr(Tokens->FlatToken));
+ if (pch >= pE)
+ continue;
+ pts = pch;
+
+ /** Found one? parse it. */
+ for (; pch < pE - 1; pch ++) {
+ if (*pch == '"')
+ InDoubleQuotes = ! InDoubleQuotes;
+ else if (*pch == '\'')
+ InQuotes = ! InQuotes;
+ else if ((!InQuotes && !InDoubleQuotes) &&
+ ((*pch!='\\')&&(*(pch + 1)=='>'))) {
+ pch ++;
+ break;
+ }
}
- break;
- case SV_SUBTEMPL:
- if (Tokens->nParameters == 1)
- DoTemplate(Tokens->Params[0]->Start, Tokens->Params[0]->len, NULL, NULL, ContextType);
- break;
+ if (pch + 1 >= pE)
+ continue;
+ pte = pch;
+ PutNewToken(NewTemplate,
+ NewTemplateSubstitute(NewTemplate->Data, pS, pts, pte, Line, NewTemplate));
+ pch ++;
+ }
+ if (LoadTemplates == 0)
+ Put(PutThere, ChrPtr(Key), StrLength(Key), NewTemplate, FreeWCTemplate);
+ return NewTemplate;
+}
+
+
+///void PrintTemplate(const char *Key, void *vSubst, int odd)
+const char* PrintTemplate(void *vSubst)
+{
+ WCTemplate *Tmpl = vSubst;
+
+ return ChrPtr(Tmpl->FileName);
+
+}
+
+int LoadTemplateDir(const char *DirName, HashList *wireless, HashList *big)
+{
+ StrBuf *FileName;
+ StrBuf *Tag;
+ StrBuf *Dir;
+ DIR *filedir = NULL;
+ struct dirent *filedir_entry;
+ int d_namelen;
+ int d_without_ext;
+ int IsMobile;
+
+ Dir = NewStrBuf();
+ StrBufPrintf(Dir, "%s/t", DirName);
+ filedir = opendir (ChrPtr(Dir));
+ if (filedir == NULL) {
+ FreeStrBuf(&Dir);
+ return 0;
+ }
+
+ FileName = NewStrBuf();
+ Tag = NewStrBuf();
+ while ((filedir_entry = readdir(filedir)))
+ {
+ char *MinorPtr;
+ char *PStart;
+#ifdef _DIRENT_HAVE_D_NAMELEN
+ d_namelen = filedir_entry->d_namelen;
+#else
+ d_namelen = strlen(filedir_entry->d_name);
+#endif
+ d_without_ext = d_namelen;
+ while ((d_without_ext > 0) && (filedir_entry->d_name[d_without_ext] != '.'))
+ d_without_ext --;
+ if ((d_without_ext == 0) || (d_namelen < 3))
+ continue;
+ if ((d_namelen > 1) && filedir_entry->d_name[d_namelen - 1] == '~')
+ continue; /* Ignore backup files... */
+
+ IsMobile = (strstr(filedir_entry->d_name, ".m.html")!= NULL);
+ PStart = filedir_entry->d_name;
+ StrBufPrintf(FileName, "%s/%s", ChrPtr(Dir), filedir_entry->d_name);
+ MinorPtr = strchr(filedir_entry->d_name, '.');
+ if (MinorPtr != NULL)
+ *MinorPtr = '\0';
+ StrBufPlain(Tag, filedir_entry->d_name, MinorPtr - filedir_entry->d_name);
+
+ if (LoadTemplates > 1)
+ lprintf(1, "%s %d %s\n",ChrPtr(FileName), IsMobile, ChrPtr(Tag));
+ if (LoadTemplates == 0)
+ load_template(FileName, Tag, (IsMobile)?wireless:big);
+ else
+ prepare_template(FileName, Tag, (IsMobile)?wireless:big);
+ }
+ closedir(filedir);
+ FreeStrBuf(&FileName);
+ FreeStrBuf(&Tag);
+ FreeStrBuf(&Dir);
+ return 1;
+}
+
+void InitTemplateCache(void)
+{
+ LoadTemplateDir(static_dirs[0],
+ WirelessTemplateCache,
+ TemplateCache);
+ LoadTemplateDir(static_dirs[1],
+ WirelessLocalTemplateCache,
+ LocalTemplateCache);
+}
+
+
+
+/*-----------------------------------------------------------------------------
+ * Filling & processing Templates
+ */
+/**
+ * \brief executes one token
+ * \param Target buffer to append to
+ * \param Token da to process.
+ * \param Template we're iterating
+ * \param Context Contextpoointer to pass in
+ * \param state are we in conditional state?
+ * \param ContextType what type of information does context giv us?
+ */
+int EvaluateToken(StrBuf *Target, WCTemplateToken *Tokens, WCTemplate *pTmpl, void *Context, int state, int ContextType)
+{
+ HashHandler *Handler;
+ void *vVar;
+// much output, since pName is not terminated...
+// lprintf(1,"Doing token: %s\n",Token->pName);
+
+ switch (Tokens->Flags) {
+ case SV_GETTEXT:
+ TmplGettext(Target, Tokens->nParameters, Tokens);
+ break;
+ case SV_CONDITIONAL: /** Forward conditional evaluation */
+ return EvaluateConditional(Target, Tokens, pTmpl, Context, 1, state, ContextType);
+ break;
+ case SV_NEG_CONDITIONAL: /** Reverse conditional evaluation */
+ return EvaluateConditional(Target, Tokens, pTmpl, Context, 0, state, ContextType);
+ break;
+ case SV_CUST_STR_CONDITIONAL: /** Conditional put custom strings from params */
+ if (Tokens->nParameters >= 6) {
+ if (EvaluateConditional(Target, Tokens, pTmpl, Context, 0, state, ContextType))
+ StrBufAppendBufPlain(Target,
+ Tokens->Params[5]->Start,
+ Tokens->Params[5]->len,
+ 0);
+ else
+ StrBufAppendBufPlain(Target,
+ Tokens->Params[4]->Start,
+ Tokens->Params[4]->len,
+ 0);
+ }
+ else {
+ lprintf(1, "Conditional [%s] (in '%s' line %ld); needs at least 6 Params![%s]\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(pTmpl->FileName),
+ Tokens->Line,
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>\nConditional [%s] (in '%s' line %ld); needs 6 Params!\n[%s]\n</pre>\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(pTmpl->FileName),
+ Tokens->Line,
+ ChrPtr(Tokens->FlatToken));
+ }
+ break;
+ case SV_SUBTEMPL:
+ if (Tokens->nParameters == 1)
+ DoTemplate(Tokens->Params[0]->Start, Tokens->Params[0]->len, NULL, NULL, ContextType);
+ break;
case SV_PREEVALUATED:
Handler = (HashHandler*) Tokens->PreEval;
if ((Handler->ContextRequired != CTX_NONE) &&
return 0;
}
+
+
void ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, void *Context, int ContextType)
{
WCTemplate *pTmpl = Tmpl;
}
}
-
-/**
- * \brief Display a variable-substituted template
- * \param templatename template file to load
- */
-void *prepare_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
-{
- WCTemplate *NewTemplate;
- NewTemplate = (WCTemplate *) malloc(sizeof(WCTemplate));
- NewTemplate->Data = NULL;
- NewTemplate->FileName = NewStrBufDup(filename);
- NewTemplate->nTokensUsed = 0;
- NewTemplate->TokenSpace = 0;
- NewTemplate->Tokens = NULL;
-
- Put(PutThere, ChrPtr(Key), StrLength(Key), NewTemplate, FreeWCTemplate);
- return NewTemplate;
-}
-
-/**
- * \brief Display a variable-substituted template
- * \param templatename template file to load
- */
-void *load_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
-{
- int fd;
- struct stat statbuf;
- const char *pS, *pE, *pch, *Err;
- long Line;
- int pos;
- WCTemplate *NewTemplate;
-
- fd = open(ChrPtr(filename), O_RDONLY);
- if (fd <= 0) {
- lprintf(1, "ERROR: could not open template '%s' - %s\n",
- ChrPtr(filename), strerror(errno));
- return NULL;
- }
-
- if (fstat(fd, &statbuf) == -1) {
- lprintf(1, "ERROR: could not stat template '%s' - %s\n",
- ChrPtr(filename), strerror(errno));
- return NULL;
- }
-
- NewTemplate = (WCTemplate *) malloc(sizeof(WCTemplate));
- NewTemplate->Data = NewStrBufPlain(NULL, statbuf.st_size);
- NewTemplate->FileName = NewStrBufDup(filename);
- NewTemplate->nTokensUsed = 0;
- NewTemplate->TokenSpace = 0;
- NewTemplate->Tokens = NULL;
- if (StrBufReadBLOB(NewTemplate->Data, &fd, 1, statbuf.st_size, &Err) < 0) {
- close(fd);
- FreeWCTemplate(NewTemplate);
- lprintf(1, "ERROR: reading template '%s' - %s<br />\n",
- ChrPtr(filename), strerror(errno));
- return NULL;
- }
- close(fd);
-
- Line = 0;
- pS = pch = ChrPtr(NewTemplate->Data);
- pE = pS + StrLength(NewTemplate->Data);
- while (pch < pE) {
- const char *pts, *pte;
- int InQuotes = 0;
- int InDoubleQuotes = 0;
-
- /** Find one <? > */
- pos = (-1);
- for (; pch < pE; pch ++) {
- if ((*pch=='<')&&(*(pch + 1)=='?'))
- break;
- if (*pch=='\n') Line ++;
- }
- if (pch >= pE)
- continue;
- pts = pch;
-
- /** Found one? parse it. */
- for (; pch < pE - 1; pch ++) {
- if (*pch == '"')
- InDoubleQuotes = ! InDoubleQuotes;
- else if (*pch == '\'')
- InQuotes = ! InQuotes;
- else if ((!InQuotes && !InDoubleQuotes) &&
- ((*pch!='\\')&&(*(pch + 1)=='>'))) {
- pch ++;
- break;
- }
- }
- if (pch + 1 >= pE)
- continue;
- pte = pch;
- PutNewToken(NewTemplate,
- NewTemplateSubstitute(NewTemplate->Data, pS, pts, pte, Line, NewTemplate));
- pch ++;
- }
- if (LoadTemplates == 0)
- Put(PutThere, ChrPtr(Key), StrLength(Key), NewTemplate, FreeWCTemplate);
- return NewTemplate;
-}
-
-
-///void PrintTemplate(const char *Key, void *vSubst, int odd)
-const char* PrintTemplate(void *vSubst)
-{
- WCTemplate *Tmpl = vSubst;
-
- return ChrPtr(Tmpl->FileName);
-
-}
-
-
/**
* \brief Display a variable-substituted template
* \param templatename template file to load
StaticLocal = LocalTemplateCache;
}
- if (len == 0)
- {
- lprintf (1, "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;
- }
-
- if (!GetHash(StaticLocal, templatename, len, &vTmpl) &&
- !GetHash(Static, templatename, len, &vTmpl)) {
- lprintf (1, "didn't find Template [%s] %ld %ld\n", templatename, len , (long)strlen(templatename));
- StrBufAppendPrintf(Target, "<pre>\ndidn't find Template [%s] %ld %ld\n</pre>",
- templatename, len,
- (long)strlen(templatename));
-/// dbg_PrintHash(Static, PrintTemplate, NULL);
-// PrintHash(Static, VarPrintTransition, PrintTemplate);
- return;
- }
- if (vTmpl == NULL)
- return;
- ProcessTemplate(vTmpl, Target, Context, ContextType);
-}
-
-int LoadTemplateDir(const char *DirName, HashList *wireless, HashList *big)
-{
- StrBuf *FileName;
- StrBuf *Tag;
- StrBuf *Dir;
- DIR *filedir = NULL;
- struct dirent *filedir_entry;
- int d_namelen;
- int d_without_ext;
- int IsMobile;
-
- Dir = NewStrBuf();
- StrBufPrintf(Dir, "%s/t", DirName);
- filedir = opendir (ChrPtr(Dir));
- if (filedir == NULL) {
- FreeStrBuf(&Dir);
- return 0;
- }
-
- FileName = NewStrBuf();
- Tag = NewStrBuf();
- while ((filedir_entry = readdir(filedir)))
- {
- char *MinorPtr;
- char *PStart;
-#ifdef _DIRENT_HAVE_D_NAMELEN
- d_namelen = filedir_entry->d_namelen;
-#else
- d_namelen = strlen(filedir_entry->d_name);
-#endif
- d_without_ext = d_namelen;
- while ((d_without_ext > 0) && (filedir_entry->d_name[d_without_ext] != '.'))
- d_without_ext --;
- if ((d_without_ext == 0) || (d_namelen < 3))
- continue;
- if ((d_namelen > 1) && filedir_entry->d_name[d_namelen - 1] == '~')
- continue; /* Ignore backup files... */
-
- IsMobile = (strstr(filedir_entry->d_name, ".m.html")!= NULL);
- PStart = filedir_entry->d_name;
- StrBufPrintf(FileName, "%s/%s", ChrPtr(Dir), filedir_entry->d_name);
- MinorPtr = strchr(filedir_entry->d_name, '.');
- if (MinorPtr != NULL)
- *MinorPtr = '\0';
- StrBufPlain(Tag, filedir_entry->d_name, MinorPtr - filedir_entry->d_name);
-
- if (LoadTemplates > 1)
- lprintf(1, "%s %d %s\n",ChrPtr(FileName), IsMobile, ChrPtr(Tag));
- if (LoadTemplates == 0)
- load_template(FileName, Tag, (IsMobile)?wireless:big);
- else
- prepare_template(FileName, Tag, (IsMobile)?wireless:big);
+ if (len == 0)
+ {
+ lprintf (1, "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;
}
- closedir(filedir);
- FreeStrBuf(&FileName);
- FreeStrBuf(&Tag);
- FreeStrBuf(&Dir);
- return 1;
-}
-void InitTemplateCache(void)
-{
- LoadTemplateDir(static_dirs[0],
- WirelessTemplateCache,
- TemplateCache);
- LoadTemplateDir(static_dirs[1],
- WirelessLocalTemplateCache,
- LocalTemplateCache);
+ if (!GetHash(StaticLocal, templatename, len, &vTmpl) &&
+ !GetHash(Static, templatename, len, &vTmpl)) {
+ lprintf (1, "didn't find Template [%s] %ld %ld\n", templatename, len , (long)strlen(templatename));
+ StrBufAppendPrintf(Target, "<pre>\ndidn't find Template [%s] %ld %ld\n</pre>",
+ templatename, len,
+ (long)strlen(templatename));
+/// dbg_PrintHash(Static, PrintTemplate, NULL);
+// PrintHash(Static, VarPrintTransition, PrintTemplate);
+ return;
+ }
+ if (vTmpl == NULL)
+ return;
+ ProcessTemplate(vTmpl, Target, Context, ContextType);
}
-
-
+/*-----------------------------------------------------------------------------
+ * Iterators
+ */
typedef struct _HashIterator {
HashList *StaticList;
int AdditionalParams;
SubTemplFunc DoSubTemplate;
} HashIterator;
+void RegisterITERATOR(const char *Name, long len,
+ int AdditionalParams,
+ HashList *StaticList,
+ RetrieveHashlistFunc GetHash,
+ SubTemplFunc DoSubTempl,
+ HashDestructorFunc Destructor,
+ int ContextType,
+ int XPectContextType)
+{
+ HashIterator *It = (HashIterator*)malloc(sizeof(HashIterator));
+ It->StaticList = StaticList;
+ It->AdditionalParams = AdditionalParams;
+ It->GetHash = GetHash;
+ It->DoSubTemplate = DoSubTempl;
+ It->Destructor = Destructor;
+ It->ContextType = ContextType;
+ It->XPectContextType = XPectContextType;
+ Put(Iterators, Name, len, It, NULL);
+}
+
void tmpl_iterate_subtmpl(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
{
void *vIt;
}
-
-
-
if (It->StaticList == NULL)
List = It->GetHash(Target, nArgs, Tokens, Context, ContextType);
else
It->Destructor(&List);
}
+
+
+/*-----------------------------------------------------------------------------
+ * Conditionals
+ */
+int EvaluateConditional(StrBuf *Target, WCTemplateToken *Tokens, WCTemplate *pTmpl, void *Context, int Neg, int state, int ContextType)
+{
+ ConditionalStruct *Cond;
+
+ if ((Tokens->Params[0]->len == 1) &&
+ (Tokens->Params[0]->Start[0] == 'X'))
+ return (state != 0)?Tokens->Params[1]->lvalue:0;
+
+ Cond = (ConditionalStruct *) Tokens->PreEval;
+ if (Cond == NULL) {
+ lprintf(1, "Conditional [%s] (in '%s' line %ld); unknown![%s]\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(pTmpl->FileName),
+ Tokens->Line,
+ ChrPtr(Tokens->FlatToken));
+ return 1;
+ }
+
+ if (Tokens->nParameters < Cond->nParams) {
+ lprintf(1, "Conditional [%s] (in '%s' line %ld); needs %ld Params![%s]\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(pTmpl->FileName),
+ Tokens->Line,
+ Cond->nParams,
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>\nConditional [%s] (in '%s' line %ld); needs %ld Params!\n[%s]\n</pre>\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(pTmpl->FileName),
+ Tokens->Line,
+ Cond->nParams,
+ ChrPtr(Tokens->FlatToken));
+ return 0;
+ }
+ if (Cond->CondF(Tokens, Context, ContextType) == Neg)
+ return Tokens->Params[1]->lvalue;
+ return 0;
+}
+
int ConditionalVar(WCTemplateToken *Tokens, void *Context, int ContextType)
{
void *vsubst;
return 0;
}
-void RegisterITERATOR(const char *Name, long len,
- int AdditionalParams,
- HashList *StaticList,
- RetrieveHashlistFunc GetHash,
- SubTemplFunc DoSubTempl,
- HashDestructorFunc Destructor,
- int ContextType,
- int XPectContextType)
-{
- HashIterator *It = (HashIterator*)malloc(sizeof(HashIterator));
- It->StaticList = StaticList;
- It->AdditionalParams = AdditionalParams;
- It->GetHash = GetHash;
- It->DoSubTemplate = DoSubTempl;
- It->Destructor = Destructor;
- It->ContextType = ContextType;
- It->XPectContextType = XPectContextType;
- Put(Iterators, Name, len, It, NULL);
-}
void RegisterConditional(const char *Name, long len,
int nParams,
Put(Conditionals, Name, len, Cond, NULL);
}
-
+/*-----------------------------------------------------------------------------
+ * Context Strings
+ */
void tmplput_ContextString(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
{
StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, (StrBuf*)Context, 0);
return strcmp(ChrPtr(TokenText), CompareToken) == 0;
}
+/*-----------------------------------------------------------------------------
+ * Boxed-API
+ */
void tmpl_do_boxed(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
{
Context,
ContextType);
DoTemplate(HKEY("endbox"), Target, Context, ContextType);
- FreeStrBuf(Headline);
+ FreeStrBuf(&Headline);
}
+/*-----------------------------------------------------------------------------
+ * Tabbed-API
+ */
void tmpl_do_tabbed(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
{
}
}
+
+/*-----------------------------------------------------------------------------
+ * Sorting-API
+ */
+
+typedef struct _SortStruct {
+ StrBuf *Name;
+ StrBuf *PrefPrepend;
+ CompareFunc Forward;
+ CompareFunc Reverse;
+
+ long ContextType;
+}SortStruct;
+
+void DestroySortStruct(void *vSort)
+{
+ SortStruct *Sort = (SortStruct*) vSort;
+ FreeStrBuf(&Sort->Name);
+ FreeStrBuf(&Sort->PrefPrepend);
+ free (Sort);
+}
+
+void RegisterSortFunc(const char *name, long len,
+ const char *prepend, long preplen,
+ CompareFunc Forward,
+ CompareFunc Reverse,
+ long ContextType)
+{
+ SortStruct *NewSort = (SortStruct*) malloc(sizeof(SortStruct));
+ NewSort->Name = NewStrBufPlain(name, len);
+ if (prepend != NULL)
+ NewSort->PrefPrepend = NewStrBufPlain(prepend, preplen);
+ else
+ NewSort->PrefPrepend = NULL;
+ NewSort->Forward = Forward;
+ NewSort->Reverse = Reverse;
+ NewSort->ContextType = ContextType;
+ Put(SortHash, name, len, NewSort, DestroySortStruct);
+}
+
+CompareFunc RetrieveSort(long ContextType, const char *OtherPrefix,
+ const char *Default, long ldefault, long DefaultDirection)
+{
+ int isdefault = 0;
+ const StrBuf *BSort;
+ SortStruct *SortBy;
+ void *vSortBy;
+ long SortOrder;
+
+ if (havebstr("SortBy")) {
+ BSort = sbstr("SortBy");
+ }
+ else { /** Try to fallback to our remembered values... */
+ if (OtherPrefix == NULL) {
+ BSort = get_room_pref("sort");
+ }
+ else {
+ ////todo: nail prefprepend to sort, and lookup this!
+ }
+ }
+
+ if (!GetHash(SortHash, SKEY(BSort), &vSortBy) ||
+ (vSortBy == NULL)) {
+ isdefault = 1;
+ if (!GetHash(SortHash, Default, ldefault, &vSortBy) ||
+ (vSortBy == NULL)) {
+ lprintf(1, "Illegal default sort: [%s]\n", Default);
+ wc_backtrace();
+ }
+ }
+ SortBy = (SortStruct*)vSortBy;
+
+ /** Ok, its us, lets see in which direction we should sort... */
+ if (havebstr("SortOrder")) {
+ SortOrder = LBSTR("SortOrder");
+ }
+ else { /** Try to fallback to our remembered values... */
+ if (SortBy->PrefPrepend == NULL) {
+ SortOrder = StrTol(get_room_pref("SortOrder"));
+ }
+ else {
+ ////todo: nail prefprepend to sort, and lookup this!
+ }
+ }
+ switch (SortOrder) {
+ default:
+ case 0:
+ return NULL;
+ case 1:
+ return SortBy->Forward;
+ case 2:
+ return SortBy->Reverse;
+ }
+}
+
+
+enum {
+ eNO_SUCH_SORT,
+ eNOT_SPECIFIED,
+ eINVALID_PARAM,
+ eFOUND
+};
+
+ConstStr SortIcons[] = {
+ {HKEY("static/sort_none.gif")},
+ {HKEY("static/up_pointer.gif")},
+ {HKEY("static/down_pointer.gif")},
+};
+
+ConstStr SortNextOrder[] = {
+ {HKEY("1")},
+ {HKEY("2")},
+ {HKEY("0")},
+};
+
+
+int GetSortMetric(WCTemplateToken *Tokens, SortStruct **Next, SortStruct **Param, long *SortOrder)
+{
+ int bSortError = eNOT_SPECIFIED;
+ const StrBuf *BSort;
+ void *vSort;
+
+ *SortOrder = 0;
+ *Next = NULL;
+ if (!GetHash(SortHash, Tokens->Params[0]->Start, Tokens->Params[0]->len, &vSort) ||
+ (vSort == NULL))
+ return eNO_SUCH_SORT;
+ *Param = (SortStruct*) vSort;
+
+
+ if (havebstr("SortBy")) {
+ BSort = sbstr("SortBy");
+ bSortError = eINVALID_PARAM;
+ }
+ else { /** Try to fallback to our remembered values... */
+ if ((*Param)->PrefPrepend == NULL) {
+ BSort = get_room_pref("sort");
+ }
+ else {
+ ////todo: nail prefprepend to sort, and lookup this!
+ }
+ }
+
+ if (!GetHash(SortHash, SKEY(BSort), &vSort) ||
+ (vSort == NULL))
+ return bSortError;
+
+ *Next = (SortStruct*) vSort;
+
+ /** Ok, its us, lets see in which direction we should sort... */
+ if (havebstr("SortOrder")) {
+ *SortOrder = LBSTR("SortOrder");
+ }
+ else { /** Try to fallback to our remembered values... */
+ if ((*Param)->PrefPrepend == NULL) {
+ *SortOrder = StrTol(get_room_pref("SortOrder"));
+ }
+ else {
+ ////todo: nail prefprepend to sort, and lookup this!
+ }
+ }
+ if (*SortOrder > 2)
+ *SortOrder = 0;
+
+ return eFOUND;
+}
+
+
+void tmplput_SORT_ICON(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ long SortOrder;
+ SortStruct *Next;
+ SortStruct *Param;
+ const ConstStr *SortIcon;
+
+ switch (GetSortMetric(Tokens, &Next, &Param, &SortOrder)){
+ case eNO_SUCH_SORT:
+ lprintf(1, "[%s] (in '%s' line %ld); "
+ " Sorter [%s] unknown! [%s]\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>\n [%s] (in '%s' line %ld);"
+ " Sorter [%s] unknown!\n[%s]\n</pre>\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FlatToken));
+ break;
+ case eINVALID_PARAM:
+ lprintf(1, "[%s] (in '%s' line %ld); "
+ " Sorter specified by BSTR 'SortBy' [%s] unknown! [%s]\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ bstr("SortBy"),
+ ChrPtr(Tokens->FlatToken));
+ case eNOT_SPECIFIED:
+ case eFOUND:
+ if (Next == Param) {
+ SortIcon = &SortIcons[SortOrder];
+ }
+ else { /** Not Us... */
+ SortIcon = &SortIcons[0];
+ }
+ StrBufAppendBufPlain(Target, SortIcon->Key, SortIcon->len, 0);
+ }
+}
+
+void tmplput_SORT_NEXT(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ long SortOrder;
+ SortStruct *Next;
+ SortStruct *Param;
+
+ switch (GetSortMetric(Tokens, &Next, &Param, &SortOrder)){
+ case eNO_SUCH_SORT:
+ lprintf(1, "[%s] (in '%s' line %ld); "
+ " Sorter [%s] unknown! [%s]\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>\n [%s] (in '%s' line %ld);"
+ " Sorter [%s] unknown!\n[%s]\n</pre>\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FlatToken));
+ break;
+ case eINVALID_PARAM:
+ lprintf(1, "[%s] (in '%s' line %ld); "
+ " Sorter specified by BSTR 'SortBy' [%s] unknown! [%s]\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ bstr("SortBy"),
+ ChrPtr(Tokens->FlatToken));
+
+ case eNOT_SPECIFIED:
+ case eFOUND:
+ StrBufAppendBuf(Target, Param->Name, 0);
+
+ }
+}
+
+void tmplput_SORT_ORDER(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ long SortOrder;
+ const ConstStr *SortOrderStr;
+ SortStruct *Next;
+ SortStruct *Param;
+
+ switch (GetSortMetric(Tokens, &Next, &Param, &SortOrder)){
+ case eNO_SUCH_SORT:
+ lprintf(1, "[%s] (in '%s' line %ld); "
+ " Sorter [%s] unknown! [%s]\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>\n [%s] (in '%s' line %ld);"
+ " Sorter [%s] unknown!\n[%s]\n</pre>\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FlatToken));
+ break;
+ case eINVALID_PARAM:
+ lprintf(1, "[%s] (in '%s' line %ld); "
+ " Sorter specified by BSTR 'SortBy' [%s] unknown! [%s]\n",
+ Tokens->pName,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ bstr("SortBy"),
+ ChrPtr(Tokens->FlatToken));
+
+ case eNOT_SPECIFIED:
+ case eFOUND:
+ if (Next == Param) {
+ SortOrderStr = &SortNextOrder[SortOrder];
+ }
+ else { /** Not Us... */
+ SortOrderStr = &SortNextOrder[0];
+ }
+ StrBufAppendBufPlain(Target, SortOrderStr->Key, SortOrderStr->len, 0);
+ }
+}
+
+
+
void
InitModule_SUBST
(void)
{
+ RegisterNamespace("SORT:ICON", 1, 1, tmplput_SORT_ICON, CTX_NONE);
+ RegisterNamespace("SORT:ORDER", 1, 1, tmplput_SORT_ORDER, CTX_NONE);
+ RegisterNamespace("SORT:NEXT", 1, 1, tmplput_SORT_NEXT, CTX_NONE);
RegisterNamespace("CONTEXTSTR", 0, 1, tmplput_ContextString, CTX_STRBUF);
RegisterNamespace("ITERATE", 2, 100, tmpl_iterate_subtmpl, CTX_NONE);
RegisterNamespace("DOBOXED", 1, 2, tmpl_do_boxed, CTX_NONE);