* move stuff in header and subst.c arround to be better grouped
authorWilfried Göesgens <willi@citadel.org>
Mon, 15 Sep 2008 21:41:22 +0000 (21:41 +0000)
committerWilfried Göesgens <willi@citadel.org>
Mon, 15 Sep 2008 21:41:22 +0000 (21:41 +0000)
* harmonize callback function types
* add pre-eval shortcut; if we know the handler while evaluating the template, store a pointer to it, so we save hash lookups at runtime.

webcit/gettext.c
webcit/roomops.c
webcit/subst.c
webcit/summary.c
webcit/webcit.c
webcit/webcit.h

index 2c12eff805a234ab306a70798d5d98329240d807..7e5caeb2f7129c9b7cd2218fd5afa55ba940a871 100644 (file)
@@ -204,7 +204,7 @@ void httplang_to_locale(StrBuf *LocaleString)
  * 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");
index 5869173a55153f2eb5b36fda03122cf4215dc193..7c291b4a9a36bcb09214c275c40feb27afe03388 100644 (file)
@@ -273,7 +273,7 @@ void zapped_list(void)
 /**
  * \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];
@@ -322,7 +322,7 @@ void readinfo(void)
  * 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_");
@@ -378,7 +378,7 @@ void embed_room_graphic(void) {
 /**
  * \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");
@@ -419,7 +419,7 @@ void embed_view_o_matic(void) {
 /**
  * \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\">");
@@ -3587,7 +3587,7 @@ void knrooms(void)
        /** 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\" "
index 32000bb3fc4f7c59b8fe89a55191c37589dcde07..adee900ba3ddbdfce7b74d5e5311e593a62c17e4 100644 (file)
@@ -38,6 +38,7 @@ int LoadTemplates = 0;
 #define SV_NEG_CONDITIONAL 3
 #define SV_CUST_STR_CONDITIONAL 4
 #define SV_SUBTEMPL 5
+#define SV_PREEVALUATED 6
 
 typedef struct _WCTemplate {
        StrBuf *Data;
@@ -66,6 +67,35 @@ void RegisterNS(const char *NSName, long len, int nMinArgs, int nMaxArgs, WCHand
        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
@@ -346,7 +376,7 @@ void SVPutLong(char *keyname, size_t keylen, long Data)
  * \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;
@@ -369,7 +399,7 @@ void SVCallback(char *keyname, size_t keylen, var_callback_fptr fcn_ptr)
 
        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);
 }
@@ -430,21 +460,21 @@ void pvo_do_cmd(StrBuf *Target, StrBuf *servcmd) {
  * \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:
@@ -454,7 +484,7 @@ void print_value_of(StrBuf *Target, const char *keyname, size_t keylen) {
                        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:
@@ -464,8 +494,8 @@ void print_value_of(StrBuf *Target, const char *keyname, size_t keylen) {
                        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);
                }
        }
 }
@@ -666,6 +696,7 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf,
        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');
@@ -692,6 +723,7 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf,
                                                        MAXPARAM,
                                                        ChrPtr(NewToken->FlatToken));
                                                free(Param);
+                                               FreeToken(&NewToken);
                                                return NULL;
                                        }
                                        NewToken->Params[NewToken->nParameters++] = Param;
@@ -721,39 +753,35 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf,
                }
                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;
@@ -808,6 +836,7 @@ int EvaluateConditional(StrBuf *Target, WCTemplateToken *Token, WCTemplate *pTmp
 
 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);
@@ -839,9 +868,15 @@ int EvaluateToken(StrBuf *Target, WCTemplateToken *Token, WCTemplate *pTmpl, voi
                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)) {
@@ -871,7 +906,7 @@ int EvaluateToken(StrBuf *Target, WCTemplateToken *Token, WCTemplate *pTmpl, voi
                        }
                }
                else {
-                       print_value_of(Target, Token->pName, Token->NameEnd);
+                       print_value_of(Target, Token, Context);
                }
        }
        return 0;
index 9f673649b9b08569b60cbae30c4ca776867161d6..00a52096dddc9e4e1cf9f99ddd8aa97617c1bae0 100644 (file)
@@ -259,7 +259,7 @@ void summary(void) {
         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>");
 
index 20b9342e2943e055232eb63b0f3378ff15e7c6a0..422f580da00c2b1c11e97015b5c7aa9f83eaf64d 100644 (file)
@@ -1066,7 +1066,7 @@ void url_do_template(void) {
 /*
  * 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("\">");
@@ -1285,6 +1285,7 @@ void seconds_since_last_gexp(void)
                wprintf("NO\n");
        }
        else {
+               memset(buf, 5, 0);
                serv_puts("NOOP");
                serv_getln(buf, sizeof buf);
                if (buf[3] == '*') {
@@ -1831,12 +1832,6 @@ void tmplput_importantmessage(StrBuf *Target, int nArgs, WCTemplateToken *Tokens
        }
 }
 
-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)
@@ -1873,5 +1868,5 @@ InitModule_WEBCIT
        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);
 }
index 8805d0aa88a4e5c55c8338215928cf69d23a28e4..ebf48cdcd3852701b4ee334d3d040c8af7c2f6b8 100644 (file)
@@ -254,18 +254,6 @@ struct roomlisting {
 };
 
 
-
-/**
- * \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
@@ -284,6 +272,7 @@ typedef struct _TemplateToken {
        size_t TokenEnd;
        const char *pTokenEnd;
        int Flags;
+       void *PreEval;
 
        const char *pName;
        size_t NameEnd;
@@ -293,16 +282,27 @@ typedef struct _TemplateToken {
        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;
@@ -325,6 +325,29 @@ void RegisterITERATOR(const char *Name, long len,
                      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
  */
@@ -659,28 +682,6 @@ void clear_substs(struct wcsession *wc);
 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);
@@ -725,7 +726,7 @@ void set_ROOM_PREFS(const char *key, size_t keylen, StrBuf *value, int save_to_s
 
 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);
@@ -794,7 +795,7 @@ void do_selected_iconbar(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);