]> code.citadel.org Git - citadel.git/blobdiff - webcit/subst.c
* add DAV namespace
[citadel.git] / webcit / subst.c
index 2cb30437ac394e54c5a69cdd1f04152267f93895..eea66ae6b98c06dcc30d58edea1a1b8dcb8c4060 100644 (file)
@@ -1,12 +1,6 @@
 /*
  * $Id$
  */
-/**
- * \defgroup Subst Variable substitution type stuff
- * \ingroup CitadelConfig
- */
-
-/*@{*/
 
 #include "sysdep.h"
 #include <sys/types.h>
@@ -20,7 +14,7 @@
 #include "webcit.h"
 #include "webserver.h"
 
-extern char *static_dirs[PATH_MAX];  /**< Disk representation */
+extern char *static_dirs[PATH_MAX];  /* Disk representation */
 
 HashList *WirelessTemplateCache;
 HashList *WirelessLocalTemplateCache;
@@ -49,15 +43,15 @@ const char EmptyStr[]="";
 
 
 /*
- * \brief Dynamic content for variable substitution in templates
+ * 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 ???*/
+       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;
 
 
@@ -110,6 +104,7 @@ const char *CtxNames[]  = {
        "Context FLOORS",
        "Context ITERATE",
        "Context ICAL",
+       "Context DavNamespace",
        "Context UNKNOWN"
 };
 
@@ -153,10 +148,14 @@ void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplpu
                Err = (TP->Tokens!= NULL)? TP->Tokens->pName:"";
                break;
        case ERR_PARM1:
-               Err = (TP->Tokens!= NULL)? TP->Tokens->Params[0]->Start:"";
+               Err = ((TP->Tokens!= NULL) && 
+                      (TP->Tokens->nParameters > 0))? 
+                       TP->Tokens->Params[0]->Start : "";
                break;
        case ERR_PARM2:
-               Err = (TP->Tokens!= NULL)? TP->Tokens->Params[1]->Start:"";
+               Err = ((TP->Tokens!= NULL) && 
+                      (TP->Tokens->nParameters > 1))? 
+                       TP->Tokens->Params[1]->Start : "";
                break;
        }
        if (TP->Tokens != NULL) 
@@ -180,8 +179,11 @@ void LogTemplateError (StrBuf *Target, const char *Type, int ErrorPos, WCTemplpu
                return;
 */
        WCC = WC;
-       if (WCC == NULL)
-               return;
+       if (WCC == NULL) {
+               FreeStrBuf(&Info);
+               FreeStrBuf(&Error);
+               return; 
+       }
 
        Header = NewStrBuf();
        if (TP->Tokens != NULL) 
@@ -396,12 +398,13 @@ void FreeWCTemplate(void *vFreeMe)
 }
 
 
-/**
- * \brief debugging function to print array to log
+/*
+ * debugging function to print array to log
  */
 void VarPrintTransition(void *vVar1, void *vVar2, int odd){}
-/**
- * \brief debugging function to print array to log
+
+/*
+ * debugging function to print array to log
  */
 void VarPrintEntry(const char *Key, void *vSubst, int odd)
 {
@@ -426,8 +429,8 @@ void VarPrintEntry(const char *Key, void *vSubst, int odd)
 
 
 
-/**
- * \brief Clear out the list of substitution variables local to this session
+/*
+ * Clear out the list of substitution variables local to this session
  */
 void clear_substs(wcsession *wc) {
 
@@ -436,8 +439,8 @@ void clear_substs(wcsession *wc) {
        }
 }
 
-/**
- * \brief Clear out the list of substitution variables local to this session
+/*
+ * Clear out the list of substitution variables local to this session
  */
 void clear_local_substs(void) {
        clear_substs (WC);
@@ -497,8 +500,8 @@ void FlushPayload(wcsubst *ptr, int reusestrbuf, int type)
 }
 
 
-/**
- * \brief destructor; kill one entry.
+/*
+ * destructor; kill one entry.
  */
 void deletevar(void *data)
 {
@@ -536,12 +539,12 @@ wcsubst *NewSubstVar(const char *keyname, int keylen, int type)
 }
 
 
-/**
- * \brief Add a substitution variable (local to this session) (strlen version...)
- * \param keyname the replacementstring to substitute
- * \param keytype the kind of the key
- * \param format the format string ala printf
- * \param ... the arguments to substitute in the formatstring
+/*
+ * Add a substitution variable (local to this session) (strlen version...)
+ * keyname the replacementstring to substitute
+ * keytype the kind of the key
+ * format the format string ala printf
+ * ... the arguments to substitute in the formatstring
  */
 void SVPRINTF(char *keyname, int keytype, const char *format,...)
 {
@@ -552,7 +555,7 @@ void SVPRINTF(char *keyname, int keytype, const char *format,...)
        wcsession *WCC = WC;
        
        keylen = strlen(keyname);
-       /**
+       /*
         * First look if we're doing a replacement of
         * an existing key
         */
@@ -567,18 +570,18 @@ void SVPRINTF(char *keyname, int keytype, const char *format,...)
                ptr = NewSubstVar(keyname, keylen, keytype);
        }
 
-       /** Format the string */
+       /* Format the string */
        va_start(arg_ptr, format);
        StrBufVAppendPrintf(ptr->wcs_value, format, arg_ptr);
        va_end(arg_ptr);
 }
 
-/**
- * \brief Add a substitution variable (local to this session)
- * \param keyname the replacementstring to substitute
- * \param keytype the kind of the key
- * \param format the format string ala printf
- * \param ... the arguments to substitute in the formatstring
+/*
+ * Add a substitution variable (local to this session)
+ * keyname the replacementstring to substitute
+ * keytype the kind of the key
+ * format the format string ala printf
+ * ... the arguments to substitute in the formatstring
  */
 void svprintf(char *keyname, size_t keylen, int keytype, const char *format,...)
 {
@@ -587,7 +590,7 @@ void svprintf(char *keyname, size_t keylen, int keytype, const char *format,...)
        wcsubst *ptr = NULL;
        wcsession *WCC = WC;
                
-       /**
+       /*
         * First look if we're doing a replacement of
         * an existing key
         */
@@ -608,12 +611,12 @@ void svprintf(char *keyname, size_t keylen, int keytype, const char *format,...)
        va_end(arg_ptr);
 }
 
-/**
- * \brief Add a substitution variable (local to this session)
- * \param keyname the replacementstring to substitute
- * \param keytype the kind of the key
- * \param format the format string ala printf
- * \param ... the arguments to substitute in the formatstring
+/*
+ * Add a substitution variable (local to this session)
+ * keyname the replacementstring to substitute
+ * keytype the kind of the key
+ * format the format string ala printf
+ * ... the arguments to substitute in the formatstring
  */
 void SVPut(char *keyname, size_t keylen, int keytype, char *Data)
 {
@@ -622,7 +625,7 @@ void SVPut(char *keyname, size_t keylen, int keytype, char *Data)
        wcsession *WCC = WC;
 
        
-       /**
+       /*
         * First look if we're doing a replacement of
         * an existing key
         */
@@ -1271,7 +1274,8 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf,
        NewToken->NameEnd = NewToken->TokenEnd - 2;
        NewToken->PreEval = NULL;
        NewToken->FlatToken = NewStrBufPlain(pTmplStart + 2, pTmplEnd - pTmplStart - 2);
-       
+       StrBufShrinkToFit(NewToken->FlatToken, 1);
+
        StrBufPeek(Buf, pTmplStart, + 1, '\0');
        StrBufPeek(Buf, pTmplEnd, -1, '\0');
        pch = NewToken->pName = pTmplStart + 2;
@@ -1432,6 +1436,7 @@ void *prepare_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
        memset(NewTemplate, 0, sizeof(WCTemplate));
        NewTemplate->Data = NULL;
        NewTemplate->FileName = NewStrBufDup(filename);
+       StrBufShrinkToFit(NewTemplate->FileName, 1);
        NewTemplate->nTokensUsed = 0;
        NewTemplate->TokenSpace = 0;
        NewTemplate->Tokens = NULL;
@@ -1493,6 +1498,7 @@ void *load_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
 
        Line = 0;
        StrBufShrinkToFit(NewTemplate->Data, 1);
+       StrBufShrinkToFit(NewTemplate->MimeType, 1);
        pS = pch = ChrPtr(NewTemplate->Data);
        pE = pS + StrLength(NewTemplate->Data);
        while (pch < pE) {
@@ -1503,7 +1509,11 @@ void *load_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
                /** Find one <? > */
                pos = (-1);
                for (; pch < pE; pch ++) {
-                       if ((*pch=='<')&&(*(pch + 1)=='?'))
+                       if ((*pch=='<')&&(*(pch + 1)=='?') &&
+                           !((pch == pS) && /* we must ommit a <?xml */
+                             (*(pch + 2) == 'x') && 
+                             (*(pch + 3) == 'm') && 
+                             (*(pch + 4) == 'l')))                          
                                break;
                        if (*pch=='\n') Line ++;
                }
@@ -1975,7 +1985,7 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP)
        while (GetNextHashPos(List, it, &Status.KeyLen, &Status.Key, &vContext)) {
                if ((Status.n >= StartAt) && (Status.n <= StopAt)) {
                        if (DetectGroupChange && Status.n > 0) {
-                               Status.GroupChange = (SortBy->GroupChange(vContext, vLastContext))? 1:0;
+                               Status.GroupChange = SortBy->GroupChange(vContext, vLastContext);
                        }
                        Status.LastN = (Status.n + 1) == nMembersUsed;
                        SubTP.Context = vContext;
@@ -2000,7 +2010,10 @@ void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP)
 int conditional_ITERATE_ISGROUPCHANGE(StrBuf *Target, WCTemplputParams *TP)
 {
        IterateStruct *Ctx = CCTX;
-       return Ctx->GroupChange;
+       if (TP->Tokens->nParameters < 3)
+               return  Ctx->GroupChange;
+
+       return TP->Tokens->Params[2]->lvalue == Ctx->GroupChange;
 }
 
 void tmplput_ITERATE_ODDEVEN(StrBuf *Target, WCTemplputParams *TP)
@@ -2027,6 +2040,12 @@ void tmplput_ITERATE_LASTN(StrBuf *Target, WCTemplputParams *TP)
        StrBufAppendPrintf(Target, "%d", Ctx->n);
 }
 
+int conditional_ITERATE_FIRSTN(StrBuf *Target, WCTemplputParams *TP)
+{
+       IterateStruct *Ctx = CCTX;
+       return Ctx->n == 0;
+}
+
 int conditional_ITERATE_LASTN(StrBuf *Target, WCTemplputParams *TP)
 {
        IterateStruct *Ctx = CCTX;
@@ -2173,7 +2192,7 @@ void tmpl_do_boxed(StrBuf *Target, WCTemplputParams *TP)
                        Headline = NewStrBufPlain(Ch, len);
                }
        }
-       memcpy (&SubTP, TP, sizeof(WCTemplputParams));
+       memcpy (&SubTP, TP, sizeof(WCTemplputParams));
        SubTP.Context = Headline;
        SubTP.Filter.ContextType = CTX_STRBUF;
        DoTemplate(HKEY("beginbox"), Target, &SubTP);
@@ -2599,6 +2618,10 @@ InitModule_SUBST
        RegisterControlConditional(HKEY("COND:ITERATE:LASTN"), 2, 
                                   conditional_ITERATE_LASTN, 
                                   CTX_ITERATE);
+       RegisterControlConditional(HKEY("COND:ITERATE:FIRSTN"), 2, 
+                                  conditional_ITERATE_FIRSTN, 
+                                  CTX_ITERATE);
+
        RegisterControlNS(HKEY("ITERATE:ODDEVEN"), 0, 0, tmplput_ITERATE_ODDEVEN, CTX_ITERATE);
        RegisterControlNS(HKEY("ITERATE:KEY"), 0, 0, tmplput_ITERATE_KEY, CTX_ITERATE);
        RegisterControlNS(HKEY("ITERATE:N"), 0, 0, tmplput_ITERATE_LASTN, CTX_ITERATE);
@@ -2670,8 +2693,3 @@ SessionDestroyModule_SUBST
 {
 
 }
-
-
-
-
-/*@}*/