HashList *Conditionals;
HashList *SortHash;
+int DumpTemplateI18NStrings = 0;
int LoadTemplates = 0;
int dbg_bactrace_template_errors = 0;
WCTemplputParams NoCtx;
+StrBuf *I18nDump = NULL;
#define SV_GETTEXT 1
#define SV_CONDITIONAL 2
#define SV_SUBTEMPL 5
#define SV_PREEVALUATED 6
+
+/*
+ * \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 */
+ WCHandlerFunc wcs_function; /* funcion hook ???*/
+} wcsubst;
+
+
typedef struct _WCTemplate {
StrBuf *Data;
StrBuf *FileName;
Type,
ChrPtr(Error));
}
+/*
if (Target == NULL)
return;
+*/
WCC = WC;
+ if (WCC == NULL)
+ return;
+
Header = NewStrBuf();
if (TP->Tokens != NULL)
{
Error,
eERROR), 1);
*/
- WildFireSerializePayload(Header, WCC->HBuf, &WCC->nWildfireHeaders, NULL);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
}
else
{
ChrPtr(Error),
ChrPtr(TP->Tokens->FlatToken));
SerializeJson(Header, WildFireException(HKEY(__FILE__), __LINE__, Info, 1), 1);
- WildFireSerializePayload(Header, WCC->HBuf, &WCC->nWildfireHeaders, NULL);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
}
FreeStrBuf(&Header);
FreeStrBuf(&Info);
}
+
+
+void LogError (StrBuf *Target, const char *Type, const char *Format, ...)
+{
+ wcsession *WCC;
+ StrBuf *Header;
+ StrBuf *Error;
+ StrBuf *Info;
+ va_list arg_ptr;
+
+ Info = NewStrBuf();
+ Error = NewStrBuf();
+
+ va_start(arg_ptr, Format);
+ StrBufVAppendPrintf(Error, Format, arg_ptr);
+ va_end(arg_ptr);
+
+ lprintf(1, ChrPtr(Error));
+
+ WCC = WC;
+ Header = NewStrBuf();
+
+
+ SerializeJson(Header, WildFireException(Type, strlen(Type),
+ 0,
+ Info,
+ 1), 1);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
+
+ FreeStrBuf(&Header);
+ FreeStrBuf(&Info);
+ FreeStrBuf(&Error);
+/*
+ if (dbg_bactrace_template_errors)
+ wc_backtrace();
+*/
+}
+
+
void RegisterNS(const char *NSName,
long len,
int nMinArgs,
}
}
-void GetTemplateTokenString(WCTemplputParams *TP,
+void GetTemplateTokenString(StrBuf *Target,
+ WCTemplputParams *TP,
int N,
const char **Value,
long *len)
WCTemplputParams SubTP;
if (TP->Tokens->nParameters < N) {
- lprintf(1, "invalid token. this shouldn't have come till here.\n");
- wc_backtrace();
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "invalid token %d. this shouldn't have come till here.\n", N);
*Value = "";
*len = 0;
return;
*len = StrLength(Buf);
break;
case TYPE_LONG:
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "Requesting parameter %d; of type LONG, want string.", N);
+ break;
case TYPE_PREFINT:
- break; /* todo: string to text? */
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "Requesting parameter %d; of type PREFINT, want string.", N);
+ break;
case TYPE_GETTEXT:
*Value = _(TP->Tokens->Params[N]->Start);
*len = strlen(*Value);
break;
default:
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "unknown param type %d; [%d]", N, TP->Tokens->Params[N]->Type);
+ break;
+ }
+}
+
+long GetTemplateTokenNumber(StrBuf *Target, WCTemplputParams *TP, int N, long dflt)
+{
+ long Ret;
+ if (TP->Tokens->nParameters < N) {
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "invalid token %d. this shouldn't have come till here.\n", N);
+ wc_backtrace();
+ return 0;
+ }
+
+ switch (TP->Tokens->Params[N]->Type) {
+
+ case TYPE_STR:
+ return atol(TP->Tokens->Params[N]->Start);
+ break;
+ case TYPE_BSTR:
+ return LBstr(TKEY(N));
break;
-/*/todo log error */
+ case TYPE_PREFSTR:
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "requesting a prefstring in param %d want a number", N);
+ if (get_PREF_LONG(TKEY(N), &Ret, dflt))
+ return Ret;
+ return 0;
+ case TYPE_LONG:
+ return TP->Tokens->Params[N]->lvalue;
+ case TYPE_PREFINT:
+ if (get_PREF_LONG(TKEY(N), &Ret, dflt))
+ return Ret;
+ return 0;
+ case TYPE_GETTEXT:
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "requesting a I18N string in param %d; want a number", N);
+ return 0;
+ case TYPE_SUBTEMPLATE:
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "requesting a subtemplate in param %d; not supported for numbers", N);
+ return 0;
+ default:
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "unknown param type %d; [%d]", N, TP->Tokens->Params[N]->Type);
+ return 0;
}
}
StrEscAppend(Target, Source, NULL, 0, 0);
break;
case 'J':
- StrECMAEscAppend(Target, Source, NULL);
+ StrECMAEscAppend(Target, Source, NULL);
break;
+ case 'U':
+ StrBufUrlescAppend(Target, Source, NULL);
+ break;
default:
StrBufAppendBuf(Target, Source, 0);
}
(*pch == ',' )||
(*pch == '\n')) pch ++;
+ if (DumpTemplateI18NStrings && (Parm->Type == TYPE_GETTEXT)) {
+ StrBufAppendPrintf(I18nDump, "_(\"%s\");\n", Parm->Start);
+ }
*pCh = pch;
return Parm;
}
NewToken->Flags = 0;
break;
}
+ if (DumpTemplateI18NStrings) {
+ StrBufAppendPrintf(I18nDump, "_(\"%s\");\n", NewToken->Params[0]->Start);
+ }
break;
case SV_SUBTEMPL:
if (NewToken->nParameters != 1) {
NewTemplate->nTokensUsed = 0;
NewTemplate->TokenSpace = 0;
NewTemplate->Tokens = NULL;
+ NewTemplate->MimeType = NewStrBufPlain(GuessMimeByFilename (SKEY(NewTemplate->FileName)), -1);
+ if (strstr(ChrPtr(NewTemplate->MimeType), "text") != NULL) {
+ StrBufAppendBufPlain(NewTemplate->MimeType, HKEY("; charset=utf-8"), 0);
+ }
Put(PutThere, ChrPtr(Key), StrLength(Key), NewTemplate, FreeWCTemplate);
return NewTemplate;
NewTemplate->TokenSpace = 0;
NewTemplate->Tokens = NULL;
NewTemplate->MimeType = NewStrBufPlain(GuessMimeByFilename (SKEY(NewTemplate->FileName)), -1);
+ if (strstr(ChrPtr(NewTemplate->MimeType), "text") != NULL) {
+ StrBufAppendBufPlain(NewTemplate->MimeType, HKEY("; charset=utf-8"), 0);
+ }
+
if (StrBufReadBLOB(NewTemplate->Data, &fd, 1, statbuf.st_size, &Err) < 0) {
close(fd);
FreeWCTemplate(NewTemplate);
case SV_CUST_STR_CONDITIONAL: /** Conditional put custom strings from params */
if (TP->Tokens->nParameters >= 6) {
if (EvaluateConditional(Target, 0, state, TP)) {
- GetTemplateTokenString(TP, 5, &AppendMe, &AppendMeLen);
+ GetTemplateTokenString(Target, TP, 5, &AppendMe, &AppendMeLen);
StrBufAppendBufPlain(Target,
AppendMe,
AppendMeLen,
0);
}
else{
- GetTemplateTokenString(TP, 4, &AppendMe, &AppendMeLen);
+ GetTemplateTokenString(Target, TP, 4, &AppendMe, &AppendMeLen);
StrBufAppendBufPlain(Target,
AppendMe,
AppendMeLen,
Put(Iterators, Name, len, It, NULL);
}
-/* typedef struct _iteratestruct {
+typedef struct _iteratestruct {
int GroupChange;
int oddeven;
const char *Key;
long KeyLen;
int n;
int LastN;
- }IterateStruct; */
+ }IterateStruct;
void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP)
{
WCTemplputParams SubTP;
IterateStruct Status;
+ long StartAt = 0;
+ long StepWidth = 0;
+ long StopAt = -1;
+
memset(&Status, 0, sizeof(IterateStruct));
memcpy (&SubTP, &TP, sizeof(WCTemplputParams));
SubTP.Filter.ContextType = It->ContextType;
SubTP.Filter.ControlContextType = CTX_ITERATE;
SubTP.ControlContext = &Status;
- it = GetNewHashPos(List, 0);
+
+ if (HAVE_PARAM(2)) {
+ StartAt = GetTemplateTokenNumber(Target, TP, 2, 0);
+ }
+ if (HAVE_PARAM(3)) {
+ StepWidth = GetTemplateTokenNumber(Target, TP, 3, 0);
+ }
+ if (HAVE_PARAM(4)) {
+ StopAt = GetTemplateTokenNumber(Target, TP, 4, -1);
+ }
+ it = GetNewHashPos(List, StepWidth);
+ if (StopAt < 0) {
+ StopAt = GetCount(List);
+ }
while (GetNextHashPos(List, it, &Status.KeyLen, &Status.Key, &vContext)) {
- if (DetectGroupChange && Status.n > 0) {
- Status.GroupChange = (SortBy->GroupChange(vContext, vLastContext))? 1:0;
- }
- Status.LastN = ++Status.LastN == nMembersUsed;
- SubTP.Context = vContext;
- if (It->DoSubTemplate != NULL)
- It->DoSubTemplate(SubBuf, &SubTP);
- DoTemplate(TKEY(1), SubBuf, &SubTP);
+ if ((Status.n >= StartAt) && (Status.n <= StopAt)) {
+ if (DetectGroupChange && Status.n > 0) {
+ Status.GroupChange = (SortBy->GroupChange(vContext, vLastContext))? 1:0;
+ }
+ Status.LastN = (Status.n + 1) == nMembersUsed;
+ SubTP.Context = vContext;
+ if (It->DoSubTemplate != NULL)
+ It->DoSubTemplate(SubBuf, &SubTP);
+ DoTemplate(TKEY(1), SubBuf, &SubTP);
- StrBufAppendBuf(Target, SubBuf, 0);
- FlushStrBuf(SubBuf);
- Status.oddeven = ! Status.oddeven;
- vLastContext = vContext;
+ StrBufAppendBuf(Target, SubBuf, 0);
+ FlushStrBuf(SubBuf);
+ Status.oddeven = ! Status.oddeven;
+ vLastContext = vContext;
+ }
+ Status.n++;
}
FreeStrBuf(&SubBuf);
DeleteHashPos(&it);
const char *CompareToken;
long len;
- GetTemplateTokenString(TP, 2, &CompareToken, &len);
+ GetTemplateTokenString(Target, TP, 2, &CompareToken, &len);
return strcmp(ChrPtr(TokenText), CompareToken) == 0;
}
else {
const char *Ch;
long len;
- GetTemplateTokenString(TP,
+ GetTemplateTokenString(Target,
+ TP,
1,
&Ch,
&len);
else if (TP->Tokens->Params[i * 2]->Type == TYPE_GETTEXT) {
const char *Ch;
long len;
- GetTemplateTokenString(TP,
+ GetTemplateTokenString(Target,
+ TP,
i * 2,
&Ch,
&len);
RegisterControlNS(HKEY("ITERATE:N"), 0, 0, tmplput_ITERATE_LASTN, CTX_ITERATE);
}
+void
+ServerStartModule_SUBST
+(void)
+{
+ WirelessTemplateCache = NewHash(1, NULL);
+ WirelessLocalTemplateCache = NewHash(1, NULL);
+ LocalTemplateCache = NewHash(1, NULL);
+ TemplateCache = NewHash(1, NULL);
+
+ GlobalNS = NewHash(1, NULL);
+ Iterators = NewHash(1, NULL);
+ Conditionals = NewHash(1, NULL);
+ SortHash = NewHash(1, NULL);
+}
+
+void
+FinalizeModule_SUBST
+(void)
+{
+
+}
+
+void
+ServerShutdownModule_SUBST
+(void)
+{
+ DeleteHash(&WirelessTemplateCache);
+ DeleteHash(&WirelessLocalTemplateCache);
+ DeleteHash(&TemplateCache);
+ DeleteHash(&LocalTemplateCache);
+
+ DeleteHash(&GlobalNS);
+ DeleteHash(&Iterators);
+ DeleteHash(&Conditionals);
+ DeleteHash(&SortHash);
+
+}
+
+
+void
+SessionNewModule_SUBST
+(wcsession *sess)
+{
+
+}
+
+void
+SessionAttachModule_SUBST
+(wcsession *sess)
+{
+ sess->vars = NewHash(1,NULL);
+}
+
+void
+SessionDetachModule_SUBST
+(wcsession *sess)
+{
+ DeleteHash(&sess->vars);
+}
+
+void
+SessionDestroyModule_SUBST
+(wcsession *sess)
+{
+
+}
+
+
+
+
/*@}*/