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 Clear out the list of substitution variables local to this session
*/
-void clear_substs(struct wcsession *wc) {
+void clear_substs(wcsession *wc) {
if (wc->vars != NULL) {
DeleteHash(&wc->vars);
wcsubst *NewSubstVar(const char *keyname, int keylen, int type)
{
wcsubst* ptr;
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
ptr = (wcsubst *) malloc(sizeof(wcsubst));
memset(ptr, 0, sizeof(wcsubst));
void *vPtr;
wcsubst *ptr = NULL;
size_t keylen;
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
keylen = strlen(keyname);
/**
va_list arg_ptr;
void *vPtr;
wcsubst *ptr = NULL;
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
/**
* First look if we're doing a replacement of
{
void *vPtr;
wcsubst *ptr = NULL;
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
/**
{
void *vPtr;
wcsubst *ptr = NULL;
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
/**
{
wcsubst *ptr;
void *vPtr;
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
/**
* First look if we're doing a replacement of
{
wcsubst *ptr;
void *vPtr;
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
/**
* First look if we're doing a replacement of
}
}
-
-/**
- * \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(Buf));
- 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,
*len = Tokens->Params[N]->len;
break;
case TYPE_BSTR:
- Buf = (StrBuf*) SBstr(Tokens->Params[N]->Start,
- Tokens->Params[N]->len);
+ Buf = (StrBuf*) SBstr(TKEY(N));
*Value = ChrPtr(Buf);
*len = StrLength(Buf);
break;
case TYPE_PREFSTR:
- get_PREFERENCE(
- Tokens->Params[N]->Start,
- Tokens->Params[N]->len,
- &Buf);
+ get_PREFERENCE(TKEY(N), &Buf);
*Value = ChrPtr(Buf);
*len = StrLength(Buf);
break;
case TYPE_LONG:
case TYPE_PREFINT:
- break; ///todo: string to text?
+ break; /* todo: string to text? */
case TYPE_GETTEXT:
*Value = _(Tokens->Params[N]->Start);
*len = strlen(*Value);
break;
default:
break;
-//todo log error
+/*/todo log error */
}
}
* \param keyname get a key to print
*/
void print_value_of(StrBuf *Target, WCTemplateToken *Tokens, void *Context, int ContextType) {
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
wcsubst *ptr;
void *vVar;
/*if (WCC->vars != NULL) PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/
- /// TODO: debricated!
+ /* TODO: depricated! */
if (Tokens->pName[0] == '=') {
DoTemplate(Tokens->pName+1, Tokens->NameEnd - 1, NULL, NULL, 0);
}
-//////TODO: if param[1] == "U" -> urlescape
-/// X -> escputs
+/*/////TODO: if param[1] == "U" -> urlescape
+/// X -> escputs */
/** Page-local variables */
if ((WCC->vars!= NULL) && GetHash(WCC->vars, Tokens->pName, Tokens->NameEnd, &vVar)) {
ptr = (wcsubst*) vVar;
int CompareSubstToToken(TemplateParam *ParamToCompare, TemplateParam *ParamToLookup)
{
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
wcsubst *ptr;
void *vVar;
int CompareSubstToStrBuf(StrBuf *Compare, TemplateParam *ParamToLookup)
{
- struct wcsession *WCC = WC;
+ wcsession *WCC = WC;
wcsubst *ptr;
void *vVar;
}
+
+/**
+ * \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)
+{
+ 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) {
case SV_CUST_STR_CONDITIONAL:
case SV_CONDITIONAL:
case SV_NEG_CONDITIONAL:
- if (NewToken->Params[1]->lvalue == 0) {
+ if (NewToken->nParameters <2) {
lprintf(1, "Conditional (in '%s' line %ld); "
- "Conditional ID mustn't be 0! [%s]\n",
+ "require at least 2 parameters, you gave %ld params [%s]\n",
ChrPtr(pTmpl->FileName),
NewToken->Line,
+ NewToken->nParameters,
ChrPtr(NewToken->FlatToken));
NewToken->Flags = 0;
break;
}
- if (NewToken->nParameters <2) {
+ if (NewToken->Params[1]->lvalue == 0) {
lprintf(1, "Conditional (in '%s' line %ld); "
- "require at least 2 parameters, you gave %ld params [%s]\n",
+ "Conditional ID mustn't be 0! [%s]\n",
ChrPtr(pTmpl->FileName),
NewToken->Line,
- NewToken->nParameters,
ChrPtr(NewToken->FlatToken));
NewToken->Flags = 0;
break;
}
if (!GetHash(Conditionals,
- NewToken->Params[0]->Start,
- NewToken->Params[0]->len,
+ NewToken->Params[0]->Start,
+ NewToken->Params[0]->len,
&vVar) ||
(vVar == NULL)) {
if ((NewToken->Params[0]->len == 1) &&
-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;
- case SV_PREEVALUATED:
- Handler = (HashHandler*) Tokens->PreEval;
- if ((Handler->ContextRequired != CTX_NONE) &&
+ 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;
+}
+
+
+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)
+{
+ const char *AppendMe;
+ long AppendMeLen;
+ 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)) {
+ GetTemplateTokenString(Tokens, 5, &AppendMe, &AppendMeLen);
+ StrBufAppendBufPlain(Target,
+ AppendMe,
+ AppendMeLen,
+ 0);
+ }
+ else{
+ GetTemplateTokenString(Tokens, 4, &AppendMe, &AppendMeLen);
+ StrBufAppendBufPlain(Target,
+ AppendMe,
+ AppendMeLen,
+ 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(TKEY(0), NULL, NULL, ContextType);
+ break;
+ case SV_PREEVALUATED:
+ Handler = (HashHandler*) Tokens->PreEval;
+ if ((Handler->ContextRequired != CTX_NONE) &&
(Handler->ContextRequired != ContextType)) {
lprintf(1, "Handler [%s] (in '%s' line %ld); "
"requires context of type %ld, have %ld [%s]\n",
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)
+void DoTemplate(const char *templatename, long len, StrBuf *Target, void *Context, int ContextType)
{
- 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;
+ HashList *Static;
+ HashList *StaticLocal;
+ void *vTmpl;
+
+ if (Target == NULL)
+ Target = WC->WBuf;
+ if (WC->is_mobile) {
+ Static = WirelessTemplateCache;
+ StaticLocal = WirelessLocalTemplateCache;
+ }
+ else {
+ Static = TemplateCache;
+ StaticLocal = LocalTemplateCache;
}
- if (fstat(fd, &statbuf) == -1) {
- lprintf(1, "ERROR: could not stat template '%s' - %s\n",
- ChrPtr(filename), strerror(errno));
- return NULL;
+ 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;
}
- 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;
+ 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));
+#if 0
+ dbg_PrintHash(Static, PrintTemplate, NULL);
+ PrintHash(Static, VarPrintTransition, PrintTemplate);
+#endif
+ return;
}
- close(fd);
+ if (vTmpl == NULL)
+ return;
+ ProcessTemplate(vTmpl, Target, Context, ContextType);
+}
- 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;
+/*-----------------------------------------------------------------------------
+ * Iterators
+ */
+typedef struct _HashIterator {
+ HashList *StaticList;
+ int AdditionalParams;
+ int ContextType;
+ int XPectContextType;
+ RetrieveHashlistFunc GetHash;
+ HashDestructorFunc Destructor;
+ SubTemplFunc DoSubTemplate;
+} HashIterator;
- /** 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
- */
-void DoTemplate(const char *templatename, long len, StrBuf *Target, void *Context, int ContextType)
-{
- HashList *Static;
- HashList *StaticLocal;
- void *vTmpl;
-
- if (Target == NULL)
- Target = WC->WBuf;
- if (WC->is_mobile) {
- Static = WirelessTemplateCache;
- StaticLocal = WirelessLocalTemplateCache;
- }
- else {
- Static = TemplateCache;
- 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);
- }
- closedir(filedir);
- FreeStrBuf(&FileName);
- FreeStrBuf(&Tag);
- FreeStrBuf(&Dir);
- return 1;
-}
-
-void InitTemplateCache(void)
+void RegisterITERATOR(const char *Name, long len,
+ int AdditionalParams,
+ HashList *StaticList,
+ RetrieveHashlistFunc GetHash,
+ SubTemplFunc DoSubTempl,
+ HashDestructorFunc Destructor,
+ int ContextType,
+ int XPectContextType)
{
- LoadTemplateDir(static_dirs[0],
- WirelessTemplateCache,
- TemplateCache);
- LoadTemplateDir(static_dirs[1],
- WirelessLocalTemplateCache,
- LocalTemplateCache);
+ 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);
}
-
-
-typedef struct _HashIterator {
- HashList *StaticList;
- int AdditionalParams;
- int ContextType;
- int XPectContextType;
- RetrieveHashlistFunc GetHash;
- HashDestructorFunc Destructor;
- SubTemplFunc DoSubTemplate;
-} HashIterator;
-
void tmpl_iterate_subtmpl(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
{
void *vIt;
HashIterator *It;
HashList *List;
HashPos *it;
+ int nMembersUsed;
+ int nMembersCounted = 0;
long len;
const char *Key;
void *vContext;
StrBuf *SubBuf;
int oddeven = 0;
- if (!GetHash(Iterators,
- Tokens->Params[0]->Start,
- Tokens->Params[0]->len,
- &vIt)) {
+ if (!GetHash(Iterators, TKEY(0), &vIt)) {
lprintf(1, "unknown Iterator [%s] (in '%s' line %ld); "
" [%s]\n",
Tokens->Params[0]->Start,
}
-
-
-
if (It->StaticList == NULL)
List = It->GetHash(Target, nArgs, Tokens, Context, ContextType);
else
List = It->StaticList;
+ nMembersUsed = GetCount(List);
SubBuf = NewStrBuf();
- it = GetNewHashPos();
+ it = GetNewHashPos(List, 0);
while (GetNextHashPos(List, it, &len, &Key, &vContext)) {
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);
if (It->DoSubTemplate != NULL)
It->DoSubTemplate(SubBuf, vContext, Tokens);
- DoTemplate(Tokens->Params[1]->Start,
- Tokens->Params[1]->len,
- SubBuf, vContext,
- It->ContextType);
+ DoTemplate(TKEY(1), SubBuf, vContext, It->ContextType);
StrBufAppendBuf(Target, SubBuf, 0);
FlushStrBuf(SubBuf);
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;
wcsubst *subst;
- if (!GetHash(WC->vars,
- Tokens->Params[2]->Start,
- Tokens->Params[2]->len,
- &vsubst))
+ if (!GetHash(WC->vars, TKEY(2), &vsubst))
return 0;
subst = (wcsubst*) vsubst;
if ((subst->ContextRequired != CTX_NONE) &&
case WCS_FUNCTION:
return (subst->wcs_function!=NULL);
case WCS_SERVCMD:
- lprintf(1, " -> Server [%s]\n", subst->wcs_value);////todo
+ lprintf(1, " -> Server [%s]\n", subst->wcs_value);/* TODO */
return 1;
case WCS_STRING:
case WCS_STRBUF:
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)
{
if (nArgs == 2) {
if (Tokens->Params[1]->Type == TYPE_STR) {
Headline = NewStrBuf();
- DoTemplate(Tokens->Params[1]->Start,
- Tokens->Params[1]->len,
- Headline,
- Context,
- ContextType);
+ DoTemplate(TKEY(1), Headline, Context, ContextType);
}
else {
const char *Ch;
}
DoTemplate(HKEY("beginbox"), Target, Headline, CTX_STRBUF);
- DoTemplate(Tokens->Params[0]->Start,
- Tokens->Params[0]->len,
- Target,
- Context,
- ContextType);
+ DoTemplate(TKEY(0), Target, Context, ContextType);
DoTemplate(HKEY("endbox"), Target, Context, ContextType);
+ FreeStrBuf(&Headline);
}
+/*-----------------------------------------------------------------------------
+ * Tabbed-API
+ */
void tmpl_do_tabbed(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
{
for (i = 0; i < ntabs; i++) {
TabNames[i] = NewStrBuf();
if (Tokens->Params[i * 2]->len > 0) {
- DoTemplate(Tokens->Params[i * 2]->Start,
- Tokens->Params[i * 2]->len,
- TabNames[i],
- Context,
- ContextType);
+ DoTemplate(TKEY(i * 2), TabNames[i], Context, ContextType);
}
else {
/** A Tab without subject? we can't count that, add it as silent */
for (i = 0; i < ntabs; i++) {
StrBeginTab(Target, i, nTabs);
- DoTemplate(Tokens->Params[i * 2 + 1]->Start,
- Tokens->Params[i * 2 + 1]->len,
- Target,
- Context,
- ContextType);
+ DoTemplate(TKEY(i * 2 + 1), Target, Context, ContextType);
StrEndTab(Target, i, nTabs);
}
}
+
+/*-----------------------------------------------------------------------------
+ * 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 = -1;
+
+ 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 (BSort != NULL)
+ putbstr("SortBy", NewStrBufDup(BSort));
+ else {
+ StrBuf *Buf;
+
+ BSort = Buf = NewStrBufPlain(Default, ldefault);
+ putbstr("SortBy", Buf);
+ }
+ }
+
+ 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... */
+ StrBuf *Buf;
+ if (SortBy->PrefPrepend == NULL) {
+ Buf = get_room_pref("SortOrder");
+ SortOrder = StrTol(Buf);
+ }
+ else {
+ /* TODO: nail prefprepend to sort, and lookup this! */
+ }
+
+ if (Buf == NULL)
+ SortOrder = DefaultDirection;
+
+ Buf = NewStrBufPlain(NULL, 64);
+ StrBufPrintf(Buf, "%ld", SortOrder);
+ putbstr("SortOrder", Buf);
+ }
+ 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, TKEY(0), &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 tmplput_long_vector(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ long *LongVector = (long*) Context;
+
+ if ((Tokens->Params[0]->Type == TYPE_LONG) &&
+ (Tokens->Params[0]->lvalue <= LongVector[0]))
+ {
+ StrBufAppendPrintf(Target, "%ld", LongVector[Tokens->Params[0]->lvalue]);
+ }
+ else
+ {
+ if (Tokens->Params[0]->Type == TYPE_LONG) {
+ lprintf(1, "longvector [%s] (in '%s' line %ld); needs a long Parameter![%s]\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>\nlongvector [%s] (in '%s' line %ld); needs a numerical Parameter!\n[%s]\n</pre>\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ ChrPtr(Tokens->FlatToken));
+ }
+ else {
+ lprintf(1, "longvector [%s] (in '%s' line %ld); doesn't have %ld Parameters,"
+ " its just the size of %ld![%s]\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[0]->lvalue,
+ LongVector[0],
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>\nlongvector [%s] (in '%s' line %ld); doesn't have %ld Parameters,"
+ " its just the size of %ld!\n[%s]\n</pre>\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[0]->lvalue,
+ LongVector[0],
+ ChrPtr(Tokens->FlatToken));
+ }
+ }
+}
+
+void dbg_print_longvector(long *LongVector)
+{
+ StrBuf *Buf = NewStrBufPlain(HKEY("Longvector: ["));
+ int nItems = LongVector[0];
+ int i;
+
+ for (i = 0; i < nItems; i++) {
+ if (i + 1 < nItems)
+ StrBufAppendPrintf(Buf, "%d: %ld | ", i, LongVector[i]);
+ else
+ StrBufAppendPrintf(Buf, "%d: %ld]\n", i, LongVector[i]);
+
+ }
+ lprintf(1, ChrPtr(Buf));
+ FreeStrBuf(&Buf);
+}
+
+int ConditionalLongVector(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ long *LongVector = (long*) Context;
+
+ if ((Tokens->Params[2]->Type == TYPE_LONG) &&
+ (Tokens->Params[2]->lvalue <= LongVector[0])&&
+ (Tokens->Params[3]->Type == TYPE_LONG) &&
+ (Tokens->Params[3]->lvalue <= LongVector[0]))
+ {
+ return LongVector[Tokens->Params[2]->lvalue] == LongVector[Tokens->Params[3]->lvalue];
+ }
+ else
+ {
+ if ((Tokens->Params[2]->Type == TYPE_LONG) ||
+ (Tokens->Params[2]->Type == TYPE_LONG)) {
+ lprintf(1, "ConditionalLongVector [%s] (in '%s' line %ld); needs two long Parameter![%s]\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ ChrPtr(Tokens->FlatToken));
+ }
+ else {
+ lprintf(1, "longvector [%s] (in '%s' line %ld); doesn't have %ld / %ld Parameters,"
+ " its just the size of %ld![%s]\n",
+ Tokens->Params[0]->Start,
+ ChrPtr(Tokens->FileName),
+ Tokens->Line,
+ Tokens->Params[2]->lvalue,
+ Tokens->Params[3]->lvalue,
+ LongVector[0],
+ ChrPtr(Tokens->FlatToken));
+ }
+ }
+ return 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);
RegisterNamespace("DOTABBED", 2, 100, tmpl_do_tabbed, CTX_NONE);
+ RegisterNamespace("LONGVECTOR", 1, 1, tmplput_long_vector, CTX_LONGVECTOR);
RegisterConditional(HKEY("COND:SUBST"), 3, ConditionalVar, CTX_NONE);
RegisterConditional(HKEY("COND:CONTEXTSTR"), 3, ConditionalContextStr, CTX_STRBUF);
+ RegisterConditional(HKEY("COND:LONGVECTOR"), 4, ConditionalLongVector, CTX_LONGVECTOR);
}
/*@}*/