* depending on the browser locale change the sequence of the
* language chooser.
*/
-void offer_languages(void) {
+void offer_languages(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context) {
int i;
#ifndef HAVE_USELOCALE
char *Lang = getenv("LANG");
/**
* \brief read this room's info file (set v to 1 for verbose mode)
*/
-void readinfo(void)
+void readinfo(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context)
{
char buf[256];
char briefinfo[128];
* keep the browser from using a cached icon from
* another room.
*/
-void embed_room_graphic(void) {
+void embed_room_graphic(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context) {
char buf[SIZ];
serv_puts("OIMG _roompic_");
/**
* \brief Display the current view and offer an option to change it
*/
-void embed_view_o_matic(void) {
+void embed_view_o_matic(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context) {
int i;
wprintf("<form name=\"viewomatic\" action=\"changeview\">\n");
/**
* \brief Display a search box
*/
-void embed_search_o_matic(void) {
+void embed_search_o_matic(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context) {
wprintf("<form name=\"searchomatic\" action=\"do_search\">\n");
wprintf("<div style=\"display: inline;\"><input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
wprintf("<label for=\"search_name\">");
/** offer the ability to switch views */
wprintf("<ul class=\"room_actions\">\n");
wprintf("<li class=\"start_page\">");
- offer_start_page();
+ offer_start_page(NULL, 0, NULL, NULL);
wprintf("</li>");
wprintf("<li><form name=\"roomlistomatic\">\n"
"<select name=\"newview\" size=\"1\" "
#define SV_NEG_CONDITIONAL 3
#define SV_CUST_STR_CONDITIONAL 4
#define SV_SUBTEMPL 5
+#define SV_PREEVALUATED 6
typedef struct _WCTemplate {
StrBuf *Data;
Put(GlobalNS, NSName, len, NewHandler, NULL);
}
+void FreeToken(WCTemplateToken **Token)
+{
+ int i;
+ FreeStrBuf(&(*Token)->FlatToken);
+ if ((*Token)->HaveParameters)
+ for (i = 0; i < (*Token)->nParameters; i++)
+ free((*Token)->Params[i]);
+ free(*Token);
+ *Token = NULL;
+}
+
+
+
+void FreeWCTemplate(void *vFreeMe)
+{
+ int i;
+ WCTemplate *FreeMe = (WCTemplate*)vFreeMe;
+
+ if (FreeMe->TokenSpace > 0) {
+ for (i = 0; i < FreeMe->nTokensUsed; i ++) {
+ FreeToken(&FreeMe->Tokens[i]);
+ }
+ free(FreeMe->Tokens);
+ }
+ FreeStrBuf(&FreeMe->FileName);
+ FreeStrBuf(&FreeMe->Data);
+ free(FreeMe);
+}
+
/**
* \brief debugging function to print array to log
* \param keyname the keystring to substitute
* \param fcn_ptr the function callback to give the substitution string
*/
-void SVCallback(char *keyname, size_t keylen, var_callback_fptr fcn_ptr)
+void SVCallback(char *keyname, size_t keylen, WCHandlerFunc fcn_ptr)
{
wcsubst *ptr;
void *vPtr;
ptr->wcs_function = fcn_ptr;
}
-inline void SVCALLBACK(char *keyname, var_callback_fptr fcn_ptr)
+inline void SVCALLBACK(char *keyname, WCHandlerFunc fcn_ptr)
{
SVCallback(keyname, strlen(keyname), fcn_ptr);
}
* \brief Print the value of a variable
* \param keyname get a key to print
*/
-void print_value_of(StrBuf *Target, const char *keyname, size_t keylen) {
+void print_value_of(StrBuf *Target, WCTemplateToken *Token, void *Context) {
struct wcsession *WCC = WC;
wcsubst *ptr;
void *vVar;
/*if (WCC->vars != NULL) PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/
/// TODO: debricated!
- if (keyname[0] == '=') {
- DoTemplate(keyname+1, keylen - 1, NULL, NULL);
+ if (Token->pName[0] == '=') {
+ DoTemplate(Token->pName+1, Token->NameEnd - 1, NULL, NULL);
}
//////TODO: if param[1] == "U" -> urlescape
/// X -> escputs
/** Page-local variables */
- if ((WCC->vars!= NULL) && GetHash(WCC->vars, keyname, keylen, &vVar)) {
+ if ((WCC->vars!= NULL) && GetHash(WCC->vars, Token->pName, Token->NameEnd, &vVar)) {
ptr = (wcsubst*) vVar;
switch(ptr->wcs_type) {
case WCS_STRING:
pvo_do_cmd(Target, ptr->wcs_value);
break;
case WCS_FUNCTION:
- (*ptr->wcs_function) ();
+ (*ptr->wcs_function) (Target, Token->nParameters, Token, Context);
break;
case WCS_STRBUF:
case WCS_STRBUF_REF:
StrBufAppendPrintf(Target, "%ld", ptr->lvalue);
break;
default:
- lprintf(1,"WARNING: invalid value in SV-Hash at %s!\n", keyname);
- StrBufAppendPrintf(Target, "<pre>WARNING: \ninvalid value in SV-Hash at %s!</pre>", keyname);
+ lprintf(1,"WARNING: invalid value in SV-Hash at %s!\n", Token->pName);
+ StrBufAppendPrintf(Target, "<pre>WARNING: \ninvalid value in SV-Hash at %s!\n</pre>", Token->pName);
}
}
}
NewToken->TokenEnd = (pTmplEnd - pStart) - NewToken->TokenStart;
NewToken->pTokenEnd = pTmplEnd;
NewToken->NameEnd = NewToken->TokenEnd - 2;
+ NewToken->PreEval = NULL;
NewToken->FlatToken = NewStrBufPlain(pTmplStart + 2, pTmplEnd - pTmplStart - 2);
StrBufPeek(Buf, pTmplStart, + 1, '\0');
MAXPARAM,
ChrPtr(NewToken->FlatToken));
free(Param);
+ FreeToken(&NewToken);
return NULL;
}
NewToken->Params[NewToken->nParameters++] = Param;
}
else pch ++;
}
- return NewToken;
-}
+
+ if (NewToken->Flags == 0) {
+ /* If we're able to find out more about the token, do it now while its fresh. */
+ void *vVar;
+ if (GetHash(GlobalNS, NewToken->pName, NewToken->NameEnd, &vVar)) {
+ HashHandler *Handler;
+ Handler = (HashHandler*) vVar;
+ if ((NewToken->nParameters < Handler->nMinArgs) ||
+ (NewToken->nParameters > Handler->nMaxArgs)) {
+ lprintf(1, "Handler [%s] (in '%s' line %ld); "
+ "doesn't work with %ld params [%s]\n",
+ NewToken->pName,
+ ChrPtr(pTmpl->FileName),
+ NewToken->Line,
+ NewToken->nParameters,
+ ChrPtr(NewToken->FlatToken));
+ }
+ else {
+ NewToken->PreEval = Handler;
+ NewToken->Flags = SV_PREEVALUATED;
+ }
+ }
+ }
-void FreeToken(WCTemplateToken **Token)
-{
- int i;
- FreeStrBuf(&(*Token)->FlatToken);
- if ((*Token)->HaveParameters)
- for (i = 0; i < (*Token)->nParameters; i++)
- free((*Token)->Params[i]);
- free(*Token);
- *Token = NULL;
+ return NewToken;
}
-void FreeWCTemplate(void *vFreeMe)
-{
- int i;
- WCTemplate *FreeMe = (WCTemplate*)vFreeMe;
-
- if (FreeMe->TokenSpace > 0) {
- for (i = 0; i < FreeMe->nTokensUsed; i ++) {
- FreeToken(&FreeMe->Tokens[i]);
- }
- free(FreeMe->Tokens);
- }
- FreeStrBuf(&FreeMe->FileName);
- FreeStrBuf(&FreeMe->Data);
- free(FreeMe);
-}
-
-
int EvaluateConditional(StrBuf *Target, WCTemplateToken *Token, WCTemplate *pTmpl, void *Context, int Neg, int state)
{
void *vConditional = NULL;
int EvaluateToken(StrBuf *Target, WCTemplateToken *Token, WCTemplate *pTmpl, void *Context, int state)
{
+ HashHandler *Handler;
void *vVar;
// much output, since pName is not terminated...
// lprintf(1,"Doing token: %s\n",Token->pName);
if (Token->nParameters == 1)
DoTemplate(Token->Params[0]->Start, Token->Params[0]->len, NULL, NULL);
break;
+ case SV_PREEVALUATED:
+ Handler = (HashHandler*) Token->PreEval;
+ Handler->HandlerFunc(Target,
+ Token->nParameters,
+ Token,
+ Context);
+ break;
default:
if (GetHash(GlobalNS, Token->pName, Token->NameEnd, &vVar)) {
- HashHandler *Handler;
Handler = (HashHandler*) vVar;
if ((Token->nParameters < Handler->nMinArgs) ||
(Token->nParameters > Handler->nMaxArgs)) {
}
}
else {
- print_value_of(Target, Token->pName, Token->NameEnd);
+ print_value_of(Target, Token, Context);
}
}
return 0;
wprintf("</h2></div>");
wprintf("<ul class=\"room_actions\">\n");
wprintf("<li class=\"start_page\">");
- offer_start_page();
+ offer_start_page(NULL, 0, NULL, NULL);
wprintf("</li></ul>");
wprintf("</div>");
/*
* Offer to make any page the user's "start page."
*/
-void offer_start_page(void) {
+void offer_start_page(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context) {
wprintf("<a href=\"change_start_page?startpage=");
urlescputs(WC->this_page);
wprintf("\">");
wprintf("NO\n");
}
else {
+ memset(buf, 5, 0);
serv_puts("NOOP");
serv_getln(buf, sizeof buf);
if (buf[3] == '*') {
}
}
-void tmplput_offer_start_page(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context)
-{
- offer_start_page();
-}
-
-
int ConditionalBstr(WCTemplateToken *Tokens, void *Context)
{
if(Tokens->nParameters == 1)
RegisterConditional(HKEY("COND:BSTR"), 1, ConditionalBstr);
RegisterNamespace("BSTR", 1, 2, tmplput_bstr);
RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage);
- RegisterNamespace("OFFERSTARTPAGE", 0, 0, tmplput_offer_start_page);
+ RegisterNamespace("OFFERSTARTPAGE", 0, 0, offer_start_page);
}
};
-
-/**
- * \brief Dynamic content for variable substitution in templates
- */
-typedef struct _wcsubst {
- 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 */
- void (*wcs_function)(void); /**< funcion hook ???*/
-} wcsubst;
-
#define TYPE_STR 1
#define TYPE_LONG 2
#define MAXPARAM 20
size_t TokenEnd;
const char *pTokenEnd;
int Flags;
+ void *PreEval;
const char *pName;
size_t NameEnd;
TemplateParam *Params[MAXPARAM];
} WCTemplateToken;
-
typedef void (*WCHandlerFunc)(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context);
+
+
+/**
+ * \brief Dynamic content for variable substitution in templates
+ */
+typedef struct _wcsubst {
+ 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;
+
+
void RegisterNS(const char *NSName, long len,
int nMinArgs,
int nMaxArgs,
WCHandlerFunc HandlerFunc);
#define RegisterNamespace(a, b, c, d) RegisterNS(a, sizeof(a)-1, b, c, d)
-
-
typedef int (*WCConditionalFunc)(WCTemplateToken *Token, void *Context);
typedef struct _ConditionalStruct {
int nParams;
HashDestructorFunc Destructor);
#define RegisterIterator(a, b, c, d, e, f) RegisterITERATOR(a, sizeof(a)-1, b, c, d, e, f)
+void SVPut(char *keyname, size_t keylen, int keytype, char *Data);
+#define svput(a, b, c) SVPut(a, sizeof(a) - 1, b, c)
+void SVPutLong(char *keyname, size_t keylen, long Data);
+#define svputlong(a, b) SVPutLong(a, sizeof(a) - 1, b)
+void svprintf(char *keyname, size_t keylen, int keytype, const char *format,...) __attribute__((__format__(__printf__,4,5)));
+void SVPRINTF(char *keyname, int keytype, const char *format,...) __attribute__((__format__(__printf__,3,4)));
+void SVCALLBACK(char *keyname, WCHandlerFunc fcn_ptr);
+void SVCallback(char *keyname, size_t keylen, WCHandlerFunc fcn_ptr);
+#define svcallback(a, b) SVCallback(a, sizeof(a) - 1, b)
+
+void SVPUTBuf(const char *keyname, int keylen, const StrBuf *Buf, int ref);
+#define SVPutBuf(a, b, c); SVPUTBuf(a, sizeof(a) - 1, b, c)
+
+void DoTemplate(const char *templatename, long len, void *Context, StrBuf *Target);
+#define do_template(a, b) DoTemplate(a, sizeof(a) -1, b, NULL);
+void url_do_template(void);
+
+int CompareSubstToToken(TemplateParam *ParamToCompare, TemplateParam *ParamToLookup);
+int CompareSubstToStrBuf(StrBuf *Compare, TemplateParam *ParamToLookup);
+
+
+
+
/**
* \brief Values for wcs_type
*/
void clear_local_substs(void);
-typedef void (*var_callback_fptr)();
-
-
-void SVPut(char *keyname, size_t keylen, int keytype, char *Data);
-#define svput(a, b, c) SVPut(a, sizeof(a) - 1, b, c)
-void SVPutLong(char *keyname, size_t keylen, long Data);
-#define svputlong(a, b) SVPutLong(a, sizeof(a) - 1, b)
-void svprintf(char *keyname, size_t keylen, int keytype, const char *format,...) __attribute__((__format__(__printf__,4,5)));
-void SVPRINTF(char *keyname, int keytype, const char *format,...) __attribute__((__format__(__printf__,3,4)));
-void SVCALLBACK(char *keyname, var_callback_fptr fcn_ptr);
-void SVCallback(char *keyname, size_t keylen, var_callback_fptr fcn_ptr);
-#define svcallback(a, b) SVCallback(a, sizeof(a) - 1, b)
-
-void SVPUTBuf(const char *keyname, int keylen, const StrBuf *Buf, int ref);
-#define SVPutBuf(a, b, c); SVPUTBuf(a, sizeof(a) - 1, b, c)
-
-void DoTemplate(const char *templatename, long len, void *Context, StrBuf *Target);
-#define do_template(a, b) DoTemplate(a, sizeof(a) -1, b, NULL);
-void url_do_template(void);
-
-int CompareSubstToToken(TemplateParam *ParamToCompare, TemplateParam *ParamToLookup);
-int CompareSubstToStrBuf(StrBuf *Compare, TemplateParam *ParamToLookup);
int lingering_close(int fd);
char *memreadline(char *start, char *buf, int maxlen);
int is_msg_in_mset(char *mset, long msgnum);
void display_addressbook(long msgnum, char alpha);
-void offer_start_page(void);
+void offer_start_page(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context);
void convenience_page(char *titlebarcolor, char *titlebarmsg, char *messagetext);
void output_html(char *, int);
void do_listsub(void);
int CtdlDecodeQuotedPrintable(char *decoded, char *encoded, int sourcelen);
void spawn_another_worker_thread(void);
void display_rss(char *roomname, StrBuf *request_method);
-void offer_languages(void);
+void offer_languages(StrBuf *Target, int nArgs, WCTemplateToken *Token, void *Context);
void set_selected_language(const char *);
void go_selected_language(void);
void stop_selected_language(void);