Diff
Not logged in

Differences From:

File src/th_main.c part of check-in [3ad9a5e210] - TH1 script now used to render the header and footer of each page. by drh on 2008-02-13 18:18:50. [view]

To:

File src/th_main.c part of check-in [ffe92f1a2f] - The entire header, including the menu bar, is now generated by TH script. This allows the menu bar to be customized by editing the header script. by drh on 2008-02-13 19:50:27. [view]

@@ -85,16 +85,21 @@
 /*
 ** Send text to the appropriate output:  Either to the console
 ** or to the CGI reply buffer.
 */
-static void sendText(const char *z, int n){
+static void sendText(const char *z, int n, int encode){
   if( enableOutput && n ){
     if( n<0 ) n = strlen(z);
+    if( encode ){
+      z = htmlize(z, n);
+      n = strlen(z);
+    }
     if( g.cgiPanic ){
       cgi_append_content(z, n);
     }else{
       fwrite(z, 1, n, stdout);
     }
+    if( encode ) free((char*)z);
   }
 }
 
 /*
@@ -112,23 +117,9 @@
 ){
   if( argc!=2 ){
     return Th_WrongNumArgs(interp, "puts STRING");
   }
-  if( enableOutput ){
-    int size;
-    char *zOut;
-    if( pConvert ){
-      zOut = htmlize((char*)argv[1], argl[1]);
-      size = strlen(zOut);
-    }else{
-      zOut = (char*)argv[1];
-      size = argl[1];
-    }
-    sendText(zOut, size);
-    if( pConvert ){
-      free(zOut);
-    }
-  }
+  sendText((char*)argv[1], argl[1], pConvert!=0);
   return TH_OK;
 }
 
 /*
@@ -143,16 +134,35 @@
   const unsigned char **argv,
   int *argl
 ){
   if( argc!=2 ){
-    return Th_WrongNumArgs(interp, "puts STRING");
+    return Th_WrongNumArgs(interp, "wiki STRING");
   }
   if( enableOutput ){
     Blob src;
     blob_init(&src, (char*)argv[1], argl[1]);
     wiki_convert(&src, 0, WIKI_INLINE);
     blob_reset(&src);
   }
+  return TH_OK;
+}
+
+/*
+** TH command:     hascap STRING
+**
+** Return true if the user has all of the capabilities listed in STRING.
+*/
+static int hascapCmd(
+  Th_Interp *interp,
+  void *p,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  if( argc!=2 ){
+    return Th_WrongNumArgs(interp, "hascap STRING");
+  }
+  Th_SetResultInt(interp, login_has_capability((char*)argv[1],argl[1]));
   return TH_OK;
 }
 
 /*
@@ -164,8 +174,9 @@
     Th_CommandProc xProc;
     void *pContext;
   } aCommand[] = {
     {"enable_output", enableOutputCmd,      0},
+    {"hascap",        hascapCmd,            0},
     {"html",          putsCmd,              0},
     {"puts",          putsCmd,       (void*)1},
     {"wiki",          wikiCmd,              0},
   };
@@ -184,9 +195,9 @@
 ** Initialize a variable in the interpreter.
 */
 void Th_InitVar(const char *zName, const char *zValue){
   initializeInterp();
-  Th_SetVar(interp, zName, -1, zValue, strlen(zValue));
+  Th_SetVar(interp, (uchar*)zName, -1, (uchar*)zValue, strlen(zValue));
 }
 
 /*
 ** Return true if the string begins with the TH1 begin-script
@@ -218,29 +229,42 @@
 ** the number of characters in that name.  Otherwise, return 0.
 */
 static int validVarName(const char *z){
   int i = 0;
+  int inBracket = 0;
+  if( z[0]=='<' ){
+    inBracket = 1;
+    z++;
+  }
   if( z[0]==':' && z[1]==':' && isalpha(z[2]) ){
     z += 3;
-    i = 3;
+    i += 3;
   }else if( isalpha(z[0]) ){
     z ++;
-    i = 1;
+    i += 1;
   }else{
     return 0;
   }
   while( isalnum(z[0]) || z[0]=='_' ){
     z++;
     i++;
   }
+  if( inBracket ){
+    if( z[0]!='>' ) return 0;
+    i += 2;
+  }
   return i;
 }
 
 /*
 ** The z[] input contains text mixed with TH1 scripts.
-** The TH1 scripts are contained within <th1>...</th1>.  This routine
-** processes the template and writes the results on either
-** stdout or into CGI.
+** The TH1 scripts are contained within <th1>...</th1>.
+** TH1 variables are $aaa or $<aaa>.  The first form of
+** variable is literal.  The second is run through htmlize
+** before being inserted.
+**
+** This routine processes the template and writes the results
+** on either stdout or into CGI.
 */
 int Th_Render(const char *z){
   int i = 0;
   int n;
@@ -248,16 +272,27 @@
   uchar *zResult;
   initializeInterp();
   while( z[i] ){
     if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
-      sendText(z, i);
-      rc = Th_GetVar(interp, &z[i+1], n);
+      const char *zVar;
+      int nVar;
+      sendText(z, i, 0);
+      if( z[i+1]=='<' ){
+        /* Variables of the form $<aaa> */
+        zVar = &z[i+2];
+        nVar = n-2;
+      }else{
+        /* Variables of the form $aaa */
+        zVar = &z[i+1];
+        nVar = n;
+      }
+      rc = Th_GetVar(interp, (uchar*)zVar, nVar);
       z += i+1+n;
       i = 0;
-      zResult = Th_GetResult(interp, &n);
-      sendText(zResult, n);
+      zResult = (uchar*)Th_GetResult(interp, &n);
+      sendText((char*)zResult, n, n>nVar);
     }else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
-      sendText(z, i);
+      sendText(z, i, 0);
       z += i+5;
       for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
       rc = Th_Eval(interp, 0, (const uchar*)z, i);
       if( rc!=SBS_OK ) break;
@@ -268,14 +303,14 @@
       i++;
     }
   }
   if( rc==TH_ERROR ){
-    sendText("<hr><p><font color=\"red\"><b>ERROR: ", -1);
-    zResult = Th_GetResult(interp, &n);
-    sendText(zResult, n);
-    sendText("</b></font></p>", -1);
+    sendText("<hr><p><font color=\"red\"><b>ERROR: ", -1, 0);
+    zResult = (uchar*)Th_GetResult(interp, &n);
+    sendText((char*)zResult, n, 1);
+    sendText("</b></font></p>", -1, 0);
   }else{
-    sendText(z, i);
+    sendText(z, i, 0);
   }
   return rc;
 }