Check-in [588bb7cd73]
Not logged in
Overview

SHA1 Hash:588bb7cd734d4c3a066a715249f8498f425518e3
Date: 2008-02-24 18:50:35
User: aku
Comment:Merged to ed26056bb5.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/blob.c from [e355ed75f1] to [2269ea6655].

@@ -241,10 +241,11 @@
 ** routine.  blob_str() will make a copy of the p if necessary
 ** to avoid modifying pBig.
 */
 char *blob_terminate(Blob *p){
   blob_is_init(p);
+  if( p->nUsed==0 ) return "";
   p->aData[p->nUsed] = 0;
   return p->aData;
 }
 
 /*

Modified src/checkin.c from [3db074a16d] to [f5120aa9ee].

@@ -327,10 +327,12 @@
   char *zUuid, *zDate;
   int noSign = 0;        /* True to omit signing the manifest using GPG */
   int isAMerge = 0;      /* True if checking in a merge */
   int forceFlag = 0;     /* Force a fork */
   char *zManifestFile;   /* Name of the manifest file */
+  int nBasename;         /* Length of "g.zLocalRoot/" */
+  Blob filename;         /* complete filename */
   Blob manifest;
   Blob muuid;            /* Manifest uuid */
   Blob mcksum;           /* Self-checksum on the manifest */
   Blob cksum1, cksum2;   /* Before and after commit checksums */
   Blob cksum1b;          /* Checksum recorded in the manifest */
@@ -447,15 +449,27 @@
   blob_appendf(&manifest, "D %s\n", zDate);
   db_prepare(&q,
     "SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid"
     " WHERE NOT deleted AND vfile.vid=%d"
     " ORDER BY 1", vid);
+  blob_zero(&filename);
+  blob_appendf(&filename, "%s/", g.zLocalRoot);
+  nBasename = blob_size(&filename);
   while( db_step(&q)==SQLITE_ROW ){
     const char *zName = db_column_text(&q, 0);
     const char *zUuid = db_column_text(&q, 1);
-    blob_appendf(&manifest, "F %F %s\n", zName, zUuid);
-  }
+    const char *zPerm;
+    blob_append(&filename, zName, -1);
+    if( file_isexe(blob_str(&filename)) ){
+      zPerm = " x";
+    }else{
+      zPerm = "";
+    }
+    blob_resize(&filename, nBasename);
+    blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
+  }
+  blob_reset(&filename);
   db_finalize(&q);
   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
   blob_appendf(&manifest, "P %s", zUuid);
 
   db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");

Modified src/checkout.c from [226cbdc63b] to [d833774799].

@@ -98,24 +98,40 @@
 */
 void manifest_to_disk(int vid){
   char *zManFile;
   Blob manifest;
   Blob hash;
+  Blob filename;
+  int baseLen;
+  int i;
+  Manifest m;
 
   blob_zero(&manifest);
   zManFile = mprintf("%smanifest", g.zLocalRoot);
   content_get(vid, &manifest);
   blob_write_to_file(&manifest, zManFile);
   free(zManFile);
   blob_zero(&hash);
   sha1sum_blob(&manifest, &hash);
-  blob_reset(&manifest);
   zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
   blob_append(&hash, "\n", 1);
   blob_write_to_file(&hash, zManFile);
   free(zManFile);
   blob_reset(&hash);
+  manifest_parse(&m, &manifest);
+  blob_zero(&filename);
+  blob_appendf(&filename, "%s/", g.zLocalRoot);
+  baseLen = blob_size(&filename);
+  for(i=0; i<m.nFile; i++){
+    int isExe;
+    blob_append(&filename, m.aFile[i].zName, -1);
+    isExe = m.aFile[i].zPerm && strstr(m.aFile[i].zPerm, "x");
+    file_setexe(blob_str(&filename), isExe);
+    blob_resize(&filename, baseLen);
+  }
+  blob_reset(&filename);
+  manifest_clear(&m);
 }
 
 /*
 ** COMMAND: checkout
 **

Modified src/file.c from [d8c82766a0] to [6f2a64a222].

@@ -65,10 +65,41 @@
   }
   return S_ISREG(buf.st_mode);
 }
 
 /*
+** Return TRUE if the named file is an executable.  Return false
+** for directories, devices, fifos, symlinks, etc.
+*/
+int file_isexe(const char *zFilename){
+  struct stat buf;
+  if( stat(zFilename, &buf)!=0 ){
+    return 0;
+  }
+  return ((S_IXUSR|S_IXGRP|S_IXOTH)&buf.st_mode)!=0;
+}
+
+/*
+** Set or clear the execute bit on a file.
+*/
+void file_setexe(const char *zFilename, int onoff){
+#ifndef __MINGW32__
+  struct stat buf;
+  if( stat(zFilename, &buf)!=0 ) return;
+  if( onoff ){
+    if( (buf.st_mode & 0111)==0 ){
+      chmod(zFilename, buf.st_mode | 0111);
+    }
+  }else{
+    if( (buf.st_mode & 0111)!=0 ){
+      chmod(zFilename, buf.st_mode & ~0111);
+    }
+  }
+#endif
+}
+
+/*
 ** Return 1 if zFilename is a directory.  Return 0 if zFilename
 ** does not exist.  Return 2 if zFilename exists but is something
 ** other than a directory.
 */
 int file_isdir(const char *zFilename){
@@ -75,24 +106,10 @@
   struct stat buf;
   if( stat(zFilename, &buf)!=0 ){
     return 0;
   }
   return S_ISDIR(buf.st_mode) ? 1 : 2;
-}
-
-/*
-** Find both the size and modification time of a file.  Return
-** the number of errors.
-*/
-int file_size_and_mtime(const char *zFilename, i64 *size, i64 *mtime){
-  struct stat buf;
-  if( stat(zFilename, &buf)!=0 ){
-    return 1;
-  }
-  *size = buf.st_size;
-  *mtime = buf.st_mtime;
-  return 0;
 }
 
 /*
 ** Create the directory named in the argument, if it does not already
 ** exist.  If forceFlag is 1, delete any prior non-directory object

Modified src/info.c from [33d2efae51] to [97d9ed98da].

@@ -21,11 +21,11 @@
 **
 *******************************************************************************
 **
 ** This file contains code to implement the "info" command.  The
 ** "info" command gives command-line access to information about
-** the current tree, or a particular file or version.
+** the current tree, or a particular artifact or baseline.
 */
 #include "config.h"
 #include "info.h"
 #include <assert.h>
 
@@ -106,11 +106,11 @@
     show_common_info(rid, "uuid:", 1);
   }
 }
 
 /*
-** Show information about descendents of a version.  Do this recursively
+** Show information about descendents of a baseline.  Do this recursively
 ** to a depth of N.  Return true if descendents are shown and false if not.
 */
 static int showDescendents(int pid, int depth, const char *zTitle){
   Stmt q;
   int cnt = 0;
@@ -158,11 +158,11 @@
   }
   return cnt;
 }
 
 /*
-** Show information about ancestors of a version.  Do this recursively
+** Show information about ancestors of a baseline.  Do this recursively
 ** to a depth of N.  Return true if ancestors are shown and false if not.
 */
 static void showAncestors(int pid, int depth, const char *zTitle){
   Stmt q;
   int cnt = 0;
@@ -203,11 +203,11 @@
   }
 }
 
 
 /*
-** Show information about versions mentioned in the "leaves" table.
+** Show information about baselines mentioned in the "leaves" table.
 */
 static void showLeaves(void){
   Stmt q;
   int cnt = 0;
   db_prepare(&q,
@@ -240,20 +240,20 @@
 }
 
 /*
 ** Show information about all tags on a given node.
 */
-static void showTags(int rid){
+static void showTags(int rid, const char *zNotGlob){
   Stmt q;
   int cnt = 0;
   db_prepare(&q,
     "SELECT tag.tagid, tagname, srcid, blob.uuid, value,"
     "       datetime(tagxref.mtime,'localtime'), tagtype"
     "  FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid"
     "       LEFT JOIN blob ON blob.rid=tagxref.srcid"
-    " WHERE tagxref.rid=%d"
-    " ORDER BY tagname", rid
+    " WHERE tagxref.rid=%d AND tagname NOT GLOB '%s'"
+    " ORDER BY tagname", rid, zNotGlob
   );
   while( db_step(&q)==SQLITE_ROW ){
     const char *zTagname = db_column_text(&q, 1);
     int srcid = db_column_int(&q, 2);
     const char *zUuid = db_column_text(&q, 3);
@@ -291,11 +291,11 @@
 
 /*
 ** WEBPAGE: vinfo
 ** URL:  /vinfo?name=RID|UUID
 **
-** Return information about a version.
+** Return information about a baseline
 */
 void vinfo_page(void){
   Stmt q;
   int rid;
   int isLeaf;
@@ -317,11 +317,11 @@
      "   AND event.objid=%d",
      rid, rid
   );
   if( db_step(&q)==SQLITE_ROW ){
     const char *zUuid = db_column_text(&q, 0);
-    char *zTitle = mprintf("Version: [%.10s]", zUuid);
+    char *zTitle = mprintf("Baseline [%.10s]", zUuid);
     style_header(zTitle);
     free(zTitle);
     /*@ <h2>Version %s(zUuid)</h2>*/
     @ <div class="section">Overview</div>
     @ <p><table class="label-value">
@@ -335,19 +335,19 @@
     @ </td></tr>
     @ <tr><th>Commands:</th>
     @   <td>
     @     <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a>
     @     | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a>
-    @     | <a href="%s(g.zBaseURL)/fview/%d(rid)">manifest</a>
+    @     | <a href="%s(g.zBaseURL)/artifact/%d(rid)">manifest</a>
     @   </td>
     @ </tr>
     @ </table></p>
   }else{
-    style_header("Version Information");
+    style_header("Baseline Information");
   }
   db_finalize(&q);
-  showTags(rid);
+  showTags(rid, "");
   @ <div class="section">Changes</div>
   @ <ul>
   db_prepare(&q,
      "SELECT name, pid, fid"
      "  FROM mlink, filename"
@@ -422,20 +422,37 @@
     }
     @ <tr><th>Original&nbsp;User:</th><td>%s(db_column_text(&q, 3))</td></tr>
     @ <tr><th>Commands:</th>
     @   <td>
 /*    @     <a href="%s(g.zBaseURL)/wdiff/%d(rid)">diff</a> | */
-    @     <a href="%s(g.zBaseURL)/whistory?page=%t(zName)">history</a>
-    @     | <a href="%s(g.zBaseURL)/fview/%d(rid)">raw-text</a>
+    @     <a href="%s(g.zBaseURL)/whistory?name=%t(zName)">history</a>
+    @     | <a href="%s(g.zBaseURL)/artifact/%d(rid)">raw-text</a>
     @   </td>
     @ </tr>
     @ </table></p>
   }else{
     style_header("Wiki Information");
+    rid = 0;
   }
   db_finalize(&q);
-  showTags(rid);
+  showTags(rid, "wiki-*");
+  if( rid ){
+    Blob content;
+    Manifest m;
+    memset(&m, 0, sizeof(m));
+    blob_zero(&m.content);
+    content_get(rid, &content);
+    manifest_parse(&m, &content);
+    if( m.type==CFTYPE_WIKI ){
+      Blob wiki;
+      blob_init(&wiki, m.zWiki, -1);
+      @ <div class="section">Content</div>
+      wiki_convert(&wiki, 0, 0);
+      blob_reset(&wiki);
+    }
+    manifest_clear(&m);
+  }
   style_footer();
 }
 
 /*
 ** WEBPAGE: finfo
@@ -499,11 +516,11 @@
     @ <td width="20"></td>
     @ <td valign="top" align="left">
     hyperlink_to_uuid(zVers);
     @ %h(zCom) (By: %h(zUser))
     @ Id: %s(zUuid)/%d(frid)
-    @ <a href="%s(g.zBaseURL)/fview/%d(frid)">[view]</a>
+    @ <a href="%s(g.zBaseURL)/artifact/%d(frid)">[view]</a>
     if( fpid ){
       @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&amp;v2=%d(frid)">[diff]</a>
     }
     @ <a href="%s(g.zBaseURL)/annotate?mid=%d(mid)&amp;fnid=%d(fnid)">
     @ [annotate]</a>
@@ -541,11 +558,11 @@
   Stmt q;
   char *zUuid;
 
   login_check_credentials();
   if( !g.okHistory ){ login_needed(); return; }
-  style_header("Version Diff");
+  style_header("Baseline Changes");
 
   rid = name_to_rid(PD("name",""));
   if( rid==0 ){
     cgi_redirect("index");
   }
@@ -556,11 +573,11 @@
      "   AND filename.fnid=mlink.fnid"
      " ORDER BY name",
      rid
   );
   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
-  @ <h2>All Changes In Version
+  @ <h2>All Changes In Baseline
   hyperlink_to_uuid(zUuid);
   @ </h2>
   while( db_step(&q)==SQLITE_ROW ){
     int pid = db_column_int(&q,0);
     int fid = db_column_int(&q,1);
@@ -580,11 +597,11 @@
 **
 ** If the object is a file then mention:
 **
 **     * It's uuid
 **     * All its filenames
-**     * The versions it was checked-in on, with times and users
+**     * The baselines it was checked-in on, with times and users
 **
 ** If the object is a manifest, then mention:
 **
 **     * It's uuid
 **     * date of check-in
@@ -644,11 +661,11 @@
     cnt++;
   }
   db_finalize(&q);
   if( nWiki==0 ){
     db_prepare(&q,
-      "SELECT datetime(mtime), user, comment, uuid"
+      "SELECT datetime(mtime), user, comment, uuid, type"
       "  FROM event, blob"
       " WHERE event.objid=%d"
       "   AND blob.rid=%d",
       rid, rid
     );
@@ -655,11 +672,20 @@
     while( db_step(&q)==SQLITE_ROW ){
       const char *zDate = db_column_text(&q, 0);
       const char *zUuid = db_column_text(&q, 3);
       const char *zUser = db_column_text(&q, 1);
       const char *zCom = db_column_text(&q, 2);
-      @ Manifest of version
+      const char *zType = db_column_text(&q, 4);
+      if( zType[0]=='w' ){
+        @ Wiki edit
+      }else if( zType[0]=='t' ){
+        @ Ticket change
+      }else if( zType[0]=='c' ){
+        @ Manifest of baseline
+      }else{
+        @ Control file referencing
+      }
       hyperlink_to_uuid(zUuid);
       @ %w(zCom) by %h(zUser) on %s(zDate)
       cnt++;
     }
     db_finalize(&q);
@@ -666,11 +692,11 @@
   }
   if( cnt==0 ){
     char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
     @ Control file %s(zUuid).
   }else if( linkToView ){
-    @ <a href="%s(g.zBaseURL)/fview/%d(rid)">[view]</a>
+    @ <a href="%s(g.zBaseURL)/artifact/%d(rid)">[view]</a>
   }
 }
 
 /*
 ** WEBPAGE: fdiff
@@ -707,17 +733,17 @@
   blob_reset(&diff);
   style_footer();
 }
 
 /*
-** WEBPAGE: fview
-** URL: /fview?name=UUID
+** WEBPAGE: artifact
+** URL: /artifact?name=UUID
 **
 ** Show the complete content of a file identified by UUID
 ** as preformatted text.
 */
-void fview_page(void){
+void artifact_page(void){
   int rid;
   Blob content;
 
   rid = name_to_rid(PD("name","0"));
   login_check_credentials();
@@ -731,11 +757,11 @@
     if( db_exists("SELECT 1 FROM plink WHERE cid=%d", rid) ){
       vinfo_page();
       return;
     }
   }
-  style_header("File Content");
+  style_header("Artifact Content");
   @ <h2>Content Of:</h2>
   @ <blockquote>
   object_description(rid, 0);
   @ </blockquote>
   @ <hr>
@@ -750,84 +776,36 @@
 /*
 ** WEBPAGE: info
 ** URL: info/UUID
 **
 ** The argument is a UUID which might be a baseline or a file or
-** a ticket or something else.  It might also be a wiki page name.
-** Figure out what the UUID is an jump to it.  If there is ambiguity,
-** draw a page and let the user select the interpretation.
+** a ticket changes or a wiki editor or something else.
+**
+** Figure out what the UUID is and jump to it.
 */
 void info_page(void){
   const char *zName;
-  int rc = 0, nName, cnt;
-  Stmt q;
+  int rid, nName;
 
   zName = P("name");
   if( zName==0 ) cgi_redirect("index");
   nName = strlen(zName);
   if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
     cgi_redirect("index");
   }
-  db_multi_exec(
-     "CREATE TEMP TABLE refs(type,link);"
-     "INSERT INTO refs "
-     "  SELECT 'f', rid FROM blob WHERE uuid GLOB '%s*'"
-     "  UNION ALL"
-     "  SELECT 'w', substr(tagname,6) FROM tag"
-     "   WHERE tagname='wiki-%q'"
-     /*"  UNION ALL"
-     "  SELECT 't', tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*';"*/,
-     zName, zName, zName
-  );
-  cnt = db_int(0, "SELECT count(*) FROM refs");
-  if( cnt==0 ){
+  rid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%s*'");
+  if( rid==0 ){
     style_header("Broken Link");
     @ <p>No such object: %h(zName)</p>
     style_footer();
     return;
   }
-  db_prepare(&q, "SELECT type, link FROM refs");
-  db_step(&q);
-  if( cnt==1 ){
-    int type = *db_column_text(&q, 0);
-    int rid = db_column_int(&q, 1);
-    db_finalize(&q);
-    if( type=='w' ){
-      wiki_page();
-    }else if( type=='t' ){
-      tktview_page();
-    }else{
-      cgi_replace_parameter("name", mprintf("%d", rid));
-      if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
-        vinfo_page();
-      }else{
-        finfo_page();
-      }
-    }
-    return;
-  }
-  /* Multiple objects */
-  style_header("Ambiguous Link");
-  @ <h2>Ambiguous Link: %h(zName)</h2>
-  @ <ul>
-  while( rc==SQLITE_ROW ){
-    int type = *db_column_text(&q, 0);
-    if( type=='f' ){
-      @ <li><p>
-      object_description(db_column_int(&q, 1), 1);
-      @ </p></li>
-    }else if( type=='w' ){
-      @ <li><p>
-      @ Wiki page <a href="%s(g.zBaseURL)/wiki?name=%s(zName)">%s(zName)</a>.
-      @ </li><p>
-    }else if( type=='t' ){
-      const char *zUuid = db_column_text(&q, 1);
-      @ <li><p>
-      @ Ticket <a href="%s(g.zBaseURL)/tktview?name=%s(zUuid)">%s(zUuid)</a>.
-      @ </li><p>
-    }
-    rc = db_step(&q);
-  }
-  @ </ul>
-  style_footer();
-  db_finalize(&q);
+  if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
+    vinfo_page();
+  }else
+  if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
+    finfo_page();
+  }else
+  {
+    artifact_page();
+  }
 }

Modified src/main.c from [fcf22176a5] to [e12b36e51e].

@@ -65,10 +65,11 @@
   const char *zContentType;  /* The content type of the input HTTP request */
   int iErrPriority;       /* Priority of current error message */
   char *zErrMsg;          /* Text of an error message */
   Blob cgiIn;             /* Input to an xfer www method */
   int cgiPanic;           /* Write error messages to CGI */
+  Th_Interp *interp;      /* The TH1 interpreter */
 
   int *aCommitFile;
 
   int urlIsFile;          /* True if a "file:" url */
   char *urlName;          /* Hostname for http: or filename for file: */

Modified src/main.mk from [3a3bee5aa8] to [b7efa1a7b7].

@@ -52,14 +52,14 @@
   $(SRCDIR)/rss.c \
   $(SRCDIR)/schema.c \
   $(SRCDIR)/setup.c \
   $(SRCDIR)/sha1.c \
   $(SRCDIR)/style.c \
-  $(SRCDIR)/subscript.c \
   $(SRCDIR)/sync.c \
   $(SRCDIR)/tag.c \
   $(SRCDIR)/tagview.c \
+  $(SRCDIR)/th_main.c \
   $(SRCDIR)/timeline.c \
   $(SRCDIR)/tkt.c \
   $(SRCDIR)/tktconfig.c \
   $(SRCDIR)/tktsetup.c \
   $(SRCDIR)/undo.c \
@@ -113,14 +113,14 @@
   rss_.c \
   schema_.c \
   setup_.c \
   sha1_.c \
   style_.c \
-  subscript_.c \
   sync_.c \
   tag_.c \
   tagview_.c \
+  th_main_.c \
   timeline_.c \
   tkt_.c \
   tktconfig_.c \
   tktsetup_.c \
   undo_.c \
@@ -174,14 +174,14 @@
   rss.o \
   schema.o \
   setup.o \
   sha1.o \
   style.o \
-  subscript.o \
   sync.o \
   tag.o \
   tagview.o \
+  th_main.o \
   timeline.o \
   tkt.o \
   tktconfig.o \
   tktsetup.o \
   undo.o \
@@ -222,12 +222,12 @@
 VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest
 	awk '{ printf "#define MANIFEST_UUID \"%s\"\n", $$1}'  $(SRCDIR)/../manifest.uuid >VERSION.h
 	awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}'  $(SRCDIR)/../manifest.uuid >>VERSION.h
 	awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n", substr($$2,1,10),substr($$2,12)}'  $(SRCDIR)/../manifest >>VERSION.h
 
-$(APPNAME):	headers $(OBJ) sqlite3.o
-	$(TCC) -o $(APPNAME) $(OBJ) sqlite3.o $(LIB)
+$(APPNAME):	headers $(OBJ) sqlite3.o th.o th_lang.o
+	$(TCC) -o $(APPNAME) $(OBJ) sqlite3.o th.o th_lang.o $(LIB)
 
 # This rule prevents make from using its default rules to try build
 # an executable named "manifest" out of the file named "manifest.c"
 #
 $(SRCDIR)/../manifest:
@@ -234,14 +234,14 @@
 	# noop
 
 clean:
 	rm -f *.o *_.c $(APPNAME) VERSION.h
 	rm -f translate makeheaders mkindex page_index.h headers
-	rm -f add.h admin.h bag.h blob.h branch.h browse.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h construct.h content.h db.h delta.h deltacmd.h descendents.h diff.h diffcmd.h encode.h file.h http.h info.h login.h main.h manifest.h md5.h merge.h merge3.h my_page.h name.h pivot.h pqueue.h printf.h rebuild.h rss.h schema.h setup.h sha1.h style.h subscript.h sync.h tag.h tagview.h timeline.h tkt.h tktconfig.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h xfer.h zip.h
+	rm -f add.h admin.h bag.h blob.h branch.h browse.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h construct.h content.h db.h delta.h deltacmd.h descendents.h diff.h diffcmd.h encode.h file.h http.h info.h login.h main.h manifest.h md5.h merge.h merge3.h my_page.h name.h pivot.h pqueue.h printf.h rebuild.h rss.h schema.h setup.h sha1.h style.h sync.h tag.h tagview.h th_main.h timeline.h tkt.h tktconfig.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h xfer.h zip.h
 
 headers:	makeheaders mkindex $(TRANS_SRC) ./VERSION.h
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	./mkindex $(TRANS_SRC) >page_index.h
 	touch headers
 
 add_.c:	$(SRCDIR)/add.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/add.c | sed -f $(SRCDIR)/VERSION >add_.c
@@ -248,591 +248,597 @@
 
 add.o:	add_.c add.h  $(SRCDIR)/config.h
 	$(XTCC) -o add.o -c add_.c
 
 add.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 admin_.c:	$(SRCDIR)/admin.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/admin.c | sed -f $(SRCDIR)/VERSION >admin_.c
 
 admin.o:	admin_.c admin.h  $(SRCDIR)/config.h
 	$(XTCC) -o admin.o -c admin_.c
 
 admin.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 bag_.c:	$(SRCDIR)/bag.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/bag.c | sed -f $(SRCDIR)/VERSION >bag_.c
 
 bag.o:	bag_.c bag.h  $(SRCDIR)/config.h
 	$(XTCC) -o bag.o -c bag_.c
 
 bag.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 blob_.c:	$(SRCDIR)/blob.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/blob.c | sed -f $(SRCDIR)/VERSION >blob_.c
 
 blob.o:	blob_.c blob.h  $(SRCDIR)/config.h
 	$(XTCC) -o blob.o -c blob_.c
 
 blob.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 branch_.c:	$(SRCDIR)/branch.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/branch.c | sed -f $(SRCDIR)/VERSION >branch_.c
 
 branch.o:	branch_.c branch.h  $(SRCDIR)/config.h
 	$(XTCC) -o branch.o -c branch_.c
 
 branch.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 browse_.c:	$(SRCDIR)/browse.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/browse.c | sed -f $(SRCDIR)/VERSION >browse_.c
 
 browse.o:	browse_.c browse.h  $(SRCDIR)/config.h
 	$(XTCC) -o browse.o -c browse_.c
 
 browse.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 cgi_.c:	$(SRCDIR)/cgi.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/cgi.c | sed -f $(SRCDIR)/VERSION >cgi_.c
 
 cgi.o:	cgi_.c cgi.h  $(SRCDIR)/config.h
 	$(XTCC) -o cgi.o -c cgi_.c
 
 cgi.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 checkin_.c:	$(SRCDIR)/checkin.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/checkin.c | sed -f $(SRCDIR)/VERSION >checkin_.c
 
 checkin.o:	checkin_.c checkin.h  $(SRCDIR)/config.h
 	$(XTCC) -o checkin.o -c checkin_.c
 
 checkin.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 checkout_.c:	$(SRCDIR)/checkout.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/checkout.c | sed -f $(SRCDIR)/VERSION >checkout_.c
 
 checkout.o:	checkout_.c checkout.h  $(SRCDIR)/config.h
 	$(XTCC) -o checkout.o -c checkout_.c
 
 checkout.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 clearsign_.c:	$(SRCDIR)/clearsign.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/clearsign.c | sed -f $(SRCDIR)/VERSION >clearsign_.c
 
 clearsign.o:	clearsign_.c clearsign.h  $(SRCDIR)/config.h
 	$(XTCC) -o clearsign.o -c clearsign_.c
 
 clearsign.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 clone_.c:	$(SRCDIR)/clone.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/clone.c | sed -f $(SRCDIR)/VERSION >clone_.c
 
 clone.o:	clone_.c clone.h  $(SRCDIR)/config.h
 	$(XTCC) -o clone.o -c clone_.c
 
 clone.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 comformat_.c:	$(SRCDIR)/comformat.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/comformat.c | sed -f $(SRCDIR)/VERSION >comformat_.c
 
 comformat.o:	comformat_.c comformat.h  $(SRCDIR)/config.h
 	$(XTCC) -o comformat.o -c comformat_.c
 
 comformat.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 construct_.c:	$(SRCDIR)/construct.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/construct.c | sed -f $(SRCDIR)/VERSION >construct_.c
 
 construct.o:	construct_.c construct.h  $(SRCDIR)/config.h
 	$(XTCC) -o construct.o -c construct_.c
 
 construct.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 content_.c:	$(SRCDIR)/content.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/content.c | sed -f $(SRCDIR)/VERSION >content_.c
 
 content.o:	content_.c content.h  $(SRCDIR)/config.h
 	$(XTCC) -o content.o -c content_.c
 
 content.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 db_.c:	$(SRCDIR)/db.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/db.c | sed -f $(SRCDIR)/VERSION >db_.c
 
 db.o:	db_.c db.h  $(SRCDIR)/config.h
 	$(XTCC) -o db.o -c db_.c
 
 db.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 delta_.c:	$(SRCDIR)/delta.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/delta.c | sed -f $(SRCDIR)/VERSION >delta_.c
 
 delta.o:	delta_.c delta.h  $(SRCDIR)/config.h
 	$(XTCC) -o delta.o -c delta_.c
 
 delta.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 deltacmd_.c:	$(SRCDIR)/deltacmd.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/deltacmd.c | sed -f $(SRCDIR)/VERSION >deltacmd_.c
 
 deltacmd.o:	deltacmd_.c deltacmd.h  $(SRCDIR)/config.h
 	$(XTCC) -o deltacmd.o -c deltacmd_.c
 
 deltacmd.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 descendents_.c:	$(SRCDIR)/descendents.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/descendents.c | sed -f $(SRCDIR)/VERSION >descendents_.c
 
 descendents.o:	descendents_.c descendents.h  $(SRCDIR)/config.h
 	$(XTCC) -o descendents.o -c descendents_.c
 
 descendents.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 diff_.c:	$(SRCDIR)/diff.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/diff.c | sed -f $(SRCDIR)/VERSION >diff_.c
 
 diff.o:	diff_.c diff.h  $(SRCDIR)/config.h
 	$(XTCC) -o diff.o -c diff_.c
 
 diff.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 diffcmd_.c:	$(SRCDIR)/diffcmd.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/diffcmd.c | sed -f $(SRCDIR)/VERSION >diffcmd_.c
 
 diffcmd.o:	diffcmd_.c diffcmd.h  $(SRCDIR)/config.h
 	$(XTCC) -o diffcmd.o -c diffcmd_.c
 
 diffcmd.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 encode_.c:	$(SRCDIR)/encode.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/encode.c | sed -f $(SRCDIR)/VERSION >encode_.c
 
 encode.o:	encode_.c encode.h  $(SRCDIR)/config.h
 	$(XTCC) -o encode.o -c encode_.c
 
 encode.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 file_.c:	$(SRCDIR)/file.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/file.c | sed -f $(SRCDIR)/VERSION >file_.c
 
 file.o:	file_.c file.h  $(SRCDIR)/config.h
 	$(XTCC) -o file.o -c file_.c
 
 file.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 http_.c:	$(SRCDIR)/http.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/http.c | sed -f $(SRCDIR)/VERSION >http_.c
 
 http.o:	http_.c http.h  $(SRCDIR)/config.h
 	$(XTCC) -o http.o -c http_.c
 
 http.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 info_.c:	$(SRCDIR)/info.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/info.c | sed -f $(SRCDIR)/VERSION >info_.c
 
 info.o:	info_.c info.h  $(SRCDIR)/config.h
 	$(XTCC) -o info.o -c info_.c
 
 info.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 login_.c:	$(SRCDIR)/login.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/login.c | sed -f $(SRCDIR)/VERSION >login_.c
 
 login.o:	login_.c login.h  $(SRCDIR)/config.h
 	$(XTCC) -o login.o -c login_.c
 
 login.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 main_.c:	$(SRCDIR)/main.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/main.c | sed -f $(SRCDIR)/VERSION >main_.c
 
 main.o:	main_.c main.h page_index.h $(SRCDIR)/config.h
 	$(XTCC) -o main.o -c main_.c
 
 main.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 manifest_.c:	$(SRCDIR)/manifest.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/manifest.c | sed -f $(SRCDIR)/VERSION >manifest_.c
 
 manifest.o:	manifest_.c manifest.h  $(SRCDIR)/config.h
 	$(XTCC) -o manifest.o -c manifest_.c
 
 manifest.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 md5_.c:	$(SRCDIR)/md5.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/md5.c | sed -f $(SRCDIR)/VERSION >md5_.c
 
 md5.o:	md5_.c md5.h  $(SRCDIR)/config.h
 	$(XTCC) -o md5.o -c md5_.c
 
 md5.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 merge_.c:	$(SRCDIR)/merge.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/merge.c | sed -f $(SRCDIR)/VERSION >merge_.c
 
 merge.o:	merge_.c merge.h  $(SRCDIR)/config.h
 	$(XTCC) -o merge.o -c merge_.c
 
 merge.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 merge3_.c:	$(SRCDIR)/merge3.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/merge3.c | sed -f $(SRCDIR)/VERSION >merge3_.c
 
 merge3.o:	merge3_.c merge3.h  $(SRCDIR)/config.h
 	$(XTCC) -o merge3.o -c merge3_.c
 
 merge3.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 my_page_.c:	$(SRCDIR)/my_page.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/my_page.c | sed -f $(SRCDIR)/VERSION >my_page_.c
 
 my_page.o:	my_page_.c my_page.h  $(SRCDIR)/config.h
 	$(XTCC) -o my_page.o -c my_page_.c
 
 my_page.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 name_.c:	$(SRCDIR)/name.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/name.c | sed -f $(SRCDIR)/VERSION >name_.c
 
 name.o:	name_.c name.h  $(SRCDIR)/config.h
 	$(XTCC) -o name.o -c name_.c
 
 name.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 pivot_.c:	$(SRCDIR)/pivot.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/pivot.c | sed -f $(SRCDIR)/VERSION >pivot_.c
 
 pivot.o:	pivot_.c pivot.h  $(SRCDIR)/config.h
 	$(XTCC) -o pivot.o -c pivot_.c
 
 pivot.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 pqueue_.c:	$(SRCDIR)/pqueue.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/pqueue.c | sed -f $(SRCDIR)/VERSION >pqueue_.c
 
 pqueue.o:	pqueue_.c pqueue.h  $(SRCDIR)/config.h
 	$(XTCC) -o pqueue.o -c pqueue_.c
 
 pqueue.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 printf_.c:	$(SRCDIR)/printf.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/printf.c | sed -f $(SRCDIR)/VERSION >printf_.c
 
 printf.o:	printf_.c printf.h  $(SRCDIR)/config.h
 	$(XTCC) -o printf.o -c printf_.c
 
 printf.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 rebuild_.c:	$(SRCDIR)/rebuild.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/rebuild.c | sed -f $(SRCDIR)/VERSION >rebuild_.c
 
 rebuild.o:	rebuild_.c rebuild.h  $(SRCDIR)/config.h
 	$(XTCC) -o rebuild.o -c rebuild_.c
 
 rebuild.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 rss_.c:	$(SRCDIR)/rss.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/rss.c | sed -f $(SRCDIR)/VERSION >rss_.c
 
 rss.o:	rss_.c rss.h  $(SRCDIR)/config.h
 	$(XTCC) -o rss.o -c rss_.c
 
 rss.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 schema_.c:	$(SRCDIR)/schema.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/schema.c | sed -f $(SRCDIR)/VERSION >schema_.c
 
 schema.o:	schema_.c schema.h  $(SRCDIR)/config.h
 	$(XTCC) -o schema.o -c schema_.c
 
 schema.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 setup_.c:	$(SRCDIR)/setup.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/setup.c | sed -f $(SRCDIR)/VERSION >setup_.c
 
 setup.o:	setup_.c setup.h  $(SRCDIR)/config.h
 	$(XTCC) -o setup.o -c setup_.c
 
 setup.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 sha1_.c:	$(SRCDIR)/sha1.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/sha1.c | sed -f $(SRCDIR)/VERSION >sha1_.c
 
 sha1.o:	sha1_.c sha1.h  $(SRCDIR)/config.h
 	$(XTCC) -o sha1.o -c sha1_.c
 
 sha1.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 style_.c:	$(SRCDIR)/style.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/style.c | sed -f $(SRCDIR)/VERSION >style_.c
 
 style.o:	style_.c style.h  $(SRCDIR)/config.h
 	$(XTCC) -o style.o -c style_.c
 
 style.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
-	touch headers
-
-subscript_.c:	$(SRCDIR)/subscript.c $(SRCDIR)/VERSION translate
-	./translate $(SRCDIR)/subscript.c | sed -f $(SRCDIR)/VERSION >subscript_.c
-
-subscript.o:	subscript_.c subscript.h  $(SRCDIR)/config.h
-	$(XTCC) -o subscript.o -c subscript_.c
-
-subscript.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 sync_.c:	$(SRCDIR)/sync.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/sync.c | sed -f $(SRCDIR)/VERSION >sync_.c
 
 sync.o:	sync_.c sync.h  $(SRCDIR)/config.h
 	$(XTCC) -o sync.o -c sync_.c
 
 sync.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 tag_.c:	$(SRCDIR)/tag.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/tag.c | sed -f $(SRCDIR)/VERSION >tag_.c
 
 tag.o:	tag_.c tag.h  $(SRCDIR)/config.h
 	$(XTCC) -o tag.o -c tag_.c
 
 tag.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 tagview_.c:	$(SRCDIR)/tagview.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/tagview.c | sed -f $(SRCDIR)/VERSION >tagview_.c
 
 tagview.o:	tagview_.c tagview.h  $(SRCDIR)/config.h
 	$(XTCC) -o tagview.o -c tagview_.c
 
 tagview.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
+	touch headers
+
+th_main_.c:	$(SRCDIR)/th_main.c $(SRCDIR)/VERSION translate
+	./translate $(SRCDIR)/th_main.c | sed -f $(SRCDIR)/VERSION >th_main_.c
+
+th_main.o:	th_main_.c th_main.h  $(SRCDIR)/config.h
+	$(XTCC) -o th_main.o -c th_main_.c
+
+th_main.h:	makeheaders
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 timeline_.c:	$(SRCDIR)/timeline.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/timeline.c | sed -f $(SRCDIR)/VERSION >timeline_.c
 
 timeline.o:	timeline_.c timeline.h  $(SRCDIR)/config.h
 	$(XTCC) -o timeline.o -c timeline_.c
 
 timeline.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 tkt_.c:	$(SRCDIR)/tkt.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/tkt.c | sed -f $(SRCDIR)/VERSION >tkt_.c
 
 tkt.o:	tkt_.c tkt.h  $(SRCDIR)/config.h
 	$(XTCC) -o tkt.o -c tkt_.c
 
 tkt.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 tktconfig_.c:	$(SRCDIR)/tktconfig.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/tktconfig.c | sed -f $(SRCDIR)/VERSION >tktconfig_.c
 
 tktconfig.o:	tktconfig_.c tktconfig.h  $(SRCDIR)/config.h
 	$(XTCC) -o tktconfig.o -c tktconfig_.c
 
 tktconfig.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 tktsetup_.c:	$(SRCDIR)/tktsetup.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/tktsetup.c | sed -f $(SRCDIR)/VERSION >tktsetup_.c
 
 tktsetup.o:	tktsetup_.c tktsetup.h  $(SRCDIR)/config.h
 	$(XTCC) -o tktsetup.o -c tktsetup_.c
 
 tktsetup.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 undo_.c:	$(SRCDIR)/undo.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/undo.c | sed -f $(SRCDIR)/VERSION >undo_.c
 
 undo.o:	undo_.c undo.h  $(SRCDIR)/config.h
 	$(XTCC) -o undo.o -c undo_.c
 
 undo.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 update_.c:	$(SRCDIR)/update.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/update.c | sed -f $(SRCDIR)/VERSION >update_.c
 
 update.o:	update_.c update.h  $(SRCDIR)/config.h
 	$(XTCC) -o update.o -c update_.c
 
 update.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 url_.c:	$(SRCDIR)/url.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/url.c | sed -f $(SRCDIR)/VERSION >url_.c
 
 url.o:	url_.c url.h  $(SRCDIR)/config.h
 	$(XTCC) -o url.o -c url_.c
 
 url.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 user_.c:	$(SRCDIR)/user.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/user.c | sed -f $(SRCDIR)/VERSION >user_.c
 
 user.o:	user_.c user.h  $(SRCDIR)/config.h
 	$(XTCC) -o user.o -c user_.c
 
 user.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 verify_.c:	$(SRCDIR)/verify.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/verify.c | sed -f $(SRCDIR)/VERSION >verify_.c
 
 verify.o:	verify_.c verify.h  $(SRCDIR)/config.h
 	$(XTCC) -o verify.o -c verify_.c
 
 verify.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 vfile_.c:	$(SRCDIR)/vfile.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/vfile.c | sed -f $(SRCDIR)/VERSION >vfile_.c
 
 vfile.o:	vfile_.c vfile.h  $(SRCDIR)/config.h
 	$(XTCC) -o vfile.o -c vfile_.c
 
 vfile.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 wiki_.c:	$(SRCDIR)/wiki.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/wiki.c | sed -f $(SRCDIR)/VERSION >wiki_.c
 
 wiki.o:	wiki_.c wiki.h  $(SRCDIR)/config.h
 	$(XTCC) -o wiki.o -c wiki_.c
 
 wiki.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 wikiformat_.c:	$(SRCDIR)/wikiformat.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/wikiformat.c | sed -f $(SRCDIR)/VERSION >wikiformat_.c
 
 wikiformat.o:	wikiformat_.c wikiformat.h  $(SRCDIR)/config.h
 	$(XTCC) -o wikiformat.o -c wikiformat_.c
 
 wikiformat.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 xfer_.c:	$(SRCDIR)/xfer.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/xfer.c | sed -f $(SRCDIR)/VERSION >xfer_.c
 
 xfer.o:	xfer_.c xfer.h  $(SRCDIR)/config.h
 	$(XTCC) -o xfer.o -c xfer_.c
 
 xfer.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 zip_.c:	$(SRCDIR)/zip.c $(SRCDIR)/VERSION translate
 	./translate $(SRCDIR)/zip.c | sed -f $(SRCDIR)/VERSION >zip_.c
 
 zip.o:	zip_.c zip.h  $(SRCDIR)/config.h
 	$(XTCC) -o zip.o -c zip_.c
 
 zip.h:	makeheaders
-	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h
+	./makeheaders  add_.c:add.h admin_.c:admin.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h my_page_.c:my_page.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h ./VERSION.h
 	touch headers
 
 sqlite3.o:	$(SRCDIR)/sqlite3.c
 	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PRIVATE= -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_FTS3=1 -c $(SRCDIR)/sqlite3.c -o sqlite3.o
+
+th.o:	$(SRCDIR)/th.c
+	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o th.o
+
+th_lang.o:	$(SRCDIR)/th_lang.c
+	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o th_lang.o
 

Modified src/makemake.tcl from [27a44eb217] to [fd0be2c190].

@@ -1,11 +1,12 @@
 #!/usr/bin/tclsh
 #
 # Run this TCL script to generate the "main.mk" makefile.
 #
 
-# Basenames of all source files:
+# Basenames of all source files that get preprocessed using
+# "translate" and "makeheaders"
 #
 set src {
   add
   admin
   bag
@@ -45,14 +46,14 @@
   rss
   schema
   setup
   sha1
   style
-  subscript
   sync
   tag
   tagview
+  th_main
   timeline
   tkt
   tktconfig
   tktsetup
   undo
@@ -131,12 +132,12 @@
 		$(SRCDIR)/../manifest.uuid >>VERSION.h
 	awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n",\
 		substr($$2,1,10),substr($$2,12)}' \
 		$(SRCDIR)/../manifest >>VERSION.h
 
-$(APPNAME):	headers $(OBJ) sqlite3.o
-	$(TCC) -o $(APPNAME) $(OBJ) sqlite3.o $(LIB)
+$(APPNAME):	headers $(OBJ) sqlite3.o th.o th_lang.o
+	$(TCC) -o $(APPNAME) $(OBJ) sqlite3.o th.o th_lang.o $(LIB)
 
 # This rule prevents make from using its default rules to try build
 # an executable named "manifest" out of the file named "manifest.c"
 #
 $(SRCDIR)/../manifest:
@@ -153,11 +154,13 @@
 set mhargs {}
 foreach s [lsort $src] {
   append mhargs " ${s}_.c:$s.h"
   set extra_h($s) {}
 }
-append mhargs " \$(SRCDIR)/sqlite3.h ./VERSION.h"
+append mhargs " \$(SRCDIR)/sqlite3.h"
+append mhargs " \$(SRCDIR)/th.h"
+append mhargs " ./VERSION.h"
 puts "headers:\tmakeheaders mkindex \$(TRANS_SRC) ./VERSION.h"
 puts "\t./makeheaders $mhargs"
 puts "\t./mkindex \$(TRANS_SRC) >page_index.h"
 puts "\ttouch headers\n"
 set extra_h(main) page_index.h
@@ -175,5 +178,11 @@
 puts "sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
 set opt {-DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PRIVATE=}
 append opt " -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4"
 append opt " -DSQLITE_ENABLE_FTS3=1"
 puts "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o sqlite3.o\n"
+
+puts "th.o:\t\$(SRCDIR)/th.c"
+puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th.c -o th.o\n"
+
+puts "th_lang.o:\t\$(SRCDIR)/th_lang.c"
+puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o th_lang.o\n"

Modified src/manifest.c from [d38866b6bd] to [64e207831c].

@@ -65,10 +65,11 @@
   int nFile;            /* Number of F lines */
   int nFileAlloc;       /* Slots allocated in aFile[] */
   struct {
     char *zName;           /* Name of a file */
     char *zUuid;           /* UUID of the file */
+    char *zPerm;           /* File permissions */
   } *aFile;
   int nParent;          /* Number of parents */
   int nParentAlloc;     /* Slots allocated in azParent[] */
   char **azParent;      /* UUIDs of parents */
   int nCChild;          /* Number of cluster children */
@@ -155,10 +156,11 @@
   blob_zero(pContent);
   pContent = &p->content;
 
   blob_zero(&a1);
   blob_zero(&a2);
+  blob_zero(&a3);
   md5sum_init();
   while( blob_line(pContent, &line) ){
     char *z = blob_buffer(&line);
     lineNo++;
     if( z[0]=='-' ){
@@ -275,24 +277,25 @@
         }
         break;
       }
 
       /*
-      **     F <filename> <uuid>
+      **     F <filename> <uuid> ?<permissions>?
       **
       ** Identifies a file in a manifest.  Multiple F lines are
       ** allowed in a manifest.  F lines are not allowed in any
       ** other control file.  The filename is fossil-encoded.
       */
       case 'F': {
-        char *zName, *zUuid;
+        char *zName, *zUuid, *zPerm;
         md5sum_step_text(blob_buffer(&line), blob_size(&line));
         if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
         if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
-        if( blob_token(&line, &a3)!=0 ) goto manifest_syntax_error;
         zName = blob_terminate(&a1);
         zUuid = blob_terminate(&a2);
+        blob_token(&line, &a3);
+        zPerm = blob_terminate(&a3);
         if( blob_size(&a2)!=UUID_SIZE ) goto manifest_syntax_error;
         if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
         defossilize(zName);
         if( !file_is_simple_pathname(zName) ){
           goto manifest_syntax_error;
@@ -303,10 +306,11 @@
           if( p->aFile==0 ) fossil_panic("out of memory");
         }
         i = p->nFile++;
         p->aFile[i].zName = zName;
         p->aFile[i].zUuid = zUuid;
+        p->aFile[i].zPerm = zPerm;
         if( i>0 && strcmp(p->aFile[i-1].zName, zName)>=0 ){
           goto manifest_syntax_error;
         }
         break;
       }

Modified src/schema.c from [07530b805a] to [f141028e53].

@@ -299,11 +299,11 @@
 @ -- is already in the repository.
 @ --
 @ --
 @ CREATE TABLE vfile(
 @   id INTEGER PRIMARY KEY,           -- ID of the checked out file
-@   vid INTEGER REFERENCES blob,      -- The version this file is part of.
+@   vid INTEGER REFERENCES blob,      -- The baseline this file is part of.
 @   chnged INT DEFAULT 0,             -- 0:unchnged 1:edited 2:m-chng 3:m-add
 @   deleted BOOLEAN DEFAULT 0,        -- True if deleted
 @   rid INTEGER,                      -- Originally from this repository record
 @   mrid INTEGER,                     -- Based on this record due to a merge
 @   pathname TEXT,                    -- Full pathname
@@ -320,21 +320,6 @@
 @   id INTEGER REFERENCES vfile,      -- VFILE entry that has been merged
 @   merge INTEGER,                    -- Merged with this record
 @   UNIQUE(id, merge)
 @ );
 @
-;
-
-const char zServerTempSchema[] =
-@ -- A copy of the vfile table schema used by the WWW server
-@ --
-@ CREATE TEMP TABLE vfile(
-@   id INTEGER PRIMARY KEY,           -- ID of the checked out file
-@   vid INTEGER REFERENCES record,    -- The version this file is part of.
-@   chnged INT DEFAULT 0,             -- 0:unchnged 1:edited 2:m-chng 3:m-add
-@   deleted BOOLEAN DEFAULT 0,        -- True if deleted
-@   rid INTEGER,                      -- Originally from this repository record
-@   mrid INTEGER,                     -- Based on this record due to a merge
-@   pathname TEXT,                    -- Full pathname
-@   UNIQUE(pathname,vid)
-@ );
 ;

Modified src/setup.c from [093a77e546] to [f8c273bde6].

@@ -645,11 +645,11 @@
   }else{
     textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader);
   }
   style_header("Edit Page Header");
   @ <form action="%s(g.zBaseURL)/setup_header" method="POST">
-  @ <p>Edit HTML text with embedded subscript that will be used to
+  @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
   @ generate the beginning of every page through start of the main
   @ menu.</p>
   textarea_attribute("", 40, 80, "header", "header", zDefaultHeader);
   @ <br />
   @ <input type="submit" name="submit" value="Apply Changes">
@@ -678,11 +678,11 @@
   }else{
     textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter);
   }
   style_header("Edit Page Footer");
   @ <form action="%s(g.zBaseURL)/setup_footer" method="POST">
-  @ <p>Edit HTML text with embedded subscript that will be used to
+  @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
   @ generate the end of every page.</p>
   textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter);
   @ <br />
   @ <input type="submit" name="submit" value="Apply Changes">
   @ <input type="submit" name="clear" value="Revert To Default">
@@ -729,19 +729,19 @@
       @ SCRIPT ERROR: %h(zErr)
       @ </b></font></p>
     }
   }
   @ <form action="%s(g.zBaseURL)/setup_ticket" method="POST">
-  @ <p>Edit the "subscript" script that defines the ticketing
+  @ <p>Edit the TH1 script that defines the ticketing
   @ system setup for this server.</p>
   @ <textarea name="cfg" rows="40" cols="80">%h(zConfig)</textarea>
   @ <br />
   @ <input type="submit" name="submit" value="Apply Changes">
   @ <input type="submit" name="clear" value="Revert To Default">
   @ </form>
   @ <hr>
-  @ Here is the default page header:
+  @ Here is the default ticket configuration:
   @ <blockquote><pre>
   @ %h(zDefaultTicketConfig)
   @ </pre></blockquote>
   db_end_transaction(0);
 }

Modified src/style.c from [72a7644b27] to [d2af091ad5].

@@ -69,76 +69,37 @@
   const struct Submenu *B = (const struct Submenu*)b;
   return strcmp(A->zLabel, B->zLabel);
 }
 
 /*
-** The Subscript interpreter used to render header and footer.
-*/
-static struct Subscript *pInterp;
-
-/*
 ** Draw the header.
 */
 void style_header(const char *zTitle){
-  const char *zLogInOut = "Login";
   const char *zHeader = db_get("header", (char*)zDefaultHeader);
   login_check_credentials();
 
-  if( pInterp ) return;
   cgi_destination(CGI_HEADER);
 
   /* Generate the header up through the main menu */
-  pInterp = SbS_Create();
-  SbS_Store(pInterp, "project_name",
-                     db_get("project-name","Unnamed Fossil Project"), 0);
-  SbS_Store(pInterp, "title", zTitle, 0);
-  SbS_Store(pInterp, "baseurl", g.zBaseURL, 0);
-  SbS_Store(pInterp, "manifest_version", MANIFEST_VERSION, 0);
-  SbS_Store(pInterp, "manifest_date", MANIFEST_DATE, 0);
+  Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
+  Th_Store("title", zTitle);
+  Th_Store("baseurl", g.zBaseURL);
+  Th_Store("manifest_version", MANIFEST_VERSION);
+  Th_Store("manifest_date", MANIFEST_DATE);
   if( g.zLogin ){
-    SbS_Store(pInterp, "login", g.zLogin, 0);
-    zLogInOut = "Logout";
+    Th_Store("login", g.zLogin);
   }
-  SbS_Render(pInterp, zHeader);
-
-  /* Generate the main menu */
-  @ <div class="mainmenu">
-  @ <a href="%s(g.zBaseURL)/home">Home</a>
-  if( g.okHistory ){
-    @ <a href="%s(g.zBaseURL)/dir">Files</a>
-  }
-  if( g.okRead ){
-    @ <a href="%s(g.zBaseURL)/leaves">Leaves</a>
-    @ <a href="%s(g.zBaseURL)/timeline">Timeline</a>
-    @ <a href="%s(g.zBaseURL)/tagview">Tags</a>
-  }
-  if( g.okRdWiki ){
-    @ <a href="%s(g.zBaseURL)/wiki">Wiki</a>
-  }
-#if 0
-  @ <font color="#888888">Search</font>
-  @ <font color="#888888">Ticket</font>
-  @ <font color="#888888">Reports</font>
-#endif
-  if( g.okSetup ){
-    @ <a href="%s(g.zBaseURL)/setup">Setup</a>
-  }
-  if( !g.noPswd ){
-    @ <a href="%s(g.zBaseURL)/login">%s(zLogInOut)</a>
-  }
-  @ </div>
+  Th_Render(zHeader);
   cgi_destination(CGI_BODY);
   g.cgiPanic = 1;
 }
 
 /*
 ** Draw the footer at the bottom of the page.
 */
 void style_footer(void){
   const char *zFooter;
-
-  if( pInterp==0 ) return;
 
   /* Go back and put the submenu at the top of the page.  We delay the
   ** creation of the submenu until the end so that we can add elements
   ** to the submenu while generating page text.
   */
@@ -162,50 +123,71 @@
   /* Put the footer at the bottom of the page.
   */
   @ <div class="content">
   zFooter = db_get("footer", (char*)zDefaultFooter);
   @ </div>
-  SbS_Render(pInterp, zFooter);
-  SbS_Destroy(pInterp);
-  pInterp = 0;
+  Th_Render(zFooter);
 }
 
 /* @-comment: // */
 /*
 ** The default page header.
 */
 const char zDefaultHeader[] =
 @ <html>
 @ <head>
-@ <title>[project_name html]: [title html]</title>
+@ <title>$<project_name>: $<title></title>
 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
-@       href="[baseurl puts]/timeline.rss">
-@ <link rel="stylesheet" href="[baseurl puts]/style.css" type="text/css"
+@       href="$baseurl/timeline.rss">
+@ <link rel="stylesheet" href="$baseurl/style.css" type="text/css"
 @       media="screen">
 @ </head>
 @ <body>
 @ <div class="header">
 @   <div class="logo">
 @     <!-- <img src="logo.gif" alt="logo"><br></br> -->
-@     <nobr>[project_name html]</nobr>
+@     <nobr>$<project_name></nobr>
 @   </div>
-@   <div class="title">[title html]</div>
-@   <div class="status"><nobr>
-@     [/login exists enable_output]     Logged in as
-@      <a href='[baseurl puts]/my'>[0 /login get html]</a>
-@     [/login exists not enable_output] Not logged in
-@     [1 enable_output]
-@   </nobr></div>
+@   <div class="title">$<title></div>
+@   <div class="status"><nobr><th1>
+@      if {[info exists login]} {
+@        html "Logged in as <a href='$baseurl/my'>$login</a>"
+@      } else {
+@        puts "Not logged in"
+@      }
+@   </th1></nobr></div>
 @ </div>
+@ <div class="mainmenu"><th1>
+@ html "<a href='$baseurl/home'>Home</a>"
+@ if {[hascap h]} {
+@   html "<a href='$baseurl/dir'>Files</a>"
+@ }
+@ if {[hascap i]} {
+@   html "<a href='$baseurl/leaves'>Leaves</a>"
+@   html "<a href='$baseurl/timeline'>Timeline</a>"
+@   html "<a href='$baseurl/tagview'>Tags</a>"
+@ }
+@ if {[hascap j]} {
+@   html "<a href='$baseurl/wiki'>Wiki</a>"
+@ }
+@ if {[hascap s]} {
+@   html "<a href='$baseurl/setup'>Setup</a>"
+@ }
+@ if {[info exists login]} {
+@   html "<a href='$baseurl/login'>Login</a>"
+@ } else {
+@   html "<a href='$baseurl/login'>Logout</a>"
+@ }
+@ </th1></div>
 ;
 
 /*
 ** The default page footer
 */
 const char zDefaultFooter[] =
 @ <div class="footer">
-@ Fossil version [manifest_version puts] [manifest_date puts]
+@ Fossil version $manifest_version $manifest_date
 @ </div>
 @ </body></html>
 ;
 
 /*

Deleted src/subscript.c version [b76caa035f]

Added src/th.c version [a687d76a2d]

@@ -1,1 +1,2674 @@
+
+/*
+** The implementation of the TH core. This file contains the parser, and
+** the implementation of the interface in th.h.
+*/
+
+#include "th.h"
+#include <string.h>
+#include <assert.h>
+
+typedef struct Th_Command   Th_Command;
+typedef struct Th_Frame     Th_Frame;
+typedef struct Th_Variable  Th_Variable;
+
+/*
+** Interpreter structure.
+*/
+struct Th_Interp {
+  Th_Vtab *pVtab;     /* Copy of the argument passed to Th_CreateInterp() */
+  uchar *zResult;     /* Current interpreter result (Th_Malloc()ed) */
+  int nResult;        /* number of bytes in zResult */
+  Th_Hash *paCmd;     /* Table of registered commands */
+  Th_Frame *pFrame;   /* Current execution frame */
+  int isListMode;     /* True if thSplitList() should operate in "list" mode */
+};
+
+/*
+** Each TH command registered using Th_CreateCommand() is represented
+** by an instance of the following structure stored in the Th_Interp.paCmd
+** hash-table.
+*/
+struct Th_Command {
+  int (*xProc)(Th_Interp *, void *, int, const uchar **, int *);
+  void *pContext;
+  void (*xDel)(Th_Interp *, void *);
+};
+
+/*
+** Each stack frame (variable scope) is represented by an instance
+** of this structure. Variable values set using the Th_SetVar command
+** are stored in the Th_Frame.paVar hash table member of the associated
+** stack frame object.
+**
+** When an interpreter is created, a single Th_Frame structure is also
+** allocated - the global variable scope. Th_Interp.pFrame (the current
+** interpreter frame) is initialised to point to this Th_Frame. It is
+** not deleted for the lifetime of the interpreter (because the global
+** frame never goes out of scope).
+**
+** New stack frames are created by the Th_InFrame() function. Before
+** invoking its callback function, Th_InFrame() allocates a new Th_Frame
+** structure with pCaller set to the current frame (Th_Interp.pFrame),
+** and sets the current frame to the new frame object. After the callback
+** has been invoked, the allocated Th_Frame is deleted and the value
+** of the current frame pointer restored.
+**
+** By default, the Th_SetVar(), Th_UnsetVar() and Th_GetVar() functions
+** access variable values in the current frame. If they need to access
+** the global frame, they do so by traversing the pCaller pointer list.
+** Likewise, the Th_LinkVar() function uses the pCaller pointers to
+** link to variables located in the global or other stack frames.
+*/
+struct Th_Frame {
+  Th_Hash *paVar;               /* Variables defined in this scope */
+  Th_Frame *pCaller;            /* Calling frame */
+};
+
+/*
+** This structure represents a value assigned to a th1 variable.
+**
+** The Th_Frame.paVar hash table maps from variable name (a th1 string)
+** to a pointer to an instance of the following structure. More than
+** one hash table entry may map to a single structure if variable
+** links have been created using Th_LinkVar(). The number of references
+** is stored in Th_Variable.nRef.
+**
+** For scalar variables, Th_Variable.zData is never 0. Th_Variable.nData
+** stores the number of bytes in the value pointed to by zData.
+**
+** For an array variable, Th_Variable.zData is 0 and pHash points to
+** a hash table mapping between array key name (a th1 string) and
+** a the pointer to the Th_Variable structure holding the scalar
+** value.
+*/
+struct Th_Variable {
+  int nRef;                   /* Number of references to this structure */
+  int nData;                  /* Number of bytes at Th_Variable.zData */
+  uchar *zData;               /* Data for scalar variables */
+  Th_Hash *pHash;             /* Data for array variables */
+};
+
+/*
+** Hash table API:
+*/
+#define TH_HASHSIZE 257
+struct Th_Hash {
+  Th_HashEntry *a[TH_HASHSIZE];
+};
+
+static int thEvalLocal(Th_Interp *, const uchar *, int);
+static int thSplitList(Th_Interp*, const uchar*, int, uchar***, int **, int*);
+
+static int thHexdigit(uchar c);
+static int thEndOfLine(const uchar *, int);
+
+static int  thPushFrame(Th_Interp*, Th_Frame*);
+static void thPopFrame(Th_Interp*);
+
+static void thFreeVariable(Th_HashEntry*, void*);
+static void thFreeCommand(Th_HashEntry*, void*);
+
+/*
+** The following are used by both the expression and language parsers.
+** Given that the start of the input string (z, n) is a language
+** construct of the relevant type (a command enclosed in [], an escape
+** sequence etc.), these functions determine the number of bytes
+** of the input consumed by the construct. For example:
+**
+**   int nByte;
+**   thNextCommand(interp, "[expr $a+1] $nIter", 18, &nByte);
+**
+** results in variable nByte being set to 11. Or,
+**
+**   thNextVarname(interp, "$a+1", 4, &nByte);
+**
+** results in nByte being set to 2.
+*/
+static int thNextCommand(Th_Interp*, const uchar *z, int n, int *pN);
+static int thNextEscape (Th_Interp*, const uchar *z, int n, int *pN);
+static int thNextVarname(Th_Interp*, const uchar *z, int n, int *pN);
+static int thNextNumber (Th_Interp*, const uchar *z, int n, int *pN);
+static int thNextSpace  (Th_Interp*, const uchar *z, int n, int *pN);
+
+/*
+** Given that the input string (z, n) contains a language construct of
+** the relevant type (a command enclosed in [], an escape sequence
+** like "\xFF" or a variable reference like "${varname}", perform
+** substitution on the string and store the resulting string in
+** the interpreter result.
+*/
+static int thSubstCommand(Th_Interp*, const uchar *z, int n);
+static int thSubstEscape (Th_Interp*, const uchar *z, int n);
+static int thSubstVarname(Th_Interp*, const uchar *z, int n);
+
+/*
+** Given that there is a th1 word located at the start of the input
+** string (z, n), determine the length in bytes of that word. If the
+** isCmd argument is non-zero, then an unescaped ";" byte not
+** located inside of a block or quoted string is considered to mark
+** the end of the word.
+*/
+static int thNextWord(Th_Interp*, const uchar *z, int n, int *pN, int isCmd);
+
+/*
+** Perform substitution on the word contained in the input string (z, n).
+** Store the resulting string in the interpreter result.
+*/
+static int thSubstWord(Th_Interp*, const uchar *z, int n);
+
+/*
+** The Buffer structure and the thBufferXXX() functions are used to make
+** memory allocation easier when building up a result.
+*/
+struct Buffer {
+  uchar *zBuf;
+  int nBuf;
+  int nBufAlloc;
+};
+typedef struct Buffer Buffer;
+static int  thBufferWrite(Th_Interp *interp, Buffer *, const uchar *, int);
+static void thBufferInit(Buffer *);
+static void thBufferFree(Th_Interp *interp, Buffer *);
+
+/*
+** Append nAdd bytes of content copied from zAdd to the end of buffer
+** pBuffer. If there is not enough space currently allocated, resize
+** the allocation to make space.
+*/
+static int thBufferWrite(
+  Th_Interp *interp,
+  Buffer *pBuffer,
+  const uchar *zAdd,
+  int nAdd
+){
+  int nReq;
+
+  if( nAdd<0 ){
+    nAdd = th_strlen(zAdd);
+  }
+  nReq = pBuffer->nBuf+nAdd+1;
+
+  if( nReq>pBuffer->nBufAlloc ){
+    uchar *zNew;
+    int nNew;
+
+    nNew = nReq*2;
+    zNew = (uchar *)Th_Malloc(interp, nNew);
+    memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
+    Th_Free(interp, pBuffer->zBuf);
+    pBuffer->nBufAlloc = nNew;
+    pBuffer->zBuf = zNew;
+  }
+
+  memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
+  pBuffer->nBuf += nAdd;
+  pBuffer->zBuf[pBuffer->nBuf] = '\0';
+
+  return TH_OK;
+}
+#define thBufferWrite(a,b,c,d) thBufferWrite(a,b,(const uchar *)c,d)
+
+/*
+** Initialize the Buffer structure pointed to by pBuffer.
+*/
+static void thBufferInit(Buffer *pBuffer){
+  memset(pBuffer, 0, sizeof(Buffer));
+}
+
+/*
+** Zero the buffer pointed to by pBuffer and free the associated memory
+** allocation.
+*/
+static void thBufferFree(Th_Interp *interp, Buffer *pBuffer){
+  Th_Free(interp, pBuffer->zBuf);
+  thBufferInit(pBuffer);
+}
+
+/*
+** Assuming parameter c contains a hexadecimal digit character,
+** return the corresponding value of that digit. If c is not
+** a hexadecimal digit character, -1 is returned.
+*/
+static int thHexdigit(uchar c){
+  switch (c) {
+    case '0': return 0;
+    case '1': return 1;
+    case '2': return 2;
+    case '3': return 3;
+    case '4': return 4;
+    case '5': return 5;
+    case '6': return 6;
+    case '7': return 7;
+    case '8': return 8;
+    case '9': return 9;
+    case 'a': case 'A': return 10;
+    case 'b': case 'B': return 11;
+    case 'c': case 'C': return 12;
+    case 'd': case 'D': return 13;
+    case 'e': case 'E': return 14;
+    case 'f': case 'F': return 15;
+  }
+  return -1;
+}
+
+/*
+** Argument pEntry points to an entry in a stack frame hash table
+** (Th_Frame.paVar). Decrement the refrerence count of the Th_Variable
+** structure that the entry points to. Free the Th_Variable if its
+** reference count reaches 0.
+**
+** Argument pContext is a pointer to the interpreter structure.
+*/
+static void thFreeVariable(Th_HashEntry *pEntry, void *pContext){
+  Th_Variable *pValue = (Th_Variable *)pEntry->pData;
+  pValue->nRef--;
+  assert( pValue->nRef>=0 );
+  if( pValue->nRef==0 ){
+    Th_Interp *interp = (Th_Interp *)pContext;
+    Th_Free(interp, pValue->zData);
+    if( pValue->pHash ){
+      Th_HashIterate(interp, pValue->pHash, thFreeVariable, pContext);
+      Th_HashDelete(interp, pValue->pHash);
+    }
+    Th_Free(interp, pValue);
+  }
+}
+
+/*
+** Argument pEntry points to an entry in the command hash table
+** (Th_Interp.paCmd). Delete the Th_Command structure that the
+** entry points to.
+**
+** Argument pContext is a pointer to the interpreter structure.
+*/
+static void thFreeCommand(Th_HashEntry *pEntry, void *pContext){
+  Th_Command *pCommand = (Th_Command *)pEntry->pData;
+  if( pCommand->xDel ){
+    pCommand->xDel((Th_Interp *)pContext, pCommand->pContext);
+  }
+  Th_Free((Th_Interp *)pContext, pEntry->pData);
+  pEntry->pData = 0;
+}
+
+/*
+** Push a new frame onto the stack.
+*/
+static int thPushFrame(Th_Interp *interp, Th_Frame *pFrame){
+  pFrame->paVar = Th_HashNew(interp);
+  pFrame->pCaller = interp->pFrame;
+  interp->pFrame = pFrame;
+  return TH_OK;
+}
+
+/*
+** Pop a frame off the top of the stack.
+*/
+static void thPopFrame(Th_Interp *interp){
+  Th_Frame *pFrame = interp->pFrame;
+  Th_HashIterate(interp, pFrame->paVar, thFreeVariable, (void *)interp);
+  Th_HashDelete(interp, pFrame->paVar);
+  interp->pFrame = pFrame->pCaller;
+}
+
+/*
+** The first part of the string (zInput,nInput) contains an escape
+** sequence. Set *pnEscape to the number of bytes in the escape sequence.
+** If there is a parse error, return TH_ERROR and set the interpreter
+** result to an error message. Otherwise return TH_OK.
+*/
+static int thNextEscape(
+  Th_Interp *interp,
+  const uchar *zInput,
+  int nInput,
+  int *pnEscape
+){
+  int i = 2;
+
+  assert(nInput>0);
+  assert(zInput[0]=='\\');
+
+  if( nInput<=1 ){
+    return TH_ERROR;
+  }
+
+  switch( zInput[1] ){
+    case 'x': i = 4;
+  }
+
+  if( i>nInput ){
+    return TH_ERROR;
+  }
+  *pnEscape = i;
+  return TH_OK;
+}
+
+/*
+** The first part of the string (zInput,nInput) contains a variable
+** reference. Set *pnVarname to the number of bytes in the variable
+** reference. If there is a parse error, return TH_ERROR and set the
+** interpreter result to an error message. Otherwise return TH_OK.
+*/
+int thNextVarname(
+  Th_Interp *interp,
+  const uchar *zInput,
+  int nInput,
+  int *pnVarname
+){
+  int i;
+
+  assert(nInput>0);
+  assert(zInput[0]=='$');
+
+  if( nInput>0 && zInput[1]=='{' ){
+    for(i=2; i<nInput && zInput[i]!='}'; i++);
+    if( i==nInput ){
+      return TH_ERROR;
+    }
+    i++;
+  }else{
+    i = 1;
+    if( nInput>2 && zInput[1]==':' && zInput[2]==':' ){
+      i += 2;
+    }
+    for(; i<nInput; i++){
+      if( zInput[i]=='(' ){
+        for(i++; i<nInput; i++){
+          if( zInput[i]==')' ) break;
+          if( zInput[i]=='\\' ) i++;
+          if( zInput[i]=='{' || zInput[i]=='[' || zInput[i]=='"' ){
+            int nWord;
+            int rc = thNextWord(interp, &zInput[i], nInput-i, &nWord, 0);
+            if( rc!=TH_OK ){
+              return rc;
+            }
+            i += nWord;
+          }
+        }
+        if( i>=nInput ){
+          Th_ErrorMessage(interp, "Unmatched brackets:", zInput, nInput);
+          return TH_ERROR;
+        }
+        i++;
+        break;
+      }
+      if( !th_isalnum(zInput[i]) && zInput[i]!='_' ) break;
+    }
+  }
+
+  *pnVarname = i;
+  return TH_OK;
+}
+
+/*
+** The first part of the string (zInput,nInput) contains a command
+** enclosed in a "[]" block. Set *pnCommand to the number of bytes in
+** the variable reference. If there is a parse error, return TH_ERROR
+** and set the interpreter result to an error message. Otherwise return
+** TH_OK.
+*/
+int thNextCommand(
+  Th_Interp *interp,
+  const uchar *zInput,
+  int nInput,
+  int *pnCommand
+){
+  int nBrace = 0;
+  int nSquare = 0;
+  int i;
+
+  assert(nInput>0);
+  assert( zInput[0]=='[' || zInput[0]=='{' );
+
+  for(i=0; i<nInput && (i==0 || nBrace>0 || nSquare>0); i++){
+    switch( zInput[i] ){
+      case '\\': i++; break;
+      case '{': nBrace++; break;
+      case '}': nBrace--; break;
+      case '[': nSquare++; break;
+      case ']': nSquare--; break;
+    }
+  }
+  if( nBrace || nSquare ){
+    return TH_ERROR;
+  }
+
+  *pnCommand = i;
+
+  return TH_OK;
+}
+
+/*
+** Set *pnSpace to the number of whitespace bytes at the start of
+** input string (zInput, nInput). Always return TH_OK.
+*/
+int thNextSpace(
+  Th_Interp *interp,
+  const uchar *zInput,
+  int nInput,
+  int *pnSpace
+){
+  int i;
+  for(i=0; i<nInput && th_isspace(zInput[i]); i++);
+  *pnSpace = i;
+  return TH_OK;
+}
+
+/*
+** The first byte of the string (zInput,nInput) is not white-space.
+** Set *pnWord to the number of bytes in the th1 word that starts
+** with this byte. If a complete word cannot be parsed or some other
+** error occurs, return TH_ERROR and set the interpreter result to
+** an error message. Otherwise return TH_OK.
+**
+** If the isCmd argument is non-zero, then an unescaped ";" byte not
+** located inside of a block or quoted string is considered to mark
+** the end of the word.
+*/
+static int thNextWord(
+  Th_Interp *interp,
+  const uchar *zInput,
+  int nInput,
+  int *pnWord,
+  int isCmd
+){
+  int iEnd = 0;
+
+  assert( !th_isspace(zInput[0]) );
+
+  if( zInput[0]=='"' ){
+    /* The word is terminated by the next unescaped '"' character. */
+    iEnd++;
+    while( iEnd<nInput && zInput[iEnd]!='"' ){
+      if( zInput[iEnd]=='\\' ){
+        iEnd++;
+      }
+      iEnd++;
+    }
+    iEnd++;
+  }else{
+    int nBrace = 0;
+    int nSq = 0;
+    while( iEnd<nInput && (nBrace>0 || nSq>0 ||
+      (!th_isspace(zInput[iEnd]) && (!isCmd || zInput[iEnd]!=';'))
+    )){
+      switch( zInput[iEnd] ){
+        case '\\': iEnd++; break;
+        case '{': if( nSq==0 ) nBrace++; break;
+        case '}': if( nSq==0 ) nBrace--; break;
+        case '[': if( nBrace==0 ) nSq++; break;
+        case ']': if( nBrace==0 ) nSq--; break;
+      }
+      iEnd++;
+    }
+    if( nBrace>0 || nSq>0 ){
+      /* Parse error */
+      return TH_ERROR;
+    }
+  }
+
+  if( iEnd>nInput ){
+    /* Parse error */
+    return TH_ERROR;
+  }
+  *pnWord = iEnd;
+  return TH_OK;
+}
+
+/*
+** The input string (zWord, nWord) contains a th1 script enclosed in
+** a [] block. Perform substitution on the input string and store the
+** resulting string in the interpreter result.
+*/
+static int thSubstCommand(
+  Th_Interp *interp,
+  const uchar *zWord,
+  int nWord
+){
+  assert(nWord>=2);
+  assert(zWord[0]=='[' && zWord[nWord-1]==']');
+  return thEvalLocal(interp, &zWord[1], nWord-2);
+}
+
+/*
+** The input string (zWord, nWord) contains a th1 variable reference
+** (a '$' byte followed by a variable name). Perform substitution on
+** the input string and store the resulting string in the interpreter
+** result.
+*/
+static int thSubstVarname(
+  Th_Interp *interp,
+  const uchar *zWord,
+  int nWord
+){
+  assert(nWord>=1);
+  assert(zWord[0]=='$');
+  assert(nWord==1 || zWord[1]!='{' || zWord[nWord-1]=='}');
+  if( nWord>1 && zWord[1]=='{' ){
+    zWord++;
+    nWord -= 2;
+  }else if( zWord[nWord-1]==')' ){
+    int i;
+    for(i=1; i<nWord && zWord[i]!='('; i++);
+    if( i<nWord ){
+      Buffer varname;
+      int nInner;
+      const uchar *zInner;
+
+      int rc = thSubstWord(interp, &zWord[i+1], nWord-i-2);
+      if( rc!=TH_OK ) return rc;
+
+      zInner = Th_GetResult(interp, &nInner);
+      thBufferInit(&varname);
+      thBufferWrite(interp, &varname, &zWord[1], i);
+      thBufferWrite(interp, &varname, zInner, nInner);
+      thBufferWrite(interp, &varname, ")", 1);
+      rc = Th_GetVar(interp, varname.zBuf, varname.nBuf);
+      thBufferFree(interp, &varname);
+      return rc;
+    }
+  }
+  return Th_GetVar(interp, &zWord[1], nWord-1);
+}
+
+/*
+** The input string (zWord, nWord) contains a th1 escape sequence.
+** Perform substitution on the input string and store the resulting
+** string in the interpreter result.
+*/
+static int thSubstEscape(
+  Th_Interp *interp,
+  const uchar *zWord,
+  int nWord
+){
+  uchar c;
+
+  assert(nWord>=2);
+  assert(zWord[0]=='\\');
+
+  switch( zWord[1] ){
+    case 'x': {
+      assert(nWord==4);
+      c = ((thHexdigit(zWord[2])<<4) + thHexdigit(zWord[3]));
+      break;
+    }
+    case 'n': {
+      c = '\n';
+      break;
+    }
+    default: {
+      assert(nWord==2);
+      c = zWord[1];
+      break;
+    }
+  }
+
+  Th_SetResult(interp, &c, 1);
+  return TH_OK;
+}
+
+/*
+** The input string (zWord, nWord) contains a th1 word. Perform
+** substitution on the input string and store the resulting
+** string in the interpreter result.
+*/
+static int thSubstWord(
+  Th_Interp *interp,
+  const uchar *zWord,
+  int nWord
+){
+  int rc = TH_OK;
+  Buffer output;
+  int i;
+
+  thBufferInit(&output);
+
+  if( nWord>1 && (zWord[0]=='{' && zWord[nWord-1]=='}') ){
+    rc = thBufferWrite(interp, &output, &zWord[1], nWord-2);
+  }else{
+
+    /* If the word is surrounded by double-quotes strip these away. */
+    if( nWord>1 && (zWord[0]=='"' && zWord[nWord-1]=='"') ){
+      zWord++;
+      nWord -= 2;
+    }
+
+    for(i=0; rc==TH_OK && i<nWord; i++){
+      int nGet;
+
+      int (*xGet)(Th_Interp *, const uchar*, int, int *) = 0;
+      int (*xSubst)(Th_Interp *, const uchar*, int) = 0;
+
+      switch( zWord[i] ){
+        case '\\':
+          xGet = thNextEscape; xSubst = thSubstEscape;
+          break;
+        case '[':
+          if( !interp->isListMode ){
+            xGet = thNextCommand; xSubst = thSubstCommand;
+            break;
+          }
+        case '$':
+          if( !interp->isListMode ){
+            xGet = thNextVarname; xSubst = thSubstVarname;
+            break;
+          }
+        default: {
+          thBufferWrite(interp, &output, &zWord[i], 1);
+          continue; /* Go to the next iteration of the for(...) loop */
+        }
+      }
+
+      rc = xGet(interp, &zWord[i], nWord-i, &nGet);
+      if( rc==TH_OK ){
+        rc = xSubst(interp, &zWord[i], nGet);
+      }
+      if( rc==TH_OK ){
+        const uchar *zRes;
+        int nRes;
+        zRes = Th_GetResult(interp, &nRes);
+        rc = thBufferWrite(interp, &output, zRes, nRes);
+        i += (nGet-1);
+      }
+    }
+  }
+
+  if( rc==TH_OK ){
+    Th_SetResult(interp, output.zBuf, output.nBuf);
+  }
+  thBufferFree(interp, &output);
+  return rc;
+}
+
+/*
+** Return true if one of the following is true of the buffer pointed
+** to by zInput, length nInput:
+**
+**   + It is empty, or
+**   + It contains nothing but white-space, or
+**   + It contains no non-white-space characters before the first
+**     newline character.
+**
+** Otherwise return false.
+*/
+static int thEndOfLine(const uchar *zInput, int nInput){
+  int i;
+  for(i=0; i<nInput && zInput[i]!='\n' && th_isspace(zInput[i]); i++);
+  return ((i==nInput || zInput[i]=='\n')?1:0);
+}
+
+/*
+** This function splits the supplied th1 list (contained in buffer zList,
+** size nList) into elements and performs word-substitution on each
+** element. If the Th_Interp.isListMode variable is true, then only
+** escape sequences are substituted (used by the Th_SplitList() function).
+** If Th_Interp.isListMode is false, then variable and command substitution
+** is also performed (used by Th_Eval()).
+**
+** If zList/nList does not contain a valid list, TH_ERROR is returned
+** and an error message stored in interp.
+**
+** If TH_OK is returned and pazElem is not NULL, the caller should free the
+** pointer written to (*pazElem) using Th_Free(). This releases memory
+** allocated for both the (*pazElem) and (*panElem) arrays. Example:
+**
+**     uchar **argv;
+**     int *argl;
+**     int argc;
+**
+**     // After this call, argv and argl point to valid arrays. The
+**     // number of elements in each is argc.
+**     //
+**     Th_SplitList(interp, zList, nList, &argv, &argl, &argc);
+**
+**     // Free all memory allocated by Th_SplitList(). The arrays pointed
+**     // to by argv and argl are invalidated by this call.
+**     //
+**     Th_Free(interp, argv);
+**
+*/
+static int thSplitList(
+  Th_Interp *interp,      /* Interpreter context */
+  const uchar *zList,     /* Pointer to buffer containing input list */
+  int nList,              /* Size of buffer pointed to by zList */
+  uchar ***pazElem,       /* OUT: Array of list elements */
+  int **panElem,          /* OUT: Lengths of each list element */
+  int *pnCount            /* OUT: Number of list elements */
+){
+  int rc = TH_OK;
+
+  Buffer strbuf;
+  Buffer lenbuf;
+  int nCount = 0;
+
+  const uchar *zInput = zList;
+  int nInput = nList;
+
+  thBufferInit(&strbuf);
+  thBufferInit(&lenbuf);
+
+  while( nInput>0 ){
+    const uchar *zWord;
+    int nWord;
+
+    thNextSpace(interp, zInput, nInput, &nWord);
+    zInput += nWord;
+    nInput = nList-(zInput-zList);
+
+    if( TH_OK!=(rc = thNextWord(interp, zInput, nInput, &nWord, 0))
+     || TH_OK!=(rc = thSubstWord(interp, zInput, nWord))
+    ){
+      goto finish;
+    }
+    zInput = &zInput[nWord];
+    nInput = nList-(zInput-zList);
+    if( nWord>0 ){
+      zWord = Th_GetResult(interp, &nWord);
+      thBufferWrite(interp, &strbuf, zWord, nWord);
+      thBufferWrite(interp, &strbuf, "\0", 1);
+      thBufferWrite(interp, &lenbuf, &nWord, sizeof(int));
+      nCount++;
+    }
+  }
+  assert((lenbuf.nBuf/sizeof(int))==nCount);
+
+  assert((pazElem && panElem) || (!pazElem && !panElem));
+  if( pazElem && rc==TH_OK ){
+    int i;
+    uchar *zElem;
+    int *anElem;
+    uchar **azElem = Th_Malloc(interp,
+      sizeof(uchar*) * nCount +      /* azElem */
+      sizeof(int) * nCount +         /* anElem */
+      strbuf.nBuf                    /* space for list element strings */
+    );
+    anElem = (int *)&azElem[nCount];
+    zElem = (uchar *)&anElem[nCount];
+    memcpy(anElem, lenbuf.zBuf, lenbuf.nBuf);
+    memcpy(zElem, strbuf.zBuf, strbuf.nBuf);
+    for(i=0; i<nCount;i++){
+      azElem[i] = zElem;
+      zElem += (anElem[i] + 1);
+    }
+    *pazElem = azElem;
+    *panElem = anElem;
+  }
+  if( pnCount ){
+    *pnCount = nCount;
+  }
+
+ finish:
+  thBufferFree(interp, &strbuf);
+  thBufferFree(interp, &lenbuf);
+  return rc;
+}
+
+/*
+** Evaluate the th1 script contained in the string (zProgram, nProgram)
+** in the current stack frame.
+*/
+static int thEvalLocal(Th_Interp *interp, const uchar *zProgram, int nProgram){
+  int rc = TH_OK;
+  const uchar *zInput = zProgram;
+  int nInput = nProgram;
+
+  while( rc==TH_OK && nInput ){
+    Th_HashEntry *pEntry;
+    int nSpace;
+    const uchar *zFirst;
+
+    uchar **argv;
+    int *argl;
+    int argc;
+
+    assert(nInput>=0);
+
+    /* Skip a semi-colon */
+    if( *zInput==';' ){
+      zInput++;
+      nInput--;
+    }
+
+    /* Skip past leading white-space. */
+    thNextSpace(interp, zInput, nInput, &nSpace);
+    zInput += nSpace;
+    nInput -= nSpace;
+    zFirst = zInput;
+
+    /* Check for a comment. If found, skip to the end of the line. */
+    if( zInput[0]=='#' ){
+      while( !thEndOfLine(zInput, nInput) ){
+        zInput++;
+        nInput--;
+      }
+      continue;
+    }
+
+    /* Gobble up input a word at a time until the end of the command
+    ** (a semi-colon or end of line).
+    */
+    while( rc==TH_OK && *zInput!=';' && !thEndOfLine(zInput, nInput) ){
+      int nWord;
+      thNextSpace(interp, zInput, nInput, &nSpace);
+      rc = thNextWord(interp, &zInput[nSpace], nInput-nSpace, &nWord, 1);
+      zInput += (nSpace+nWord);
+      nInput -= (nSpace+nWord);
+    }
+    if( rc!=TH_OK ) continue;
+
+    /* Split the command into an array of words. This call also does
+    ** substitution of each individual word.
+    */
+    rc = thSplitList(interp, zFirst, zInput-zFirst, &argv, &argl, &argc);
+    if( rc!=TH_OK ) continue;
+
+    if( argc>0 ){
+
+      /* Look up the command name in the command hash-table. */
+      pEntry = Th_HashFind(interp, interp->paCmd, argv[0], argl[0], 0);
+      if( !pEntry ){
+        Th_ErrorMessage(interp, "no such command: ", argv[0], argl[0]);
+        rc = TH_ERROR;
+      }
+
+      /* Call the command procedure. */
+      if( rc==TH_OK ){
+        Th_Command *p = (Th_Command *)(pEntry->pData);
+        const uchar **azArg = (const uchar **)argv;
+        rc = p->xProc(interp, p->pContext, argc, azArg, argl);
+      }
+
+      /* If an error occured, add this command to the stack trace report. */
+      if( rc==TH_ERROR ){
+        uchar *zRes;
+        int nRes;
+        uchar *zStack = 0;
+        int nStack = 0;
+
+        zRes = Th_TakeResult(interp, &nRes);
+        if( TH_OK==Th_GetVar(interp, (uchar *)"::th_stack_trace", -1) ){
+          zStack = Th_TakeResult(interp, &nStack);
+        }
+        Th_ListAppend(interp, &zStack, &nStack, zFirst, zInput-zFirst);
+        Th_SetVar(interp, (uchar *)"::th_stack_trace", -1, zStack, nStack);
+        Th_SetResult(interp, zRes, nRes);
+        Th_Free(interp, zRes);
+        Th_Free(interp, zStack);
+      }
+    }
+
+    Th_Free(interp, argv);
+  }
+
+  return rc;
+}
+
+/*
+** Interpret an integer frame identifier passed to either Th_Eval() or
+** Th_LinkVar(). If successful, return a pointer to the identified
+** Th_Frame structure. If unsuccessful (no such frame), return 0 and
+** leave an error message in the interpreter result.
+**
+** Argument iFrame is interpreted as follows:
+**
+**   * If iFrame is 0, this means the current frame.
+**
+**   * If iFrame is negative, then the nth frame up the stack, where
+**     n is the absolute value of iFrame. A value of -1 means the
+**     calling procedure.
+**
+**   * If iFrame is +ve, then the nth frame from the bottom of the
+**     stack. An iFrame value of 1 means the toplevel (global) frame.
+*/
+static Th_Frame *getFrame(Th_Interp *interp, int iFrame){
+  Th_Frame *p = interp->pFrame;
+  int i;
+  if( iFrame>0 ){
+    for(i=0; p; i++){
+      p = p->pCaller;
+    }
+    iFrame = (i*-1) + iFrame;
+    p = interp->pFrame;
+  }
+  for(i=0; p && i<(iFrame*-1); i++){
+    p = p->pCaller;
+  }
+
+  if( !p ){
+    uchar *zFrame;
+    int nFrame;
+    Th_SetResultInt(interp, iFrame);
+    zFrame = Th_TakeResult(interp, &nFrame);
+    Th_ErrorMessage(interp, "no such frame:", zFrame, nFrame);
+    Th_Free(interp, zFrame);
+  }
+  return p;
+}
+
+
+/*
+** Evaluate th1 script (zProgram, nProgram) in the frame identified by
+** argument iFrame. Leave either an error message or a result in the
+** interpreter result and return a th1 error code (TH_OK, TH_ERROR,
+** TH_RETURN, TH_CONTINUE or TH_BREAK).
+*/
+int Th_Eval(Th_Interp *interp, int iFrame, const uchar *zProgram, int nProgram){
+  int rc = TH_OK;
+  Th_Frame *pSavedFrame = interp->pFrame;
+
+  /* Set Th_Interp.pFrame to the frame that this script is to be
+  ** evaluated in. The current frame is saved in pSavedFrame and will
+  ** be restored before this function returns.
+  */
+  interp->pFrame = getFrame(interp, iFrame);
+
+  if( !interp->pFrame ){
+    rc = TH_ERROR;
+  }else{
+    int nInput = nProgram;
+
+    if( nInput<0 ){
+      nInput = th_strlen(zProgram);
+    }
+    rc = thEvalLocal(interp, zProgram, nInput);
+  }
+
+  interp->pFrame = pSavedFrame;
+  return rc;
+}
+
+/*
+** Input string (zVarname, nVarname) contains a th1 variable name. It
+** may be a simple scalar variable name or it may be a reference
+** to an array member. The variable name may or may not begin with
+** "::", indicating that the name refers to a global variable, not
+** a local scope one.
+**
+** This function inspects and categorizes the supplied variable name.
+**
+** If the name is a global reference, *pisGlobal is set to true. Otherwise
+** false. Output string (*pzOuter, *pnOuter) is set to the variable name
+** if it is a scalar reference, or the name of the array if it is an
+** array variable. If the variable is a scalar, *pzInner is set to 0.
+** If it is an array variable, (*pzInner, *pnInner) is set to the
+** array key name.
+*/
+static int thAnalyseVarname(
+  const uchar *zVarname,
+  int nVarname,
+  const uchar **pzOuter,     /* OUT: Pointer to scalar/array name */
+  int *pnOuter,              /* OUT: Number of bytes at *pzOuter */
+  const uchar **pzInner,     /* OUT: Pointer to array key (or null) */
+  int *pnInner,              /* OUT: Number of bytes at *pzInner */
+  int *pisGlobal             /* OUT: Set to true if this is a global ref */
+){
+  const uchar *zOuter = zVarname;
+  int nOuter;
+  const uchar *zInner = 0;
+  int nInner = 0;
+  int isGlobal = 0;
+  int i;
+
+  if( nVarname<0 ){
+    nVarname = th_strlen(zVarname);
+  }
+  nOuter = nVarname;
+
+  /* If the variable name starts with "::", then do the lookup is in the
+  ** uppermost (global) frame.
+  */
+  if( nVarname>2 && zVarname[0]==':' && zVarname[1]==':' ){
+    zOuter += 2;
+    nOuter -= 2;
+    isGlobal = 1;
+  }
+
+  /* Check if this is an array reference. */
+  if( zOuter[nOuter-1]==')' ){
+    for(i=0; i<nOuter; i++){
+      if( zOuter[i]=='(' ){
+        zInner = &zOuter[i+1];
+        nInner = nOuter-i-2;
+        nOuter = i;
+        break;
+      }
+    }
+  }
+
+  *pzOuter = zOuter;
+  *pnOuter = nOuter;
+  *pzInner = zInner;
+  *pnInner = nInner;
+  *pisGlobal = isGlobal;
+  return TH_OK;
+}
+
+/*
+** Input string (zVar, nVar) contains a variable name. This function locates
+** the Th_Variable structure associated with the named variable. The
+** variable name may be a global or local scalar or array variable
+**
+** If the create argument is non-zero and the named variable does not exist
+** it is created. Otherwise, an error is left in the interpreter result
+** and NULL returned.
+**
+** If the arrayok argument is false and the named variable is an array,
+** an error is left in the interpreter result and NULL returned. If
+** arrayok is true an array name is Ok.
+*/
+static Th_Variable *thFindValue(
+  Th_Interp *interp,
+  const uchar *zVar,     /* Pointer to variable name */
+  int nVar,              /* Number of bytes at nVar */
+  int create,            /* If true, create the variable if not found */
+  int arrayok            /* If true, an array is Ok. Othewise array==error */
+){
+  const uchar *zOuter;
+  int nOuter;
+  const uchar *zInner;
+  int nInner;
+  int isGlobal;
+
+  Th_HashEntry *pEntry;
+  Th_Frame *pFrame = interp->pFrame;
+  Th_Variable *pValue;
+
+  thAnalyseVarname(zVar, nVar, &zOuter, &nOuter, &zInner, &nInner, &isGlobal);
+  if( isGlobal ){
+    while( pFrame->pCaller ) pFrame = pFrame->pCaller;
+  }
+
+  pEntry = Th_HashFind(interp, pFrame->paVar, zOuter, nOuter, create);
+  assert(pEntry || !create);
+  if( !pEntry ){
+    goto no_such_var;
+  }
+
+  pValue = (Th_Variable *)pEntry->pData;
+  if( !pValue ){
+    assert(create);
+    pValue = Th_Malloc(interp, sizeof(Th_Variable));
+    pValue->nRef = 1;
+    pEntry->pData = (void *)pValue;
+  }
+
+  if( zInner ){
+    if( pValue->zData ){
+      Th_ErrorMessage(interp, "variable is a scalar:", zOuter, nOuter);
+      return 0;
+    }
+    if( !pValue->pHash ){
+      if( !create ){
+        goto no_such_var;
+      }
+      pValue->pHash = Th_HashNew(interp);
+    }
+    pEntry = Th_HashFind(interp, pValue->pHash, zInner, nInner, create);
+    if( !pEntry ){
+      goto no_such_var;
+    }
+    pValue = (Th_Variable *)pEntry->pData;
+    if( !pValue ){
+      assert(create);
+      pValue = Th_Malloc(interp, sizeof(Th_Variable));
+      pValue->nRef = 1;
+      pEntry->pData = (void *)pValue;
+    }
+  }else{
+    if( pValue->pHash && !arrayok ){
+      Th_ErrorMessage(interp, "variable is an array:", zOuter, nOuter);
+      return 0;
+    }
+  }
+
+  return pValue;
+
+no_such_var:
+  Th_ErrorMessage(interp, "no such variable:", zVar, nVar);
+  return 0;
+}
+
+/*
+** String (zVar, nVar) must contain the name of a scalar variable or
+** array member. Look up the variable, store its current value in
+** the interpreter result and return TH_OK.
+**
+** If the named variable does not exist, return TH_ERROR and leave
+** an error message in the interpreter result.
+*/
+int Th_GetVar(Th_Interp *interp, const uchar *zVar, int nVar){
+  Th_Variable *pValue;
+
+  pValue = thFindValue(interp, zVar, nVar, 0, 0);
+  if( !pValue ){
+    return TH_ERROR;
+  }
+  if( !pValue->zData ){
+    Th_ErrorMessage(interp, "no such variable:", zVar, nVar);
+    return TH_ERROR;
+  }
+
+  return Th_SetResult(interp, pValue->zData, pValue->nData);
+}
+
+/*
+** String (zVar, nVar) must contain the name of a scalar variable or
+** array member. If the variable does not exist it is created. The
+** variable is set to the value supplied in string (zValue, nValue).
+**
+** If (zVar, nVar) refers to an existing array, TH_ERROR is returned
+** and an error message left in the interpreter result.
+*/
+int Th_SetVar(
+  Th_Interp *interp,
+  const uchar *zVar,
+  int nVar,
+  const uchar *zValue,
+  int nValue
+){
+  Th_Variable *pValue;
+
+  pValue = thFindValue(interp, zVar, nVar, 1, 0);
+  if( !pValue ){
+    return TH_ERROR;
+  }
+
+  if( nValue<0 ){
+    nValue = th_strlen(zValue);
+  }
+  if( pValue->zData ){
+    Th_Free(interp, pValue->zData);
+    pValue->zData = 0;
+  }
+
+  assert(zValue || nValue==0);
+  pValue->zData = Th_Malloc(interp, nValue+1);
+  pValue->zData[nValue] = '\0';
+  memcpy(pValue->zData, zValue, nValue);
+  pValue->nData = nValue;
+
+  return TH_OK;
+}
+
+/*
+** Create a variable link so that accessing variable (zLocal, nLocal) is
+** the same as accessing variable (zLink, nLink) in stack frame iFrame.
+*/
+int Th_LinkVar(
+  Th_Interp *interp,                 /* Interpreter */
+  const uchar *zLocal, int nLocal,   /* Local varname */
+  int iFrame,                        /* Stack frame of linked var */
+  const uchar *zLink, int nLink      /* Linked varname */
+){
+  Th_Frame *pSavedFrame = interp->pFrame;
+  Th_Frame *pFrame;
+  Th_HashEntry *pEntry;
+  Th_Variable *pValue;
+
+  pFrame = getFrame(interp, iFrame);
+  if( !pFrame ){
+    return TH_ERROR;
+  }
+  pSavedFrame = interp->pFrame;
+  interp->pFrame = pFrame;
+  pValue = thFindValue(interp, zLink, nLink, 1, 1);
+  interp->pFrame = pSavedFrame;
+
+  pEntry = Th_HashFind(interp, interp->pFrame->paVar, zLocal, nLocal, 1);
+  if( pEntry->pData ){
+    Th_ErrorMessage(interp, "variable exists:", zLocal, nLocal);
+    return TH_ERROR;
+  }
+  pEntry->pData = (void *)pValue;
+  pValue->nRef++;
+
+  return TH_OK;
+}
+
+/*
+** Input string (zVar, nVar) must contain the name of a scalar variable,
+** an array, or an array member. If the identified variable exists, it
+** is deleted and TH_OK returned. Otherwise, an error message is left
+** in the interpreter result and TH_ERROR is returned.
+*/
+int Th_UnsetVar(Th_Interp *interp, const uchar *zVar, int nVar){
+  Th_Variable *pValue;
+
+  pValue = thFindValue(interp, zVar, nVar, 1, 1);
+  if( !pValue ){
+    return TH_ERROR;
+  }
+
+  Th_Free(interp, pValue->zData);
+  pValue->zData = 0;
+  if( pValue->pHash ){
+    Th_HashIterate(interp, pValue->pHash, thFreeVariable, (void *)interp);
+    Th_HashDelete(interp, pValue->pHash);
+    pValue->pHash = 0;
+  }
+  return TH_OK;
+}
+
+/*
+** Return an allocated buffer containing a copy of string (z, n). The
+** caller is responsible for eventually calling Th_Free() to free
+** the returned buffer.
+*/
+uchar *th_strdup(Th_Interp *interp, const uchar *z, int n){
+  uchar *zRes;
+  if( n<0 ){
+    n = th_strlen(z);
+  }
+  zRes = Th_Malloc(interp, n+1);
+  memcpy(zRes, z, n);
+  zRes[n] = '\0';
+  return zRes;
+}
+
+/*
+** Argument zPre must be a nul-terminated string. Set the interpreter
+** result to a string containing the contents of zPre, followed by
+** a space (" ") character, followed by a copy of string (z, n).
+**
+** In other words, the equivalent of:
+*
+**     printf("%s %.*s", zPre, n, z);
+**
+** Example:
+**
+**     Th_ErrorMessage(interp, "no such variable:", zVarname, nVarname);
+**
+*/
+int Th_ErrorMessage(Th_Interp *interp, const char *zPre, const uchar *z, int n){
+  if( interp ){
+    uchar *zRes = 0;
+    int nRes = 0;
+    int nPre = th_strlen(zPre);
+
+    Th_SetVar(interp, (uchar *)"::th_stack_trace", -1, 0, 0);
+
+    Th_StringAppend(interp, &zRes, &nRes, zPre, -1);
+    if( zRes[nRes-1]=='"' ){
+      Th_StringAppend(interp, &zRes, &nRes, z, n);
+      Th_StringAppend(interp, &zRes, &nRes, (const uchar *)"\"", 1);
+    }else{
+      Th_StringAppend(interp, &zRes, &nRes, (const uchar *)" ", 1);
+      Th_StringAppend(interp, &zRes, &nRes, z, n);
+    }
+
+    Th_SetResult(interp, zRes, nRes);
+    Th_Free(interp, zRes);
+  }
+
+  return TH_OK;
+}
+
+/*
+** Set the current interpreter result by taking a copy of the buffer
+** pointed to by z, size n bytes. TH_OK is always returned.
+*/
+int Th_SetResult(Th_Interp *pInterp, const uchar *z, int n){
+
+  /* Free the current result */
+  Th_Free(pInterp, pInterp->zResult);
+  pInterp->zResult = 0;
+  pInterp->nResult = 0;
+
+  if( n<0 ){
+    n = th_strlen(z);
+  }
+
+  if( z && n>0 ){
+    uchar *zResult;
+    zResult = Th_Malloc(pInterp, n+1);
+    memcpy(zResult, z, n);
+    zResult[n] = '\0';
+    pInterp->zResult = zResult;
+    pInterp->nResult = n;
+  }
+
+  return TH_OK;
+}
+
+/*
+** Return a pointer to the buffer containing the current interpreter
+** result. If pN is not NULL, set *pN to the size of the returned
+** buffer.
+*/
+const uchar *Th_GetResult(Th_Interp *pInterp, int *pN){
+  assert(pInterp->zResult || pInterp->nResult==0);
+  if( pN ){
+    *pN = pInterp->nResult;
+  }
+  return (pInterp->zResult ? pInterp->zResult : (const uchar *)"");
+}
+
+/*
+** Return a pointer to the buffer containing the current interpreter
+** result. If pN is not NULL, set *pN to the size of the returned
+** buffer.
+**
+** This function is the same as Th_GetResult() except that the
+** caller is responsible for eventually calling Th_Free() on the
+** returned buffer. The internal interpreter result is cleared
+** after this function is called.
+*/
+uchar *Th_TakeResult(Th_Interp *pInterp, int *pN){
+  if( pN ){
+    *pN = pInterp->nResult;
+  }
+  if( pInterp->zResult ){
+    uchar *zResult = pInterp->zResult;
+    pInterp->zResult = 0;
+    pInterp->nResult = 0;
+    return zResult;
+  }else{
+    return (uchar *)Th_Malloc(pInterp, 1);
+  }
+}
+
+
+/*
+** Wrappers around the supplied malloc() and free()
+*/
+void *Th_Malloc(Th_Interp *pInterp, int nByte){
+  void *p = pInterp->pVtab->xMalloc(nByte);
+  if( p ){
+    memset(p, 0, nByte);
+  }
+  return p;
+}
+void Th_Free(Th_Interp *pInterp, void *z){
+  if( z ){
+    pInterp->pVtab->xFree(z);
+  }
+}
+
+/*
+** Install a new th1 command.
+**
+** If a command of the same name already exists, it is deleted automatically.
+*/
+int Th_CreateCommand(
+  Th_Interp *interp,
+  const char *zName,                 /* New command name */
+  Th_CommandProc xProc,              /* Command callback proc */
+  void *pContext,                    /* Value to pass as second arg to xProc */
+  void (*xDel)(Th_Interp *, void *)  /* Command destructor callback */
+){
+  Th_HashEntry *pEntry;
+  Th_Command *pCommand;
+
+  pEntry = Th_HashFind(interp, interp->paCmd, (const uchar *)zName, -1, 1);
+  if( pEntry->pData ){
+    pCommand = pEntry->pData;
+    if( pCommand->xDel ){
+      pCommand->xDel(interp, pCommand->pContext);
+    }
+  }else{
+    pCommand = Th_Malloc(interp, sizeof(Th_Command));
+  }
+  pCommand->xProc = xProc;
+  pCommand->pContext = pContext;
+  pCommand->xDel = xDel;
+  pEntry->pData = (void *)pCommand;
+
+  return TH_OK;
+}
+
+/*
+** Rename the existing command (zName, nName) to (zNew, nNew). If nNew is 0,
+** the command is deleted instead of renamed.
+**
+** If successful, TH_OK is returned. If command zName does not exist, or
+** if command zNew already exists, an error message is left in the
+** interpreter result and TH_ERROR is returned.
+*/
+int Th_RenameCommand(
+  Th_Interp *interp,
+  const uchar *zName,            /* Existing command name */
+  int nName,                     /* Number of bytes at zName */
+  const uchar *zNew,             /* New command name */
+  int nNew                       /* Number of bytes at zNew */
+){
+  Th_HashEntry *pEntry;
+  Th_HashEntry *pNewEntry;
+
+  pEntry = Th_HashFind(interp, interp->paCmd, zName, nName, 0);
+  if( !pEntry ){
+    Th_ErrorMessage(interp, "no such command:", zName, nName);
+    return TH_ERROR;
+  }
+  assert(pEntry->pData);
+
+  if( nNew>0 ){
+    pNewEntry = Th_HashFind(interp, interp->paCmd, zNew, nNew, 1);
+    if( pNewEntry->pData ){
+      Th_ErrorMessage(interp, "command exists:", zNew, nNew);
+      return TH_ERROR;
+    }
+    pNewEntry->pData = pEntry->pData;
+  }else{
+    Th_Command *pCommand = (Th_Command *)(pEntry->pData);
+    if( pCommand->xDel ){
+      pCommand->xDel(interp, pCommand->pContext);
+    }
+    Th_Free(interp, pCommand);
+  }
+
+  Th_HashFind(interp, interp->paCmd, zName, nName, -1);
+  return TH_OK;
+}
+
+/*
+** Push a stack frame onto the interpreter stack, invoke the
+** callback, and pop the frame back off again. See the implementation
+** of [proc] (th_lang.c) for an example.
+*/
+int Th_InFrame(Th_Interp *interp,
+  int (*xCall)(Th_Interp *, void *pContext1, void *pContext2),
+  void *pContext1,
+  void *pContext2
+){
+  Th_Frame frame;
+  int rc;
+  thPushFrame(interp, &frame);
+  rc = xCall(interp, pContext1, pContext2);
+  thPopFrame(interp);
+  return rc;
+}
+
+/*
+** Split a th1 list into its component elements. The list to split is
+** passed via arguments (zList, nList). If successful, TH_OK is returned.
+** If an error occurs (if (zList, nList) is not a valid list) an error
+** message is left in the interpreter result and TH_ERROR returned.
+**
+** If successful, *pnCount is set to the number of elements in the list.
+** panElem is set to point at an array of *pnCount integers - the lengths
+** of the element values. *pazElem is set to point at an array of
+** pointers to buffers containing the array element's data.
+**
+** To free the arrays allocated at *pazElem and *panElem, the caller
+** should call Th_Free() on *pazElem only. Exactly one such call to
+** Th_Free() must be made per call to Th_SplitList().
+**
+** Example:
+**
+**     int nElem;
+**     int *anElem;
+**     uchar **azElem;
+**     int i;
+**
+**     Th_SplitList(interp, zList, nList, &azElem, &anElem, &nElem);
+**     for(i=0; i<nElem; i++){
+**       int nData = anElem[i];
+**       uchar *zData = azElem[i];
+**       ...
+**     }
+**
+**     Th_Free(interp, azElem);
+**
+*/
+int Th_SplitList(
+  Th_Interp *interp,
+  const uchar *zList,             /* Pointer to buffer containing list */
+  int nList,                      /* Number of bytes at zList */
+  uchar ***pazElem,               /* OUT: Array of pointers to element data */
+  int **panElem,                  /* OUT: Array of element data lengths */
+  int *pnCount                    /* OUT: Number of elements in list */
+){
+  int rc;
+  interp->isListMode = 1;
+  rc = thSplitList(interp, zList, nList, pazElem, panElem, pnCount);
+  interp->isListMode = 0;
+  if( rc ){
+    Th_ErrorMessage(interp, "Expected list, got: \"", zList, nList);
+  }
+  return rc;
+}
+
+/*
+** Append a new element to an existing th1 list. The element to append
+** to the list is (zElem, nElem).
+**
+** A pointer to the existing list must be stored at *pzList when this
+** function is called. The length must be stored in *pnList. The value
+** of *pzList must either be NULL (in which case *pnList must be 0), or
+** a pointer to memory obtained from Th_Malloc().
+**
+** This function calls Th_Free() to free the buffer at *pzList and sets
+** *pzList to point to a new buffer containing the new list value. *pnList
+** is similarly updated before returning. The return value is always TH_OK.
+**
+** Example:
+**
+**     uchar *zList = 0;
+**     int nList = 0;
+**     for (...) {
+**       uchar *zElem = <some expression>;
+**       Th_ListAppend(interp, &zList, &nList, zElem, -1);
+**     }
+**     Th_SetResult(interp, zList, nList);
+**     Th_Free(interp, zList);
+**
+*/
+int Th_ListAppend(
+  Th_Interp *interp,           /* Interpreter context */
+  uchar **pzList,              /* IN/OUT: Ptr to ptr to list */
+  int *pnList,                 /* IN/OUT: Current length of *pzList */
+  const uchar *zElem,          /* Data to append */
+  int nElem                    /* Length of nElem */
+){
+  Buffer output;
+  int i;
+
+  int hasSpecialChar = 0;
+  int hasEscapeChar = 0;
+  int nBrace = 0;
+
+  output.zBuf = *pzList;
+  output.nBuf = *pnList;
+  output.nBufAlloc = output.nBuf;
+
+  if( nElem<0 ){
+    nElem = th_strlen(zElem);
+  }
+  if( output.nBuf>0 ){
+    thBufferWrite(interp, &output, " ", 1);
+  }
+
+  for(i=0; i<nElem; i++){
+    uchar c = zElem[i];
+    if( th_isspecial(c) ) hasSpecialChar = 1;
+    if( c=='\\' ) hasEscapeChar = 1;
+    if( c=='{' ) nBrace++;
+    if( c=='}' ) nBrace--;
+  }
+
+  if( nElem==0 || (!hasEscapeChar && hasSpecialChar && nBrace==0) ){
+    thBufferWrite(interp, &output, "{", 1);
+    thBufferWrite(interp, &output, zElem, nElem);
+    thBufferWrite(interp, &output, "}", 1);
+  }else{
+    for(i=0; i<nElem; i++){
+      uchar c = zElem[i];
+      if( th_isspecial(c) ) thBufferWrite(interp, &output, "\\", 1);
+      thBufferWrite(interp, &output, &c, 1);
+    }
+  }
+
+  *pzList = output.zBuf;
+  *pnList = output.nBuf;
+
+  return TH_OK;
+}
+
+/*
+** Append a new element to an existing th1 string. This function uses
+** the same interface as the Th_ListAppend() function.
+*/
+int Th_StringAppend(
+  Th_Interp *interp,           /* Interpreter context */
+  uchar **pzStr,               /* IN/OUT: Ptr to ptr to list */
+  int *pnStr,                  /* IN/OUT: Current length of *pzStr */
+  const uchar *zElem,          /* Data to append */
+  int nElem                    /* Length of nElem */
+){
+  uchar *zNew;
+  int nNew;
+
+  if( nElem<0 ){
+    nElem = th_strlen(zElem);
+  }
+
+  nNew = *pnStr + nElem;
+  zNew = Th_Malloc(interp, nNew);
+  memcpy(zNew, *pzStr, *pnStr);
+  memcpy(&zNew[*pnStr], zElem, nElem);
+
+  Th_Free(interp, *pzStr);
+  *pzStr = zNew;
+  *pnStr = nNew;
+
+  return TH_OK;
+}
+
+/*
+** Delete an interpreter.
+*/
+void Th_DeleteInterp(Th_Interp *interp){
+  assert(interp->pFrame);
+  assert(0==interp->pFrame->pCaller);
+
+  /* Delete the contents of the global frame. */
+  thPopFrame(interp);
+
+  /* Delete any result currently stored in the interpreter. */
+  Th_SetResult(interp, 0, 0);
+
+  /* Delete all registered commands and the command hash-table itself. */
+  Th_HashIterate(interp, interp->paCmd, thFreeCommand, (void *)interp);
+  Th_HashDelete(interp, interp->paCmd);
+
+  /* Delete the interpreter structure itself. */
+  Th_Free(interp, (void *)interp);
+}
+
+/*
+** Create a new interpreter.
+*/
+Th_Interp * Th_CreateInterp(Th_Vtab *pVtab){
+  Th_Interp *p;
+
+  /* Allocate and initialise the interpreter and the global frame */
+  p = pVtab->xMalloc(sizeof(Th_Interp) + sizeof(Th_Frame));
+  memset(p, 0, sizeof(Th_Interp));
+  p->pVtab = pVtab;
+  p->paCmd = Th_HashNew(p);
+  thPushFrame(p, (Th_Frame *)&p[1]);
+
+  return p;
+}
+
+/*
+** These two types are used only by the expression module, where
+** the expression module means the Th_Expr() and exprXXX() functions.
+*/
+typedef struct Operator Operator;
+struct Operator {
+  const char *zOp;
+  int eOp;
+  int iPrecedence;
+  int eArgType;
+};
+typedef struct Expr Expr;
+struct Expr {
+  Operator *pOp;
+  Expr *pParent;
+  Expr *pLeft;
+  Expr *pRight;
+
+  uchar *zValue;     /* Pointer to literal value */
+  int nValue;        /* Length of literal value buffer */
+};
+
+/* Unary operators */
+#define OP_UNARY_MINUS  2
+#define OP_UNARY_PLUS   3
+#define OP_BITWISE_NOT  4
+#define OP_LOGICAL_NOT  5
+
+/* Binary operators */
+#define OP_MULTIPLY     6
+#define OP_DIVIDE       7
+#define OP_MODULUS      8
+#define OP_ADD          9
+#define OP_SUBTRACT    10
+#define OP_LEFTSHIFT   11
+#define OP_RIGHTSHIFT  12
+#define OP_LT          13
+#define OP_GT          14
+#define OP_LE          15
+#define OP_GE          16
+#define OP_EQ          17
+#define OP_NE          18
+#define OP_SEQ         19
+#define OP_SNE         20
+#define OP_BITWISE_AND 21
+#define OP_BITWISE_XOR 22
+#define OP_BITWISE_OR  24
+#define OP_LOGICAL_AND 25
+#define OP_LOGICAL_OR  26
+
+/* Other symbols */
+#define OP_OPEN_BRACKET  27
+#define OP_CLOSE_BRACKET 28
+
+/* Argument types. Each operator in the expression syntax is defined
+** as requiring either integer, number (real or integer) or string
+** operands.
+*/
+#define ARG_INTEGER 1
+#define ARG_NUMBER  2
+#define ARG_STRING  3
+
+static Operator aOperator[] = {
+
+  {"(",  OP_OPEN_BRACKET,   -1, 0},
+  {")",  OP_CLOSE_BRACKET, -1, 0},
+
+  /* Note: all unary operators have (iPrecedence==1) */
+  {"-",  OP_UNARY_MINUS,    1, ARG_NUMBER},
+  {"+",  OP_UNARY_PLUS,     1, ARG_NUMBER},
+  {"~",  OP_BITWISE_NOT,    1, ARG_INTEGER},
+  {"!",  OP_LOGICAL_NOT,    1, ARG_INTEGER},
+
+  /* Binary operators. It is important to the parsing in Th_Expr() that
+   * the two-character symbols ("==") appear before the one-character
+   * ones ("="). And that the priorities of all binary operators are
+   * integers between 2 and 12.
+   */
+  {"<<", OP_LEFTSHIFT,      4, ARG_INTEGER},
+  {">>", OP_RIGHTSHIFT,     4, ARG_INTEGER},
+  {"<=", OP_LE,             5, ARG_NUMBER},
+  {">=", OP_GE,             5, ARG_NUMBER},
+  {"==", OP_EQ,             6, ARG_NUMBER},
+  {"!=", OP_NE,             6, ARG_NUMBER},
+  {"eq", OP_SEQ,            7, ARG_STRING},
+  {"ne", OP_SNE,            7, ARG_STRING},
+  {"&&", OP_LOGICAL_AND,   11, ARG_INTEGER},
+  {"||", OP_LOGICAL_OR,    12, ARG_INTEGER},
+
+  {"*",  OP_MULTIPLY,       2, ARG_NUMBER},
+  {"/",  OP_DIVIDE,         2, ARG_NUMBER},
+  {"%",  OP_MODULUS,        2, ARG_INTEGER},
+  {"+",  OP_ADD,            3, ARG_NUMBER},
+  {"-",  OP_SUBTRACT,       3, ARG_NUMBER},
+  {"<",  OP_LT,             5, ARG_NUMBER},
+  {">",  OP_GT,             5, ARG_NUMBER},
+  {"&",  OP_BITWISE_AND,    8, ARG_INTEGER},
+  {"^",  OP_BITWISE_XOR,    9, ARG_INTEGER},
+  {"|",  OP_BITWISE_OR,    10, ARG_INTEGER},
+
+  {0,0,0}
+};
+
+/*
+** The first part of the string (zInput,nInput) contains a number.
+** Set *pnVarname to the number of bytes in the numeric string.
+*/
+static int thNextNumber(
+  Th_Interp *interp,
+  const uchar *zInput,
+  int nInput,
+  int *pnLiteral
+){
+  int i;
+  int seenDot = 0;
+  for(i=0; i<nInput; i++){
+    uchar c = zInput[i];
+    if( (seenDot || c!='.') && !th_isdigit(c) ) break;
+    if( c=='.' ) seenDot = 1;
+  }
+  *pnLiteral = i;
+  return TH_OK;
+}
+
+/*
+** Free an expression tree.
+*/
+static void exprFree(Th_Interp *interp, Expr *pExpr){
+  if( pExpr ){
+    exprFree(interp, pExpr->pLeft);
+    exprFree(interp, pExpr->pRight);
+    Th_Free(interp, pExpr->zValue);
+    Th_Free(interp, pExpr);
+  }
+}
+
+/*
+** Evaluate an expression tree.
+*/
+static int exprEval(Th_Interp *interp, Expr *pExpr){
+  int rc = TH_OK;
+
+  if( pExpr->pOp==0 ){
+    /* A literal */
+    rc = thSubstWord(interp, pExpr->zValue, pExpr->nValue);
+  }else{
+    int eArgType;           /* Actual type of arguments */
+
+    /* Argument values */
+    int iLeft;
+    int iRight;
+    double fLeft;
+    double fRight;
+
+    /* Left and right arguments as strings */
+    uchar *zLeft = 0; int nLeft;
+    uchar *zRight = 0; int nRight;
+
+    /* Evaluate left and right arguments, if they exist. */
+    if( pExpr->pLeft ){
+      rc = exprEval(interp, pExpr->pLeft);
+      if( rc==TH_OK ){
+        zLeft = Th_TakeResult(interp, &nLeft);
+      }
+    }
+    if( rc==TH_OK && pExpr->pRight ){
+      rc = exprEval(interp, pExpr->pRight);
+      if( rc==TH_OK ){
+        zRight = Th_TakeResult(interp, &nRight);
+      }
+    }
+
+    /* Convert arguments to their required forms. */
+    if( rc==TH_OK ){
+      eArgType = pExpr->pOp->eArgType;
+      if( eArgType==ARG_NUMBER ){
+        if( (zLeft==0 || TH_OK==Th_ToInt(0, zLeft, nLeft, &iLeft))
+         && (zRight==0 || TH_OK==Th_ToInt(0, zRight, nRight, &iRight))
+        ){
+          eArgType = ARG_INTEGER;
+        }else if(
+          (zLeft && TH_OK!=Th_ToDouble(interp, zLeft, nLeft, &fLeft)) ||
+          (zRight && TH_OK!=Th_ToDouble(interp, zRight, nRight, &fRight))
+        ){
+          /* A type error. */
+          rc = TH_ERROR;
+        }
+      }else if( eArgType==ARG_INTEGER ){
+        rc = Th_ToInt(interp, zLeft, nLeft, &iLeft);
+        if( rc==TH_OK && zRight ){
+          rc = Th_ToInt(interp, zRight, nRight, &iRight);
+        }
+      }
+    }
+
+    if( rc==TH_OK && eArgType==ARG_INTEGER ){
+      int iRes;
+      switch( pExpr->pOp->eOp ) {
+        case OP_MULTIPLY:     iRes = iLeft*iRight;  break;
+        case OP_DIVIDE:       iRes = iLeft/iRight;  break;
+        case OP_MODULUS:      iRes = iLeft%iRight;  break;
+        case OP_ADD:          iRes = iLeft+iRight;  break;
+        case OP_SUBTRACT:     iRes = iLeft-iRight;  break;
+        case OP_LEFTSHIFT:    iRes = iLeft<<iRight; break;
+        case OP_RIGHTSHIFT:   iRes = iLeft>>iRight; break;
+        case OP_LT:           iRes = iLeft<iRight;  break;
+        case OP_GT:           iRes = iLeft>iRight;  break;
+        case OP_LE:           iRes = iLeft<=iRight; break;
+        case OP_GE:           iRes = iLeft>=iRight; break;
+        case OP_EQ:           iRes = iLeft==iRight; break;
+        case OP_NE:           iRes = iLeft!=iRight; break;
+        case OP_BITWISE_AND:  iRes = iLeft&iRight;  break;
+        case OP_BITWISE_XOR:  iRes = iLeft^iRight;  break;
+        case OP_BITWISE_OR:   iRes = iLeft|iRight;  break;
+        case OP_LOGICAL_AND:  iRes = iLeft&&iRight; break;
+        case OP_LOGICAL_OR:   iRes = iLeft||iRight; break;
+        case OP_UNARY_MINUS:  iRes = -iLeft;        break;
+        case OP_UNARY_PLUS:   iRes = +iLeft;        break;
+        case OP_LOGICAL_NOT:  iRes = !iLeft;        break;
+        default: assert(!"Internal error");
+      }
+      Th_SetResultInt(interp, iRes);
+    }else if( rc==TH_OK && eArgType==ARG_NUMBER ){
+      switch( pExpr->pOp->eOp ) {
+        case OP_MULTIPLY: Th_SetResultDouble(interp, fLeft*fRight);  break;
+        case OP_DIVIDE:   Th_SetResultDouble(interp, fLeft/fRight);  break;
+        case OP_ADD:      Th_SetResultDouble(interp, fLeft+fRight);  break;
+        case OP_SUBTRACT: Th_SetResultDouble(interp, fLeft-fRight);  break;
+        case OP_LT:       Th_SetResultInt(interp, fLeft<fRight);  break;
+        case OP_GT:       Th_SetResultInt(interp, fLeft>fRight);  break;
+        case OP_LE:       Th_SetResultInt(interp, fLeft<=fRight); break;
+        case OP_GE:       Th_SetResultInt(interp, fLeft>=fRight); break;
+        case OP_EQ:       Th_SetResultInt(interp, fLeft==fRight); break;
+        case OP_NE:       Th_SetResultInt(interp, fLeft!=fRight); break;
+        default: assert(!"Internal error");
+      }
+    }else if( rc==TH_OK ){
+      int iEqual = 0;
+      assert( eArgType==ARG_STRING );
+      if( nRight==nLeft && 0==memcmp(zRight, zLeft, nRight) ){
+        iEqual = 1;
+      }
+      switch( pExpr->pOp->eOp ) {
+        case OP_SEQ:       Th_SetResultInt(interp, iEqual); break;
+        case OP_SNE:       Th_SetResultInt(interp, !iEqual); break;
+        default: assert(!"Internal error");
+      }
+    }
+
+    Th_Free(interp, zLeft);
+    Th_Free(interp, zRight);
+  }
+
+  return rc;
+}
+
+/*
+** Create an expression tree from an array of tokens. If successful,
+** the root of the tree is stored in apToken[0].
+*/
+int exprMakeTree(Th_Interp *interp, Expr **apToken, int nToken){
+  int iLeft;
+  int i;
+  int jj;
+
+  assert(nToken>0);
+#define ISTERM(x) (apToken[x] && (!apToken[x]->pOp || apToken[x]->pLeft))
+
+  for(jj=0; jj<nToken; jj++){
+    if( apToken[jj]->pOp && apToken[jj]->pOp->eOp==OP_OPEN_BRACKET ){
+      int nNest = 1;
+      int iLeft = jj;
+
+      for(jj++; jj<nToken; jj++){
+        Operator *pOp = apToken[jj]->pOp;
+        if( pOp && pOp->eOp==OP_OPEN_BRACKET ) nNest++;
+        if( pOp && pOp->eOp==OP_CLOSE_BRACKET ) nNest--;
+        if( nNest==0 ) break;
+      }
+      if( jj==nToken ){
+        return TH_ERROR;
+      }
+      if( (jj-iLeft)>1 ){
+        if( exprMakeTree(interp, &apToken[iLeft+1], jj-iLeft-1) ){
+          return TH_ERROR;
+        }
+        exprFree(interp, apToken[jj]);
+        exprFree(interp, apToken[iLeft]);
+        apToken[jj] = 0;
+        apToken[iLeft] = 0;
+      }
+    }
+  }
+
+  iLeft = 0;
+  for(jj=nToken-1; jj>=0; jj--){
+    if( apToken[jj] ){
+      if( apToken[jj]->pOp && apToken[jj]->pOp->iPrecedence==1 && iLeft>0 ){
+        apToken[jj]->pLeft = apToken[iLeft];
+        apToken[jj]->pLeft->pParent = apToken[jj];
+        apToken[iLeft] = 0;
+      }
+      iLeft = jj;
+    }
+  }
+  for(i=2; i<=12; i++){
+    iLeft = -1;
+    for(jj=0; jj<nToken; jj++){
+      Expr *pToken = apToken[jj];
+      if( apToken[jj] ){
+        if( pToken->pOp && !pToken->pLeft && pToken->pOp->iPrecedence==i ){
+          int iRight = jj+1;
+
+          iRight = jj+1;
+          for(iRight=jj+1; !apToken[iRight] && iRight<nToken; iRight++);
+          if( iRight==nToken || iLeft<0 || !ISTERM(iRight) || !ISTERM(iLeft) ){
+            return TH_ERROR;
+          }
+          pToken->pLeft = apToken[iLeft];
+          apToken[iLeft] = 0;
+          pToken->pLeft->pParent = pToken;
+          pToken->pRight = apToken[iRight];
+          apToken[iRight] = 0;
+          pToken->pRight->pParent = pToken;
+        }
+        iLeft = jj;
+      }
+    }
+  }
+  for(jj=1; jj<nToken; jj++){
+    assert( !apToken[jj] || !apToken[0] );
+    if( apToken[jj] ){
+      apToken[0] = apToken[jj];
+      apToken[jj] = 0;
+    }
+  }
+
+  return TH_OK;
+}
+
+/*
+** Parse a string containing a TH expression to a list of tokens.
+*/
+static int exprParse(
+  Th_Interp *interp,        /* Interpreter to leave error message in */
+  const uchar *zExpr,       /* Pointer to input string */
+  int nExpr,                /* Number of bytes at zExpr */
+  Expr ***papToken,         /* OUT: Array of tokens. */
+  int *pnToken              /* OUT: Size of token array */
+){
+  int i;
+
+  int rc = TH_OK;
+  int nToken = 0;
+  Expr **apToken = 0;
+
+  for(i=0; rc==TH_OK && i<nExpr; ){
+    uchar c = zExpr[i];
+    if( th_isspace(c) ){                                /* White-space     */
+      i++;
+    }else{
+      Expr *pNew = (Expr *)Th_Malloc(interp, sizeof(Expr));
+      const uchar *z = &zExpr[i];
+
+      switch (c) {
+        case '0': case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+          thNextNumber(interp, z, nExpr-i, &pNew->nValue);
+          break;
+
+        case '$':
+          thNextVarname(interp, z, nExpr-i, &pNew->nValue);
+          break;
+
+        case '{': case '[': {
+          thNextCommand(interp, z, nExpr-i, &pNew->nValue);
+          break;
+        }
+
+        case '"': {
+          int iEnd = i;
+          while( ++iEnd<nExpr && zExpr[iEnd]!='"' ){
+            if( zExpr[iEnd]=='\\' ) iEnd++;
+          }
+          if( iEnd<nExpr ){
+            pNew->nValue = iEnd+1-i;
+          }
+          break;
+        }
+
+        default: {
+          int j;
+          for(j=0; aOperator[j].zOp; j++){
+            int nOp;
+            if( aOperator[j].iPrecedence==1 && nToken>0 ){
+              Expr *pPrev = apToken[nToken-1];
+              if( !pPrev->pOp || pPrev->pOp->eOp==OP_CLOSE_BRACKET ){
+                continue;
+              }
+            }
+            nOp = th_strlen((const uchar *)aOperator[j].zOp);
+            if( (nExpr-i)>=nOp && 0==memcmp(aOperator[j].zOp, &zExpr[i], nOp) ){
+              pNew->pOp = &aOperator[j];
+              i += nOp;
+              break;
+            }
+          }
+        }
+      }
+
+      if( pNew->pOp || pNew->nValue ){
+        if( pNew->nValue ){
+          /* A terminal. Copy the string value. */
+          assert( !pNew->pOp );
+          pNew->zValue = Th_Malloc(interp, pNew->nValue);
+          memcpy(pNew->zValue, z, pNew->nValue);
+          i += pNew->nValue;
+        }
+        if( (nToken%16)==0 ){
+          /* Grow the apToken array. */
+          Expr **apTokenOld = apToken;
+          apToken = Th_Malloc(interp, sizeof(Expr *)*(nToken+16));
+          memcpy(apToken, apTokenOld, sizeof(Expr *)*nToken);
+        }
+
+        /* Put the new token at the end of the apToken array */
+        apToken[nToken] = pNew;
+        nToken++;
+      }else{
+        Th_Free(interp, pNew);
+        rc = TH_ERROR;
+      }
+    }
+  }
+
+  *papToken = apToken;
+  *pnToken = nToken;
+  return rc;
+}
+
+/*
+** Evaluate the string (zExpr, nExpr) as a Th expression. Store
+** the result in the interpreter interp and return TH_OK if
+** successful. If an error occurs, store an error message in
+** the interpreter result and return an error code.
+*/
+int Th_Expr(Th_Interp *interp, const uchar *zExpr, int nExpr){
+  int rc;                           /* Return Code */
+  int i;                            /* Loop counter */
+
+  int nToken = 0;
+  Expr **apToken = 0;
+
+  if( nExpr<0 ){
+    nExpr = th_strlen(zExpr);
+  }
+
+  /* Parse the expression to a list of tokens. */
+  rc = exprParse(interp, zExpr, nExpr, &apToken, &nToken);
+
+  /* If the parsing was successful, create an expression tree from
+  ** the parsed list of tokens. If successful, apToken[0] is set
+  ** to point to the root of the expression tree.
+  */
+  if( rc==TH_OK ){
+    rc = exprMakeTree(interp, apToken, nToken);
+  }
+
+  if( rc!=TH_OK ){
+    Th_ErrorMessage(interp, "syntax error in expression: \"", zExpr, nExpr);
+  }
+
+  /* Evaluate the expression tree. */
+  if( rc==TH_OK ){
+    rc = exprEval(interp, apToken[0]);
+  }
+
+  /* Free memory allocated by exprParse(). */
+  for(i=0; i<nToken; i++){
+    exprFree(interp, apToken[i]);
+  }
+  Th_Free(interp, apToken);
+
+  return rc;
+}
+
+/*
+** Allocate and return a pointer to a new hash-table. The caller should
+** (eventually) delete the hash-table by passing it to Th_HashDelete().
+*/
+Th_Hash *Th_HashNew(Th_Interp *interp){
+  Th_Hash *p;
+  p = Th_Malloc(interp, sizeof(Th_Hash));
+  return p;
+}
+
+/*
+** Iterate through all values currently stored in the hash table. Invoke
+** the callback function xCallback for each entry. The second argument
+** passed to xCallback is a copy of the fourth argument passed to this
+** function.
+*/
+void Th_HashIterate(
+  Th_Interp *interp,
+  Th_Hash *pHash,
+  void (*xCallback)(Th_HashEntry *pEntry, void *pContext),
+  void *pContext
+){
+  int i;
+  for(i=0; i<TH_HASHSIZE; i++){
+    Th_HashEntry *pEntry;
+    Th_HashEntry *pNext;
+    for(pEntry=pHash->a[i]; pEntry; pEntry=pNext){
+      pNext = pEntry->pNext;
+      xCallback(pEntry, pContext);
+    }
+  }
+}
+
+/*
+** Helper function for Th_HashDelete().
+*/
+static void xFreeHashEntry(Th_HashEntry *pEntry, void *pContext){
+  Th_Free((Th_Interp *)pContext, (void *)pEntry);
+}
+
+/*
+** Free a hash-table previously allocated by Th_HashNew().
+*/
+void Th_HashDelete(Th_Interp *interp, Th_Hash *pHash){
+  if( pHash ){
+    Th_HashIterate(interp, pHash, xFreeHashEntry, (void *)interp);
+    Th_Free(interp, pHash);
+  }
+}
+
+/*
+** This function is used to insert or delete hash table items, or to
+** query a hash table for an existing item.
+**
+** If parameter op is less than zero, then the hash-table element
+** identified by (zKey, nKey) is removed from the hash-table if it
+** exists. NULL is returned.
+**
+** Otherwise, if the hash-table contains an item with key (zKey, nKey),
+** a pointer to the associated Th_HashEntry is returned. If parameter
+** op is greater than zero, then a new entry is added if one cannot
+** be found. If op is zero, then NULL is returned if the item is
+** not already present in the hash-table.
+*/
+Th_HashEntry *Th_HashFind(
+  Th_Interp *interp,
+  Th_Hash *pHash,
+  const uchar *zKey,
+  int nKey,
+  int op                      /* -ve = delete, 0 = find, +ve = insert */
+){
+  unsigned int iKey = 0;
+  int i;
+  Th_HashEntry *pRet;
+  Th_HashEntry **ppRet;
+
+  if( nKey<0 ){
+    nKey = th_strlen(zKey);
+  }
+
+  for(i=0; i<nKey; i++){
+    iKey = (iKey<<3) ^ iKey ^ zKey[i];
+  }
+  iKey = iKey % TH_HASHSIZE;
+
+  for(ppRet=&pHash->a[iKey]; (pRet=*ppRet); ppRet=&pRet->pNext){
+    assert( pRet && ppRet && *ppRet==pRet );
+    if( pRet->nKey==nKey && 0==memcmp(pRet->zKey, zKey, nKey) ) break;
+  }
+
+  if( op<0 && pRet ){
+    assert( ppRet && *ppRet==pRet );
+    *ppRet = pRet->pNext;
+    Th_Free(interp, pRet);
+    pRet = 0;
+  }
+
+  if( op>0 && !pRet ){
+    pRet = (Th_HashEntry *)Th_Malloc(interp, sizeof(Th_HashEntry) + nKey);
+    pRet->zKey = (uchar *)&pRet[1];
+    pRet->nKey = nKey;
+    memcpy(pRet->zKey, zKey, nKey);
+    pRet->pNext = pHash->a[iKey];
+    pHash->a[iKey] = pRet;
+  }
+
+  return pRet;
+}
+
+/*
+** This function is the same as the standard strlen() function, except
+** that it returns 0 (instead of being undefined) if the argument is
+** a null pointer.
+*/
+int th_strlen(const unsigned char *zStr){
+  int n = 0;
+  if( zStr ){
+    while( zStr[n] ) n++;
+  }
+  return n;
+}
+
+/* Whitespace characters:
+**
+**     ' '    0x20
+**     '\t'   0x09
+**     '\n'   0x0A
+**     '\v'   0x0B
+**     '\f'   0x0C
+**     '\r'   0x0D
+**
+** Whitespace characters have the 0x01 flag set. Decimal digits have the
+** 0x2 flag set. Single byte printable characters have the 0x4 flag set.
+** Alphabet characters have the 0x8 bit set.
+**
+** The special list characters have the 0x10 flag set
+**
+**    { } [ ] \ ; ' "
+**
+**    " 0x22
+**
+*/
+static unsigned char aCharProp[256] = {
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  1,  1,  1,  1,  1,  0,  0,   /* 0x0. */
+  0,  0,  1,  1,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0x1. */
+  5,  4, 20,  4,  4,  4,  4,  4,     4,  4,  4,  4,  4,  4,  4,  4,   /* 0x2. */
+  6,  6,  6,  6,  6,  6,  6,  6,     6,  6,  4, 20,  4,  4,  4,  4,   /* 0x3. */
+  4, 12, 12, 12, 12, 12, 12, 12,    12, 12, 12, 12, 12, 12, 12, 12,   /* 0x4. */
+ 12, 12, 12, 12, 12, 12, 12, 12,    12, 12, 12, 20, 20, 20,  4,  4,   /* 0x5. */
+  4, 12, 12, 12, 12, 12, 12, 12,    12, 12, 12, 12, 12, 12, 12, 12,   /* 0x6. */
+ 12, 12, 12, 12, 12, 12, 12, 12,    12, 12, 12, 20,  4, 20,  4,  4,   /* 0x7. */
+
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0x8. */
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0x9. */
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0xA. */
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0xB. */
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0xC. */
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0xD. */
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0xE. */
+  0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0    /* 0xF. */
+};
+
+/*
+** Clone of the standard isspace() and isdigit function/macros.
+*/
+int th_isspace(unsigned char c){
+  return (aCharProp[c] & 0x01);
+}
+int th_isdigit(unsigned char c){
+  return (aCharProp[c] & 0x02);
+}
+int th_isspecial(unsigned char c){
+  return (aCharProp[c] & 0x11);
+}
+int th_isalnum(unsigned char c){
+  return (aCharProp[c] & 0x0A);
+}
+
+#ifndef LONGDOUBLE_TYPE
+# define LONGDOUBLE_TYPE long double
+#endif
+typedef uchar u8;
+
+
+/*
+** Return TRUE if z is a pure numeric string.  Return FALSE if the
+** string contains any character which is not part of a number. If
+** the string is numeric and contains the '.' character, set *realnum
+** to TRUE (otherwise FALSE).
+**
+** An empty string is considered non-numeric.
+*/
+static int sqlite3IsNumber(const char *z, int *realnum){
+  int incr = 1;
+  if( *z=='-' || *z=='+' ) z += incr;
+  if( !th_isdigit(*(u8*)z) ){
+    return 0;
+  }
+  z += incr;
+  if( realnum ) *realnum = 0;
+  while( th_isdigit(*(u8*)z) ){ z += incr; }
+  if( *z=='.' ){
+    z += incr;
+    if( !th_isdigit(*(u8*)z) ) return 0;
+    while( th_isdigit(*(u8*)z) ){ z += incr; }
+    if( realnum ) *realnum = 1;
+  }
+  if( *z=='e' || *z=='E' ){
+    z += incr;
+    if( *z=='+' || *z=='-' ) z += incr;
+    if( !th_isdigit(*(u8*)z) ) return 0;
+    while( th_isdigit(*(u8*)z) ){ z += incr; }
+    if( realnum ) *realnum = 1;
+  }
+  return *z==0;
+}
+
+/*
+** The string z[] is an ascii representation of a real number.
+** Convert this string to a double.
+**
+** This routine assumes that z[] really is a valid number.  If it
+** is not, the result is undefined.
+**
+** This routine is used instead of the library atof() function because
+** the library atof() might want to use "," as the decimal point instead
+** of "." depending on how locale is set.  But that would cause problems
+** for SQL.  So this routine always uses "." regardless of locale.
+*/
+static int sqlite3AtoF(const char *z, double *pResult){
+  int sign = 1;
+  const char *zBegin = z;
+  LONGDOUBLE_TYPE v1 = 0.0;
+  while( th_isspace(*(u8*)z) ) z++;
+  if( *z=='-' ){
+    sign = -1;
+    z++;
+  }else if( *z=='+' ){
+    z++;
+  }
+  while( th_isdigit(*(u8*)z) ){
+    v1 = v1*10.0 + (*z - '0');
+    z++;
+  }
+  if( *z=='.' ){
+    LONGDOUBLE_TYPE divisor = 1.0;
+    z++;
+    while( th_isdigit(*(u8*)z) ){
+      v1 = v1*10.0 + (*z - '0');
+      divisor *= 10.0;
+      z++;
+    }
+    v1 /= divisor;
+  }
+  if( *z=='e' || *z=='E' ){
+    int esign = 1;
+    int eval = 0;
+    LONGDOUBLE_TYPE scale = 1.0;
+    z++;
+    if( *z=='-' ){
+      esign = -1;
+      z++;
+    }else if( *z=='+' ){
+      z++;
+    }
+    while( th_isdigit(*(u8*)z) ){
+      eval = eval*10 + *z - '0';
+      z++;
+    }
+    while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
+    while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
+    while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
+    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
+    if( esign<0 ){
+      v1 /= scale;
+    }else{
+      v1 *= scale;
+    }
+  }
+  *pResult = sign<0 ? -v1 : v1;
+  return z - zBegin;
+}
+
+/*
+** Try to convert the string passed as arguments (z, n) to an integer.
+** If successful, store the result in *piOut and return TH_OK.
+**
+** If the string cannot be converted to an integer, return TH_ERROR.
+** If the interp argument is not NULL, leave an error message in the
+** interpreter result too.
+*/
+int Th_ToInt(Th_Interp *interp, const uchar *z, int n, int *piOut){
+  int i = 0;
+  int iOut = 0;
+
+  if( n<0 ){
+    n = th_strlen(z);
+  }
+
+  if( n>0 && (z[0]=='-' || z[0]=='+') ){
+    i = 1;
+  }
+  for(; i<n; i++){
+    if( !th_isdigit(z[i]) ){
+      Th_ErrorMessage(interp, "expected integer, got: \"", z, n);
+      return TH_ERROR;
+    }
+    iOut = iOut * 10 + (z[i] - 48);
+  }
+
+  if( n>0 && z[0]=='-' ){
+    iOut *= -1;
+  }
+
+  *piOut = iOut;
+  return TH_OK;
+}
+
+/*
+** Try to convert the string passed as arguments (z, n) to a double.
+** If successful, store the result in *pfOut and return TH_OK.
+**
+** If the string cannot be converted to a double, return TH_ERROR.
+** If the interp argument is not NULL, leave an error message in the
+** interpreter result too.
+*/
+int Th_ToDouble(
+  Th_Interp *interp,
+  const uchar *z,
+  int n,
+  double *pfOut
+){
+  if( !sqlite3IsNumber((const char *)z, 0) ){
+    Th_ErrorMessage(interp, "expected number, got: \"", z, n);
+    return TH_ERROR;
+  }
+
+  sqlite3AtoF((const char *)z, pfOut);
+  return TH_OK;
+}
+
+/*
+** Set the result of the interpreter to the th1 representation of
+** the integer iVal and return TH_OK.
+*/
+int Th_SetResultInt(Th_Interp *interp, int iVal){
+  int isNegative = 0;
+  uchar zBuf[32];
+  uchar *z = &zBuf[32];
+
+  if( iVal<0 ){
+    isNegative = 1;
+    iVal = iVal * -1;
+  }
+  *(--z) = '\0';
+  *(--z) = (uchar)(48+(iVal%10));
+  while( (iVal = (iVal/10))>0 ){
+    *(--z) = (uchar)(48+(iVal%10));
+    assert(z>zBuf);
+  }
+  if( isNegative ){
+    *(--z) = '-';
+  }
+
+  return Th_SetResult(interp, z, -1);
+}
+
+/*
+** Set the result of the interpreter to the th1 representation of
+** the double fVal and return TH_OK.
+*/
+int Th_SetResultDouble(Th_Interp *interp, double fVal){
+  int i;                /* Iterator variable */
+  double v = fVal;      /* Input value */
+  uchar zBuf[128];      /* Output buffer */
+  uchar *z = zBuf;      /* Output cursor */
+  int iDot = 0;         /* Digit after which to place decimal point */
+  int iExp = 0;         /* Exponent (NN in eNN) */
+  const uchar *zExp;    /* String representation of iExp */
+
+  /* Precision: */
+  #define INSIGNIFICANT 0.000000000001
+  #define ROUNDER       0.0000000000005
+  double insignificant = INSIGNIFICANT;
+
+  /* If the real value is negative, write a '-' character to the
+   * output and transform v to the corresponding positive number.
+   */
+  if( v<0.0 ){
+    *z++ = '-';
+    v *= -1.0;
+  }
+
+  /* Normalize v to a value between 1.0 and 10.0. Integer
+   * variable iExp is set to the exponent. i.e the original
+   * value is (v * 10^iExp) (or the negative thereof).
+   */
+  if( v>0.0 ){
+    while( (v+ROUNDER)>=10.0 ) { iExp++; v *= 0.1; }
+    while( (v+ROUNDER)<1.0 )   { iExp--; v *= 10.0; }
+  }
+  v += ROUNDER;
+
+  /* For a small (<12) positive exponent, move the decimal point
+   * instead of using the "eXX" notation.
+   */
+  if( iExp>0 && iExp<12 ){
+    iDot = iExp;
+    iExp = 0;
+  }
+
+  /* For a small (>-4) negative exponent, write leading zeroes
+   * instead of using the "eXX" notation.
+   */
+  if( iExp<0 && iExp>-4 ){
+    *z++ = '0';
+    *z++ = '.';
+    for(i=0; i>(iExp+1); i--){
+      *z++ = '0';
+    }
+    iDot = -1;
+    iExp = 0;
+  }
+
+  /* Output the digits in real value v. The value of iDot determines
+   * where (if at all) the decimal point is placed.
+   */
+  for(i=0; i<=(iDot+1) || v>=insignificant; i++){
+    *z++ = (uchar)(48 + (int)v);
+    v = (v - ((double)(int)v)) * 10.0;
+    insignificant *= 10.0;
+    if( iDot==i ){
+      *z++ = '.';
+    }
+  }
+
+  /* If the exponent is not zero, add the "eXX" notation to the
+   * end of the string.
+   */
+  if( iExp!=0 ){
+    *z++ = 'e';
+    Th_SetResultInt(interp, iExp);
+    zExp = Th_GetResult(interp, 0);
+    for(i=0; zExp[i]; i++){
+      *z++ = zExp[i];
+    }
+  }
+
+  *z = '\0';
+  return Th_SetResult(interp, zBuf, -1);
+}
+
+/*
+** Set the result of the interpreter to the th1 representation of
+** the pointer p and return TH_OK. The th1 representation can be
+** converted back to a pointer using Th_ToPtr().
+*/
+int Th_SetResultPtr(Th_Interp *interp, void *p){
+  char zBuf[32];
+  char *z;
+  int i;
+  unsigned int v = (unsigned int)p;
+
+  const char zHex[16] = "0123456789ABCDEF";
+
+  assert( sizeof(unsigned int)==sizeof(void *) );
+
+  zBuf[31] = '\0';
+  z = &zBuf[30];
+
+  for(i=0; i<(sizeof(unsigned int)*2); i++){
+    *z-- = zHex[(v&0x0000000F)];
+    v = v>>4;
+  }
+
+  *z-- = 'x';
+  *z = '0';
+
+  return Th_SetResult(interp, (uchar *)z, -1);
+}
+
+/*
+** Convert input string (z, n) to a generic pointer. If the conversion
+** is successful, store the result in *pp and return TH_OK.
+**
+** If the string cannot be converted to a pointer, return TH_ERROR.
+** If the interp argument is not NULL, leave an error message in the
+** interpreter result too.
+*/
+int Th_ToPtr(Th_Interp *interp, const uchar *z, int n, void **pp){
+  unsigned int iPtr;
+  int i;
+  assert(sizeof(unsigned int)==sizeof(void *));
+
+  if( n<3 || z[0]!='0' || z[1]!='x' ){
+    goto error_out;
+  }
+
+  iPtr = 0;
+  for(i=2; i<n; i++){
+    int digit = thHexdigit(z[i]);
+    if( digit<0 ){
+      goto error_out;
+    }
+    iPtr = (iPtr<<4) + digit;
+  }
+
+  *pp = (void *)iPtr;
+  return TH_OK;
+
+error_out:
+  Th_ErrorMessage(interp, "expected pointer, got: \"", z, n);
+  return TH_ERROR;
+}
 

Added src/th.h version [7d3866629e]

@@ -1,1 +1,186 @@
 
+/* This header file defines the external interface to the custom Scripting
+** Language (TH) interpreter used to create test cases for SQLiteRT. The
+** interpreted language and API are both based on Tcl.
+*/
+
+typedef unsigned char uchar;
+
+/*
+** Before creating an interpreter, the application must allocate and
+** populate an instance of the following structure. It must remain valid
+** for the lifetime of the interpreter.
+*/
+struct Th_Vtab {
+  void *(*xMalloc)(unsigned int);
+  void (*xFree)(void *);
+};
+typedef struct Th_Vtab Th_Vtab;
+
+/*
+** Opaque handle for interpeter.
+*/
+typedef struct Th_Interp Th_Interp;
+
+/*
+** Create and delete interpreters.
+*/
+Th_Interp * Th_CreateInterp(Th_Vtab *pVtab);
+void Th_DeleteInterp(Th_Interp *);
+
+/*
+** Evaluate an TH program in the stack frame identified by parameter
+** iFrame, according to the following rules:
+**
+**   * If iFrame is 0, this means the current frame.
+**
+**   * If iFrame is negative, then the nth frame up the stack, where n is
+**     the absolute value of iFrame. A value of -1 means the calling
+**     procedure.
+**
+**   * If iFrame is +ve, then the nth frame from the bottom of the stack.
+**     An iFrame value of 1 means the toplevel (global) frame.
+*/
+int Th_Eval(Th_Interp *interp, int iFrame, const uchar *zProg, int nProg);
+
+/*
+** Evaluate a TH expression. The result is stored in the
+** interpreter result.
+*/
+int Th_Expr(Th_Interp *interp, const uchar *, int);
+
+/*
+** Access TH variables in the current stack frame. If the variable name
+** begins with "::", the lookup is in the top level (global) frame.
+*/
+int Th_GetVar(Th_Interp *, const uchar *, int);
+int Th_SetVar(Th_Interp *, const uchar *, int, const uchar *, int);
+int Th_LinkVar(Th_Interp *, const uchar *, int, int, const uchar *, int);
+int Th_UnsetVar(Th_Interp *, const uchar *, int);
+
+typedef int (*Th_CommandProc)(Th_Interp *, void *, int, const uchar **, int *);
+
+/*
+** Register new commands.
+*/
+int Th_CreateCommand(
+  Th_Interp *interp,
+  const char *zName,
+  /* int (*xProc)(Th_Interp *, void *, int, const uchar **, int *), */
+  Th_CommandProc xProc,
+  void *pContext,
+  void (*xDel)(Th_Interp *, void *)
+);
+
+/*
+** Delete or rename commands.
+*/
+int Th_RenameCommand(Th_Interp *, const uchar *, int, const uchar *, int);
+
+/*
+** Push a new stack frame (local variable context) onto the interpreter
+** stack, call the function supplied as parameter xCall with the two
+** context arguments,
+**
+**   xCall(interp, pContext1, pContext2)
+**
+** , then pop the frame off of the interpreter stack. The value returned
+** by the xCall() function is returned as the result of this function.
+**
+** This is intended for use by the implementation of commands such as
+** those created by [proc].
+*/
+int Th_InFrame(Th_Interp *interp,
+  int (*xCall)(Th_Interp *, void *pContext1, void *pContext2),
+  void *pContext1,
+  void *pContext2
+);
+
+/*
+** Valid return codes for xProc callbacks.
+*/
+#define TH_OK       0
+#define TH_ERROR    1
+#define TH_BREAK    2
+#define TH_RETURN   3
+#define TH_CONTINUE 4
+
+/*
+** Set and get the interpreter result.
+*/
+int Th_SetResult(Th_Interp *, const uchar *, int);
+const uchar *Th_GetResult(Th_Interp *, int *);
+uchar *Th_TakeResult(Th_Interp *, int *);
+
+/*
+** Set an error message as the interpreter result. This also
+** sets the global stack-trace variable $::th_stack_trace.
+*/
+int Th_ErrorMessage(Th_Interp *, const char *, const uchar *, int);
+
+/*
+** Access the memory management functions associated with the specified
+** interpreter.
+*/
+void *Th_Malloc(Th_Interp *, int);
+void Th_Free(Th_Interp *, void *);
+
+/*
+** Functions for handling TH lists.
+*/
+int Th_ListAppend(Th_Interp *, uchar **, int *, const uchar *, int);
+int Th_SplitList(Th_Interp *, const uchar *, int, uchar ***, int **, int *);
+
+int Th_StringAppend(Th_Interp *, uchar **, int *, const uchar *, int);
+
+/*
+** Functions for handling numbers and pointers.
+*/
+int Th_ToInt(Th_Interp *, const uchar *, int, int *);
+int Th_ToDouble(Th_Interp *, const uchar *, int, double *);
+int Th_ToPtr(Th_Interp *, const uchar *, int, void **);
+int Th_SetResultInt(Th_Interp *, int);
+int Th_SetResultDouble(Th_Interp *, double);
+int Th_SetResultPtr(Th_Interp *, void *);
+
+/*
+** Drop in replacements for the corresponding standard library functions.
+*/
+int th_strlen(const unsigned char *);
+int th_isdigit(unsigned char);
+int th_isspace(unsigned char);
+int th_isalnum(unsigned char);
+int th_isspecial(unsigned char);
+uchar *th_strdup(Th_Interp *interp, const uchar *z, int n);
+
+/*
+** Interfaces to register the language extensions.
+*/
+int th_register_language(Th_Interp *interp);            /* th_lang.c */
+int th_register_sqlite(Th_Interp *interp);              /* th_sqlite.c */
+int th_register_vfs(Th_Interp *interp);                 /* th_vfs.c */
+int th_register_testvfs(Th_Interp *interp);             /* th_testvfs.c */
+
+/*
+** General purpose hash table from th_lang.c.
+*/
+typedef struct Th_Hash      Th_Hash;
+typedef struct Th_HashEntry Th_HashEntry;
+struct Th_HashEntry {
+  void *pData;
+  uchar *zKey;
+  int nKey;
+  Th_HashEntry *pNext;     /* Internal use only */
+};
+Th_Hash *Th_HashNew(Th_Interp *);
+void Th_HashDelete(Th_Interp *, Th_Hash *);
+void Th_HashIterate(Th_Interp*,Th_Hash*,void (*x)(Th_HashEntry*, void*),void*);
+Th_HashEntry *Th_HashFind(Th_Interp*, Th_Hash*, const uchar*, int, int);
+
+/*
+** Useful functions from th_lang.c.
+*/
+int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg);
+
+typedef struct Th_SubCommand {char *zName; Th_CommandProc xProc;} Th_SubCommand;
+int Th_CallSubCommand(Th_Interp*,void*,int,const uchar**,int*,Th_SubCommand*);

Added src/th_lang.c version [1db6c88ca5]

@@ -1,1 +1,1071 @@
 
+/*
+** This file contains the implementation of all of the TH language
+** built-in commands.
+**
+** All built-in commands are implemented using the public interface
+** declared in th.h, so this file serves as both a part of the language
+** implementation and an example of how to extend the language with
+** new commands.
+*/
+
+#include "th.h"
+#include <string.h>
+#include <assert.h>
+
+int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg){
+  Th_ErrorMessage(interp,
+      "wrong # args: should be \"", (const uchar*)zMsg, -1
+  );
+  return TH_ERROR;
+}
+
+/*
+** Syntax:
+**
+**   catch script ?varname?
+*/
+static int catch_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int rc;
+
+  if( argc!=2 && argc!=3 ){
+    return Th_WrongNumArgs(interp, "catch script ?varname?");
+  }
+
+  rc = Th_Eval(interp, 0, argv[1], -1);
+  if( argc==3 ){
+    int nResult;
+    const uchar *zResult = Th_GetResult(interp, &nResult);
+    Th_SetVar(interp, argv[2], argl[2], zResult, nResult);
+  }
+
+  Th_SetResultInt(interp, rc);
+  return TH_OK;
+}
+
+/*
+** TH Syntax:
+**
+**   if expr1 body1 ?elseif expr2 body2? ? ?else? bodyN?
+*/
+static int if_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int rc = TH_OK;
+
+  int iCond;           /* Result of evaluating expression */
+  int i;
+
+  const uchar *zResult;
+  int nResult;
+
+  if( argc<3 ){
+    goto wrong_args;
+  }
+
+  for(i=0; i<argc && rc==TH_OK; i+=3){
+    if( i>argc-3 ){
+      i = argc-3;
+      iCond = 1;
+    }else{
+      if( TH_OK!=Th_Expr(interp, argv[i+1], argl[i+1]) ){
+        return TH_ERROR;
+      }
+      zResult = Th_GetResult(interp, &nResult);
+      rc = Th_ToInt(interp, zResult, nResult, &iCond);
+    }
+    if( iCond && rc==TH_OK ){
+      rc = Th_Eval(interp, 0, argv[i+2], -1);
+      break;
+    }
+  }
+
+  return rc;
+
+wrong_args:
+  return Th_WrongNumArgs(interp, "if ...");
+}
+
+/*
+** TH Syntax:
+**
+**   expr expr
+*/
+static int expr_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  if( argc!=2 ){
+    return Th_WrongNumArgs(interp, "expr expression");
+  }
+
+  return Th_Expr(interp, argv[1], argl[1]);
+}
+
+/*
+** Evaluate the th1 script (zBody, nBody) in the local stack frame.
+** Return the result of the evaluation, except if the result
+** is TH_CONTINUE, return TH_OK instead.
+*/
+static int eval_loopbody(Th_Interp *interp, const uchar *zBody, int nBody){
+  int rc = Th_Eval(interp, 0, zBody, nBody);
+  if( rc==TH_CONTINUE ){
+    rc = TH_OK;
+  }
+  return rc;
+}
+
+/*
+** TH Syntax:
+**
+**   for init condition incr script
+*/
+static int for_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int rc;
+  int iCond;
+
+  if( argc!=5 ){
+    return Th_WrongNumArgs(interp, "for init condition incr script");
+  }
+
+  /* Evaluate the 'init' script */
+  rc = Th_Eval(interp, 0, argv[1], -1);
+
+  while( rc==TH_OK
+     && TH_OK==(rc = Th_Expr(interp, argv[2], -1))
+     && TH_OK==(rc = Th_ToInt(interp, Th_GetResult(interp, 0), -1, &iCond))
+     && iCond
+     && TH_OK==(rc = eval_loopbody(interp, argv[4], argl[4]))
+  ){
+    rc = Th_Eval(interp, 0, argv[3], -1);
+  }
+
+  if( rc==TH_BREAK ) rc = TH_OK;
+  return rc;
+}
+
+/*
+** TH Syntax:
+**
+**   list ?arg1 ?arg2? ...?
+*/
+static int list_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  uchar *zList = 0;
+  int nList = 0;
+  int i;
+
+  for(i=1; i<argc; i++){
+    Th_ListAppend(interp, &zList, &nList, argv[i], argl[i]);
+  }
+
+  Th_SetResult(interp, zList, nList);
+  Th_Free(interp, zList);
+
+  return TH_OK;
+}
+
+/*
+** TH Syntax:
+**
+**   lindex list index
+*/
+static int lindex_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int iElem;
+  int rc;
+
+  uchar **azElem;
+  int *anElem;
+  int nCount;
+
+  if( argc!=3 ){
+    return Th_WrongNumArgs(interp, "lindex list index");
+  }
+
+  if( TH_OK!=Th_ToInt(interp, argv[2], argl[2], &iElem) ){
+    return TH_ERROR;
+  }
+
+  rc = Th_SplitList(interp, argv[1], argl[1], &azElem, &anElem, &nCount);
+  if( rc==TH_OK ){
+    if( iElem<nCount && iElem>=0 ){
+      Th_SetResult(interp, azElem[iElem], anElem[iElem]);
+    }else{
+      Th_SetResult(interp, 0, 0);
+    }
+    Th_Free(interp, azElem);
+  }
+
+  return rc;
+}
+
+/*
+** TH Syntax:
+**
+**   llength list
+*/
+static int llength_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int nElem;
+  int rc;
+
+  if( argc!=2 ){
+    return Th_WrongNumArgs(interp, "llength list");
+  }
+
+  rc = Th_SplitList(interp, argv[1], argl[1], 0, 0, &nElem);
+  if( rc==TH_OK ){
+    Th_SetResultInt(interp, nElem);
+  }
+
+  return rc;
+}
+
+/*
+** TH Syntax:
+**
+**   set varname ?value?
+*/
+static int set_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  if( argc!=2 && argc!=3 ){
+    return Th_WrongNumArgs(interp, "set varname ?value?");
+  }
+
+  if( argc==3 ){
+    Th_SetVar(interp, argv[1], argl[1], argv[2], argl[2]);
+  }
+  return Th_GetVar(interp, argv[1], argl[1]);
+}
+
+/*
+** When a new command is created using the built-in [proc] command, an
+** instance of the following structure is allocated and populated. A
+** pointer to the structure is passed as the context (second) argument
+** to function proc_call1() when the new command is executed.
+*/
+typedef struct ProcDefn ProcDefn;
+struct ProcDefn {
+  int nParam;                /* Number of formal (non "args") parameters */
+  uchar **azParam;           /* Parameter names */
+  int *anParam;              /* Lengths of parameter names */
+  uchar **azDefault;         /* Default values */
+  int *anDefault;            /* Lengths of default values */
+  int hasArgs;               /* True if there is an "args" parameter */
+  uchar *zProgram;           /* Body of proc */
+  int nProgram;              /* Number of bytes at zProgram */
+  uchar *zUsage;             /* Usage message */
+  int nUsage;                /* Number of bytes at zUsage */
+};
+
+/* This structure is used to temporarily store arguments passed to an
+** invocation of a command created using [proc]. A pointer to an
+** instance is passed as the second argument to the proc_call2() function.
+*/
+typedef struct ProcArgs ProcArgs;
+struct ProcArgs {
+  int argc;
+  const uchar **argv;
+  int *argl;
+};
+
+/*
+** Each time a command created using [proc] is invoked, a new
+** th1 stack frame is allocated (for the proc's local variables) and
+** this function invoked.
+**
+** Argument pContext1 points to the associated ProcDefn structure.
+** Argument pContext2  points to a ProcArgs structure that contains
+** the arguments passed to this specific invocation of the proc.
+*/
+static int proc_call2(Th_Interp *interp, void *pContext1, void *pContext2){
+  int i;
+  ProcDefn *p = (ProcDefn *)pContext1;
+  ProcArgs *pArgs = (ProcArgs *)pContext2;
+
+  /* Check if there are the right number of arguments. If there are
+  ** not, generate a usage message for the command.
+  */
+  if( (pArgs->argc>(p->nParam+1) && !p->hasArgs)
+   || (pArgs->argc<=(p->nParam) && !p->azDefault[pArgs->argc-1])
+  ){
+    uchar *zUsage = 0;
+    int nUsage = 0;
+    Th_StringAppend(interp, &zUsage, &nUsage, pArgs->argv[0], pArgs->argl[0]);
+    Th_StringAppend(interp, &zUsage, &nUsage, p->zUsage, p->nUsage);
+    Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"", 1);
+    Th_WrongNumArgs(interp, zUsage);
+    Th_Free(interp, zUsage);
+    return TH_ERROR;
+  }
+
+  /* Populate the formal proc parameters. */
+  for(i=0; i<p->nParam; i++){
+    const uchar *zVal;
+    int nVal;
+    if( pArgs->argc>(i+1) ){
+      zVal = pArgs->argv[i+1];
+      nVal = pArgs->argl[i+1];
+    }else{
+      zVal = p->azDefault[i];
+      nVal = p->anDefault[i];
+    }
+    Th_SetVar(interp, p->azParam[i], p->anParam[i], zVal, nVal);
+  }
+
+  /* Populate the "args" parameter, if it exists */
+  if( p->hasArgs ){
+    uchar *zArgs = 0;
+    int nArgs = 0;
+    for(i=p->nParam+1; i<pArgs->argc; i++){
+      Th_ListAppend(interp, &zArgs, &nArgs, pArgs->argv[i], pArgs->argl[i]);
+    }
+    Th_SetVar(interp, (const uchar *)"args", -1, zArgs, nArgs);
+  }
+
+  Th_SetResult(interp, 0, 0);
+  return Th_Eval(interp, 0, p->zProgram, p->nProgram);
+}
+
+/*
+** This function is the command callback registered for all commands
+** created using the [proc] command. The second argument, pContext,
+** is a pointer to the associated ProcDefn structure.
+*/
+static int proc_call1(
+  Th_Interp *interp,
+  void *pContext,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int rc;
+
+  ProcDefn *p = (ProcDefn *)pContext;
+  ProcArgs procargs;
+
+  /* Call function proc_call2(), which will call Th_Eval() to evaluate
+  ** the body of the [proc], in a new Th stack frame. This is so that
+  ** the proc body has its own local variable context.
+  */
+  procargs.argc = argc;
+  procargs.argv = argv;
+  procargs.argl = argl;
+  rc = Th_InFrame(interp, proc_call2, (void *)p, (void *)&procargs);
+
+  if( rc==TH_RETURN ){
+    rc = TH_OK;
+  }
+  return rc;
+}
+
+/*
+** This function is registered as the delete callback for all commands
+** created using the built-in [proc] command. It is called automatically
+** when a command created using [proc] is deleted.
+**
+** It frees the ProcDefn structure allocated when the command was created.
+*/
+static void proc_del(Th_Interp *interp, void *pContext){
+  ProcDefn *p = (ProcDefn *)pContext;
+  Th_Free(interp, (void *)p->zUsage);
+  Th_Free(interp, (void *)p);
+}
+
+/*
+** TH Syntax:
+**
+**   proc name arglist code
+*/
+static int proc_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int rc;
+  char *zName;
+
+  ProcDefn *p;
+  int nByte;
+  int i;
+  uchar *zSpace;
+
+  uchar **azParam;
+  int *anParam;
+  int nParam;
+
+  uchar *zUsage = 0;               /* Build up a usage message here */
+  int nUsage = 0;                  /* Number of bytes at zUsage */
+
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "proc name arglist code");
+  }
+  if( Th_SplitList(interp, argv[2], argl[2], &azParam, &anParam, &nParam) ){
+    return TH_ERROR;
+  }
+
+  /* Allocate the new ProcDefn structure. */
+  nByte = sizeof(ProcDefn) +                        /* ProcDefn structure */
+      (sizeof(uchar *) + sizeof(int)) * nParam +    /* azParam, anParam */
+      (sizeof(uchar *) + sizeof(int)) * nParam +    /* azDefault, anDefault */
+      argl[3] +                                     /* zProgram */
+      argl[2];     /* Space for copies of parameter names and default values */
+  p = (ProcDefn *)Th_Malloc(interp, nByte);
+
+  /* If the last parameter in the parameter list is "args", then set the
+  ** ProcDefn.hasArgs flag. The "args" parameter does not require an
+  ** entry in the ProcDefn.azParam[] or ProcDefn.azDefault[] arrays.
+  */
+  if( anParam[nParam-1]==4 && 0==memcmp(azParam[nParam-1], "args", 4) ){
+    p->hasArgs = 1;
+    nParam--;
+  }
+
+  p->nParam    = nParam;
+  p->azParam   = (uchar **)&p[1];
+  p->anParam   = (int *)&p->azParam[nParam];
+  p->azDefault = (uchar **)&p->anParam[nParam];
+  p->anDefault = (int *)&p->azDefault[nParam];
+  p->zProgram = (uchar *)&p->anDefault[nParam];
+  memcpy(p->zProgram, argv[3], argl[3]);
+  p->nProgram = argl[3];
+  zSpace = &p->zProgram[p->nProgram];
+
+  for(i=0; i<nParam; i++){
+    uchar **az;
+    int *an;
+    int n;
+    if( Th_SplitList(interp, azParam[i], anParam[i], &az, &an, &n) ){
+      goto error_out;
+    }
+    if( n<1 || n>2 ){
+      const char expected[] = "expected parameter, got \"";
+      Th_ErrorMessage(interp, expected, azParam[i], anParam[i]);
+      Th_Free(interp, az);
+      goto error_out;
+    }
+    p->anParam[i] = an[0];
+    p->azParam[i] = zSpace;
+    memcpy(zSpace, az[0], an[0]);
+    zSpace += an[0];
+    if( n==2 ){
+      p->anDefault[i] = an[1];
+      p->azDefault[i] = zSpace;
+      memcpy(zSpace, az[1], an[1]);
+      zSpace += an[1];
+    }
+
+    Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)" ", 1);
+    if( n==2 ){
+      Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"?", 1);
+      Th_StringAppend(interp, &zUsage, &nUsage, az[0], an[0]);
+      Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"?", 1);
+    }else{
+      Th_StringAppend(interp, &zUsage, &nUsage, az[0], an[0]);
+    }
+
+    Th_Free(interp, az);
+  }
+  assert( zSpace-(uchar *)p<=nByte );
+
+  /* If there is an "args" parameter, append it to the end of the usage
+  ** message. Set ProcDefn.zUsage to point at the usage message. It will
+  ** be freed along with the rest of the proc-definition by proc_del().
+  */
+  if( p->hasArgs ){
+    Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)" ?args...?", -1);
+  }
+  p->zUsage = zUsage;
+  p->nUsage = nUsage;
+
+  /* Register the new command with the th1 interpreter. */
+  zName = (char *)argv[1];
+  rc = Th_CreateCommand(interp, zName, proc_call1, (void *)p, proc_del);
+  if( rc==TH_OK ){
+    Th_SetResult(interp, 0, 0);
+  }
+
+  Th_Free(interp, azParam);
+  return TH_OK;
+
+ error_out:
+  Th_Free(interp, azParam);
+  Th_Free(interp, zUsage);
+  return TH_ERROR;
+}
+
+/*
+** TH Syntax:
+**
+**   rename oldcmd newcmd
+*/
+static int rename_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  if( argc!=3 ){
+    return Th_WrongNumArgs(interp, "rename oldcmd newcmd");
+  }
+  return Th_RenameCommand(interp, argv[1], argl[1], argv[2], argl[2]);
+}
+
+/*
+** TH Syntax:
+**
+**   break    ?value...?
+**   continue ?value...?
+**   ok       ?value...?
+**   error    ?value...?
+*/
+static int simple_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  if( argc!=1 && argc!=2 ){
+    return Th_WrongNumArgs(interp, "return ?value?");
+  }
+  if( argc==2 ){
+    Th_SetResult(interp, argv[1], argl[1]);
+  }
+  return (int)ctx;
+}
+
+/*
+** TH Syntax:
+**
+**   return ?-code code? ?value?
+*/
+static int return_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int iCode = TH_RETURN;
+  if( argc<1 || argc>4 ){
+    return Th_WrongNumArgs(interp, "return ?-code code? ?value?");
+  }
+  if( argc>2 ){
+    int rc = Th_ToInt(interp, argv[2], argl[2], &iCode);
+    if( rc!=TH_OK ){
+      return rc;
+    }
+  }
+  if( argc==2 || argc==4 ){
+    Th_SetResult(interp, argv[argc-1], argl[argc-1]);
+  }
+  return iCode;
+}
+
+/*
+** TH Syntax:
+**
+**   string compare STRING1 STRING2
+*/
+static int string_compare_command(
+  Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
+){
+  const uchar *zRight; int nRight;
+  const uchar *zLeft; int nLeft;
+
+  int i;
+  int iRes = 0;
+
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "string compare str1 str2");
+  }
+
+  zLeft = argv[2];
+  nLeft = argl[2];
+  zRight = argv[3];
+  nRight = argl[3];
+
+  for(i=0; iRes==0 && i<nLeft && i<nRight; i++){
+    iRes = zLeft[i]-zRight[i];
+  }
+  if( iRes==0 ){
+    iRes = nLeft-nRight;
+  }
+
+  if( iRes<0 ) iRes = -1;
+  if( iRes>0 ) iRes = 1;
+
+  return Th_SetResultInt(interp, iRes);
+}
+
+/*
+** TH Syntax:
+**
+**   string first NEEDLE HAYSTACK
+*/
+static int string_first_command(
+  Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
+){
+  const uchar *zNeedle;
+  int nNeedle;
+  const uchar *zHaystack;
+  int nHaystack;
+  int i;
+  int iRes;
+
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "string first needle haystack");
+  }
+
+  zNeedle = argv[2];
+  nNeedle = argl[2];
+  zHaystack = argv[3];
+  nHaystack = argl[3];
+
+  for(i=0; i<(nHaystack-nNeedle); i++){
+    if( 0==memcmp(zNeedle, &zHaystack[i], nNeedle) ){
+      iRes = i;
+      break;
+    }
+  }
+
+  return Th_SetResultInt(interp, iRes);
+}
+
+/*
+** TH Syntax:
+**
+**   string is CLASS STRING
+*/
+static int string_is_command(
+  Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
+){
+  int i;
+  int iRes = 1;
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "string is class string");
+  }
+  if( argl[2]!=5 || 0!=memcmp(argv[2], "alnum", 5) ){
+    Th_ErrorMessage(interp, "Expected alnum, got: ", argv[2], argl[2]);
+    return TH_ERROR;
+  }
+
+  for(i=0; i<argl[3]; i++){
+    if( !th_isalnum(argv[3][i]) ){
+      iRes = 0;
+    }
+  }
+
+  return Th_SetResultInt(interp, iRes);
+}
+
+/*
+** TH Syntax:
+**
+**   string last NEEDLE HAYSTACK
+*/
+static int string_last_command(
+  Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
+){
+  const uchar *zNeedle;
+  int nNeedle;
+  const uchar *zHaystack;
+  int nHaystack;
+  int i;
+  int iRes;
+
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "string first needle haystack");
+  }
+
+  zNeedle = argv[2];
+  nNeedle = argl[2];
+  zHaystack = argv[3];
+  nHaystack = argl[3];
+
+  for(i=nHaystack-nNeedle-1; i>=0; i--){
+    if( 0==memcmp(zNeedle, &zHaystack[i], nNeedle) ){
+      iRes = i;
+      break;
+    }
+  }
+
+  return Th_SetResultInt(interp, iRes);
+}
+
+/*
+** TH Syntax:
+**
+**   string length STRING
+*/
+static int string_length_command(
+  Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
+){
+  if( argc!=3 ){
+    return Th_WrongNumArgs(interp, "string length string");
+  }
+  return Th_SetResultInt(interp, argl[2]);
+}
+
+/*
+** TH Syntax:
+**
+**   string range STRING FIRST LAST
+*/
+static int string_range_command(
+  Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
+){
+  int iStart;
+  int iEnd;
+
+  if( argc!=5 ){
+    return Th_WrongNumArgs(interp, "string range string first last");
+  }
+
+  if( argl[4]==3 && 0==memcmp("end", argv[4], 3) ){
+    iEnd = argl[2];
+  }else if( Th_ToInt(interp, argv[4], argl[4], &iEnd) ){
+    Th_ErrorMessage(
+        interp, "Expected \"end\" or integer, got:", argv[4], argl[4]);
+    return TH_ERROR;
+  }
+  if( Th_ToInt(interp, argv[3], argl[3], &iStart) ){
+    return TH_ERROR;
+  }
+
+  if( iStart<0 ) iStart = 0;
+  if( iEnd>=argl[2] ) iEnd = argl[2]-1;
+  if( iStart>iEnd ) iEnd = iStart-1;
+
+  return Th_SetResult(interp, &argv[2][iStart], iEnd-iStart+1);
+}
+
+/*
+** TH Syntax:
+**
+**   string repeat STRING COUNT
+*/
+static int string_repeat_command(
+  Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
+){
+  int n;
+  int i;
+  int nByte;
+  uchar *zByte;
+
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "string repeat string n");
+  }
+  if( Th_ToInt(interp, argv[3], argl[3], &n) ){
+    return TH_ERROR;
+  }
+
+  nByte = argl[2] * n;
+  zByte = Th_Malloc(interp, nByte+1);
+  for(i=0; i<nByte; i+=argl[2]){
+    memcpy(&zByte[i], argv[2], argl[2]);
+  }
+
+  Th_SetResult(interp, zByte, nByte);
+  Th_Free(interp, zByte);
+  return TH_OK;
+}
+
+/*
+** TH Syntax:
+**
+**   info exists VAR
+*/
+static int info_exists_command(
+  Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
+){
+  int rc;
+
+  if( argc!=3 ){
+    return Th_WrongNumArgs(interp, "info exists var");
+  }
+  rc = Th_GetVar(interp, argv[2], argl[2]);
+  Th_SetResultInt(interp, rc?0:1);
+  return TH_OK;
+}
+
+/*
+** TH Syntax:
+**
+**   unset VAR
+*/
+static int unset_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  if( argc!=2 ){
+    return Th_WrongNumArgs(interp, "unset var");
+  }
+  return Th_UnsetVar(interp, argv[1], argl[1]);
+}
+
+int Th_CallSubCommand(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl,
+  Th_SubCommand *aSub
+){
+  int i;
+  for(i=0; aSub[i].zName; i++){
+    uchar *zName = (uchar *)aSub[i].zName;
+    if( th_strlen(zName)==argl[1] && 0==memcmp(zName, argv[1], argl[1]) ){
+      return aSub[i].xProc(interp, ctx, argc, argv, argl);
+    }
+  }
+
+  Th_ErrorMessage(interp, "Expected sub-command, got:", argv[1], argl[1]);
+  return TH_ERROR;
+}
+
+/*
+** TH Syntax:
+**
+**   string compare STR1 STR2
+**   string first   NEEDLE HAYSTACK ?STARTINDEX?
+**   string is      CLASS STRING
+**   string last    NEEDLE HAYSTACK ?STARTINDEX?
+**   string length  STRING
+**   string range   STRING FIRST LAST
+**   string repeat  STRING COUNT
+*/
+static int string_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  Th_SubCommand aSub[] = {
+    { "compare", string_compare_command },
+    { "first",   string_first_command },
+    { "is",      string_is_command },
+    { "last",    string_last_command },
+    { "length",  string_length_command },
+    { "range",   string_range_command },
+    { "repeat",  string_repeat_command },
+    { 0, 0 }
+  };
+  return Th_CallSubCommand(interp, ctx, argc, argv, argl, aSub);
+}
+
+/*
+** TH Syntax:
+**
+**   info exists VARNAME
+*/
+static int info_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  Th_SubCommand aSub[] = {
+    { "exists",  info_exists_command },
+    { 0, 0 }
+  };
+  return Th_CallSubCommand(interp, ctx, argc, argv, argl, aSub);
+}
+
+/*
+** Convert the script level frame specification (used by the commands
+** [uplevel] and [upvar]) in (zFrame, nFrame) to an integer frame as
+** used by Th_LinkVar() and Th_Eval(). If successful, write the integer
+** frame level to *piFrame and return TH_OK. Otherwise, return TH_ERROR
+** and leave an error message in the interpreter result.
+*/
+static int thToFrame(
+  Th_Interp *interp,
+  const uchar *zFrame,
+  int nFrame,
+  int *piFrame
+){
+  int iFrame;
+  if( th_isdigit(zFrame[0]) ){
+    int rc = Th_ToInt(interp, zFrame, nFrame, &iFrame);
+    if( rc!=TH_OK ) return rc;
+    iFrame = iFrame * -1;
+  }else if( zFrame[0]=='#' ){
+    int rc = Th_ToInt(interp, &zFrame[1], nFrame-1, &iFrame);
+    if( rc!=TH_OK ) return rc;
+    iFrame = iFrame + 1;
+  }else{
+    return TH_ERROR;
+  }
+  *piFrame = iFrame;
+  return TH_OK;
+}
+
+/*
+** TH Syntax:
+**
+**   uplevel ?LEVEL? SCRIPT
+*/
+static int uplevel_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int iFrame = -1;
+
+  if( argc!=2 && argc!=3 ){
+    return Th_WrongNumArgs(interp, "uplevel ?level? script...");
+  }
+  if( argc==3 && TH_OK!=thToFrame(interp, argv[1], argl[1], &iFrame) ){
+    return TH_ERROR;
+  }
+  return Th_Eval(interp, iFrame, argv[argc-1], -1);
+}
+
+/*
+** TH Syntax:
+**
+**   upvar ?FRAME? OTHERVAR MYVAR ?OTHERVAR MYVAR ...?
+*/
+static int upvar_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int iVar = 1;
+  int iFrame = -1;
+  int rc = TH_OK;
+  int i;
+
+  if( TH_OK==thToFrame(0, argv[1], argl[1], &iFrame) ){
+    iVar++;
+  }
+  if( argc==iVar || (argc-iVar)%2 ){
+    return Th_WrongNumArgs(interp,
+        "upvar frame othervar myvar ?othervar myvar...?");
+  }
+  for(i=iVar; rc==TH_OK && i<argc; i=i+2){
+    rc = Th_LinkVar(interp, argv[i+1], argl[i+1], iFrame, argv[i], argl[i]);
+  }
+  return rc;
+}
+
+/*
+** TH Syntax:
+**
+**   breakpoint ARGS
+**
+** This command does nothing at all. Its purpose in life is to serve
+** as a point for setting breakpoints in a debugger.
+*/
+static int breakpoint_command(
+  Th_Interp *interp,
+  void *ctx,
+  int argc,
+  const uchar **argv,
+  int *argl
+){
+  int cnt = 0;
+  cnt++;
+  return TH_OK;
+}
+
+/*
+** Register the built-in th1 language commands with interpreter interp.
+** Usually this is called soon after interpreter creation.
+*/
+int th_register_language(Th_Interp *interp){
+  /* Array of built-in commands. */
+  struct _Command {
+    const char *zName;
+    Th_CommandProc xProc;
+    void *pContext;
+  } aCommand[] = {
+    {"catch",    catch_command,   0},
+    {"expr",     expr_command,    0},
+    {"for",      for_command,     0},
+    {"if",       if_command,      0},
+    {"info",     info_command,    0},
+    {"lindex",   lindex_command,  0},
+    {"list",     list_command,    0},
+    {"llength",  llength_command, 0},
+    {"proc",     proc_command,    0},
+    {"rename",   rename_command,  0},
+    {"set",      set_command,     0},
+    {"string",   string_command,  0},
+    {"unset",    unset_command,   0},
+    {"uplevel",  uplevel_command, 0},
+    {"upvar",    upvar_command,   0},
+
+    {"breakpoint", breakpoint_command, 0},
+
+    {"return",   return_command, 0},
+    {"break",    simple_command, (void *)TH_BREAK},
+    {"continue", simple_command, (void *)TH_CONTINUE},
+    {"error",    simple_command, (void *)TH_ERROR},
+
+    {0, 0}
+  };
+  int i;
+
+  /* Add the language commands. */
+  for(i=0; i<(sizeof(aCommand)/sizeof(aCommand[0])); i++){
+    void *ctx = aCommand[i].pContext;
+    Th_CreateCommand(interp, aCommand[i].zName, aCommand[i].xProc, ctx, 0);
+  }
+
+  return TH_OK;
+}

Added src/th_main.c version [7258c955ba]

@@ -1,1 +1,428 @@
+/*
+** Copyright (c) 2008 D. Richard Hipp
+**
+** This program is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public
+** License version 2 as published by the Free Software Foundation.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+** General Public License for more details.
+**
+** You should have received a copy of the GNU General Public
+** License along with this library; if not, write to the
+** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+** Boston, MA  02111-1307, USA.
+**
+** Author contact information:
+**   drh@hwaci.com
+**   http://www.hwaci.com/drh/
+**
+*******************************************************************************
+**
+** This file contains an interface between the TH scripting language
+** (an independent project) and fossil.
+*/
+#include "config.h"
+#include "th_main.h"
+
+/*
+** Global variable counting the number of outstanding calls to malloc()
+** made by the th1 implementation. This is used to catch memory leaks
+** in the interpreter. Obviously, it also means th1 is not threadsafe.
+*/
+static int nOutstandingMalloc = 0;
+
+/*
+** Implementations of malloc() and free() to pass to the interpreter.
+*/
+static void *xMalloc(unsigned int n){
+  void *p = malloc(n);
+  if( p ){
+    nOutstandingMalloc++;
+  }
+  return p;
+}
+static void xFree(void *p){
+  if( p ){
+    nOutstandingMalloc--;
+  }
+  free(p);
+}
+static Th_Vtab vtab = { xMalloc, xFree };
+
+
+/*
+** True if output is enabled.  False if disabled.
+*/
+static int enableOutput = 1;
+
+/*
+** TH command:     enable_output BOOLEAN
+**
+** Enable or disable the puts and hputs commands.
+*/
+static int enableOutputCmd(
+  Th_Interp *interp,
+  void *p,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  if( argc!=2 ){
+    return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
+  }
+  return Th_ToInt(interp, argv[1], argl[1], &enableOutput);
+}
+
+/*
+** Send text to the appropriate output:  Either to the console
+** or to the CGI reply buffer.
+*/
+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);
+  }
+}
+
+/*
+** TH command:     puts STRING
+** TH command:     html STRING
+**
+** Output STRING as HTML (html) or unchanged (puts).
+*/
+static int putsCmd(
+  Th_Interp *interp,
+  void *pConvert,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  if( argc!=2 ){
+    return Th_WrongNumArgs(interp, "puts STRING");
+  }
+  sendText((char*)argv[1], argl[1], pConvert!=0);
+  return TH_OK;
+}
+
+/*
+** TH command:      wiki STRING
+**
+** Render the input string as wiki.
+*/
+static int wikiCmd(
+  Th_Interp *interp,
+  void *p,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  if( argc!=2 ){
+    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;
+}
+
+/*
+** TH1 command:  combobox NAME TEXT-LIST NUMLINES
+**
+** Generate an HTML combobox.  NAME is both the name of the
+** CGI parameter and the name of a variable that contains the
+** currently selected value.  TEXT-LIST is a list of possible
+** values for the combobox.  NUMLINES is 1 for a true combobox.
+** If NUMLINES is greater than one then the display is a listbox
+** with the number of lines given.
+*/
+static int comboboxCmd(
+  Th_Interp *interp,
+  void *p,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES");
+  }
+  if( enableOutput ){
+    int height;
+    Blob list, elem, name;
+    int nValue;
+    const char *zValue;
+    char *z, *zH;
+
+    if( Th_ToInt(interp, argv[3], argl[3], &height) ) return TH_ERROR;
+    blob_init(&list, (char*)argv[2], argl[2]);
+    blob_init(&name, (char*)argv[1], argl[1]);
+    zValue = Th_Fetch(blob_str(&name), &nValue);
+    z = mprintf("<select name=\"%z\" size=\"%d\">",
+                 htmlize(blob_buffer(&name), blob_size(&name)), height);
+    sendText(z, -1, 0);
+    free(z);
+    blob_reset(&name);
+    while( blob_token(&list, &elem) ){
+      zH = htmlize(blob_buffer(&elem), blob_size(&elem));
+      if( zValue && blob_size(&elem)==nValue
+             && memcmp(zValue, blob_buffer(&elem), nValue)==0 ){
+        z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH);
+      }else{
+        z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
+      }
+      free(zH);
+      sendText(z, -1, 0);
+      free(z);
+    }
+    sendText("</select>", -1, 0);
+    blob_reset(&list);
+  }
+  return TH_OK;
+}
+
+/*
+** TH1 command:     linecount STRING MAX MIN
+**
+** Return one more than the number of \n characters in STRING.  But
+** never return less than MIN or more than MAX.
+*/
+static int linecntCmd(
+  Th_Interp *interp,
+  void *p,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  const uchar *z;
+  int size, n, i;
+  int iMin, iMax;
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "linecount STRING MAX MIN");
+  }
+  if( Th_ToInt(interp, argv[2], argl[2], &iMax) ) return TH_ERROR;
+  if( Th_ToInt(interp, argv[3], argl[3], &iMin) ) return TH_ERROR;
+  z = argv[1];
+  size = argl[1];
+  for(n=1, i=0; i<size; i++){
+    if( z[i]=='\n' ){
+      n++;
+      if( n>=iMax ) break;
+    }
+  }
+  if( n<iMin ) n = iMin;
+  if( n>iMax ) n = iMax;
+  Th_SetResultInt(interp, n);
+  return TH_OK;
+}
+
+/*
+** Make sure the interpreter has been initialized.
+*/
+void Th_FossilInit(void){
+  static struct _Command {
+    const char *zName;
+    Th_CommandProc xProc;
+    void *pContext;
+  } aCommand[] = {
+    {"combobox",      comboboxCmd,          0},
+    {"enable_output", enableOutputCmd,      0},
+    {"linecount",     linecntCmd,           0},
+    {"hascap",        hascapCmd,            0},
+    {"html",          putsCmd,              0},
+    {"puts",          putsCmd,       (void*)1},
+    {"wiki",          wikiCmd,              0},
+  };
+  if( g.interp==0 ){
+    int i;
+    g.interp = Th_CreateInterp(&vtab);
+    th_register_language(g.interp);       /* Basic scripting commands. */
+    for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
+      Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
+                       aCommand[i].pContext, 0);
+    }
+  }
+}
+
+/*
+** Store a string value in a variable in the interpreter.
+*/
+void Th_Store(const char *zName, const char *zValue){
+  Th_FossilInit();
+  Th_SetVar(g.interp, (uchar*)zName, -1, (uchar*)zValue, strlen(zValue));
+}
+
+/*
+** Retrieve a string value from the interpreter.  If no such
+** variable exists, return NULL.
+*/
+char *Th_Fetch(const char *zName, int *pSize){
+  int rc;
+  Th_FossilInit();
+  rc = Th_GetVar(g.interp, (uchar*)zName, -1);
+  if( rc==TH_OK ){
+    return (char*)Th_GetResult(g.interp, pSize);
+  }else{
+    return 0;
+  }
+}
+
+/*
+** Return true if the string begins with the TH1 begin-script
+** tag:  <th1>.
+*/
+static int isBeginScriptTag(const char *z){
+  return z[0]=='<'
+      && (z[1]=='t' || z[1]=='T')
+      && (z[2]=='h' || z[2]=='H')
+      && z[3]=='1'
+      && z[4]=='>';
+}
+
+/*
+** Return true if the string begins with the TH1 end-script
+** tag:  </th1>.
+*/
+static int isEndScriptTag(const char *z){
+  return z[0]=='<'
+      && z[1]=='/'
+      && (z[2]=='t' || z[2]=='T')
+      && (z[3]=='h' || z[3]=='H')
+      && z[4]=='1'
+      && z[5]=='>';
+}
+
+/*
+** If string z[0...] contains a valid variable name, return
+** 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;
+  }else if( isalpha(z[0]) ){
+    z ++;
+    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>.
+** 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;
+  int rc = TH_OK;
+  uchar *zResult;
+  Th_FossilInit();
+  while( z[i] ){
+    if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
+      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(g.interp, (uchar*)zVar, nVar);
+      z += i+1+n;
+      i = 0;
+      zResult = (uchar*)Th_GetResult(g.interp, &n);
+      sendText((char*)zResult, n, n>nVar);
+    }else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
+      sendText(z, i, 0);
+      z += i+5;
+      for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
+      rc = Th_Eval(g.interp, 0, (const uchar*)z, i);
+      if( rc!=TH_OK ) break;
+      z += i;
+      if( z[0] ){ z += 6; }
+      i = 0;
+    }else{
+      i++;
+    }
+  }
+  if( rc==TH_ERROR ){
+    sendText("<hr><p><font color=\"red\"><b>ERROR: ", -1, 0);
+    zResult = (uchar*)Th_GetResult(g.interp, &n);
+    sendText((char*)zResult, n, 1);
+    sendText("</b></font></p>", -1, 0);
+  }else{
+    sendText(z, i, 0);
+  }
+  return rc;
+}
 
+/*
+** COMMAND: test-th-render
+*/
+void test_th_render(void){
+  Blob in;
+  if( g.argc<3 ){
+    usage("FILE");
+  }
+  blob_zero(&in);
+  blob_read_from_file(&in, g.argv[2]);
+  Th_Render(blob_str(&in));
+}

Modified src/timeline.c from [edd15bb80e] to [d21da06aad].

@@ -277,11 +277,11 @@
   if( !g.okHistory &&
       db_exists("SELECT 1 FROM user"
                 " WHERE login='anonymous'"
                 "   AND cap LIKE '%%h%%'") ){
     @ <p><b>Note:</b> You will be able to access <u>much</u> more
-    @ historical information if <a href="%s(g.zTop)/login">login</a>.</p>
+    @ historical information if you <a href="%s(g.zTop)/login">login</a>.</p>
   }
   blob_zero(&sql);
   blob_append(&sql, timeline_query_for_www(), -1);
   if( zType ){
     blob_appendf(&sql, " AND event.type=%Q", zType);

Modified src/tkt.c from [1c6be6341e] to [e7e06add5c].

@@ -37,15 +37,10 @@
 static char **azField = 0;    /* Names of database fields */
 static char **azValue = 0;    /* Original values */
 static char **azAppend = 0;   /* Value to be appended */
 
 /*
-** A subscript interpreter used for processing Tickets.
-*/
-static struct Subscript *pInterp = 0;
-
-/*
 ** Compare two entries in azField for sorting purposes
 */
 static int nameCmpr(const void *a, const void *b){
   return strcmp(*(char**)a, *(char**)b);
 }
@@ -121,21 +116,21 @@
         if( strcmp(azField[j],zName)==0 ){
           azValue[j] = mprintf("%s", zVal);
           break;
         }
       }
-      if( SbS_Fetch(pInterp, zName, -1, &size)==0 ){
-        SbS_Store(pInterp, db_column_name(&q,i), zVal, 1);
+      if( Th_Fetch(zName, &size)==0 ){
+        Th_Store(db_column_name(&q,i), zVal);
       }
     }
   }else{
     db_finalize(&q);
     db_prepare(&q, "PRAGMA table_info(ticket)");
     while( db_step(&q)==SQLITE_ROW ){
       const char *zField = db_column_text(&q, 1);
-      if( SbS_Fetch(pInterp, zField, -1, &size)==0 ){
-        SbS_Store(pInterp, zField, "", 0);
+      if( Th_Fetch(zField, &size)==0 ){
+        Th_Store(zField, "");
       }
     }
   }
   db_finalize(&q);
 }
@@ -146,11 +141,11 @@
 static void initializeVariablesFromCGI(void){
   int i;
   const char *z;
 
   for(i=0; (z = cgi_parameter_name(i))!=0; i++){
-    SbS_Store(pInterp, z, P(z), 0);
+    Th_Store(z, P(z));
   }
 }
 
 /*
 ** Rebuild all tickets named in the _pending_ticket table.
@@ -254,15 +249,14 @@
 /*
 ** Create the subscript interpreter and load the ticket configuration.
 */
 void ticket_init(void){
   char *zConfig;
-  if( pInterp ) return;
-  pInterp = SbS_Create();
+  Th_FossilInit();
   zConfig = db_text((char*)zDefaultTicketConfig,
              "SELECT value FROM config WHERE name='ticket-configuration'");
-  SbS_Eval(pInterp, zConfig, -1);
+  Th_Eval(g.interp, 0, (const uchar*)zConfig, -1);
 }
 
 /*
 ** Recreate the ticket table.
 */
@@ -270,11 +264,11 @@
   char *zSql;
   int nSql;
 
   db_multi_exec("DROP TABLE IF EXISTS ticket;");
   ticket_init();
-  zSql = (char*)SbS_Fetch(pInterp, "ticket_sql", -1, &nSql);
+  zSql = (char*)Th_Fetch("ticket_sql", &nSql);
   if( zSql==0 ){
     fossil_panic("no ticket_sql defined by ticket configuration");
   }
   if( separateConnection ){
     zSql = mprintf("%.*s", nSql, zSql);
@@ -319,54 +313,62 @@
         g.zTop, PD("name",""));
   }
   style_header("View Ticket");
   ticket_init();
   initializeVariablesFromDb();
-  zScript = (char*)SbS_Fetch(pInterp, "tktview_template", -1, &nScript);
+  zScript = (char*)Th_Fetch("tktview_template", &nScript);
   zScript = mprintf("%.*s", nScript, zScript);
-  SbS_Render(pInterp, zScript);
+  Th_Render(zScript);
   style_footer();
 }
 
-
-
 /*
-** Subscript command:   STRING FIELD append_field
+** TH command:   append_field FIELD STRING
 **
 ** FIELD is the name of a database column to which we might want
 ** to append text.  STRING is the text to be appended to that
 ** column.  The append does not actually occur until the
-** submit_ticket_change verb is run.
+** submit_ticket command is run.
 */
-static int appendRemarkCmd(struct Subscript *p, void *notUsed){
-  int idx;
-  const char *zField, *zValue;
-  int nField, nValue;
+static int appendRemarkCmd(
+  Th_Interp *interp,
+  void *p,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  int idx;
 
-  if( SbS_RequireStack(p, 2, "append_field") ) return 1;
-  zField = SbS_StackValue(p, 0, &nField);
+  if( argc!=3 ){
+    return Th_WrongNumArgs(interp, "append_field FIELD STRING");
+  }
   for(idx=0; idx<nField; idx++){
-    if( strncmp(azField[idx], zField, nField)==0 && azField[idx][nField]==0 ){
+    if( strncmp(azField[idx], (const char*)argv[1], argl[1])==0
+        && azField[idx][argl[1]]==0 ){
       break;
     }
   }
   if( idx>=nField ){
-    SbS_SetErrorMessage(p, "no such TICKET column: %.*s", nField, zField);
-    return SBS_ERROR;
-  }
-  zValue = SbS_StackValue(p, 1, &nValue);
-  azAppend[idx] = mprintf("%.*s", nValue, zValue);
-  SbS_Pop(p, 2);
-  return SBS_OK;
+    Th_ErrorMessage(g.interp, "no such TICKET column: ", argv[1], argl[1]);
+    return TH_ERROR;
+  }
+  azAppend[idx] = mprintf("%.*s", argl[2], argv[2]);
+  return TH_OK;
 }
 
 /*
 ** Subscript command:   submit_ticket
 **
 ** Construct and submit a new ticket artifact.
 */
-static int submitTicketCmd(struct Subscript *p, void *pUuid){
+static int submitTicketCmd(
+  Th_Interp *interp,
+  void *pUuid,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
   char *zDate;
   const char *zUuid;
   int i;
   int rid;
   Blob tktchng, cksum;
@@ -382,11 +384,11 @@
     int nValue;
     if( azAppend[i] ){
       blob_appendf(&tktchng, "J +%s %z\n", azField[i],
                    fossilize(azAppend[i], -1));
     }else{
-      zValue = SbS_Fetch(p, azField[i], -1, &nValue);
+      zValue = Th_Fetch(azField[i], &nValue);
       if( zValue ){
         while( nValue>0 && isspace(zValue[nValue-1]) ){ nValue--; }
         if( strncmp(zValue, azValue[i], nValue)
                 || strlen(azValue[i])!=nValue ){
           blob_appendf(&tktchng, "J %s %z\n",
@@ -411,20 +413,19 @@
   if( strncmp(g.zPath,"debug_",6)==0 ){
     @ <hr><pre>
     @ %h(blob_str(&tktchng))
     @ </pre><hr>
     blob_zero(&tktchng);
-    SbS_Pop(p, 1);
-    return SBS_OK;
+    return TH_OK;
   }
 
   rid = content_put(&tktchng, 0, 0);
   if( rid==0 ){
     fossil_panic("trouble committing ticket: %s", g.zErrMsg);
   }
   manifest_crosslink(rid, &tktchng);
-  return SBS_RETURN;
+  return TH_RETURN;
 }
 
 
 /*
 ** WEBPAGE: tktnew
@@ -446,18 +447,20 @@
   login_check_credentials();
   if( !g.okNewTkt ){ login_needed(); return; }
   style_header("New Ticket");
   ticket_init();
   getAllTicketFields();
+  initializeVariablesFromDb();
   initializeVariablesFromCGI();
   @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
-  zScript = (char*)SbS_Fetch(pInterp, "tktnew_template", -1, &nScript);
+  zScript = (char*)Th_Fetch("tktnew_template", &nScript);
   zScript = mprintf("%.*s", nScript, zScript);
-  SbS_Store(pInterp, "login", g.zLogin, 0);
-  SbS_Store(pInterp, "date", db_text(0, "SELECT datetime('now')"), 2);
-  SbS_AddVerb(pInterp, "submit_ticket", submitTicketCmd, (void*)&zNewUuid);
-  if( SbS_Render(pInterp, zScript)==SBS_RETURN && zNewUuid ){
+  Th_Store("login", g.zLogin);
+  Th_Store("date", db_text(0, "SELECT datetime('now')"));
+  Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
+                   (void*)&zNewUuid, 0);
+  if( Th_Render(zScript)==TH_RETURN && zNewUuid ){
     cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zNewUuid));
     return;
   }
   @ </form>
   style_footer();
@@ -507,17 +510,17 @@
   getAllTicketFields();
   initializeVariablesFromCGI();
   initializeVariablesFromDb();
   @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
   @ <input type="hidden" name="name" value="%s(zName)">
-  zScript = (char*)SbS_Fetch(pInterp, "tktedit_template", -1, &nScript);
+  zScript = (char*)Th_Fetch("tktedit_template", &nScript);
   zScript = mprintf("%.*s", nScript, zScript);
-  SbS_Store(pInterp, "login", g.zLogin, 0);
-  SbS_Store(pInterp, "date", db_text(0, "SELECT datetime('now')"), 2);
-  SbS_AddVerb(pInterp, "append_field", appendRemarkCmd, 0);
-  SbS_AddVerb(pInterp, "submit_ticket", submitTicketCmd, (void*)&zName);
-  if( SbS_Render(pInterp, zScript)==SBS_RETURN && zName ){
+  Th_Store("login", g.zLogin);
+  Th_Store("date", db_text(0, "SELECT datetime('now')"));
+  Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
+  Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
+  if( Th_Render(zScript)==TH_RETURN && zName ){
     cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zName));
     return;
   }
   @ </form>
   style_footer();
@@ -528,11 +531,10 @@
 ** be well-formed.  If everything is OK, return NULL.  If something is
 ** amiss, then return a pointer to a string (obtained from malloc) that
 ** describes the problem.
 */
 char *ticket_config_check(const char *zConfig){
-  struct Subscript *p;
   char *zErr = 0;
   const char *z;
   int n;
   int i;
   int rc;
@@ -541,41 +543,36 @@
      "tktnew_template",
      "tktview_template",
      "tktedit_template",
   };
 
-  p = SbS_Create();
-  rc = SbS_Eval(p, zConfig, strlen(zConfig));
-  if( rc!=SBS_OK ){
-    zErr = mprintf("%s", SbS_GetErrorMessage(p));
-    SbS_Destroy(p);
+  Th_FossilInit();
+  rc = Th_Eval(g.interp, 0, (const uchar*)zConfig, strlen(zConfig));
+  if( rc!=TH_OK ){
+    zErr = (char*)Th_TakeResult(g.interp, 0);
     return zErr;
   }
   for(i=0; i<sizeof(azRequired)/sizeof(azRequired[0]); i++){
-    z = SbS_Fetch(p, azRequired[i], -1, &n);
+    z = Th_Fetch(azRequired[i], &n);
     if( z==0 ){
       zErr = mprintf("missing definition: %s", azRequired[i]);
-      SbS_Destroy(p);
       return zErr;
     }
   }
-  z = SbS_Fetch(p, "ticket_sql", -1, &n);
+  z = Th_Fetch("ticket_sql", &n);
   if( z==0 ){
     zErr = mprintf("missing definition: ticket_sql");
-    SbS_Destroy(p);
     return zErr;
   }
   rc = sqlite3_open(":memory:", &db);
   if( rc==SQLITE_OK ){
     char *zSql = mprintf("%.*s", n, z);
     rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
     if( rc!=SQLITE_OK ){
       sqlite3_close(db);
-      SbS_Destroy(p);
       return zErr;
     }
     /* TODO: verify that the TICKET table exists and has required fields */
     sqlite3_close(db);
   }
-  SbS_Destroy(p);
   return 0;
 }

Modified src/tktconfig.c from [c567cf64e8] to [9beffaf065].

@@ -33,60 +33,12 @@
 ** There is considerable flexibility in how tickets are defined
 ** in fossil.  Each repository can define its own ticket setup
 ** differently.  Each repository has an instance of a file, like
 ** this one that defines how that repository deals with tickets.
 **
-** This file is in the form of a script in an exceedingly
-** minimalist scripting language called "subscript".  Here are
-** the rules:
-**
-** SYNTAX
-**
-**     *  The script consists of a sequence of whitespace
-**        separated tokens.  Whitespace is ignored, except
-**        as its role as a token separator.
-**
-**     *  Lines that begin with '#' are considered to be whitespace.
-**
-**     *  Text within matching {...} is consider to be a single "string"
-**        token, even if the text spans multiple lines and includes
-**        embedded whitespace.  The outermost {...} are not part of
-**        the text of the token.
-**
-**     *  A token that begins with "/" is a string token.
-**
-**     *  A token that looks like a number is a string token.
-**
-**     *  Tokens that do not fall under the previous three rules
-**        are "verb" tokens.
-**
-**  PROCESSING:
-**
-**     *  When a script is processed, the engine reads tokens
-**        one by one.
-**
-**     *  String tokens are pushed onto the stack.
-**
-**     *  Verb tokens which correspond to the names of variables
-**        cause the corresponding variable to be pushed onto the
-**        stack.
-**
-**     *  Verb tokens which correspond to procedures cause the
-**        procedures to run.  The procedures might push or pull
-**        values from the stack.
-**
-** There are just a handful of verbs.  For the purposes of this
-** configuration script, there is only a single verb: "set".  The
-** "set" verb pops two arguments from the stack.  The topmost is
-** the name of a variable.  The second element is the value.  The
-** "set" verb sets the value of the named variable.
-**
-**      VALUE NAME set
-**
-** This configuration file just sets the values of various variables.
-** Some of the variables have special meanings.  The content of some
-** of the variables are additional subscript scripts.
+** This file is in the form of a script in TH1 - a minimalist
+** TCL clone.
 */
 
 /* @-comment: ** */
 const char zDefaultTicketConfig[] =
 @ ############################################################################
@@ -95,11 +47,11 @@
 @ # tkt_id, tkt_uuid, and tkt_mtime.  tkt_id must be the integer primary
 @ # key and tkt_uuid and tkt_mtime must be unique.  A configuration should
 @ # define addition columns as necessary.  All columns should be in all
 @ # lower-case letters and should not begin with "tkt".
 @ #
-@ {
+@ set ticket_sql {
 @    CREATE TABLE ticket(
 @      -- Do not change any column that begins with tkt_
 @      tkt_id INTEGER PRIMARY KEY,
 @      tkt_uuid TEXT,
 @      tkt_mtime DATE,
@@ -109,32 +61,33 @@
 @      subsystem TEXT,
 @      priority TEXT,
 @      severity TEXT,
 @      foundin TEXT,
 @      contact TEXT,
+@      resolution TEXT,
 @      title TEXT,
 @      comment TEXT,
 @      -- Do not alter this UNIQUE clause:
 @      UNIQUE(tkt_uuid, tkt_mtime)
 @    );
 @    -- Add indices as desired
-@ } /ticket_sql set
+@ }
 @
 @ ############################################################################
 @ # You can define additional variables here.  These variables will be
 @ # accessible to the page templates when they run.
 @ #
-@ {
+@ set type_choices {
 @    Code_Defect
 @    Build_Problem
 @    Documentation
 @    Feature_Request
 @    Incident
-@ } /type_choices set
-@ {Immediate High Medium Low Zero} /priority_choices set
-@ {Critical Severe Important Minor Cosmetic} /severity_choices set
-@ {
+@ }
+@ set priority_choices {Immediate High Medium Low Zero}
+@ set severity_choices {Critical Severe Important Minor Cosmetic}
+@ set resolution_choices {
 @   Open
 @   Fixed
 @   Rejected
 @   Unable_To_Reproduce
 @   Works_As_Designed
@@ -141,68 +94,70 @@
 @   External_Bug
 @   Not_A_Bug
 @   Duplicate
 @   Overcome_By_Events
 @   Drive_By_Patch
-@ } /resolution_choices set
-@ {
+@ }
+@ set status_choices {
 @   Open
 @   Verified
 @   In_Process
 @   Deferred
 @   Fixed
 @   Tested
 @   Closed
-@ } /status_choices set
-@ {one two three} /subsystem_choices set
+@ }
+@ set subsystem_choices {one two three}
 @
 @ ##########################################################################
 @ # The "tktnew_template" variable is set to text which is a template for
 @ # the HTML of the "New Ticket" page.  Within this template, text contained
 @ # within [...] is subscript.  That subscript runs when the page is
 @ # rendered.
 @ #
-@ {
+@ set tktnew_template {
 @   <!-- load database field names not found in CGI with an empty string -->
 @   <!-- start a form -->
-@   [{
-@      {Open} /status set
-@       submit_ticket
-@   } /submit exists if]
+@   <th1>
+@     if {[info exists submit]} {
+@        set status Open
+@        submit_ticket
+@     }
+@   </th1>
 @   <table cellpadding="5">
 @   <tr>
 @   <td colspan="2">
 @   Enter a one-line summary of the problem:<br>
-@   <input type="text" name="title" size="60" value="[{} /title get html]">
+@   <input type="text" name="title" size="60" value="$<title>">
 @   </td>
 @   </tr>
 @
 @   <tr>
 @   <td align="right">Type:
-@   [/type type_choices 1 combobox]
+@   <th1>combobox type $type_choices 1</th1>
 @   </td>
 @   <td>What type of ticket is this?</td>
 @   </tr>
 @
 @   <tr>
 @   <td align="right">Version:
-@   <input type="text" name="foundin" size="20" value="[{} /foundin get html]">
+@   <input type="text" name="foundin" size="20" value="$<foundin>">
 @   </td>
 @   <td>In what version or build number do you observer the problem?</td>
 @   </tr>
 @
 @   <tr>
 @   <td align="right">Severity:
-@   [/severity severity_choices 1 combobox]
+@   <th1>combobox severity $severity_choices 1</th1>
 @   </td>
 @   <td>How debilitating is the problem?  How badly does the problem
 @   effect the operation of the product?</td>
 @   </tr>
 @
 @   <tr>
 @   <td align="right">EMail:
-@   <input type="text" name="contact" value="[{} /contact get html]" size="30">
+@   <input type="text" name="contact" value="$<contact>" size="30">
 @   </td>
 @   <td>Not publically visible. Used by developers to contact you with
 @   questions.</td>
 @   </tr>
 @
@@ -211,23 +166,23 @@
 @   Enter a detailed description of the problem.
 @   For code defects, be sure to provide details on exactly how
 @   the problem can be reproduced.  Provide as much detail as
 @   possible.
 @   <br>
-@   <textarea name="comment" cols="80"
-@    rows="[{} /comment get linecount 50 max 10 min html]"
-@    wrap="virtual" class="wikiedit">[{} /comment get html]</textarea><br>
+@   <th1>set nline [linecount $comment 50 10]</th1>
+@   <textarea name="comment" cols="80" rows="$nline"
+@    wrap="virtual" class="wikiedit">$<comment></textarea><br>
 @   <input type="submit" name="preview" value="Preview">
 @   </tr>
 @
-@   [/preview exists enable_output]
+@   <th1>enable_output [info exists preview]</th1>
 @   <tr><td colspan="2">
 @   Description Preview:<br><hr>
-@   [{} /comment get wiki]
+@   <th1>wiki $comment</th1>
 @   <hr>
 @   </td></tr>
-@   [1 enable_output]
+@   <th1>enable_output 1</th1>
 @
 @   <tr>
 @   <td align="right">
 @   <input type="submit" name="submit" value="Submit">
 @   </td>
@@ -234,136 +189,132 @@
 @   <td>After filling in the information above, press this button to create
 @   the new ticket</td>
 @   </tr>
 @   </table>
 @   <!-- end of form -->
-@ } /tktnew_template set
+@ }
 @
 @ ##########################################################################
 @ # The template for the "edit ticket" page
 @ #
 @ # Then generated text is inserted inside a form which feeds back to itself.
 @ # All CGI parameters are loaded into variables.  All database files are
 @ # loaded into variables if they have not previously been loaded by
 @ # CGI parameters.
-@ {
-@   [
-@     login /username get /username set
-@     {
-@       {
-@         username login eq /samename set
-@         {
-@            "\n\n<hr><i>" login " added on " date ":</i><br>\n"
-@            cmappnd 6 concat /comment append_field
-@         } samename if
-@         {
-@            "\n\n<hr><i>" login " claiming to be " username " added on " date
-@            "</i><br>\n" cmappnd 8 concat /comment append_field
-@         } samename not if
-@       } 0 {} /cmappnd get length lt if
+@ set tktedit_template {
+@   <th1>
+@     if {![info exists username]} {set username $login}
+@     if {[info exists submit]} {
+@       if {[info exists $cmappnd] && [string length $cmappnd]>0} {
+@         set ctxt "\n\n<hr><i>"
+@         if {$username==$login} {
+@           set usr "$ctxt[htmlize $login]"
+@         } else {
+@           set usr "[htmlize $login claimingn to be [htmlize $username]"
+@         }
+@         append_field comment \
+@            "\n\n<hr><i>$usr added on [date]:</i><br>\n$comment"
+@       }
 @       submit_ticket
-@     } /submit exists if
-@   ]
+@     }
+@   </th1>
 @   <table cellpadding="5">
 @   <tr><td align="right">Title:</td><td>
-@   <input type="text" name="title" value="[title html]" size="60">
+@   <input type="text" name="title" value="$<title>" size="60">
 @   </td></tr>
 @   <tr><td align="right">Status:</td><td>
-@   [/status status_choices 1 combobox]
+@   <th1>combobox status $status_choices 1</th1>
 @   </td></tr>
 @   <tr><td align="right">Type:</td><td>
-@   [/type type_choices 1 combobox]
+@   <th1>combobox type $type_choices 1</th1>
 @   </td></tr>
 @   <tr><td align="right">Severity:</td><td>
-@   [/severity severity_choices 1 combobox]
+@   <th1>combobox severity $severity_choices 1</th1>
 @   </td></tr>
 @   <tr><td align="right">Priority:</td><td>
-@   [/priority priority_choices 1 combobox]
+@   <th1>combobox priority $priority_choices 1</th1>
 @   </td></tr>
 @   <tr><td align="right">Resolution:</td><td>
-@   [/resolution resolution_choices 1 combobox]
+@   <th1>combobox resolution $resolution_choices 1</th1>
 @   </td></tr>
 @   <tr><td align="right">Subsystem:</td><td>
-@   [/subsystem subsystem_choices 1 combobox]
-@   </td></tr>
-@   [/e hascap enable_output]
+@   <th1>combobox subsystem $subsystem_choices 1</th1>
+@   </td></tr>
+@   <th1>enable_output [hascap e]</th1>
 @     <tr><td align="right">Contact:</td><td>
-@     <input type="text" name="contact" size="40" value="[contact html]">
+@     <input type="text" name="contact" size="40" value="$<contact>">
 @     </td></tr>
-@   [1 enable_output]
+@   <th1>enable_output 1</th1>
 @   <tr><td align="right">Version&nbsp;Found&nbsp;In:</td><td>
-@   <input type="text" name="foundin" size="50" value="[foundin html]">
+@   <input type="text" name="foundin" size="50" value="$<foundin>">
 @   </td></tr>
 @   <tr><td colspan="2">
-@
-@   [
-@      0 /eall get /eall set           # eall means "edit all".  default==no
-@      /aonlybtn exists not /eall set  # Edit all if no aonlybtn CGI param
-@      /eallbtn exists /eall set       # Edit all if eallbtn CGI param
-@      /w hascap eall and /eall set    # WrTkt permission needed to edit all
-@   ]
-@
-@   [eall enable_output]
+@   <th1>
+@     if {![info exists eall]} {set eall 0}
+@     if {[info exists aonlybtn]} {set eall 0}
+@     if {[info exists eallbtn]} {set eall 1}
+@     if {![hascap w]} {set eall 0}
+@     if {![info exists cmappnd]} {set cmappnd {}}
+@     set nline [linecount $comment 15 10]
+@     enable_output $eall
+@   </th1>
 @     Description And Comments:<br>
-@     <textarea name="comment" cols="80"
-@      rows="[{} /comment get linecount 15 max 10 min html]"
-@      wrap="virtual" class="wikiedit">[comment html]</textarea><br>
+@     <textarea name="comment" cols="80" rows="$nline"
+@      wrap="virtual" class="wikiedit">$<comment></textarea><br>
 @     <input type="hidden" name="eall" value="1">
 @     <input type="submit" name="aonlybtn" value="Append Remark">
-@
-@   [eall not enable_output]
+@   <th1>enable_output [expr {!$eall}]</th1>
 @     Append Remark from
-@     <input type="text" name="username" value="[username html]" size="30">:<br>
+@     <input type="text" name="username" value="$<username>" size="30">:<br>
 @     <textarea name="cmappnd" cols="80" rows="15"
-@      wrap="virtual" class="wikiedit">[{} /cmappnd get html]</textarea><br>
-@     [/w hascap eall not and enable_output]
+@      wrap="virtual" class="wikiedit">$<cmappnd></textarea><br>
+@   <th1>enable_output [expr {[hascap w] && !$eall}]</th1>
 @     <input type="submit" name="eallbtn" value="Edit All">
-@
-@   [1 enable_output]
+@   <th1>enable_output 1</th1>
 @   </td></tr>
 @   <tr><td align="right"></td><td>
 @   <input type="submit" name="submit" value="Submit Changes">
 @   </td></tr>
 @   </table>
-@ } /tktedit_template set
+@ }
 @
 @ ##########################################################################
 @ # The template for the "view ticket" page
-@ {
+@ set tktview_template {
 @   <!-- load database fields automatically loaded into variables -->
 @   <table cellpadding="5">
 @   <tr><td align="right">Title:</td><td>
-@   [title html]
+@   $<title>
 @   </td></tr>
 @   <tr><td align="right">Status:</td><td>
-@   [status html]
+@   $<status>
 @   </td></tr>
 @   <tr><td align="right">Type:</td><td>
-@   [type html]
+@   $<type>
 @   </td></tr>
 @   <tr><td align="right">Severity:</td><td>
-@   [severity html]
+@   $<severity>
 @   </td></tr>
 @   <tr><td align="right">Priority:</td><td>
-@   [priority html]
+@   $<priority>
 @   </td></tr>
 @   <tr><td align="right">Resolution:</td><td>
-@   [priority html]
+@   $<resolution>
 @   </td></tr>
 @   <tr><td align="right">Subsystem:</td><td>
-@   [subsystem html]
+@   $<subsystem>
 @   </td></tr>
-@   [{e} hascap enable_output]
+@   <th1>enable_output [hascap e]</th1>
 @     <tr><td align="right">Contact:</td><td>
-@     [contact html]
+@     $<contact>
 @     </td></tr>
-@   [1 enable_output]
+@   <th1>enable_output 1</th1>
 @   <tr><td align="right">Version&nbsp;Found&nbsp;In:</td><td>
-@   [foundin html]
+@   $<foundin>
 @   </td></tr>
 @   <tr><td colspan="2">
 @   Description And Comments:<br>
-@   [comment wiki]
+@   <th1>wiki $comment</th1>
 @   </td></tr>
 @   </table>
-@ } /tktview_template set
+@ }
 ;

Modified src/update.c from [69c9aea1a1] to [70dcd36640].

@@ -67,17 +67,10 @@
     fossil_fatal("cannot find current version");
   }
   if( db_exists("SELECT 1 FROM vmerge") ){
     fossil_fatal("cannot update an uncommitted merge");
   }
-#if 0
-  /* Always do the update.  If it does not work out, the user can back out
-  ** the changes using "undo" */
-  if( !forceFlag && unsaved_changes() ){
-    fossil_fatal("uncommitted changes; use -f or --force to override");
-  }
-#endif
 
   if( g.argc==3 ){
     tid = name_to_rid(g.argv[2]);
     if( tid==0 ){
       fossil_fatal("not a version: %s", g.argv[2]);

Modified src/zip.c from [0e35e8f120] to [8367a41493].

@@ -372,9 +372,10 @@
     @ Not found
     return;
   }
   if( nName>10 ) zName[10] = 0;
   zip_of_baseline(rid, &zip, zName);
+  free( zName );
   cgi_set_content(&zip);
   cgi_set_content_type("application/zip");
   cgi_reply();
 }

Modified www/fileformat.html from [66d0102569] to [40a53b49c4].

@@ -9,11 +9,11 @@
 Fossil File Formats
 </h1>
 
 <p>
 The global state of a fossil repository is determined by an unordered
-set of files.  A file in fossil is called an "artifact".
+set of artifacts.
 An artifact might be a source code file, the text of a wiki page,
 part of a trouble ticket, or one of several special control artifacts
 used to show the relationships between other artifacts within the
 project.  Artifacts can be text or binary.
 </p>

Modified www/index.html from [834da7be86] to [0f4c91fa34].

@@ -18,11 +18,11 @@
 <p>Design Goals For Fossil:</p>
 
 <ul>
 <li>Supports disconnected, distributed development (like
 <a href="http://kerneltrap.org/node/4982">git</a>,
-<a href="http://www.venge.net/monotone/">monotone</a>,
+<a href="http://www.monotone.ca/">monotone</a>,
 <a href="http://www.selenic.com/mercurial/wiki/index.cgi">mercurial</a>, or
 <a href="http://www.bitkeeper.com/">bitkeeper</a>)
 or client/server operation (like
 <a href="http://www.nongnu.org/cvs/">CVS</a> or
 <a href="http://subversion.tigris.org/">subversion</a>)
@@ -95,9 +95,22 @@
 <li>The <a href="sync.html">synchronization protocol</a>.
 <li>There is a <a href="http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users">
     mailing list</a> available for discussing fossil issues.</li>
 <li>The <a href="http://www.fossil-scm.org/fossil/wiki">self-hosting
     fossil wiki</a>.
+</ul>
+
+<p>Competing Projects:</p>
+
+<ul>
+<li><a href="http://www.ditrack.org/">DITrace</a>
+     - A Distributed Issue  Tracker</li>
+<li><a href="http://www.distract.wellquite.org/">DisTract</a>
+     - Another distributed issue tracker based on
+     <a href="http://www.monotone.ca/">monotone</a>.
+<li><a href="http://www.monotone.ca/">Monotone</a> - distributed
+     SCM in a single-file executable with a single-file SQLite
+     database repository.</li>
 </ul>
 
 </body>
 </html>

Modified www/pop.html from [be259767d3] to [f5f93db90a].

@@ -12,12 +12,13 @@
 which Fossil is built.
 </p>
 
 <ul>
 <li><p>A project consists of source files, wiki pages, and
-trouble tickets.  All historical copies of all these
-entities are saved.  The project maintains an audit
+trouble tickets, and control files (collectively "artifacts").
+All historical copies of all artifacts
+are saved.  The project maintains an audit
 trail.</p></li>
 
 <li><p>A project resides in one or more repositories.  Each
 repository is administered and operates independently
 of the others.</p></li>
@@ -30,49 +31,49 @@
 The global state represents the content of the project.
 The local state identifies the authorized users and
 access policies for a particular repository.</p></li>
 
 <li><p>The global state of a repository is an unordered
-collection of files.  Each file is named by
-its SHA1 hash encoded in hexadecimal.
+collection of artifacts.  Each artifact is named by
+its SHA1 hash encoded in lowercase hexadecimal.
 In many contexts, the name can be
 abbreviated to a unique prefix.  A five- or six-character
 prefix usually suffices to uniquely identify a file.</p></li>
 
-<li><p>Because files are named by their SHA1 hash, all files
-are immutable.  Any change to the content of a file also
-changes the hash that forms the files name, thus
-creating a new file.  Both the old original version of the
-file and the new change are preserved under different names.</p></li>
+<li><p>Because artifacts are named by their SHA1 hash, all artifacts
+are immutable.  Any change to the content of a artifact also
+changes the hash that forms the artifacts name, thus
+creating a new artifact.  Both the old original version of the
+artifact and the new change are preserved under different names.</p></li>
 
-<li><p>It is theoretically possible for two files with different
+<li><p>It is theoretically possible for two artifacts with different
 content to share the same hash.  But finding two such
-files is so incredibly difficult and unlikely that we
+artifacts is so incredibly difficult and unlikely that we
 consider it to be an impossibility.</p></li>
 
-<li><p>The signature of a file is the SHA1 hash of the
-file itself, exactly as it appears on disk.  No prefix
-or meta-information about the file is added before computing
+<li><p>The signature of an artifact is the SHA1 hash of the
+artifact itself, exactly as it would appear in a disk file.  No prefix
+or meta-information about the artifact is added before computing
 the hash.  So you can
 always find the SHA1 signature of a file by using the
 "sha1sum" command-line utility.</p></li>
 
-<li><p>The files that comprise the global state of a repository
+<li><p>The artifacts that comprise the global state of a repository
 are the complete global state of that repository.  The SQLite
 database that holds the repository contains additional information
-about linkages between files, but all of that added information
+about linkages between artifacts, but all of that added information
 can be discarded and reconstructed by rescanning the content
-files.</p></li>
+artifacts.</p></li>
 
 <li><p>Two repositories for the same project can synchronize
-their global states simply by sharing files.  The local
+their global states simply by sharing artifacts.  The local
 state of repositories is not normally synchronized or
 shared.</p></li>
 
-<li><p>Every repository has a special file at the top-level
+<li><p>Every baseline has a special file at the top-level
 named "manifest" which is an index of all other files in
-the system.  The manifest is automatically created and
+that baseline.  The manifest is automatically created and
 maintained by the system.</p></li>
 
 <li><p>The <a href="fileformat.html">file formats</a>
 used by Fossil are all very simple so that with access
 to the original content files, one can easily reconstruct